Value from binding in LFE interpreter using Erlang - erlang

I'd like to use Lisp Flavored Erlang as a scripting extension language for an Erlang application. If you want, in a similar way GNU Emacs is configured and extended via Emacs Lisp.
I know that the argument is wide and structured; but in the specific case of this question I'd like being able to read a binding name (or variable, if you prefer) defined in LFE from Erlang code.
I'm not an expert of LFE internal architecture (which is an excellent example of software engineering and Erlang programming), but I was not able to find an answer neither in the sources nor in the documentation.
Looking at sources I can see that LFE contains both a compiler that target Erlang VM and an interpreter.
The latter is the one I'm trying to use.
If I start Erlang shell/REPL in LFE installation path (on my system $HOME/opt/lfe):
$ cd /path/to/LFE-install-dir
$ erl -pa ./ebin
I'm able to calculate a value:
1> {ok, Expr} = lfe_io:read_string("(+ 1 10)").
{ok,['+',1,10]}
2> Result = lfe_eval:expr(Expr).
11
This is a first step, but not exactly what I want. I'd like rather to bind a variable and read its value; that's my issue:
3> {ok, Expr2} = lfe_io:read_string("(set a 10)").
{ok,[set,a,10]}
4> lfe_eval:expr(Expr2).
** exception error: {unbound_func,{set,2}}
in function lfe_eval:eval_expr/2
Why set is recognized as an unbound function? In LFE REPL this expression is valid:
Erlang/OTP 17 [erts-6.4] [source] [64-bit] [smp:4:4] ...
LFE Shell V6.4 (abort with ^G)
> (set a 10)
10
> a
10
I'm obviously using the API in the wrong way. How can I read the content of a and/or properly initialize the LFE interpreter?
(If this is explained somewhere, please provide the reference).

