Showing posts with label erlang. Show all posts
Showing posts with label erlang. Show all posts

Sunday, August 16, 2015

"Getting" Functional Programming

We all know there's something to "get" -- but is it one massive "Eureka!" moment, or is it a series of smaller "Aha!" steps? I think that it's the latter, but that most functional languages drop them in your lap in one undigested lump, because I had an odd introduction to the style.

Back around the turn of the century, I encountered the famous Why Functional Programming Matters paper; and while I’m a mathematician by background, that was always in Applied -- crunching differential equations or re-casting multiple integrals as Fourier transforms -- and I simply didn't get it. How could you do anything in your programs if your variables didn't vary? Then after some years, I encountered an article -- no longer on the web, alas -- suggesting that Erlang was well placed to be the "next Java", and my curiosity was piqued.

Some while later, I spotted Joe Armstrong's Programming Erlang on the shelves of the local Borders, so picked it up; and though the syntax and conventions of the language were bizarre and alien -- very "spiky" looking -- the mystery of how you did things with immutables was dispelled in the first couple of chapters. And it was revealed to be quite mundane -- you keep your scopes small (general good practise, anyway) to avoid running out of sensible write-once names, and you recurse or use callbacks rather than iterate.

So, despite its unrelentingly immutable nature (process dictionary aside), it turned out that Erlang had a very low barrier to the program after “Hello world!” Writing non-trivial programs (a few hundred lines of networking code) that accomplished and outperformed what had taken me thousands of lines in ‘C’ was easy. Yes, there were compilation errors along the way, but those were mostly simple syntax (putting the correct punctuation marks at the ends of lines), and I debugged at run-time as usual.

Really, despite the alien syntax and strict immutability, this felt like OO in the abstract -- you send an object process a message, and it responds in a Smalltalk-esque (or even Win32 message loop-alike) fashion. First class functions were just familiar callbacks with a different name, even in cases like a transformative map over a list. Indeed so OO is the paradigm that people talked about implementing Ruby in an "object → process" style on the Erlang VM, and then actually implemented such a near-Ruby.

Then I found out that this F# language was not Fortran.net, but a functional language on the CLR and gave it a whirl. And I felt like an utter dunce who “didn’t get it” for months; not helped by the lack of good introductory material -- like the original Foundations of F# book, which for the newcomer was frankly terrible on account of the volume of assumed knowledge it brought along.

In hindsight, the big shift was between Erlang's dynamic type model, and the static, inferred, typing of F#; the feature that means that a program that compiles will probably also work as well. Unfortunately, that also means that you have in a sense to debug your program at this stage, which is the massively unfamiliar bit. And it's not helped when your program fails to compile with a message that's about as comprehensible as a C++ template failure -- it wasn't until F# for Scientists that I found my Wittgenstein's Ladder, a book that actually explained enough of the the types and type notations, and suddenly made sense of the bizarre arrow-filled compile failures (and API definitions).

Then, and only then, did the list-processing nature of LISP, and Haskell's mysterious monads, all suddenly become things that fall naturally out of the new style of thought. The extra constraint of type exactness is indeed what makes operations like bind to transform types a meaningful and necessary concept rather than being approached ad hoc.

The other shift, related to the debugging at compile time is that, like template metaprograming in C++, suddenly computation can happen as compilation -- a pure function with fixed compile time inputs can in principle be evaluated at that point. And where your program does take inputs, the way of looking at it approaches being an aggregation of functions where input comes in and results come out through a transformative process built of little stateless sub-transformations; rather than as a collection of stateful objects talking to each other about the input.

And at that point, I think what is being practised is functional programming.

Tuesday, December 28, 2010

“Hello, OTP!” from F# revisited

That previous F# code was just too ugly to leave as it was; so after a little bit of work, I've factored out a general purpose wrapper to convert the Otp.Erlang types into values of a discriminated union on the F# side of the fence. Like this we can directly pattern match, without the descent into massive nesting that we had before, and keep the Otp.Erlang types encapsulated into wrappers for method calls on the Otp types.

With this addition the main program above can be revised to become

which looks a lot more like the language we're trying to write in. All the magic happens in this file

Of course, as OTP.Net is some revs behind the current Erlang distro's JInterface, this type mapping is incomplete (no BitStr or Fun types) compared with what we could be using. The main advantage is that it works right now.

“Hello, OTP!” from F#

Nothing earth-shattering here, just recording the results of a little bit of playing around with OTP.Net and F#. This is all building on the original work done elsewhere Integrating .NET and Erlang using OTP.NET and Integrating F# and Erlang Using OTP.NET, as a little bit of a five-finger exercise using the OTP framework as now explained in Erlang and OTP in Action.

So, simple gen_server to export the same sort of API as the mathserver example in the former:

Compile this using erlc and start werl -sname servernode -setcookie cookie. Meanwhile the matching F# program to build and run is

Matching the dynamic types possible with Erlang, and the F# way with type hierarchies, makes this code somewhat ugly (as in multiply nested decision points and the start of the arrow anti-pattern) when trying to unpick the return values, especially trying to decode the possible return values when requesting that the far end server start up.

Some of the repeated noise has been factored out into the Atom active pattern for dealing with {Reason, Payload}, but the underlying data model in OTP.Net is simply not very F# friendly.

Saturday, October 03, 2009

SyntaxHighlighter 2.0 Brushes for F# and Erlang

Updating the Erlang brush

This also required the following in the CSS theme


And for F#


which is as incomplete as it always was; but doesn't use any extra CSS.


Later -- another brush for F# that was published at about the same time can be found at Pense-Moi.

Tuesday, August 18, 2009

wxErlang in Action -- Listing 2.3

Listing 2.1 is an example of using wxApp.redirect() -- but that feature doesn't seem to exist in wxErlang at current; and listing 2.2 is an example of a Frame subclass that fixes size, position and title, something implicit in this and the previous listing. So we move on to putting a new control on and listening to its events.

in which I note a systematic error (now corrected) in the previous examples to do with window closing. I had been closing a window a second time in response to its Close event (raised by hitting the kiss-of-death or explicitly calling wxWindow:close(Frame,[])) in the #wx{event=#wxClose{type=close_window}} clauses; more than that, after raising the Close event explicitly, I'd not been handling it, but exiting the main loop.

As seen here, in the handler for the close event, returning the simple atom ok suffices; but after raising the close event, I need to tail-recurse back into the main loop method.

When I didn't handle a close event that I'd raised myself, when I went

C:\Users\Steve\Documents\erlang>"\Program Files\erl5.7.2\bin\erl.exe"
Eshell V5.7.2  (abort with ^G)
1> insertframe:start().
ok
2> insertframe:start().
ok
3>

then having dismissed the first window, when I launched it again, the new window was visible only fleetingly, because the close event I'd raised after close was still in the mailbox for the console. Now I do actually handle it, I can relaunch the app over and over.

Monday, August 17, 2009

wxErlang in Action -- Listings 1.4 & 1.5

These two listings are the same UI shown in C++ then Python. The wxErlang equivalent is awfully close to the miniblog example in the O'Reilly Erlang Programming book.

Still looking for an approach that doesn't end up with all the message handling logic quite so jammed together into one God-function for the message loop, and is vaguely re-usable in more than just structure.

And that ends the first chapter of fairly trivial examples. Things should get more interesting from here on in.

Friday, August 14, 2009

wxErlang in Action -- Listing 1.3

This decorates the previous frame with an image. The prototype used the wxPython logo, so for this version, I used the Erlang logo as found here:

And this is what the application looks like when superposed on the stand-alone image; the comments in the code give my interpretation of what is going on here.

Thursday, August 13, 2009

Improved Syntax Highlight Brush for Erlang

Updating last December's post, about a SyntaxHighlighter brush for Erlang, to allow for compounds like 'wxErlang' with interior capitals and not mark them as values:

This manipulates the output of the RegExp to discard the first (non-identifier) character, to work around the lack of lookbehind (in one of the many possible ways the same effect could be achieved).

Wednesday, August 12, 2009

wxErlang in Action -- Listing 1.2

So, after a long episode of IRL (and work), and some fruitless delving through the wxErlang docs...

Now there are factorings that could be made to make this more "subclass"-able -- let loop take an arbitrary term and a fun/3 of loop, the term and a message term, passed in as a handler for any other message, and return ok if looping is to continue, and allowing for code hot-swapping; but this is probably better to just be a template at the source level.

Thursday, August 06, 2009

wxErlang in Action -- Listing 1.1

So, to teach myself wxWidgets in the context of Erlang, what else to do than start with the book I already have to hand (wxPython in Action), and work through the examples one by one...

This is the equivalent of the Listing 1-1 showing a not quite trivial wxPython example in 20 lines. Erlang makes 25 lines, mainly due to having to explicitly wire up the frame close event:

which demonstrates hooking up the frame's inherent exit button (in windows, the kiss of death at the upper right); and a mouse-move event handler, from which we extract the coordinate information.

It's all quite simple once you've figured out how one might convert from the simple examples in Erlang Programming and the rather less than pellucid wxErlang documentation.