Hidden Features of Erlang [closed]
Asked Answered
F

17

17

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.

Friedafriedberg answered 30/6, 2009 at 12:52 Comment(3)
Please Community Wiki this.Peccavi
I suggest adding a hidden-features tag to this, and making the notes on the hidden features of other languages links to those questions.Glowing
@Olafur how? help! @Avihu done. thanks for the suggestioN! :)Friedafriedberg
M
19

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
Mariel answered 30/6, 2009 at 12:52 Comment(1)
And using rp(expression(...)) to have the result printed out without pretty-printing too deeply nested structures, instead it prints it fullyKentiggerma
I
25

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
Intermarry answered 6/7, 2009 at 12:7 Comment(3)
Yup. Interesting! Although I haven't seen it in any libraries I've used to date...Intermarry
However it's not welcomed to use parameterized modules: They add variables to functions and it's not good when it comes to debug them. They break the functional paradigm adding a layer of complexity introduced by variables you should keep track of (like global variables in imperative languages), they are immutable but destroy transparency. There've been the thoughts that they (parameterized modules) still exist in the language only because of products utilizing them, mochiweb is an example. Just think, why appeared in 2003 they still officially undocumented?Cafeteria
This comment belongs to the "Parameterized Modules" answer...Intermarry
M
19

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
Mariel answered 30/6, 2009 at 12:52 Comment(1)
And using rp(expression(...)) to have the result printed out without pretty-printing too deeply nested structures, instead it prints it fullyKentiggerma
I
14

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
Intermarry answered 6/7, 2009 at 12:13 Comment(3)
I spotted this when I was trying to grok the mochiweb source. Took a while to google what the hell it was actually doing, as the syntax was totally different to the Erlang I've seen before.Chippy
It's pretty interesting! I also saw it for the first time in mochiweb. Combining this with inheritance could create some interesting possibilities...Intermarry
For the case you wonders the downvotes, this was an accident, please check this meta topic. I'll edit your question so that they can be removed.Saraband
S
12

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

Scleroprotein answered 1/7, 2009 at 13:33 Comment(0)
S
10

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))]).
Scleroprotein answered 1/7, 2009 at 13:35 Comment(0)
K
9

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.

Kentiggerma answered 23/7, 2009 at 8:9 Comment(0)
K
8

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.

Kentiggerma answered 23/7, 2009 at 7:4 Comment(0)
S
7

.erlang_hosts gives a nice way to share names across machines

Scleroprotein answered 1/7, 2009 at 13:35 Comment(0)
I
6

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"
Intermarry answered 30/6, 2009 at 12:52 Comment(0)
K
5

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.

Kentiggerma answered 23/7, 2009 at 7:29 Comment(0)
S
4

.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.

Scleroprotein answered 1/7, 2009 at 13:34 Comment(0)
O
3

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]
Oversexed answered 30/6, 2009 at 12:52 Comment(0)
O
2

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.

Oversexed answered 30/6, 2009 at 12:52 Comment(0)
E
2

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.

Ealdorman answered 30/6, 2009 at 12:52 Comment(0)
C
2

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!
Cote answered 30/6, 2009 at 12:52 Comment(0)
K
2

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.

Kentiggerma answered 23/7, 2009 at 7:36 Comment(0)
U
1

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.

Unmoral answered 30/6, 2009 at 12:52 Comment(2)
How is this a hidden feature? A notable feature for sure, but this is one of the language's primary boasting points, not hidden at all.Thebaid
But why the hell no upvotes? :DDionysiac

© 2022 - 2024 — McMap. All rights reserved.