tag:blogger.com,1999:blog-71187789658886771912024-03-17T08:15:14.811+01:00Robert on anythingRobert Virdinghttp://www.blogger.com/profile/16187415127098159771noreply@blogger.comBlogger21125tag:blogger.com,1999:blog-7118778965888677191.post-36162047302119852752019-01-31T00:31:00.003+01:002019-01-31T00:35:40.714+01:00The Erlang Rationale<div dir="ltr" style="text-align: left;" trbidi="on">
It's been a very long time since the last post.<br />
<br />
So there have come up questions about the Erlang Rationale. I wrote this over 10 years ago and while it has come up in some presentations it has never been published in any way. Until now that is.<br />
<br />
It is an attempt to
explain why things look like they do in Erlang and our thinking behind
many of the properties and features of the language. There is also some
descriptions of part of the system which today seem to lack description,
for example the i/o system and groups. The Rationale mainly deals with
the core parts of the language and the older parts of the libraries and
not OTP.<br />
<br />
It can be found here <a href="https://drive.google.com/file/d/1zKsOgwZJ_YZ1bY3b3gNRjAxpn6VneR8b/view?usp=sharing" target="_blank">The Erlang Rationale</a><br />
<br />
The
rationale is not finished and I am adding to it and expanding/improving
what is already there. When there has been a significant enough change I
will release a new version. However, someone suggested I could release
new bits as they come and get comments and suggestions. This seems like a
good idea and I will try it.<br />
<br />
<b>EDIT:</b> I saw there was an old blog post as well. I have updated the link in it so it works.<br />
</div>
Robert Virdinghttp://www.blogger.com/profile/16187415127098159771noreply@blogger.com240Stockholm, Sweden59.329323499999987 18.06858080000006359.07010549999999 17.423133800000063 59.588541499999984 18.714027800000064tag:blogger.com,1999:blog-7118778965888677191.post-65740257918754297592015-09-20T03:57:00.000+02:002015-09-21T00:15:50.440+02:00Reducees and Erlang I/O<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: left;">
Last week there was discussion on twitter after I made a comment that I had now found that the Erlang I/O used reducees not iteratees, and that I got the terminology wrong was not surprising seeing that neither existed when I did it. In the follow-up discussion I also commented that I thought them so simple as to be hardly worth naming. Also, that the difficult bit is formulating the problem so you know what to solve.<br />
<br />
I still hold by that.<br />
<br />
So how do reducees, not iteratees, relate to the Erlang I/O system and why is the concept simple, almost trivial, while getting the problem right is the hard bit? That I will now try to explain.<br />
<br />
We must go way back in time to when we (Joe Armstrong, Mike Williams and myself) were migrating Erlang from being a Prolog based interpreter to being its own system. So while Joe was hacking the compiler, in Erlang of course, and Mike writing the VM, in C of course, I was writing many of the libraries, in Erlang of course. And one of the libraries was about I/O.<br />
<br />
After a bit of thinking I arrived at the following basic requirements:</div>
<ol style="text-align: left;">
<li>It must work in a highly concurrent environment.</li>
<li>It must be able to interface many different device types.</li>
<li>I should be able to reuse the I/O functions irrespective of the device type.</li>
<li>It should never block on doing I/O to a device.</li>
<li>While the device speaks bytes the Erlang side need not.</li>
</ol>
<div style="text-align: left;">
So what do I mean by these requirements?</div>
- It must work in a highly concurrent environment.<br />
<div style="text-align: left;">
There are going to be many processes accessing a "device" simultaneously and it must be able to handle this sensibly. This is not a performance problem. So basing the I/O on a getchar/putchar model won't work, and if anyone doubts me try starting multiple UNIX programs in one shell all doing I/O and see the resultant mess on the screen.<br />
<br />
- It must be able to interface many different device types.</div>
<div style="text-align: left;">
This, of course, is nothing special or strange and is expected of most i/o systems.<br />
<br />
- I should be able to reuse the I/O functions irrespective of the device type.</div>
<div style="text-align: left;">
This again is nothing strange. I want to avoid having to write special I/O formatting functions for different device types.<br />
<br />
- It should never block on doing I/O to a device.<br />
Now, we are getting interesting. Seeing one of the most important requirements for the Erlang language/system is that it must be reactive and non-blocking then naturally this also extends to the I/O system. Not just at the device level where is all I/O operations already are non-blocking (yes, we have had this from the very beginning) but through all levels of the I/O system. No I/O function call should block the system more than any other function call.<br />
<br />
- While the device speaks bytes the Erlang side need not.<br />
This again is nothing strange, it just allows to have nicer interface to the I/O system.<br />
<br />
I just want to point out that these requirements didn't just spring out of nowhere but evolved as I was thinking about the problem, from past experience and from how other systems do it. System 5 streams were influential.<br />
<br />
So where did we go from here?<br />
<br />
My idea was to make the I/O system built on processes, very Erlangy, very concurrent and non-blocking and also very scalable. It is based around the concept of an "I/O-server". This is a process which handles all the I/O requests to/from a device, a device being a physical device, a file, the screen, a TCP socket, etc. It has two "sides". On one side the I/O-server speaks Erlang I/O requests and on the other side it speaks the device, basically sending receiving bytes to/from the device in the right format. At this level devices speak bytes. It would typically go through an Erlang port.<br />
<br />
The I/O-server is then a process which sits in a receive loop processing i/o requests as they come. It would handle one request at a time. This is just the standard Erlang way of processing requests so it would be just as non-blocking and reactive as the rest of system.<br />
<br />
So output is easy. When you do an output call you send a chunk of bytes, an iolist, to the I/O-server and it device side will see that it is sent to the device. Or you could send the I/O-server a function to generate bytes which it evaluates and then sends the bytes to the device. The Erlang I/O system has both. The I/O-server would guarantee that all the output from each request was sent as one block of data to the device.<br />
<br />
Input is more difficult. A fundamental problem is that most times when you do a read of some sort you don't know how many bytes you need from the device. Even for the "trivial" case of getting a line this can be very difficult. How long is the line, 0 bytes, 1 byte, 42 bytes, 4711 bytes, ...? And what if the number of bytes you need in no way relates to the bytes are received from the device.<br />
<br />
Now things are getting interesting! So an obvious way to solve this is to send the I/O-server a function which is used to collect bytes until it gets enough and then return them to the caller. You first call it with the bytes you have. What happens if it needs more bytes?<br />
<br />
One solution is for the collect function to call a function which returns more bytes. A major problem with this solution is that the I/O-server now loses control and is no longer in charge which in really needs to be. For example it may need to handle messages from the device or other I/O requests, all this while we are processing the original input request.<br />
<br />
A much better solution is for the collect function to work with the bytes that it has been given and return a status:<br />
<br />
- <b><i>OK</i></b>, I could collect what I was supposed to and here is the result to send back and here are the remaining bytes.<br />
- <b><i>More</i></b>, I need more bytes and here is a continuation to call me with when you get more bytes.<br />
- <b><i>Error</i></b>, an error occurred, here is the error and the remaining bytes.<br />
<br />
So the I/O-server will keep calling the collect function as long is it requires more and then send back the reply when it is done. The I/O-server is then ready to process the next request. It has always been in control if necessary. Also the collect function is completely general as it has no knowledge of how the bytes are collected or how the return value is handled, which was our third requirement.<br />
<br />
The collect function with this type of interface is a reducee. QED<br />
<br />
Would it have been easier if reducees had already been "invented" and I knew about them? I don't think so. The major difficulty here was trying to clearly formulate the problem and define a structure which solved the problem. Once that was done the reducee part just naturally fell out, but without that structure the reducee had no meaning. That is why I commented that I found them so simple as to be hardly worth naming. I still don't.<br />
<br />
OK, this became much longer than I intended, sorry for that.<br />
<br />
<b>EDIT:</b><br />
Using processes like the I/O-server to build the I/O system makes many things very easy, almost trivial, for example:<br />
<ul style="text-align: left;">
<li>Having a master/slave nodes for file system where all file access goes through the master node.</li>
<li>Starting a task on another and have all its default I/O go to your node.</li>
<li>With a TCP I/O-server open a listen socket and for every connection start a new shell and have all its default I/O go through the socket (10 lines of code).</li>
</ul>
Once you get used to structuring your application using processes and concurrency many things become quite straightforward.<br />
<br />
Robert</div>
<div style="text-align: left;">
<br /></div>
</div>
Robert Virdinghttp://www.blogger.com/profile/16187415127098159771noreply@blogger.com186Stockholm, Sweden59.329323499999987 18.06858080000006359.07010549999999 17.423133800000063 59.588541499999984 18.714027800000064tag:blogger.com,1999:blog-7118778965888677191.post-73123032209861321062014-04-09T01:02:00.000+02:002014-04-09T01:02:43.477+02:00Extending OTP<div dir="ltr" style="text-align: left;" trbidi="on">
This question came in an Elixir discussion but it is definitely not Elixir specific so I thought it might interest people.<br /><br />Many people seem to think that OTP is set in stone, encased inside an armoured concrete block and practically impossible to do anything with without launching a major attack. So if it doesn't have just the feature you are looking for then there is not much you can do except grit your teeth and accept it or avoid OTP completely and roll your own instead. This is a fundamental faulty assumption.<br /><br />First, however, what is OTP? It is many things: it is a large collection of libraries for doing things; a set of design principles and patterns for building systems and tools; and code, the behaviours, for implementing and supporting these principles and patterns. Most of these principles and patterns link together. So a system is a release, which consists of applications, which consist of code and processes at runtime organised into supervision tree. And at each level you can define how it is to manage the underlying systems. Many of the libraries are independent of the design patterns, you can do all the wonderful stuff with TCP without being in a behaviour.<br /><br />OTP is actually quite an open system which is very amenable to development and extension. This is actually not surprising as it all implemented in Erlang and the Erlang ecosystem is a very egalitarian system: all modules are equal, all processes are equal, and all applications are equal. The only difference is who wrote them. There are of course some properties you can't change, for example how releases, applications and supervision trees interact, but within those limitations you can do a lot.<br /><br />For example it is easy to create a new behaviour. So if you feel that gen_server does not give you the functionality you need or want then the easiest solution to create a new behaviour which has the right functionality. One way to this is to build your new behaviour on top of an existing behaviour. For example implement your behaviour on top of a gen_server using the gen_server callbacks to implement a base to call the callbacks in your new behaviour. There is nothing strange about this, it is done in many places. For example the supervisor is implemented as a gen_server behaviour. Doing it this way allows you to inherit a lot of functionality for free, the new behaviour will automatically follow all the rules.<br /><br />Another way is of course to write the behaviour yourself. For example if the functionality you want does not fit nicely into an existing behaviour. This is also very easy, in some ways even easier than building on top of something else. All the tools, modules, which are used inside OTP are available. By using them and following a simple set of rules it easy to create a process which fits smoothly into a supervision and behaves exactly as it should to make OTP happy. Everything is also documented, look under the <span style="font-family: "Courier New",Courier,monospace;">proc_lib</span> and <span style="font-family: "Courier New",Courier,monospace;">sys</span> modules for starters.<br /><br />Sometimes you don't need or want another behaviours then using these tools it of course easy to a create a singleton type of process. Again all the tools for doing this is there.<br /><br />My point is that it is easy to extend OTP to provide the functionality you need without having to do any serious hacking of the system. Unfortunately too few people seem to know this. It is sometimes amazing to see the lengths people go to squeeze something into a gen_server when it would have been much easier to roll their own.<br /><br />OTP was never meant to be the answer to (life, the universe and) everything, it "just" provides the basic building blocks and all the tools necessary to extend it. View the existing behaviours as a starter kit. So if you feel that OTP is lacking something then don't complain but fix it.<br />
<br />
Robert<br />
<br /></div>
Robert Virdinghttp://www.blogger.com/profile/16187415127098159771noreply@blogger.com5Stockholm, Sweden59.328930000000007 18.06491000000005459.06971200000001 17.419463000000054 59.588148000000004 18.710357000000055tag:blogger.com,1999:blog-7118778965888677191.post-35670302716946724572014-03-16T23:49:00.000+01:002014-03-17T13:35:51.636+01:00Erlang/Elixir communities<div dir="ltr" style="text-align: left;" trbidi="on">
After the keynote by José Valim and Dave Thomas at the <a href="http://www.erlang-factory.com/conference/show/conference-6/home/" target="_blank">Erlang Factory in San Francisco</a> there were of course many discussions on the IRC Elixir channel. Some were advocating a split in the community into two separate communities. I personally think this would be a bad thing for a number of reasons:<br />
<ul style="text-align: left;">
<li>The Erlang/Elixir combined community is not that large and splitting it into smaller parts would not help any of us. It would also be an easy target of derision: "look only 2 members and already 3 groups".</li>
</ul>
<ul style="text-align: left;">
<li>Both Erlang and Elixir are part of the Erlang "ecosystem" and not really independant. This also applies to other languages like LFE and Joxa which are also based on the fundamental principle that the interface between the language and OTP should be seemless. This could easily and unnecessarily confuse people who aren't in the know.</li>
</ul>
Fortunately, from my point of view, there were others who disagreed with this and would prefer to keep it as one community.<br />
<br />
Robert</div>
Robert Virdinghttp://www.blogger.com/profile/16187415127098159771noreply@blogger.com6tag:blogger.com,1999:blog-7118778965888677191.post-18260243785302289922014-01-20T23:58:00.000+01:002014-01-21T02:40:15.540+01:00Erlang syntax again ... and again ... and again ...<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
Every once in a while there is a blogg complaining about Erlang and its syntax. To save you the trouble here are the main syntax complaints:<br />
<br />
- The use of ';' (and ',' and '.') is strange, different and very confusing. I.e. it's not like Java.<br />
- 'if' is very strange. I.e. it is not like Java.<br />
- Variables must start with an uppercase letter. I.e. it is not like Java.<br />
- The record syntax is very strange.<br />
<br />
Actually only the record syntax <span style="font-size: small;"><i>is</i></span> strange. Unfortunately, given Erlang and the original requirements for records it is not really possible to do better. So while many have complained, very few have accepted the challenge of coming up with something that looks better and works, and no-one has succeeded.<br />
<br />
What I don't understand is when people want Erlang to look like XXXX, their language of choice. This idea I find very strange for many reasons:<br />
<br />
- Unless the XXXX is Lisp it usually has a much more complex and messy syntax than Erlang. While the Erlang syntax may be different it is actually quite small, simple, regular and concise; much more so than the common choices of XXXX are.<br />
<br />
- Usually XXXX has completely different semantics from Erlang. In most languages the syntax is (hopefully) tuned to its semantics, at least Erlang's is, so using XXXX syntax for Erlang would definitely be trying to fit a square peg in a round hole.<br />
<br />
- A more philosophical reason is that I think if a language looks like XXXX it should behave like XXXX, not like something completely different. If it behaves differently it will just cause confusion and disappointment in the long run: "It looks like XXXX, but my XXXX code doesn't work the way it is supposed to". This is actually a valid criticism.<br />
<br />
While I can understand people may dislike the syntax of a certain language, even <i>I</i> dislike some syntaxes, I don't understand people who say "I was going to learn Erlang but the syntax was so strange I quit". For me the syntax is the easiest part of learning a new language, it is really just a RTFM. At last count I have actively programmed in the following languages: Basic, Fortran, Pascal, C, Lisp, Prolog, Erlang, Lua and a number of different assembly languages. I am now teaching myself Python and Haskell. Lisp and Prolog are really groups of languages but they are so similar I class them together. I don't know whether to include Awk and Sh as well. All have different syntaxes. And I don't think I am in anyway unique in this as most programmers will find that they actually have used many languages.<br />
<br />
My point is that the syntax is the easy part of learning a new language, just look it up in the manual. It is learning the semantics of the new language and how to use it efficiently to solve your problems which are the major difficulties. How do I structure my solution to best make use of the language and its environment? This is where major rethinks will occur. This is what takes time to learn and understand. Not in what it looks like.<br />
<br />
Robert<br />
<br />
P.S. Yes, I have implemented another syntax front-end for Erlang, but it is Lisp based so that is quite a natural thing to do. Lisp has such a simple and powerful syntax so how could I <i>not</i> do it. It is the syntaxes from other languages which are more complicated and messy.</div>
Robert Virdinghttp://www.blogger.com/profile/16187415127098159771noreply@blogger.com17Stockholm, Sweden59.328930000000007 18.06491000000005459.06971200000001 17.419463000000054 59.588148000000004 18.710357000000055tag:blogger.com,1999:blog-7118778965888677191.post-60880498648455628602014-01-14T00:19:00.000+01:002014-01-14T00:19:21.842+01:00LFE, Lisp and Erlang<div dir="ltr" style="text-align: left;" trbidi="on">
<br />My LFE (Lisp Flavoured Erlang), <a href="https://github.com/rvirding/lfe" target="_blank">here</a> and <a href="http://lfe.github.io/" target="_blank">here</a>, is not a Lisp-1 but a Lisp-2 as I think this fits better with Erlang. Well, it is really a Lisp-2+ which I will explain in a moment.<br /><br />What are Lisp-1 and Lisp-2? Richard P. Gabriel in his <a href="http://www.dreamsongs.org/Separation.html" target="_blank">paper</a> defined the two as follows:<br />
<blockquote>
Lisp-1 has a single namespace that serves a dual role as the function namespace and value namespace; that is, its function namespace and value namespace are not distinct. In Lisp-1, the functional position of a form and the argument positions of forms are evaluated according to the same rules. Scheme is a Lisp-1 dialect. </blockquote>
<blockquote>
Lisp-2 has distinct function and value namespaces. In Lisp-2, the rules for evaluation in the functional position of a form are distinct from those for evaluation in the argument positions of the form. Common Lisp is a Lisp-2 dialect. </blockquote>
<br />What does this mean? For example take the expression <span style="font-family: "Courier New",Courier,monospace;">(f a)</span>. In Lisp-1 you take the value of <span style="font-family: "Courier New",Courier,monospace;">f</span> as the function to call with the value of <span style="font-family: "Courier New",Courier,monospace;">a</span> as the argument, while in Lisp-2 you take the function of <span style="font-family: "Courier New",Courier,monospace;">f</span> to call with the value of <span style="font-family: "Courier New",Courier,monospace;">a</span> as the argument; you don't use the value of <span style="font-family: "Courier New",Courier,monospace;">f</span>. In Lisp-2 if you want to use the value of <span style="font-family: "Courier New",Courier,monospace;">f</span> as a function, for example if it a local variable, you can't do this directly but need to do something like <span style="font-family: "Courier New",Courier,monospace;">(funcall f a)</span> to do this, which is how it is done in LFE.<br />
<br />Lisp-1 is generally considered more elegant and simpler to understand, so why not use it for LFE? Well, this is where the properties of Erlang and the BEAM step in.<br /><br />In Erlang you can define many top-level functions with the same name but with different arities, for example <span style="font-family: "Courier New",Courier,monospace;">f/1</span>, <span style="font-family: "Courier New",Courier,monospace;">f/2</span> and <span style="font-family: "Courier New",Courier,monospace;">f/3</span>. While it was not strictly necessary to be able to do this in LFE, it is a basic property of Erlang which I felt was necessary to handle. Lisp-1 is clearly one value/function per name so it is difficult to extend the concept in a clean way. If we allow a symbol to have many functions at the top-level it seemed natural to be able to do this for local symbols/variables as well. <br /><br />So in LFE we can both many top-level functions with the same name but different arities like Erlang:<br /><br /><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">(defun f (x) x)<br />(defun f (x y) (+ x y))<br />(defun f (x y z) (+ x y z))</span></span><br />And we can also define many local functions with the same name but different arities:<br /><br /><span style="font-family: "Courier New",Courier,monospace;">(flet ((f (x) x)<br /> (f (x y) (+ x y))<br /> (f (x y z) (+ x y z)))<br /> (list (f 5) (f 5 6) (f 5 6 7)))<br /><br />=> (5 11 18)</span><br /><br />I felt this was easier to do in a clean way if LFE was a Lisp-2.<br /><br />This is what I meant in the beginning when I said LFE is a Lisp-2+, it not only has separate value and function space but it also allows multiple function definitions for the same name. Like Erlang does.<br /><br />Robert<br /></div>
Robert Virdinghttp://www.blogger.com/profile/16187415127098159771noreply@blogger.com0Stockholm, Sweden59.328930000000007 18.06491000000005459.06971200000001 17.419463000000054 59.588148000000004 18.710357000000055tag:blogger.com,1999:blog-7118778965888677191.post-87205268237637527112013-12-30T02:30:00.000+01:002014-01-10T19:59:29.720+01:00SL busslinje 52<div dir="ltr" style="text-align: left;" trbidi="on">
Ibland undrar man seriöst hur de tänker.<br />
<br />
Ena ändhållplats för SL buss 52 ligger vid Nybroplan. För de som inte vet så ligger Nybroplan längst in i Nybroviken och vid början på Strandvägen. Nu är det så att bussen inte kan vända vid Nybroplan utan den måste åka till andra ändan av Strandvägen där det går att vända och det finns plats för bussen att stå och vänta. Nu är det så att på vägen längs Strandvägen åker den förbi två hållplatser åt vardera håll där den inte stannar eftersom den är ur trafik.<br />
<br />
Jag antar att det finns någon vettigt anledning till ändhållplatsen finns där den är men jag kan inte förstå den. Varför inte bara flytta den så att bussarna kan stanna på hållplatserna de ändå åker förbi?<br /><br />
Som sagt ibland undrar man hur de tänker.<br /><br />Robert<br /></div>
Robert Virdinghttp://www.blogger.com/profile/16187415127098159771noreply@blogger.com1Östermalm, Östermalm59.336704 18.08531tag:blogger.com,1999:blog-7118778965888677191.post-76019171094539085312013-12-29T20:28:00.000+01:002014-06-07T22:37:48.556+02:00Reactive Programming manifesto<div dir="ltr" style="text-align: left;" trbidi="on">
A few months ago I apparently managed rile up people on Twitter with some comments I made about the "Reactive Manifesto". I don't really know why because, as I explicitly tweeted, I am all for reactive programming and I think it is the cat's whiskers.<br />
<br />
What greatly irritated me, and it still irritates me, is that claim that this is something new:<br />
<blockquote class="tr_bq">
"But now a new architecture has evolved to let developers conceptualize and build applications that satisfy today's demands. We call these Reactive Applications."</blockquote>
This is pure BS. Reactive programming has been around as long as computers have been controlling hardware, which is quite a while. The "today's demands" are the same as they have always been. None of the concepts discussed in the manifesto, <i>responsive</i>, <i>event-drive</i>, <i>scalable</i> and <i>resilient</i>, are new or novel.<br />
<br />
For example we, the Erlang community, have been doing reactive programming for around 25 years, and FRP (Functional Reactive Programming) at that. And I am not claiming we were the first to do FRP, but we did invent it on our own. In fact before that were doing LRP (Logical Reactive Programming), and we weren't first with that either. All the concepts mentioned in the manifesto, are commonplace to us, and, again, I am not claiming we were the first.<br />
<br />
So while I am definitely a fan of reactive programming I will not sign the manifesto until becomes more honest about the origins of the concept.<br />
<br />
A cause for reflection is that apparently a large portion of the (web)programming community believes that this is new and novel.<br />
<br />
Who have I not managed to rile up now?<br />
<br />
<b>EDIT: </b>I understand very well that writing:<br />
<blockquote class="tr_bq">
"But there is an old, well tried and tested architecture which lets developers conceptualize and build applications that satisfy today's demands."</blockquote>
is not going to attract any hipster wannabes. And I also understand that advertising puts a lost of effort into reselling old ideas, but writing things like this makes this manifesto seem more like advertising. At least to me.<br />
<br />
Strangely enough there is an improvement to this on the github page which declares <i>some</i> of these ideas at least as "long-known" but that never made it into the actual manifesto.<br />
<br />
Robert<br />
<a href="https://twitter.com/rvirding" target="_blank">@rvirding</a><br />
<br />
P.S. On reflection there is one thing which I understand people could get riled up about: my travesties of Monty Python, "I didn't expect the Manifesto! NOBODY expects the Manifesto!", and Long John Baldry, "Don't try to lay no manifesto on the king of reactive programming".</div>
Robert Virdinghttp://www.blogger.com/profile/16187415127098159771noreply@blogger.com2Stockholm, Sweden59.328930000000007 18.06491000000005459.06971200000001 17.419463000000054 59.588148000000004 18.710357000000055tag:blogger.com,1999:blog-7118778965888677191.post-21499445439213817952012-06-19T23:43:00.000+02:002012-06-19T23:43:29.640+02:00Twitter arguments and languages<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="font-family: inherit;">
I recently got into a discussion/argument on twitter. I try to avoid this as it is basically impossible to argue properly in 140 character chunks but sometimes I succumb to the temptation.</div>
<div style="font-family: inherit;">
<br /></div>
<div style="font-family: inherit;">
This discussion was about Erlang and what it was good for. Towards the end the other guy said that he hated "Languages that cram bizarre "paradigms" down people's throats", to which I replied that if he doesn't like them then don't use them and to stop whining about it. Which is not a too bad reply in 140 characters.</div>
<div style="font-family: inherit;">
<br /></div>
<div style="font-family: inherit;">
Thinking about it later I realised that <i><b>all</b></i> languages cram their more or less bizarre paradigms down people's throats, some even multiple paradigms. It's just that we don't notice it when it is a paradigm with which we are familiar. I find functional programming natural so to me Erlang is just stating the obvious; it is much worse with these weird OO-languages which have some strange concepts like "mutable data". Whatever that is? And how can they live with not using {} for tuples?<br />
<br />
Seriously, just pick the best language/paradigm for what you are doing, stop whining and get on with it. And accept the fact in a larger application there is generally no one <i>best</i> language so be prepared to go polyglot. Though I will admit that <i>best</i> is not always easy to define and you don't always like the answer.<br />
<br /></div>
</div>Robert Virdinghttp://www.blogger.com/profile/16187415127098159771noreply@blogger.com5Stockholm, Sweden59.32893 18.0649159.199335 17.749053 59.458525 18.380767000000002tag:blogger.com,1999:blog-7118778965888677191.post-29305681011176485352009-10-24T17:13:00.002+02:002009-10-24T17:16:45.518+02:00What are BIF's?There has always been much confusion about what a BIF really is, how they relate to the Erlang language. An example of this was a discussion earlier this year when someone wanted to have some more functions in lists coded in C and so become part of Erlang. Saying that they are functions coded in C just tell us how they are implemented not what they *are*.<br /><br />The source of this confusion is very old and exists in the earliest documentation, where a BIF was described as function "which could not be written in Erlang or written in C for efficiency". They were in some sense implicitly part of Erlang and considered to be in the module 'erlang'. Some could be used without specifying the module but there was no clear reason why some needed the module and others did<br />not.<br /><br />A first proper attempt to define what a BIF is came when Jonas Barklund and I wrote the Erlang specification. There we proposed that a BIF was part of the Erlang language that did not have a special syntax but looked like a normal function call. Spawn, link and trapexit are just as much part of Erlang as ! and receive even though they use normal function syntax and semantics. We also decided that it was irrelevant in what language the function was written, what was important was the function itself. This is analogous to processes where the semantics are what is important. I think this definition is correct but calling them BIFs was wrong.<br /><br />Our BIF proposals were put on ice together with the Erlang specification.<br /><br />The problem still remains and has not become better - there is still much confusion as to what a BIF is, if being coded in C has anything to do with it, and if being coded in C means that the functions automatically becomes part of the language. BEAM and the compiler also handle BIFs in many different ways which does not always help.<br /><br />Currently BIF is used to describe at least three different things:<br /><br />- Functions which are part of Erlang, spawn and link are examples of this.<br /><br />- Functions which are not part of Erlang but which are part of a basic runtime system, the trace BIFs are an example of this.<br /><br />- Functions which have been coded in C for efficiency, for example lists:reverse.<br />(Some might not agree with separating the first two)<br /><br />Moving the module 'erlang' from kernel to erts is a step in the right direction. As is putting the new unicode BIFs (?) in a separate module, because they are not part of the language just a library where some functions are coded in C.<br /><br />OK, so why worry about it? Does it really matter? I think it does (or else I wouldn't be writing this mail) for the following reasons:<br /><br />- We need a proper language specification and this would be a part of it. Some day I plan to resurrect the old Erlang spec and get it up to date and we have to start somewhere.<br /><br />- It would clarify what is part of the language and what is not. This would put various discussions about adding things to the implementation/language in their proper context. So coding a function in lists in C would just become an implementation detail where the issue would be whether it is worth the extra effort to do this, and not misplaced discussions about adding to the language.<br /><br />- I think it would allow you to do more with the FFI than is proposed today and still be consistent with the language.<br /><br />- And it would help people realise and understand what is what - unclarity and confusion are never good.Robert Virdinghttp://www.blogger.com/profile/16187415127098159771noreply@blogger.com2tag:blogger.com,1999:blog-7118778965888677191.post-12438317810662210902009-04-09T03:16:00.006+02:002009-12-09T21:17:01.813+01:00Backtracking in Erlang, part 2 - passing dataIn the first part I showed how we could program backtracking in a generic way in Erlang. While Erlang does not directly support it, it is relatively easy to do. In this part we will look at some ways of handling data within this context. The basic problem is how to get data out of a function as in this context functions never return.<br /><br />For a specific application this may not be a problem as either each function always explcitly knows what the contunation is, or a it is possible to have a local convention of how to pass arguments. For an example of this see the Erlog parser in the file erlog_parse.erl where each continuation function has two arguments, the remaining tokens and the term parsed so far. This works well for this specific case.<br /><br />This is not possible in the general case or when writing generic functions. Seeing we cannot return values we will adopt the method used in logic languages like prolog (or C) of "returning" values through the function arguments. For example the following "function" fubar/2 (written in a logic style) which takes input in the argument X and "returns" data through the argument Y:<br /><pre><br />fubar(X, Y) :- foo(X, M, N), bar(M, O), baz(N, O, Y).<br /></pre><br />Each of the functions foo/3, bar/2 and baz/3 behave in a similar way but they have varying numbers of input and output arguments.<br /><br />I will show one way how this can done. We will define a variables structure which contains the bindings of variables. It has the following interface:<br /><pre><br />new_vars() -> Vars.<br />new_var(Vars) -> {Var,Vars}.<br />bind_var(Var, Value, Vars) -> Vars.<br />get_var(Var, Vars) -> Value.<br /></pre><br />A requirement on the Vars structure is that all variable bindings are undone on backtracking. Note that we are not really defining logical variables here or implementing unification, we are just creating variables and binding them. There is no default value for a variable, trying to get the value of an unbound variable will generate an error.<br /><br />We will adopt the convention that all continuation functions have one argument and they will be called with the current Vars structure. We will also adopt the convention that each normal function will have its arguments in the following order: first come normal Erlang arguments, then the Vars structure, then the arguments which use the Vars structure with the input arguments first followed by the output arguments, and finally the continuation. Using Vars and this convention we could translate fubar/2 into the following Erlang function:<br /><pre><br />fubar(Vars0, X, Y, Next) -><br /> %% Create the new variables in fubar.<br /> {M,Vars1} = new_var(Vars0),<br /> {N,Vars2} = new_var(Vars1),<br /> {O,Vars3} = new_var(Vars2),<br /> Next2 = fun (Vars) -> baz(Vars, N, O, Y, Next) end,<br /> Next1 = fun (Vars) -> bar(Vars, M, O, Next2) end,<br /> foo(Vars, X, M, N, Next1).<br /></pre><br />Here we have assumed that fubar is part of a larger application which has created the Vars structure. The continuation function is called with the current Vars. So for example the (trivial) function bar/2 which has M as input and binds O for output could be written:<br /><pre><br />bar(Vars0, M, O, Next) -><br /> Mval = get_var(M, Vars),<br /> Oval = <do>do_stuff(Mval),<br /> Vars1 = bind_var(O, Oval, Vars),<br /> Next(Vars1).<br /></pre><br />Choice points are now introduced by:<br /><pre><br />cp([fun (Vs) -> do_stuff_a(Vs, Next) end,<br /> fun (Vs) -> do_stuff_b(Vs, Next) end,<br /> fun (Vs) -> do_stuff_c(Vs, Next) end,<br /> ...], Vars).<br /></pre><br />The code for cp/2, is still simple:<br /><pre><br />cp(Vars, [G|Gs]) -><br /> case G(Vars) of<br /> {succeed,Value} -> {succeed,Value};<br /> fail -> cp(Vars, Gs)<br /> end;<br />cp(_, []) -> fail.<br /></pre><br />We see here that if the Vars structure does not use side effects then we will automatically undo all bindings on backtrackíng.<br /><br />I will give a simple definition of the Vars structure and its interface. It uses dicts to store the variable bindings.<br /><pre><br />-record(vars, {vc,dict}).<br /><br />new_vars() -> #vars{vc=0,dict=dict:new()}.<br /><br />new_var(#vars{vc=Vc,dict=Dict}=Vars) -><br /> {{var,Vc},Vars#vars{vc=Vc+1}}.<br /><br />bind_var({var,Var}, Value, #vars{dict=Dict}=Vars) -><br /> Vars#vars{dict=dict:store(Var, Value, Dict)}.<br /><br />get_var({var,Var}, #vars{dict=Dict}) -><br /> dict:fetch(Var, Dict).<br /></pre><br />That's it, we're done. Again a lot of explanation for quite a simple concept and very little code.<br /><br />In the next installment I will give an example of how this can be used and some problems with the current implementation.</do>Robert Virdinghttp://www.blogger.com/profile/16187415127098159771noreply@blogger.com1tag:blogger.com,1999:blog-7118778965888677191.post-74191552452568912142009-03-18T02:47:00.010+01:002009-12-09T21:23:26.757+01:00Backtracking in Erlang, part 1 - controlSometimes you need to be able to do search algorithms which can step back and try other alternate ways of finding a solution, "backtracking". Generally this is difficult to do in functional languages like Erlang (most other languages too for that matter). A classic example of this type of problem is parsing ambiguous grammars.<br /><br />Prolog syntax is like that, in some cases you need almost indefinite look-ahead before you can decide how input is to be parsed. When I implemented Erlog (a prolog in and for Erlang) I decided to do the parser in Erlang so that it could run stand-alone and so I ran straight into this problem.<br /><br />Here is *a* solution to the problem. It is in two parts, the first describing the control structures and the second (more difficult) describing handling of data. There may also be a third part discussing some problems with the solution to control, if anyone is still interested.<br /><br />The main problem we have to overcome is that normally when you choose a path you "commit" to it and can't go back and try an alternate path. For example in:<br /><pre><br />case get_a_value() of<br /> Choice1 -> ... ;<br /> Choice2 -> ... ;<br /> ...<br />end<br /></pre><br />once you have chosen a path, say Choice1, there is no (simple) way to go back try Choice2 if you later decide that Choice1 was wrong. We can't backtrack.<br /><br />Another problem is that if we have:<br /><pre><br />a() -> foo(), bar(), baz().<br /></pre><br />and once we have completed foo() then even if it gave an answer which later was shown to be wrong there is no way to step back into it, backtrack, and let it give a new answer.<br /><br />In this first section we will (almost) completely ignore arguments and return values.<br /><br />When looking at control we will (almost) completely ignore arguments and returning values. We will use the convention that functions return either '{succeed,Value}' when they succeed or 'fail' when they can't find a solution.<br /><br />The trick is to ensure that functions only return at all when they fail, otherwise they just continue by explicitly calling the next thing which should be done. We will do this by using a Continue Passing Style (CPS) where each function will have an argument which is the next function call to continue. (CPS is not new and is generally known) So functions will usually look like this:<br /><pre><br />a(Next) -><br /> do_stuff(),<br /> OurNext = fun () -> even_more_stuff(Next) end,<br /> more_stuff(OurNext).<br /></pre><br />We will use the convention that when a function fails and cannot go on it will return 'fail'. When *the* solution has been found then the final test will return {succeed,Value}. So the top level function will look something like:<br /><pre><br />top_call() -><br /> Succeed = fun () -> {succeed,yes} end, %We have succeeded<br /> find_solution(Succeed).<br /></pre><br />So now our program will keep going forwards until it finally calls the Succeed fun when it all returns back to the initial caller.<br /><br />The next problem is to introduce 'choice points' where we can choose one path but still allow the code to backtrack and make another choice. This is the done in the function cp/1 where the argument is a list functions which are separate paths to choose from:<br /><pre><br />cp([fun () -> do_stuff_a(Next) end,<br /> fun () -> do_stuff_b(Next) end,<br /> fun () -> do_stuff_c(Next) end,<br /> ...]).<br /></pre><br />Cp/1 will try the functions in order, if one succeeds then the choice point will succeed and return the same succeed value, if it fails then the next function in the list will be tried, until no more exist when the choice point will fail: The code for cp is simple:<br /><pre><br />cp([G|Gs]) -><br /> case G() of<br /> {succeed,Value} -> {succeed,Value};<br /> fail -> cp(Gs)<br /> end;<br />cp([]) -> fail.<br /></pre><br />That's it, we're done. A lot of explanation for very little code.<br /><br />A slight variation is to not chain the continuation together as shown here but to have Next as a list of functions to call. Instead of directly calling Next you call next/1 with argument Next, next(Next), where next/1 is defined as:<br /><pre><br />next([N|Ns]) -> N(Ns).<br /></pre><br />There is no functional difference it just make writing some code a bit easier. For example the function defined above:<br /><pre><br />a() -> foo(), bar(), baz().<br /></pre><br />would look like this in the normal way:<br /><pre><br />a(Next) -><br /> Next1 = fun () -> baz(Next) end,<br /> Next2 = fun () -> bar(Next1) end,<br /> foo(Next2).<br /></pre><br />while using the list variant it would look like:<br /><pre><br />a(Next) -><br /> foo([fun (Ns) -> bar(Ns) end,<br /> fun (Ns) -> baz(Ns) end | Next]).<br /></pre><br />which can be easier to read, especially if there many calls in the continuation.<br /><br />After I introduce handling data in the next installment I can give a proper example.Robert Virdinghttp://www.blogger.com/profile/16187415127098159771noreply@blogger.com8tag:blogger.com,1999:blog-7118778965888677191.post-87675845145352044252008-11-28T22:18:00.002+01:002014-02-07T02:59:27.390+01:00The Erlang Rationale - The problem with ‘if’<div dir="ltr" style="text-align: left;" trbidi="on">
Sigh. If was added as an almost “on the spur of the moment” hack. We knew how to compile guards and thought it might be useful in the case where you don’t have a value to match against. As Erlang has pattern matching we found that a “pure” if is used less than in many other languages, we never used it much ourselves and therefore didn’t really worry much about it. This is not really that strange as in many languages if is used in way which resembles very trivial pattern matching. For example in C:<br />
<pre><span style="font-family: "Courier New",Courier,monospace;">if ((x = get_some_value()) != 0) {
do stuff with x
else {
do some other stuff
}
</span></pre>
Also I don’t really have a problem using case when I want to do a conditional, but then again I am so used to it I don't think about it.<br />
<br />
There have been repeated suggestions and discussions of either extending if to allow user defined boolean functions or adding a new construct. The problem with extending if is that the tests would no longer be guard tests and would handle differently for exceptions. A guard test silently just fails while a normal expression generates an error, which would make the change incompatible. We actually made cond a reserved word but never got around to adding it to the language.</div>
Robert Virdinghttp://www.blogger.com/profile/16187415127098159771noreply@blogger.com6tag:blogger.com,1999:blog-7118778965888677191.post-19773183682317136322008-11-08T23:23:00.002+01:002008-11-08T23:25:20.740+01:00The Erlang Rationale - Characters and stringsThis is one non-terminating discussion we had.<br /><br />There have been many suggestions whether to have a proper type character data type or to leave them as integers. While adding a new type would not have been difficult we could not quite agree as to whether we should do it. If so which encoding should we use, stay with ASCII or go to ISO-8859-1 (Latin1) or UNICODE? If we changed to UNICODE should we also allow that in atoms as well? In the end we decided not to add a character type but make sure we could handle Latin1 in the libraries. As our primary application area was not handling text we felt that this was sufficient.<br /><br />Very early on we decided that strings were lists. This was partly environment as many of the languages we were using, such as Prolog, use lists and partly practical as lists are a very powerful data type.<br /><br />Using a general data type like lists and having characters is seldom as problem as you usually know what if you are processing a list which is a string or if it is something else. It is only within generic functions like printing or the shell where you can have problems with such a general data type.Robert Virdinghttp://www.blogger.com/profile/16187415127098159771noreply@blogger.com6tag:blogger.com,1999:blog-7118778965888677191.post-63423775841808166452008-11-03T22:33:00.003+01:002019-01-31T00:33:50.795+01:00The Erlang Rationale<div dir="ltr" style="text-align: left;" trbidi="on">
A while back I released the Erlang Rationale which is an attempt to explain why things look like they do in Erlang and our thinking behind many of the properties and features of the language. There is also some descriptions of part of the system which today seem to lack description, for example the i/o system and groups. The Rationale mainly deals with the core parts of the language and the older parts of the libraries and not OTP.<br />
<br />
It can be found here <a href="https://drive.google.com/open?id=1zKsOgwZJ_YZ1bY3b3gNRjAxpn6VneR8b" target="_blank">The Erlang Rationale</a><br />
<br />
The rationale is not finished and I am adding to it and expanding/improving what is already there. When there has been a significant enough change I will release a new version. However, someone suggested I could release new bits as they come and get comments and suggestions. This seems like a good idea and i will try it.</div>
Robert Virdinghttp://www.blogger.com/profile/16187415127098159771noreply@blogger.com4tag:blogger.com,1999:blog-7118778965888677191.post-86741140300902540502008-07-07T00:24:00.002+02:002008-07-07T00:29:17.800+02:00Gogol på Roma TeaternIgår var vi på Roma Teatern på Gotland och såg på Revisorn av Gogol. Det var en riktigt bra uppsättning och väl värt att se. Jag kan rekomendera att ni går och ser den om ni är på Gotland under sommaren.<br /><br />Det enda tråkiga var att få reda på hur lite bidrag Roma teatern får jämfört med t.ex. riktsteatrar och olika "fria" teatergrupper. Tydligen att göra bra uppsättningar år efter år som folk uppskattar är inte något som prioriteras av stat och kommun.Robert Virdinghttp://www.blogger.com/profile/16187415127098159771noreply@blogger.com0tag:blogger.com,1999:blog-7118778965888677191.post-68381313142169589092008-03-19T02:34:00.003+01:002008-03-19T08:53:14.065+01:00"Optimerad laddning"Jag har en Sony Ericsson K610i som för det mesta tycks fungera bra (fast ibland tror jag att den stänger av sig själv). Det som förundrar mig är att när man laddar den så säger den "Optimerad laddning". Då undrar jag förstås om den även klarar av "Ooptimerad laddning" och vad i så fall är skillnaden. Eller är det bara någon marketroid som har en tänkt lite mer än vad han/hon borde?Robert Virdinghttp://www.blogger.com/profile/16187415127098159771noreply@blogger.com1tag:blogger.com,1999:blog-7118778965888677191.post-37910313815453779792008-01-11T03:02:00.000+01:002008-01-11T12:00:22.910+01:00Virding's First Rule of Programming<span class="q"><span style="font-family:verdana;font-size:85%;">After reading the blogs about how good Erlang's concurrency model is and how we just just made a super implementation of it in XXX I have been led to formulate Virding's First Rule of Programming</span></span><span style=";font-family:verdana;font-size:85%;" >:<br /><br />Any sufficiently complicated concurrent program in another language contains </span><span style=";font-family:verdana;font-size:85%;" >an ad hoc informally-specified bug-ridden slow implementation of half of Erlang.<br /><br />With all respect to Greenspun.<br /><br /></span>Robert Virdinghttp://www.blogger.com/profile/16187415127098159771noreply@blogger.com10tag:blogger.com,1999:blog-7118778965888677191.post-15592227983283466512007-09-30T14:56:00.000+02:002013-12-30T02:33:07.891+01:00Att installera Windows XP på en Dell XPS M1330<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="font-family: arial;">I veckan fick jag en ny dator. Det är en Dell XPS M1330, en trevlig liten dator med god prestanda och ett bra grafikkort för att vara så liten. Enda verkliga nackdelen med den är att den endast leveras med Windows Vista.<br /><br />Av någon mystiskt anledning leveras den bara med Vista eftersom Dell anser att det är en dator för privatpersoner och dessa <span style="font-weight: bold;">skall</span> använda Vista. Nu skall jag ha den till jobbet där vi kör XP och jag f.ö. inte är intresserad av att använda Vista. Definitivt inte innan ett par service packs och troligen inte efter det heller.<br /><br />Då var problemet att få XP att fungera på den och att få rätta drivers till den. Dell supportar <span style="font-weight: bold;">inte</span> XP men det finns några drivers och applikationer på deras support sida. Efter lite sökning så hittade jag denna fantastiska tråd på dellcommunity som "tells it all":<br /><br /><a href="http://www.dellcommunity.com/supportforums/board/message?board.id=insp_general&thread.id=253132">http://www.dellcommunity.com/supportforums/board/message?board.id=insp_general&thread.id=253132</a></span><span style="font-family: arial;"><br />Jag har bara två kommentarer till vad som sägs där:</span><br />
<span style="font-family: arial;">1. Jag behövde inte ladda ner något extra för att få ljudkortet att fungera, bara drivers</span><br />
<span style="font-family: arial;">2. Jag hittade en bättre (och nyare) driver för grafikkortet genom:</span><br />
<span style="font-family: arial;"><a href="http://www.laptopvideo2go.com/forum/index.php?showtopic=8128"><br />http://www.laptopvideo2go.com/forum/index.php?showtopic=8128</a><br /><a href="http://www.laptopvideo2go.com/forum/index.php?showtopic=13742">http://www.laptopvideo2go.com/forum/index.php?showtopic=13742</a><br /><br />Med den info som fanns här kunde jag ladda ner drivers från NVIDIA's hemsida och mycket enkellt få det att fungera. Jag använder v162.18 nu.<br /><br />På det hela gick det mycket smärtfritt och var bara att ladda ner och installera allt.<br /></span></div>
Robert Virdinghttp://www.blogger.com/profile/16187415127098159771noreply@blogger.com1tag:blogger.com,1999:blog-7118778965888677191.post-50365431979213671382007-05-22T01:40:00.000+02:002007-05-22T01:52:06.642+02:00New Erlang bookThere is a new Erlang book coming out soon, <span style="font-style: italic;">Programming Erla</span><span style="font-style: italic;">ng: So</span><span style="font-style: italic;">ftware for a Concurrent World</span> by Joe Armstrong, which is very good and a great improvement over the old book. Apart from a very understandable description of the language it all also describes some of the more generally useful libraries, and gives real-world examples of how to use them. As I already know the language it is the second part of the book which I find most helpful.<br /><br />In all the book is well worth reading.Robert Virdinghttp://www.blogger.com/profile/16187415127098159771noreply@blogger.com0tag:blogger.com,1999:blog-7118778965888677191.post-15779947831677074552007-05-13T23:20:00.000+02:002007-05-22T01:40:21.959+02:00Dåliga förlorareEfter att ha lyssnat en del på <span class="blsp-spelling-error" id="SPELLING_ERROR_0">ESC</span> i går kväll så tycker jag att <span class="blsp-spelling-corrected" id="SPELLING_ERROR_1">kommentatorerna</span> visade tecken på att vara extremt dåliga förlorare. Bara för att vi inte vann var allting kasst, östländerna bara kompisröstade och det hela var en stor skandal. Detsamma gäller många av de inlägg man läser i tidningarna idag.<br /><br />Den som ger sig in i leken får leken tåla, och det gör vi visst inte.<br /><span style=""></span>Robert Virdinghttp://www.blogger.com/profile/16187415127098159771noreply@blogger.com0