How to create a function using merl given a list of clauses

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

How to create a function using merl given a list of clauses

Frans Schneider-2

Dear list,

 From a set of user defined rules, I want to create functions of the form:

fun([V1, V2]) ->
     fun () when V1 < 1, is_atom(V2) -> foo();
         () when V2 =/= b -> bar();
         () -> false
     end
end.

The number of arguments, clauses and guards differ. Guards always are
ANDed or andalso should be used.

To build the internal fun I do something like:

...
-include_lib("syntax_tools/include/merl.hrl").
...
tst() ->
     %% This is the end result I want
     V1 = 10,
     V2 = a,
     Func = ?Q(["fun () when _@V1@ < 1, is_atom(_@V2@) -> foo();",
            "    () when _@V2@ =/= b -> bar();",
            "    () -> false ",
            "end"]),
     %% io:format("Func ~p~n", [Func]),
     merl:print(Func),

     %% This is the data produced by some function
     Guard1 = ?Q("_@V1@ < 1"),
     Guard2 = ?Q("is_atom(_@V2@)"),
     Guard3 = ?Q("_@V2@ =/= b"),
     GSeq1 = [Guard1, Guard2],
     GSeq2 = [Guard3],

     %% Now start assembling the fun
     Clause1 = ?Q("() when _@GSeq1 -> foo()"),
     Clause2 = ?Q("() when _@GSeq2 -> bar()"),
     Clauses = [Clause1, Clause2],
     merl:print(Clauses),

     %% And this gives the error: syntax error before: 'fun'"
     Func1 = ?Q("fun _@Clauses end"),
     merl:print(Func1).

I just can't figure out a way to make the last step assembling the fun work.

Your suggestions are highly appreciated!

Frans

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

How to create a function using merl given a list of clauses

Svilen Ivanov
On Wed, 2018-02-14 at 13:31 +0100, Frans Schneider wrote:

> Dear list,
>
>  From a set of user defined rules, I want to create functions of the
> form:
>
> fun([V1, V2]) ->
>      fun () when V1 < 1, is_atom(V2) -> foo();
>          () when V2 =/= b -> bar();
>          () -> false
>      end
> end.
>
> The number of arguments, clauses and guards differ. Guards always
> are
> ANDed or andalso should be used.
>
> To build the internal fun I do something like:
>
> ...
> -include_lib("syntax_tools/include/merl.hrl").
> ...
> tst() ->
>      %% This is the end result I want
>      V1 = 10,
>      V2 = a,
>      Func = ?Q(["fun () when _@V1@ < 1, is_atom(_@V2@) -> foo();",
>             "    () when _@V2@ =/= b -> bar();",
>             "    () -> false ",
>             "end"]),
>      %% io:format("Func ~p~n", [Func]),
>      merl:print(Func),
>
>      %% This is the data produced by some function
>      Guard1 = ?Q("_@V1@ < 1"),
>      Guard2 = ?Q("is_atom(_@V2@)"),
>      Guard3 = ?Q("_@V2@ =/= b"),
>      GSeq1 = [Guard1, Guard2],
>      GSeq2 = [Guard3],
>
>      %% Now start assembling the fun
>      Clause1 = ?Q("() when _@GSeq1 -> foo()"),
>      Clause2 = ?Q("() when _@GSeq2 -> bar()"),
>      Clauses = [Clause1, Clause2],
>      merl:print(Clauses),
>
>      %% And this gives the error: syntax error before: 'fun'"
>      Func1 = ?Q("fun _@Clauses end"),
>      merl:print(Func1).
>
> I just can't figure out a way to make the last step assembling the
> fun work.
>
> Your suggestions are highly appreciated!
>
> Frans
>

You should look at "lifting" in http://erlang.org/doc/man/merl.html ,
something like this seems to work:
----------------------------------------------------
-include_lib("syntax_tools/include/merl.hrl").

