How i can use temporary variables in macros for building code in the Crystal Lang. For examle, i have:
module Rule
macro included
{% rules = [] of TypeDeclaration %}
macro rule(declaration)
raise("Should be TypeDeclaration") unless \{{declaration.is_a?(TypeDeclaration)}}
\{% {{rules}} << declaration %}
end
macro finished
\{% for declaration in rules %}
puts \{{declaration}}
\{% end %}
end
end
end
class StringRule
include Rule
rule min : Int32 = 0
rule max : Int32 = 255
end
And i have compile error
> 6 | {% [] << declaration %}
^
Error: for empty arrays use '[] of ElementType'
I need store all rules for reusing it in a hook finished. Is it posible?
Variables in macro expressions are scoped to the respective macro context. So a variable defined in macro included is not visible in macro rule.
But you can use constants for this: RULES = [] of _. The _ underscore makes the array untyped, it is only to be used during compilation and not for actual code. If you refer to RULES outside a macro expression, the compiler will complain.
module Rule
macro included
RULES = [] of _
macro rule(declaration)
\{% raise("Should be TypeDeclaration") unless declaration.is_a?(TypeDeclaration) %}
\{% RULES << declaration %}
end
macro finished
\{% for declaration in RULES %}
puts \{{ declaration.stringify }}
\{% end %}
end
end
end
class StringRule
include Rule
rule min : Int32 = 0
rule max : Int32 = 255
end
For example, i want to get looks-like-native "for" loop, which was implemented in crystal's embedded macro language, but it is absent (for reasons of principle) in main, "runtime" language:
for i in list do
end
for k, v in hash do
end
(Here "{}" is a simple block. I cant use do .. end syntax here anyway (maybe not)).
Will be very good to implement multi-inlcude directive, such as:
includes MixinX, MixinY, MixinZ
and so on...
As i know, macro (named "for" and "includes" in the provided snippets) can't accept "i in list" without double-quoting. So... is there only one way to do so - extending crystal's syntax/lexical parser and analyzer itself?
Maybe, you could use something like this:
module Foo
def foo
"foo"
end
end
module Bar
def bar
"bar"
end
end
class Object
macro includes(*mods)
{% for mod in mods %}
include {{ mod }}
{% end %}
end
end
class Baz
includes Foo, Bar
end
Baz.new.foo # => "foo"
Baz.new.bar # => "bar"
I love MATLAB "smart indenting". Ctrl-A, Ctrl-I is hardwired with me. However, in my some-3000-lines script, I have one section of about 100 lines of code which I would like not to be touched by MATLAB.
(Why, you ask? That's why:
x = ...
aaaaaaaaaaaaaaaaa ...
- ...
( ...
bbbbbbbbbbbbbb ...
+ ...
cccccccccccccccccccccc ...
);
That's my way of encoding that this is a difference of two things, one of which is aaaaaaaaaaaaaaaaa, the other being a set of parentheses, ... etc etc.
So, how can I teach MATLAB to not re-indent this part?
You can use the %{ and %} for comment block:
a = 3;
b = 5;
%{
some other code to be ignored
%}
and if you want to toggle this ON, all you need is one more % in the right place:
a = 3;
b = 5;
%%{
some other code to be ignored
%}
I am trying to write recursive anonymous function, so far what works for me is to use the Y combinator.
%{ Call lambda function with any number of arguments. %}
call_ = #feval;
%{ Internal subroutine for function IF_. %}
if__ = #(varargin) varargin{3 - varargin{1}}();
%{ If predicate PRED is true, evaluate thunk IF_CLAUSE. %}
% { Otherwise, evaluate thunk ELSE_CLAUSE. %}
if_ = #(pred, if_clause, else_clause) if__(pred, if_clause, else_clause);
%{ Determine if X is a cell array. %}
is_cell_ = #(x) isa(x, 'cell');
%{ Call function FUNC with elements in argument list ARG_LS as arguments. %}
apply_ = #(func, arg_ls) if_(is_cell_(arg_ls), ...
#() func(arg_ls{:}), ...
#() func(arg_ls(:)));
%{ Compute a fixed point for the function H. %}
Y_ = #(h) call_(#(x) x(x), #(g) h(#(varargin) apply_(g(g), varargin)));
So, for example, to define factorial, we can use the Y combinator:
make_fact__ = #(f) #(n, accum) if_(n == 0, #() accum, #() f(n - 1, n * accum))
fact__ = Y_(make_fact__)
fact_ = #(n) fact__(n, 1)
fact_(5)
Note the factorial defined above is tail recursive. Is there anyway to optimize the tail call, so that the tail recursive function won't blow the stack for large N?
Searching the internet gives me the equivalent question in Python (Does Python optimize tail recursion?), but I can't really make it work in Octave/Matlab, using only anonymous function.
I have also found some articles about trampoline, again I find it difficult to implement try-catch using only anonymous function, which is needed in the implementation of trampoline.
Thanks!
I have following tuple
{{
'_id',{<<85,192,187,141,133,234,141,13,74,0,0,1>>},
mobile_no,<<"9930050224">>,
email,<<"prakhar#bwa.io">>,
name,<<"PT">>,
user_role,<<"broker">>,
user_id,<<"fp85od1zv5x4jddkens6648z5bc9jroj">>
}}
In form of =>
{{
key1, value1
key2, value2....
}}
Can a simple function call sort on basis of keys as under without parentheses?:
{{
'_id',{<<85,192,187,141,133,234,141,13,74,0,0,1>>},
email,<<"prakhar#bwa.io">>,
mobile_no,<<"9930050224">>,
name,<<"PT">>,
user_id,<<"fp85od1zv5x4jddkens6648z5bc9jroj">>,
user_role,<<"broker">>
}}
Can you define a simple function to sort the all parameters in {key, value} based on key parameters, but there are no parenthesis around each key, value
I won't comment about why you need this function, though I agree with "#I GIVE TERRIBLE ADVICE" and #Hynek. Here is a solution to your question:
1> Ut = {{'_id',{<<85,192,187,141,133,234,141,13,74,0,0,1>>},mobile_no,
<<"9930050224">>,email,<<"prakhar#bwa.io">>,name,<<"PT">>,user_role,<<"broker">>,user_id,<<"fp85od1zv5x4jddkens6648z5bc9jroj">>}}.
{{'_id',{<<85,192,187,141,133,234,141,13,74,0,0,1>>},
mobile_no,<<"9930050224">>,email,<<"prakhar#bwa.io">>,name,
<<"PT">>,user_role,<<"broker">>,user_id,
<<"fp85od1zv5x4jddkens6648z5bc9jroj">>}}
2> Group2 = fun Group2([],R) -> R; Group2([A,B|T],R) -> Group2(T,[{A,B}|R]) end.
#Fun<erl_eval.36.54118792>
3> Group = fun(L) -> Group2(L,[]) end.
#Fun<erl_eval.6.54118792>
4> F = fun(In) -> {X} = In, list_to_tuple(lists:sort(Group(tuple_to_list(X)))) end.
#Fun<erl_eval.6.54118792>
5> F(Ut).
{{'_id',{<<85,192,187,141,133,234,141,13,74,0,0,1>>}},
{email,<<"prakhar#bwa.io">>},
{mobile_no,<<"9930050224">>},
{name,<<"PT">>},
{user_id,<<"fp85od1zv5x4jddkens6648z5bc9jroj">>},
{user_role,<<"broker">>}}
6>
Shlok, you're fighting an uphill battle working directly with raw BSON tuples. Use the BSON library API to access the data that they contain:
2> RawDoc.
{'_id',{<<85,192,187,141,133,234,141,13,74,0,0,1>>},
email,<<"xxxxyyyy#bwa.io">>,mobile_no,<<"0000022222">>,name,
<<"PT">>,user_id,<<"fp85od1zv5x4jddkens6648z5bc9jroj">>,
user_role,<<"broker">>}
3> bson:at(email, RawDoc).
<<"xxxxyyyy#bwa.io">>
5> Key = fun(Key, Doc) -> {Key, bson:at(Key, Doc} end.
7> {Key(user_id, RawDoc), Key(user_role,RawDoc)}.
{{user_id,<<"fp85od1zv5x4jddkens6648z5bc9jroj">>},
{user_role,<<"broker">>}}
Ideally, you should write a function to convert there BSON tuples to the Erlang #record{} you're using to model your data, end of story.
If you assume you'll be getting BSON objects with a variable number of keys, and you want to sort them 'just in case', you're going to have a bad time in the long run.
P.S. Don't post your users' real data online ;)