Lesser-known Erlang tips and tricks?

Following on from the Do you make use of term_to_binary? thread, do you know of any other lesser known tips or tricks you think others might be interested in?

If so please share! :052:

3 Likes

There’s a compact way to do a one-line conditional (ab)using list comprehensions:

[do_thing() || BooleanValue, check_stuff()]

It works because you can have both list generators and filters, but the generators are optional.

It even works with conditions not allowed in guards. But be aware of readability concerns :wink:

5 Likes

Oh, here’s another one: there’s a built-in function in the shell—rp(Term)—that pretty-prints terms to infinite depth. That way you don’t have to type io:format(“~p~n”, [Term]) all the time! :grin:

5 Likes

If you want to learn more about this, you can check the article(s) I wrote a while back…

As a matter of fact, the whole Erlang Battleground blog is full of articles that would be proper responses to the topic of this thread.

6 Likes

In Erlang/OTP 26, we have documented some previously undocumented details about list comprehensions, including what happens when filters fail:

(to be included in the second release candidate, which will be released this week)

10 Likes

The right-hand operands of andalso and orelse can be any term, it doesn’t have to be true or false.

As a (contrived) example, if maps:get/3 didn’t exist, it could be written like this:

maps_get_with_default(Key, Map, Default) ->
    case maps:is_key(Key, Map) andalso {value, maps:get(Key, Map)} of
        false -> Default;
        {value, Value} -> Value
    end.
6 Likes

I got the feeling that I’ll be doing this a lot in this thread. When you folks get tired of this, let me know… :roll_eyes:

But… I also wrote an article about that semantically questionable technique…

2 Likes

I was a bit reluctant to share this “trick”, TBH, and I’m definitely not encouraging it :smile:

Maybe all posts in this thread should flash a warning like “Don’t do this at home!:sweat_smile:
Those lesser know tricks are lesser known not so much because they are secret magic but because they are dirty tricks :wink:

3 Likes

IMHO:

  1. “The right-hand operands of andalso and orelse” is not a trick.
  2. “List incomrehentions” is a needless boasting.
bc(B) when byte_size(B) > 64 -> binary:copy(B);
bc(B) -> B.

I use this to store values is process state when such values are received from an external large BLOB (like a JSON) after jsone:decode/1.

2 Likes

I like to write it that way, Mainly to avoid multiple case
I also defined some macros

Blockquote
-define(IF(IFTure, DoThat), (IFTure) andalso (DoThat)).
-define(IIF(Cond, Then, That), case Cond of true → Then; _ → That end).
-define(IIF(Expr, Expect, Then, ExprRet, That), case Expr of Expect → Then; ExprRet → That end).

this is just to make the code look like it’s on one line

1 Like

That is why I put “trick” in quotes :wink:

1 Like

Using ets:match_spec_run/2 over lists for dynamic filtering at runtime.

Meant I could avoid erl_parse/erl_eval/runtime-module-compilation.

I vaguely remember it being ‘fast enough’ for a small-time advertising auction hot path when I last used it (5+ years ago), no idea if it still is the best option. The need here was to take the request, turn it into a match_spec and run it over targeting rules.

On a related note, merl was helpful for my RADIUS encoder/decoder. I parsed the dictionaries and emitted code directly…in a similar vain to using ASN.1 but for RADIUS.

4 Likes

I use it in pge_ps.
And no, I didn’t come up with it myself, but I spied on gproc_ps.

1 Like