I won't attempt to answer completely your broader question about the "best practices" of adding scripting. It seems to me that choosing between "hook-based" solution (in which you define hook implementations by name convention and they are automatically recognized) and "explicit api" solution (in which you use functions predefinied in the scripting enviroment to register your hooks or otherwise call configuration functions) is largely a matter of taste. Explicit calls like (set-connection-timeout-handler ...) may be more readable, easier to debug (no misspelling problems, no surprises on api changes), easier to document, and a bit more flexible, but more, well, explicit.
Building from your simple variable definition example, here are a few ways you could get started going further the "interpreted" path:
1> {ok, Expr} = lfe_io:read_string("'((a 10))").
{ok,[quote,[[a,10]]]}
2> lfe_eval:expr (Expr).
[[a,10]]
3> EvalAll = fun (Conf) -> {ok, E} = lfe_io:read_string("'(" ++ Conf ++ ")"), lfe_eval:expr(E) end.
#Fun<erl_eval.6.90072148>
4> EvalAll ("(a 10) (b 11)").
[[a,10],[b,11]]
5> EvalAllL = fun (Conf) -> {ok, E} = lfe_io:read_string("(list " ++ Conf ++ ")"), lfe_eval:expr(E) end.
#Fun<erl_eval.6.90072148>
6> [{f, F}] = EvalAllL ("(tuple 'f (lambda (x) (+ 10 x)))").
[{f,#Fun<lfe_eval.12.2018457>}]
7> F (12).
22
8> G = fun (X) -> X * 2 end.
#Fun<erl_eval.6.90072148>
9> lfe_eval:expr (element (2, lfe_io:read_string ("(g 15)")), lfe_eval:add_lexical_func(g, 1, G, lfe_env:new ())).
30

A simple way is use to the 'lfe' command to run LFE scripts. The 'lfe' behaves in similar fashion to 'bash' in that you can use it to run scripts. The 'lfec' script defined in bin/lfec is a good example of this. It is an LFE shell script which parses it arguments and run the LFE compiler.

Related

Erlang atoms and ".."

This is output of erlang shell:
1> atom.
atom
2> next_atom.
next_atom
3> atom#erlang.
atom#erlang
4> 'atom in single quotes'.
'atom in single quotes'
5> atom = 'atom'.
atom
6> a.tom.
'a.tom'
7> a..tom.
* 1: syntax error before: '..'
When there is just one dot . within atom (line 6), I get no errors. However, when there is .., I get syntax error. Does .. have some special meaning in Erlang or why do I get error when . works fine?
Dots are not allowed as such in atoms, but a dot between two atoms: 'foo'.'bar',
is a compile time operator that concatenates the atoms to 'foo.bar'.
This is an extension which was made to support the (still not officially
supported) Java-like package system. That's why it's not documented.

How do I use erl_tidy and erl_lint?

I know the docs explain these tools, but I don't understand the explanation. Can someone provide an example or two?
Of erl_tidy, the simplest way - and the most direct, if you have one running in your source directory all the time anyway, is to use it directly from Eshell, as in
$ erl
1> m(erl_tidy).
% output snipped
2> erl_tidy:dir(). % recursively tidy the present directory and its children
% output snipped
3> erl_tidy:dir("", [{recursive, false}]). % just the present directory
reading module `./bad.erl'.
made backup of file `./bad.erl'.
writing to file `./bad.erl'.
4>
In this case, bad.erl went from
-module(bad).
-compile(export_all).
bad(0)->1;bad(1)->2;bad(N)->3.bad()->0.
to the tidied
-module(bad).
-compile(export_all).
bad ( 0 ) -> 1 ; bad ( 1 ) -> 2 ; bad ( N ) -> 3 . bad ( ) -> 0 .
... well, it's not a magician :-)
erl_tidy can also be invoked through arguments to erl, as in
$ # unix prompt
$ erl -s erl_tidy dir
tidying directory `./wesnoth'.
tidying directory `./wesnoth/Vix'.
tidying directory `./wesnoth/Vix/utils'.
...
erl_lint however is completely different. To understand how to use it, first understand what's going on in this string evaluation example. erl_lint is designed to act on an intermediate representation of Erlang source, not on strings of it.

Erlang macros with different arity

For my logging I wanted the ability to macro out the statements at compile time, so -define to the rescue!
For my compiler flags I'm compiling with erlc -DFOO, is there a way for -ifdef to determine the difference between FOO = ok, FOO/0, and FOO/1?
-module(foo).
-define(FOO, ok).
-define(FOO(X), io:format("~p~n", [X])).
-export([test_x/1]).
%% i want this to be true iff FOO = ok, not if ?FOO/1 exists
-ifdef(FOO).
test_x(X) ->
?FOO(":) " ++ X).
-else.
test_x(X) ->
?FOO(":( " ++ X).
-endif.
I had better write a fuller reply.
No, there is no way to test the actual macro definition, you can only test if a macro with that name has been defined. And you can only test on the macro name, not on alternative macro definitions with different arities. This is relic from the past, before R13B, when you could only have one macro definition per name. The new one more closely mimics functions in a module.
The "standard" way of doing it is to use some flag macro to determine which set of macros/functions to use. For example:
-ifdef(DEBUG).
-define(DEBUG_PRINT(X), <... something long here ...>).
foo(X) -> <... debuggy stuff here ...>.
-else
-define(DEBUG_PRINT(X), ok).
foo(X) -> <... normal stuff here ...>.
-endif.

Can I disable printing lists of small integers as strings in Erlang shell?

The Erlang shell "guesses" whether a given list is a printable string and prints it that way for convenience. Can this "convenience" be disabled?
I don't know if it's possible to change the default behavior of the shell, but you can at least format your output correctly, using io:format.
Here is an example:
1> io:format("~p~n", [[65, 66, 67]]).
"ABC"
ok
2> io:format("~w~n", [[65, 66, 67]]).
[65,66,67]
ok
And since the shell is only for experimenting / maintenance, io:format() should be at least enough for your real application. Maybe you should also consider to write your own format/print method, e.g. formatPerson() or something like that, which formats everything nicely.
You can disable such behavior with shell:strings/1 function starting with Erlang R16B.
Just remember that this is option global to all node shells, and it might be wise to set it back after finishing playing is shell in longer living nodes.
I tend to do it by prepending an atom to my list in the shell.
for example:
Eshell V5.7.4 (abort with ^G)
1> [65,66,67].
"ABC"
2> [a|[65,66,67]].
[a,65,66,67]
could also be [a,65,66,67], of course. but [a|fun_that_returns_a_list()] will print "the right thing(ish) most of the time"
As of Erlang/OTP R16B, you can use the function shell:strings/1 to turn this on or off. Note that it also affects printing of things that are actually meant to be strings, such as "foo" in the following example:
1> {[8,9,10], "foo"}.
{"\b\t\n","foo"}
2> shell:strings(false).
true
3> {[8,9,10], "foo"}.
{[8,9,10],[102,111,111]}
No, there is no way to disable it. The best alternative I find is to either explicitly print out the value in the query (with io:format) or after the fact do: io:format("~w\n", [v(-1)]).
I don't think you can prevent it.
Prepending an atom seems like a kludge - it does alter your original string.
I typically use lists:flatten(String) to force it to a string - especially the returnvalue of io_lib:format() does not always print as a string. Using lists:flatten() on it makes it one.
I use the following "C-style":
sprintf(Format) ->
sprintf(Format, []).
sprintf(Format, Args) ->
lists:flatten(io_lib:format(Format, Args)).
The problem is that the string is not a type in Erlang. A string is just a list of integers, so there's no way for the shell to distinguish a printable string from a generic list. Don't know if this answer to your question.

Hidden Features of Erlang [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
In the spirit of:
Hidden Features of C#
Hidden Features of Java
Hidden Features of ASP.NET
Hidden Features of Python
Hidden Features of HTML
and other Hidden Features questions
What are the hidden features of Erlang that every Erlang developer should be aware of?
One hidden feature per answer, please.
Inheritance! http://www.erlang.se/euc/07/papers/1700Carlsson.pdf
Parent
-module(parent).
-export([foo/0, bar/0]).
foo() ->
io:format("parent:foo/0 ~n", []).
bar() ->
io:format("parent:bar/0 ~n", []).
Child
-module(child).
-extends(parent).
-export([foo/0]).
foo() ->
io:format("child:foo/0 ~n", []).
Console
23> parent:foo().
parent:foo/0
ok
24> parent:bar().
parent:bar/0
ok
25> child:foo().
child:foo/0
ok
26> child:bar().
parent:bar/0
ok
The magic commands in the shell. The full list is in the manual, but the ones I use most are:
f() - forget all variables
f(X) - forget X
v(42) - recall result from line 42
v(-1) - recall result from previous line
e(-1) - reexecute expression on previous line
rr(foo) - read record definitions from module foo
rr("*/*") - read record definitions from every module in every subdirectory
rp(expression) - print full expression with record formating
Parameterized Modules! From http://www.lshift.net/blog/2008/05/18/late-binding-with-erlang and http://www.erlang.se/euc/07/papers/1700Carlsson.pdf
-module(myclass, [Instvar1, Instvar2]).
-export([getInstvar1/0, getInstvar2/0]).
getInstvar1() -> Instvar1.
getInstvar2() -> Instvar2.
And
Eshell V5.6 (abort with ^G)
1> Handle = myclass:new(123, 234).
{myclass,123,234}
2> Handle:getInstvar1().
123
3> Handle:getInstvar2().
234
user_default.erl - you can build your own shell builtins by having a compiled user_default.beam in your path which can be pretty nifty
beam_lib:chunks can get source code from a beam that was compiled with debug on which can be really usefull
{ok,{_,[{abstract_code,{_,AC}}]}} = beam_lib:chunks(Beam,[abstract_code]).
io:fwrite("~s~n", [erl_prettypr:format(erl_syntax:form_list(AC))]).
Ports, external or linked-in, accept something called io-lists for sending data to them. An io-list is a binary or a (possibly deep) list of binaries or integers in the range 0..255.
This means that rather than concatenating two lists before sending them to a port, one can just send them as two items in a list. So instead of
"foo" ++ "bar"
one do
["foo", "bar"]
In this example it is of course of miniscule difference. But the iolist in itself allows for convenient programming when creating output data. io_lib:format/2,3 itself returns an io list for example.
The function erlang:list_to_binary/1 accepts io lists, but now we have erlang:iolist_to_binary/1 which convey the intention better. There is also an erlang:iolist_size/1.
Best of all, since files and sockets are implemented as ports, you can send iolists to them. No need to flatten or append.
That match specifications can be built using ets:fun2ms(...) where the Erlang fun syntax is used and translated into a match specification with a parse transform.
1> ets:fun2ms(fun({Foo, _, Bar}) when Foo > 0 -> {Foo, Bar} end).
[{{'$1','_','$2'},[{'>','$1',0}],[{{'$1','$2'}}]}]
So no fun-value is ever built, the expression gets replaced with the match-spec at compile-time. The fun may only do things a match expression could do.
Also, ets:fun2ms is available for usage in the shell, so fun-expressions can be tested easily.
.erlang_hosts gives a nice way to share names across machines
Not necessarily "hidden", but I don't see this often. Anonymous functions can have multiple clauses, just like module functions, i.e.
-module(foo).
-compile(export_all).
foo(0) -> "zero";
foo(1) -> "one";
foo(_) -> "many".
anon() ->
fun(0) ->
"zero";
(1) ->
"one";
(_) ->
"many"
end.
1> foo:foo(0).
"zero"
2> foo:foo(1).
"one"
3> foo:foo(2).
"many"
4> (foo:anon())(0).
"zero"
5> (foo:anon())(1).
"one"
6> (foo:anon())(2).
"many"
The gen___tcp and ssl sockets have a {packet, Type} socket option to aid in decoding a number of protocols. The function erlang:decode_packet/3 has a good description on what the various Type values can be and what they do.
Together with a {active, once} or {active, true} setting, each framed value will be delivered as a single message.
Examples: the packet http mode is used heavily for iserve and the packet fcgi mode for ifastcgi. I can imagine that many of the other http servers use packet http as well.
.erlang can preload libraries and run commands on a shells startup, you can also do specific commands for specific nodes by doing a case statement on node name.
If you want to execute more than one expression in a list comprehension, you can use a block. For example:
> [begin erlang:display(N), N*10 end || N <- lists:seq(1,3)].
1
2
3
[10,20,30]
It is possible to define your own iterator for QLC to use. For example, a result set from an SQL query could be made into a QLC table, and thus benefit from the features of QLC queries.
Besides mnesia tables, dets and ets have the table/1,2 functions to return such a "Query Handle" for them.
Not so hidden, but one of the most important aspects, when chosing Erlang as platform for development:
Possibility of enhanced tracing on live nodes (in-service) and being one of the best in debugging!
You can hide an Erlang node by starting it with:
erl -sname foo -hidden
You can still connect to the node, but it won't appear in the list returned by nodes/0.
Matching with the append operator:
"pajamas:" ++ Color = "pajamas:blue"
Color now has the value "blue". Be aware that this trick has it’s limitations - as far as I know it only works with a single variable and a single constant in the order given above.
Hot code loading. From wiki.
Code is loaded and managed as "module" units, the module is a compilation unit. The system can keep two versions of a module in memory at the same time, and processes can concurrently run code from each.
The versions are referred to the "new" and the "old" version. A process will not move into the new version until it makes an external call to its module.

Resources