[erlang-questions] Was Re: Bug ?! now Erlang comment (LONG LONG)

Robert Virding <>
Mon Oct 16 23:43:32 CEST 2006


Thomas Lindgren wrote:
> 
> --- Robert Virding <> wrote:
> 
> 
>>I believe it is important to keep things clean,
>>consistent and elegant 
>>otherwise you will end up with a language built on
>>exceptions.
> 
> 
> So what is your opinion on Erlang of today? (half :-)
> 
> Best,
> Thomas

I have been debating with myself whether to answer this but in the end I 
gave in and decided that I would.

Omn the whole I think we got things right but there are some things 
which are wrong. Some are new, some are old and some are even my fault. 
:-) So here is a collection of comments, major and minor (major marked 
with +):

- The naming and argument orders of the standard libraries is 
inconsistent. While this can seem trivial it does break the principle of 
least astonishment and therefore causes unnecessary problems.

- The syntax could have been cleaned up a bit. No, I don't see any 
problems with having ';' as separator not a terminator. Being able to 
write "foo(X) -> X;." sucks.

+ Should have had proper variable scoping, what is right for Prolog is 
not best for Erlang. I would also have all variables in patterns as 
fresh variables and have explicit tests for equality with already bound 
variables.

+ The concept of what a BIF (Built In function) is is a mess. Now it 
seems to mean something written in C. That is something we addressed in 
the standard and got right. A BIF is a function which is part of the 
langauge but without special syntax. So spawn and link are just as much 
Erlang as ! and receive but they look like functions. BIFs have the same 
dignity as the emulator, both ARE the language.

What language a BIF is written in is irrelevant.

Most BIFs can be called through the module erlang so having the module 
erlang as part of OTP just does not make sense.

- Some of the BIF names are too long, tget and tset would have been better.

- A suggestion in the standard was to have BIFsin different modules not 
just erlang, for example atom, tuple, number, proc, ... This would have 
been much better and could have been added with a minimum of trouble.

+ There is no layering in the standard libraries, all is part of OTP. 
This make is difficult to build small, stand-alone application. In 
essence you tend to get what OO was accused of: you want the banana but 
get the whole gorilla as well. Yes, you can make a tool which extracts 
what you want but that is a work-around not a fix.

Many of the libraries are so fundamental that having them managed by OTP 
does not really make sense, they are below that necessary for it.

Joe and I discussed this alot and we agreed on the principle but not on 
all the details. I would like to see something like:

____________________________________________________________________

		erlang emulator + BIFs (see above)
____________________________________________________________________

	basic libraries - lists, file, io etc. (maybe layered as well)
____________________________________________________________________
						|
   OTP	| included applications - compiler, etc	|
_________________________________________________

			user apps, OTP based or otherwise
____________________________________________________________________

The system is useable without OTP and applications can choose at what 
level they need the libraries. I hope the diagram is understandable.

- Binaries are nice but I don't really like the bit syntax, although I 
haven't really sat down and come up with a better alternative.

- Records as they stand are not beautiful. However, it is important to 
remember that when they were introduced it was an absolute requirement 
that they would be as fast as using tuples directly. Even this 
implementation was suspect. I kid you not.

- Structs or dictionaries as suggested by Richard O'K would be a BIG WIN.

+ All forms of communication between processes should be asynchronous. 
Messages signals, links, ALL of them. You send them off and depending on 
what you do you may get an exit signal back. Originally the only thing 
which broke this principle was sending to a local registered process, 
now, however, more things break it. Link for example.

Why worry you may ask. Well, everything which is asynchronous will 
automatically scale to distributed systems, synchronous calls don't! 
This may also affect multi-core implementations which are going to be 
very important.

+ Originally there were two basically different types of objects in 
Erlang: static terms and things with dynamic state, processes.

A process is something which has process semantics, you communicate 
through messages, can link to it and exchange exit signals. N.B. how a 
process is implemented is irrelevant it is the external semantics which 
define a process.

Unfortunately there two (at least) things in erlangwhich don't conform 
to this principle, ETS tables and ports. They're coming next.

+ ETS tables are neither and this causes problems. ETS was conceived to 
solve two main problems: fast, near constant access to large tables; and 
to get around the garbage collection problem in the erlang 
implementation. If you have a LARGE process then it is noticeable when 
the emulator stops during a collection. This problem still exists today.

The solution to the second problem was to keep ETS tables in a 
completely separate area and copy data to/from processes. Unfortunately 
this implementation detail, which it is, affected the interface and 
instead of solving the real problem, i.e. the copying, work-arounds were 
added to minimise this, match_XXXX, select_XXXX, ms_transforms. No one 
can claim that match patterns and matchspecs are beautiful or fit in 
with the rest of erlang. These are just work-arounds to minimise copying 
and would be unnecessary if the implementations was fixed. Then you 
could use a proper pattern to select and all you would need is fold.

Getting back ETS tables are neither static data or processes and break 
the principle.

+ Ports are funny. Originally when they were conceived they had only 
process semantics, in fact we actually debated whether to have a 
separate data type at all. They were modelled on UNIX streams, the idea 
being that you could insert various filters along the way without the 
users noticing. This is no problem with processes.

However, the the various port_XXXX commands were added and now ports are 
different. Ironically, the manual calls the process interface illogical 
because it is different from the function interface.

- if should really have been what cond is today. Is cond today?

- The abstract form of the erlang syntax should have been in a form 
which could be described by records.

- and/or and andalso/orelse are different semantically and having both 
is a win, although some people don't think so.

- catch should not have been an operator but instead catch ... end.

- Erlang does not need currying.

- Erlang was originally designed to follow the KISS principle.

+ Perhaps we should have defined the message interface more often 
instead of wrapping everything in an access function? You can do more 
with the interface.

+ You need both link and monitor_process, it would have been better to 
have a more basic primitive on which both are built. Easier to under 
stand the interactions.

Having everything consistent makes it easier to understand and lessens 
the risk of strange interactions. If everything is a process and obeys 
the (asynchronous) process semantics then it easier to understand the 
interactions. They will all be explicit in the code (even the mistakes 
:-)) and not so dependant on which order you do things because sometimes 
you get a fault and sometimes a signal so if they are in the wrong order 
then somethings won't get done.

Special cases just cause problems in the long run.

That's about it for the first go. I will willingly debate any of my 
comments on the erlang, but don't expect me to change my mind. Being, as 
I am, right.

Robert

"I'm not arrogant, I'm right!"



More information about the erlang-questions mailing list