Ordinary Programming

Here I discuss of how to write "ordinary" looking programs in Fexl, in spite of the apparent challenge of not being able to use mutable data.

In response to Monadic Data, a colleague writes:

Oh...wow.

That's something I wonder about with Fexl. I love how there's barely any implementation. I love the simplicity and potential power. But am I smart enough to write something useful with it? I'm hesitant to find out :)

I replied as follows.

It's easy as pie, except for one thing: the inability to use mutable global values. But I think I know what to do there. You can actually make Fexl look as "procedural" as you like, with *apparent* mutable values, thanks to the "monadic" style.

So for example, if you want to emulate key-value storage, you can write code like this:

put "x" 4;
put "y" 5;

get "x" \x
print "The value of x is ";print x; nl;

get "y" \y
print "The value of y is ";print y; nl;

put "x" 44;
put "y" 55;

get "x" \x
print "The value of x is ";print x; nl;

get "y" \y
print "The value of y is ";print y; nl;

Or you can compress that code as follows:

\show = (\name\next
   get name \value
   print "The value of ";print name;print " is ";print value;nl;
   next
   )

put "x" 4;
put "y" 5;

show "x";
show "y";

put "x" 44;
put "y" 55;

show "x";
show "y";

I've actually tested that, so I know it works.

In short, you can make a Fexl program look as "ordinary" as you like.

Now in Perl I have traditionally done everything using flat key-value maps. But on some recent projects I've been taking another approach. I write functions which compute everything on demand, from scratch -- even to the extreme of reading in an entire data file, processing it, and grabbing just one number out of that result. Then, because that can be slow, I just go into the Perl routines and drop in a simple caching mechanism here and there, using a single global variable %g_cache. Now suddenly the code is fast.

I believe that same approach will be useful in Fexl as well. So, I can just write a bunch of "pure" functions which compute results from scratch. Then I can drop in some caching where needed -- but of course, since Fexl does not have mutable global variables, I would have to use the monadic put/get approach outlined above. Your main code would never see the put and get operations though, it would just call high-level functions like (get_annual_return fund_name year) and such, which would do the caching internally (typically using a simple assoc list, with perhaps some nesting if necessary).

I think that will get you the best of both conceptual worlds, functional and procedural, but without the need for any actual mutable values.