Erlang/OTP 17.0 has been released
erlang.org
erlang.org
Manpage for Maps: http://www.erlang.org/doc/man/maps.html
Older documentation for Maps (EEP): http://www.erlang.org/eeps/eep-0043.html
Important note found on the reference manual page:
Maps are considered experimental during OTP 17 and may be subject to change.
The documentation below describes it being possible to use arbitrary expressions or variables as keys, this is NOT implemented in the current version of Erlang/OTP.
Exceptions returns badarg instead of badmap, this will change in the future releases.
M4 = #{{"w", 1} => f()}. % compound key associated with an evaluated expression
And of course self-referencing is a welcome addition (especially on the terminal) Fac = fun(0) -> 1; (N) -> N*Fac(N-1) end
~B fun Fac(0) -> 1; Fac(N) -> N*Fac(N-1) end
Note that the name `Fac` is not visible outside of the fun's scope, and to use the same variable name outside, you still need to bind it: F = fun Fac(0) -> 1; Fac(N) -> N*Fac(N-1) end var f = function fac(n) { if (n==0) { return 1; } else {return fac(n-1)*n; } };
console.log(f(3));
console.log(fac(3));
This will log '6' and error out on the last one (fac is undefined). This is the same scoping Erlang uses for anonymous function names as far as I can tell, with one difference: Erlang's function name is a variable that can be used as such internally. In Javascript, the function name doesn't refer to a variable per se: var f = function fac() { console.log(fac) };
console.log(f);
f();
Which will log 'fac()' and 'undefined'. In Erlang: 1> F = fun Fac() -> Fac end.
#Fun<erl_eval.44.71889879>
2> F().
#Fun<erl_eval.44.71889879>
Both instances (F and Fac within the right scope) return the same anonymous function. var f = function foo() { console.log('Me:', foo); }
f();
Me: function foo() { console.log('Me:', foo); }
undefinedWith maps this whole class of problems goes away.
A friendly warning from long time dictionary (ab)user. They introduce their own class of problems. Basically the strong vs weak type ones.
I'm curious whether this efficiency-in-storage translates to effiency-in-messaging, though:
• When you pass a map N times to another process, is the key-set copied N times? (Not that bad if true, so I'm guessing so.)
• When you pass a map N times over the distribution protocol, is the key-set serialized and transmitted N times? (This'd be pretty bad if true.)
The second one: yes and no. The format is described at http://erlang.org/doc/apps/erts/erl_ext_dist.html and maps are laid out as a serialized construction like you say. Two points balances this out: There is an atom-cache which allow you to cache atoms and make their representation small. And you can zlib-compress the data.
It is not set in stone yet and might even change in a later versions. The term format is versioned so you can upgrade it later if need be.
But the rule of the Ericsson OTP team is to get it correct before making it fast.
For seeing where it's heading, read Duncan's website: http://technicae.cogitat.io/search/label/lfe He gave an excellent presentation on this at Erlang Factory conference in San Francisco last month.
Otherwise, the main website is: http://lfe.github.io
Note that the functionality is experimental, and not
supported. This functionality will be subject to backward
incompatible changes. You should not enable the dirty
scheduler functionality on production systems. It is only
provided for testing.http://www.erlang.org/download/armstrong_thesis_2003.pdf
A few quotes:
-------------------
The central problem addressed by this thesis is the problem of constructing reliable systems from programs which may themselves contain errors. Constructing such systems imposes a number of requirements on any programming language that is to be used for the construction. I discuss these language requirements, and show how they are satisfied by Erlang…
History:
1998 — Ericsson delivered the first AXD301. The AXD301 is the subject of one of our case studies in Chapter 8. At the time of writing (2003) the AXD301 has over 1.7 million lines of Erlang code which probably makes it the largest system ever to be written in a functional style of programming.
…Telephone exchanges are expected to be extremely reliable: Typically having less than two hours of down-time in 40 years
…We organise the software into a hierarchy of tasks that the system has to perform. Each task corresponds to the achievement of a number of goals. The software for a given task has to try and achieve the goals associated with the task.
Tasks are ordered by complexity. The top level task is the most complex, when all the goals in the top level task can be achieved then the system should function perfectly. Lower level tasks should still allow the system to function in an acceptable manner, though it may offer a reduced level of service.
Programming a hierarchy of tasks needs a strong encapsulation method. We need strong encapsulation for error isolation. We want to stop programming errors in one part of the system adversely affecting software in other parts of the system.
The essential problem that must be solved in making a fault-tolerant software system is therefore that of fault-isolation. Different programmers will write different modules, some modules will be correct, others will have errors. We do not want the errors in one module to adversely affect the behaviour of a module which does not have any errors.
…Our applications are structured using large numbers of communicating parallel processes. We take this approach because [it] provides an architectural infrastructure — we can organize our system as a set of communicating processes. By enumerating all the processes in our system, and defining the message passing channels between the processes we can conveniently partition the system into a number of well-defined sub-components which can be independently implemented, and tested.
Concurrent processes with no data sharing provide a strong measure of fault isolation. A software error in a concurrent process should not influence processing in the other processes in the system.
…In our system concurrency plays a central role, so much so that I have coined the term Concurrency Oriented Programming to distinguish this style of programming from other programming styles.
In Concurrency Oriented Programming the concurrent structure of the program should follow the concurrent structure of the application. It is particularly suited to programming applications which model or interact with the real world.
Concurrency Oriented Programming also provides the two major advantages commonly associated with object-oriented programming. These are polymorphism and the use of defined protocols having the same message passing interface between instances of different process types.
…In the real world sequential activities are a rarity. As we walk down the street we would be very surprised to find only one thing happening, we expect to encounter many simultaneous events. If we did not have the ability to analyze and predict the outcome of many simultaneous events we would live in great danger, and tasks like driving a car would be impossible. The fact that we can do things which require processing massive amounts of parallel information suggests that we are equipped with perceptual mechanisms which allow us to intuitively understand concurrency without consciously thinking about it.
When it comes to computer programming things suddenly become inverted. Programming a sequential chain of activities is viewed the norm , and in some sense is thought of as being easy, whereas programming collections of concurrent activities is avoided as much as possible, and is generally perceived as being difficult.
I believe that this is due to the poor support which is provided for concurrency in virtually all conventional programming languages. The vast majority of programming languages are essentially sequential; any concurrency in the language is provided by the underlying operating system, and not by the programming language.
The inability to isolate software components from each other is the main reason why many popular programming languages cannot be used for making robust system software.
…”It is essential for security to be able to isolate mistrusting programs from one another, and to protect the host platform from such programs. Isolation is difficult in object-oriented systems because objects can easily become aliased. (An aliased object is one where at least two other objects hold a reference to it.)” — Bryce
Bryce goes on to say that object aliasing is difficult if not impossible to detect in practice, and recommends the use of protection domains (akin to OS processes) to solve this problem.
…In a paper on Java Czajkowski, and Dayn`es, from Sun Microsystems, write:
“The only safe way to execute multiple applications, written in the Java programming language, on the same computer is to use a separate JVM for each of them, and to execute each JVM in a separate OS process. This introduces various inefficiencies in resource utilization, which downgrades performance, scalability, and application startup time. The benefits the language can offer are thus reduced mainly to portability and improved programmer productivity. Granted these are important, but the full potential of language-provided safety is not realized. Instead there exists a curious distinction between “language safety,” and “real safety”. ”
In this paper they introduce the MVM (an extension to the JVM) where their goal is:
… to turn the JVM into an execution environment akin to an OS. In particular, the abstraction of a process, offered by modern OSes, is the role model in terms of features; isolation from other computations, resources accountability and control, and ease of termination and resource reclamation.
To achieve this they conclude that:
… tasks cannot directly share objects, and that the only way for tasks to communicate is to use standard, copying communication mechanisms, …
…Many of the features of the Tandem computer bear a striking similarity to the design principles in the OTP system, and to the fundamental principles of Concurrency Oriented Programming which where discussed earlier.
Here are two quotes from the paper, firstly the design principles on page 15
There is considerable controversy about how to modularize software. Starting with Burroughs’ Espol and continuing through languages like Mesa and Ada, compiler writers have assumed perfect hardware and contended that they can provide good isolation through static compile-time type checking. In contrast, operating systems designers have advocated run-time checking combined with the process as the unit of protection and failure.
Although compiler checking and exception handling provided by programming languages are real assets, history seems to have favored the run-time checks plus the process approach to fault-containment. It has the virtue of simplicity—if a process or its processor misbehaves, stop it. The process provides a clean unit of modularity, service, fault containment and failure.
More modern work with object-oriented systems has also recognised the importance of isolating software components from each other. In [21] Bryce and Razafimahefa argue that is is essential to isolate programs from one another, and from the programs which run in the host operating system. This, they consider, is the essential characteristic that any object system must have. As they point out in their paper, this is a difficult problem in an object-oriented context.
https://www.erlang-solutions.com/downloads/download-erlang-o...
While R17 wasn't ready for this approach immediately upon the announcement, I'd expect it any day since other pre-compiled packages have been made available already.
Essentially:
wget http://packages.erlang-solutions.com/erlang-solutions_1.0_al...
sudo dpkg -i erlang-solutions_1.0_all.deb
sudo apt-get update
sudo apt-get install erlang