here is a daemon that runs forever
foo()->
foo().
1. processes as tail-recursive functions
it's callstack will never grow. you can have multiple of these running and the scheduler will still split work between them.
a process is a tail-recursive function where the argument becomes its state.
a process ceases to exist when it stops being tail-recursive.
erlang's distributed computing strengths can in ways be attributed to tail-recursive approach to network programming & beginning with concurrency in mind. everything else came as a side-effect.
for anyone interested for more examples of expressiveness/composition, this is from my talk at functionalconf
http://www.slideshare.net/bosky101/recursion-and-erlang/43
2. Node's or machine's are first-class citizens.
you can decide to replicate data over to them, make the data on one node location-transparent, or decide to just abstract it all in a distributed system.
3. binary patten matching
you can pattern match not just [A,B] = [1,2] but also contents of A,B. or do gaurds against contents . eg if the contents of this binary variable begin with "foo".
4. you never have to import any header or module. the vm uses all modules available in its (ebin) path. big cyclic dependency headaches good bye.
5. as many schedulers as there are cores in your machine. (configurable)
6. hot code swapping.
albeit little contrived for the beginner on production systems.
7. otp
comes bundled with the fsm,client-server,etc skeletons called "otp", the same that runs 40% of the worlds telecom traffic.
~B
PS: the root link describes more such features you may find useful