tst() ->
     V1 = merl:var('V1'),
     V2 = merl:var('V2'),

     Guard1 = ?Q("_@V1 < 1"),
     Guard2 = ?Q("is_atom(_@V2)"),
     Guard3 = ?Q("_@V2 =/= b"),
     GSeq1 = [Guard1, Guard2],
     GSeq2 = [Guard3],

     Clause1 = ?Q("() when _@GSeq1 -> foo()"),
     Clause2 = ?Q("() when _@GSeq2 -> bar()"),
     Clauses = [Clause1, Clause2],

     Func1 = ?Q("fun() -> _@_@Clauses end"),

     Func2 = ?Q("fun([_@V1,_@V2]) -> _@Func1 end"),

     merl:print(Func2).
------------------------------------------------------

Svilen
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: How to create a function using merl given a list of clauses

Frans Schneider-2
Thanks Svilen, works now!
As always, it is in the docs but it sometimes requires reading it
several times.

Frans

On 02/14/2018 08:47 PM, Svilen Ivanov wrote:

> On Wed, 2018-02-14 at 13:31 +0100, Frans Schneider wrote:
>> Dear list,
>>
>>   From a set of user defined rules, I want to create functions of the
>> form:
>>
>> fun([V1, V2]) ->
>>       fun () when V1 < 1, is_atom(V2) -> foo();
>>           () when V2 =/= b -> bar();
>>           () -> false
>>       end
>> end.
>>
>> The number of arguments, clauses and guards differ. Guards always
>> are
>> ANDed or andalso should be used.
>>
>> To build the internal fun I do something like:
>>
>> ...
>> -include_lib("syntax_tools/include/merl.hrl").
>> ...
>> tst() ->
>>       %% This is the end result I want
>>       V1 = 10,
>>       V2 = a,
>>       Func = ?Q(["fun () when _@V1@ < 1, is_atom(_@V2@) -> foo();",
>>              "    () when _@V2@ =/= b -> bar();",
>>              "    () -> false ",
>>              "end"]),
>>       %% io:format("Func ~p~n", [Func]),
>>       merl:print(Func),
>>
>>       %% This is the data produced by some function
>>       Guard1 = ?Q("_@V1@ < 1"),
>>       Guard2 = ?Q("is_atom(_@V2@)"),
>>       Guard3 = ?Q("_@V2@ =/= b"),
>>       GSeq1 = [Guard1, Guard2],
>>       GSeq2 = [Guard3],
>>
>>       %% Now start assembling the fun
>>       Clause1 = ?Q("() when _@GSeq1 -> foo()"),
>>       Clause2 = ?Q("() when _@GSeq2 -> bar()"),
>>       Clauses = [Clause1, Clause2],
>>       merl:print(Clauses),
>>
>>       %% And this gives the error: syntax error before: 'fun'"
>>       Func1 = ?Q("fun _@Clauses end"),
>>       merl:print(Func1).
>>
>> I just can't figure out a way to make the last step assembling the
>> fun work.
>>
>> Your suggestions are highly appreciated!
>>
>> Frans
>>
>
> You should look at "lifting" in http://erlang.org/doc/man/merl.html ,
> something like this seems to work:
> ----------------------------------------------------
> -include_lib("syntax_tools/include/merl.hrl").
>
> tst() ->
>       V1 = merl:var('V1'),
>       V2 = merl:var('V2'),
>
>       Guard1 = ?Q("_@V1 < 1"),
>       Guard2 = ?Q("is_atom(_@V2)"),
>       Guard3 = ?Q("_@V2 =/= b"),
>       GSeq1 = [Guard1, Guard2],
>       GSeq2 = [Guard3],
>
>       Clause1 = ?Q("() when _@GSeq1 -> foo()"),
>       Clause2 = ?Q("() when _@GSeq2 -> bar()"),
>       Clauses = [Clause1, Clause2],
>
>       Func1 = ?Q("fun() -> _@_@Clauses end"),
>
>       Func2 = ?Q("fun([_@V1,_@V2]) -> _@Func1 end"),
>
>       merl:print(Func2).
> ------------------------------------------------------
>
> Svilen
>
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions