Does Erlang have methods? - erlang

E.g. is there something like this:
O = widget:new(),
O:whirl()
I seem to recall seeing some code like this (maybe I was imagining it), but I haven't seen it in the tutorials that I've read. From what I've seen, the closest thing is this:
O = widget:new(),
widget:whirl(O)
That's not too bad, but not having to repeat widget: in the second expression would be nice.

This is syntax for parametrized modules which was removed from Erlang in R16 (2012).

No, Erlang does not have methods. Erlang has processes, not objects, and you communicate with them by messaging them, not calling methods on them. That's it. That's all there is to it.
The closest thing to new in Erlang that means what it means in Java or C++ is spawn. (The parameterized module discussion touches on something very different from what you would expect coming from a C++ type language where new reserves memory, calls a constructor, etc.)
There are actually two aspects to this: data objects (like a dict or list or something) and processes (things you create with spawn).
Within a function definition you might see something like
SomeDict = dict:new(),
or
OtherDict = dict:from_list(KV_List)
This does indeed create something, but its not an "object" in the Java or C++ sense, it is an "object" in the (older) sense of the term that it is a named reference to something in memory. And indeed you interact with it the same way you demonstrated above:
D = dict:new(),
ok = some_operation(D),
where some_operation/1 might be anything, whether it is dict:foo() or something else. The part before the colon is a module identifier, telling the runtime what namespace that function you're calling exists in -- nothing more.
The other thing, spawn, is much more like new in C++, where you want to create a complete thing that is alive and has arms and legs -- a noun that can do verby things:
Pid = spawn(Mod, Fun, Args),
Pid ! {some, message},
Most of the time you only see the erlang:send/2 function (also written as the infix ! operator) in prototype or non-OTP code. Usually this is hidden from you by interface functions that abstract away the fact that you are sending async messages all the time to communicate with your processes.
For some more in-depth explanation, I recommend reading Learn You Some Erlang -- the author explains this and other basic concepts in some depth.
Whatever you do, do not fall into the simpleton's trap of thinking Erlang is Java. That is just a great way to trip over your own preconceptions and get frustrated. This is probably the #1 beginner mistake I see people make...

Related

Why does Erlang if statement support only specific functions in its guard?

Why does the Erlang if statement support only specific functions in its guard?
i.e -
ok(A) ->
if
whereis(abc)=:=undefined ->
register(abc,A);
true -> exit(already_registered)
end.
In this case we get an "illegal guard" error.
What would be the best practice to use function's return values as conditions?
Coming from other programming languages, Erlang's if seems strangely restrictive, and in fact, isn't used very much, with most people opting to use case instead. The distinction between the two is that while case can test any expression, if can only use valid Guard Expressions.
As explained in the above link, Guard Expressions are limited to known functions that are guaranteed to be free of side-effects. There are a number of reasons for this, most of which boil down to code predictability and inspectability. For instance, since matching is done top-down, guard expressions that don't match will be executed until one is found that does. If those expressions had side-effects, it could easily lead to unpredictable and confusing outcomes during debugging. While you can still accomplish that with case expressions, if you see an if you can know there are no side effects being introduced in the test without needing to check.
One last, but important thing, is that guards have to terminate. If they did not, the reduction of a function call could go on forever, and as the scheduler is based around reductions, that would be very bad indeed, with little to go on when things went badly.
As a counter-example, you can starve the scheduler in Go for exactly this reason. Because Go's scheduler (like all micro-process schedulers) is co-operatively multitasked, it has to wait for a goroutine to yield before it can schedule another one. Much like in Erlang, it waits for a function to finish what it's currently doing before it can move on. The difference is that Erlang has no loop-alike. To accomplish looping, you recurse, which necessitates a function call/reduction, and allows a point for the scheduler to intervene. In Go, you have C-style loops, which do not require a function call in their body, so code akin to for { i = i+1 } will starve the scheduler. Not that such loops without function calls in their body are super-common, but this issue does exist.
On the contrary, in Erlang it's extremely difficult to do something like this without setting out to do so explicitly. But if guards contained code that didn't terminate, it would become trivial.
Check this question: About the usage of "if" in Erlang language
In short:
Only a limited number of functions are allowed in guard sequences, and whereis is not one of them
Use case instead.

Is a 'standard module' part of the 'programming language'?

On page 57 of the book "Programming Erlang" by Joe Armstrong (2007) 'lists:map/2' is mentioned in the following way:
Virtually all the modules that I write use functions like
lists:map/2 —this is so common that I almost consider map
to be part of the Erlang language. Calling functions such
as map and filter and partition in the module lists is extremely
common.
The usage of the word 'almost' got me confused about what the difference between Erlang as a whole and the Erlang language might be, and if there even is a difference at all. Is my confusion based on semantics of the word 'language'? It seems to me as if a standard module floats around the borders of what does and does not belong to the actual language it's implemented in. What are the differences between a programming language at it's core and the standard libraries implemented in them?
I'm aware of the fact that this is quite the newby question, but in my experience jumping to my own conclusions can lead to bad things. I was hoping someone could clarify this somewhat.
Consider this simple program:
1> List = [1, 2, 3, 4, 5].
[1,2,3,4,5]
2> Fun = fun(X) -> X*2 end.
#Fun<erl_eval.6.50752066>
3> lists:map(Fun, List).
[2,4,6,8,10]
4> [Fun(X) || X <- List].
[2,4,6,8,10]
Both produce the same output, however the first one list:map/2 is a library function, and the second one is a language construct at its core, called list comprehension. The first one is implemented in Erlang (accidentally also using list comprehension), the second one is parsed by Erlang. The library function can be optimized only as much as the compiler is able to optimize its implementation in Erlang. However, the list comprehension may be optimized as far as being written in assembler in the Beam VM and called from the resulted beam file for maximum performance.
Some language constructs look like they are part of the language, whereas in fact they are implemented in the library, for example spawn/3. When it's used in the code it looks like a keyword, but in Erlang it's not one of the reserved words. Because of that, Erlang compiler will automatically add the erlang module in front of it and call erlang:spawn/3, which is a library function. Those functions are called BIFs (Build-In Functions).
In general, what belongs to the language itself is what that language's compiler can parse and translate to the executable code (or in other words, what's defined by the language's grammar). Everything else is a library. Libraries are usually written in the language for which they are designed, but it doesn't necessarily have to be the case, e.g. some of Erlang library functions are written using C as Erlang NIFs.

Elixir: rationale behind allowing rebinding of variables

What is the rationale behind allowing rebinding of variables in Elixir, when Erlang doesn't allow that?
Most functional languages don't allow rebinding of variables in the same scope. So Elixir allowing this does definitely give it an non-functional, imperative feel. Erlang's problem is rather lack of scope, or to be more precise that there is only one scope in a whole function clause. We did have serious discussions whether to introduce scope but in the end we decided against it as it was backwards incompatible with the existing system. And developers hate backwards inconsistent changes.
The Erlang way has one serious benefit: when you get it wrong you generally get an error so you can SEE the mistake. This compared just getting strange behaviour when a variable doesn't have the value you expect it to have which is MUCH harder to detect and correct.
Personally I think that the problem of new variable names, for example using the number scheme, is greatly overblown. Compared to the time it takes me to work out WHAT I am going to do changing variable names is trivial. And after a while you just see it without reflecting about it. Honestly.
EDIT:
Also when chaining data through a sequence of functions the actual meaning of the data changes so reusing the same variable name can be very misleading. It can end up just meaning a generic "data I am passing from one function to another".
Here's the rationale straight from the horse's mouth:
http://blog.plataformatec.com.br/2016/01/comparing-elixir-and-erlang-variables/
Because it's simpler.
Take a look at this question posted to the Erlang mailing list in 2009. Specifically this part:
I like pattern matching in the majority of cases, but I find I write
enough code where I need to incrementally update a data structure, and
maintaining that code is a pain when I have code like:
X = foo(),
X1 = bar(X),
X2 = xyzzy(X1),
blah(X2).
and later want to change it to:
X = foo(),
X1 = whee(X),
X2 = bar(X1),
X3 = xyzzy(X2),
blah(X3).
Editor's note--this is the reply to that question.
This goes through IRC a lot. This is a result of poor variable naming
practice, and there is no need to introduce rebinding to "fix" it;
just stop using single letters and counters as variable names.
If for example that was written
FooStateX = foo(),
PostBarX = bar(FooStateX),
OnceXyzziedX = xyzzy(PostBarX),
blah(OnceXyzziedX).
The code demonstrated there isn't all that uncommon in Erlang (note the remark "this goes through IRC a lot"). Elixir's ability to simply rebind names saves us from having to generate new dummy names for things all the time. That's all. It's wise to bear in mind that the original creators of Erlang weren't trying to build a functional language. They were simply pragmatic developers who had a problem to solve. Elixir's approach is simple pragmatism.

Erlang: Compute data structure literal (constant) at compile time?

This may be a naive question, and I suspect the answer is "yes," but I had no luck searching here and elsewhere on terms like "erlang compiler optimization constants" etc.
At any rate, can (will) the erlang compiler create a data structure that is constant or literal at compile time, and use that instead of creating code that creates the data structure over and over again? I will provide a simple toy example.
test() -> sets:from_list([usd, eur, yen, nzd, peso]).
Can (will) the compiler simply stick the set there at the output of the function instead of computing it every time?
The reason I ask is, I want to have a lookup table in a program I'm developing. The table is just constants that can be calculated (at least theoretically) at compile time. I'd like to just compute the table once, and not have to compute it every time. I know I could do this in other ways, such as compute the thing and store it in the process dictionary for instance (or perhaps an ets or mnesia table). But I always start simple, and to me the simplest solution is to do it like the toy example above, if the compiler optimizes it.
If that doesn't work, is there some other way to achieve what I want? (I guess I could look into parse transforms if they would work for this, but that's getting more complicated than I would like?)
THIS JUST IN. I used compile:file/2 with an 'S' option to produce the following. I'm no erlang assembly expert, but it looks like the optimization isn't performed:
{function, test, 0, 5}.
{label,4}.
{func_info,{atom,exchange},{atom,test},0}.
{label,5}.
{move,{literal,[usd,eur,yen,nzd,peso]},{x,0}}.
{call_ext_only,1,{extfunc,sets,from_list,1}}.
No, erlang compiler doesn't perform partial evaluation of calls to external modules which set is. You can use ct_expand module of famous parse_trans to achieve this effect.
providing that set is not native datatype for erlang, and (as matter of fact) it's just a library, written in erlang, I don't think it's feasibly for compiler to create sets at compile time.
As you could see, sets are not optimized in erlang (as any other library written in erlang).
The way of solving your problem is to compute the set once and pass it as a parameter to the functions or to use ETS/Mnesia.

Is there an idiomatic way to order function arguments in Erlang?

Seems like it's inconsistent in the lists module. For example, split has the number as the first argument and the list as the second, but sublists has the list as the first argument and the len as the second argument.
OK, a little history as I remember it and some principles behind my style.
As Christian has said the libraries evolved and tended to get the argument order and feel from the impulses we were getting just then. So for example the reason why element/setelement have the argument order they do is because it matches the arg/3 predicate in Prolog; logical then but not now. Often we would have the thing being worked on first, but unfortunately not always. This is often a good choice as it allows "optional" arguments to be conveniently added to the end; for example string:substr/2/3. Functions with the thing as the last argument were often influenced by functional languages with currying, for example Haskell, where it is very easy to use currying and partial evaluation to build specific functions which can then be applied to the thing. This is very noticeable in the higher order functions in lists.
The only influence we didn't have was from the OO world. :-)
Usually we at least managed to be consistent within a module, but not always. See lists again. We did try to have some consistency, so the argument order in the higher order functions in dict/sets match those of the corresponding functions in lists.
The problem was also aggravated by the fact that we, especially me, had a rather cavalier attitude to libraries. I just did not see them as a selling point for the language, so I wasn't that worried about it. "If you want a library which does something then you just write it" was my motto. This meant that my libraries were structured, just not always with the same structure. :-) That was how many of the initial libraries came about.
This, of course, creates unnecessary confusion and breaks the law of least astonishment, but we have not been able to do anything about it. Any suggestions of revising the modules have always been met with a resounding "no".
My own personal style is a usually structured, though I don't know if it conforms to any written guidelines or standards.
I generally have the thing or things I am working on as the first arguments, or at least very close to the beginning; the order depends on what feels best. If there is a global state which is chained through the whole module, which there usually is, it is placed as the last argument and given a very descriptive name like St0, St1, ... (I belong to the church of short variable names). Arguments which are chained through functions (both input and output) I try to keep the same argument order as return order. This makes it much easier to see the structure of the code. Apart from that I try to group together arguments which belong together. Also, where possible, I try to preserve the same argument order throughout a whole module.
None of this is very revolutionary, but I find if you keep a consistent style then it is one less thing to worry about and it makes your code feel better and generally be more readable. Also I will actually rewrite code if the argument order feels wrong.
A small example which may help:
fubar({f,A0,B0}, Arg2, Ch0, Arg4, St0) ->
{A1,Ch1,St1} = foo(A0, Arg2, Ch0, St0),
{B1,Ch2,St2} = bar(B0, Arg4, Ch1, St1),
Res = baz(A1, B1),
{Res,Ch2,St2}.
Here Ch is a local chained through variable while St is a more global state. Check out the code on github for LFE, especially the compiler, if you want a longer example.
This became much longer than it should have been, sorry.
P.S. I used the word thing instead of object to avoid confusion about what I was talking.
No, there is no consistently-used idiom in the sense that you mean.
However, there are some useful relevant hints that apply especially when you're going to be making deeply recursive calls. For instance, keeping whichever arguments will remain unchanged during tail calls in the same order/position in the argument list allows the virtual machine to make some very nice optimizations.

Resources