Saturday, June 28, 2014

Currying Explained Simply

I know there are many articles about "currying" on the web, especially aimed at JavaScript programmers.  Do we need another one?  Well last time I looked I didn't find a really easy-to-understand article about it, so let me try my best. It can be a confusing topic and I admit I have been confused myself, at least dazed. Maybe I can help you if you feel that way too.

The reason it is confusing is that most articles about it are based on the unspoken assumption that you NEED currying, regardless of your PL. But you rarely do in JavaScript.  I'll try to explain in this blog-post why not. And then you need to understand what currying is NOT, why it's not the same thing as "partial application". But I'll focus on explaining "currying" in the simplest way possible.

It is confusing to try to understand something if you don't know why you need it. And even more so if you really don't need it.  So here we go ...

Imagine your programming department has the rule that functions can only take max. one argument. You think, who would make such a silly rule. But there are programming languages where a function can take just one argument. Wink wink: Haskell, F#.  Then your manager asks you to write a piece of code that calculates the maximum of two numbers:

  function maxOfTwo (a, b) 
  { // Return a if it is bigger than b, 
    // else return b.
    ...
  }

You're in a pickle. You're supposed to return max of two numbers, but your function can only take one argument. What to do? The answer, the secret sauce:  currying.  Curry to the rescue. Can you do it? You can, if you can write something like this:

  max (5) (22);   //  ==  22

Notice above you are not passing multiple arguments to a function.  You are doing something else. You are calling max(5) and it seems to be returning something you can pass (22) into.  This is only possible if  max(5) RETURNS A FUNCTION. Yes, functions can return functions, this is JavaScript!

So how would you write the above function 'max'?  Like this:

  function max(a)
  { return maxB;
    function maxB (b)
    { return a < b ? b : a;
    }
  }

Try it.  You see it works. "max(5)" returns the function 'maxB' and if you pass 22 to that, you will get the result 22.

The process of implementing 2- or more argument functions by combining 1-argument functions in this manner is called "currying". 

So is currying useful?   How often do you have 1-argument functions laying around you  want to combine in this manner, to do the job of a 2-argument function?  Maybe you do, but typically it is much simpler to write a 2-argument function to start with - if your language allows it. 

Haskell and F# don't because "pure functions can only take one argument".  But they "fake it".  If you write the equivalent of  max(a,b) in them, they automatically, behind the scenes, turn it into the form of our single-arg max(a) above. Why? That would be another blog-post. But if you program in JavaScript you don't need to know. 

If you program in Haskell or F# you never need to DO currying, it is done for you. If you program in them it's good to KNOW about it, so you know what goes on "behind the scenes".  

In JavaScript, you can forget about it. We rarely start with a two-argument function which we want to turn into two 1-argument functions.  If we already have a 2-argument function we just use it. 

The "pattern" in the max -example above is in fact a very useful JavaScript idiom. You could call it "currying" if that is the thought-process that led you to write it in that manner. But note that executing the function max() does not DO currying. The function  max() is the RESULT of you  doing currying, writing a two-argument function in the "curried form". And it is not doing 'partial application' either. That will be the topic of my next blog-post, I hope.

So what is "currying"?  Let me offer this definition:
 
"Currying is the process by which a function of N arguments is implemented as N single-argument functions such that first of them takes in the first argument and returns a function which takes in the 2nd argument and so on, until the Nth single-argument function finally returns the value of the multi-argument function being implemented."


 © 2014 Panu Viljamaa. All rights reserved

Thursday, June 12, 2014

Virtual Virtualization

I find it interesting and useful that we can run virtual machines inside virtual machines. I'm probably not the only one. Here's my story.

I recently bought a new PC running Windows 8. Rather than replace my older Vista-PC with it, I use the new machine over a Remote Desktop -connection, from the old machine.

That way I don't have to REPLACE the old one with the new, but can combine the processing power of both. I can use just a single keyboard and the same set of monitors for both. I also get to keep the existing applications and peripherals on the older machine, without compatibility issues, or having to buy new licenses for them.

The new machine running Windows-8  (which I use over remote-desktop-connection) runs a virtual machine running Windows-7, which I log into. From that Windows-7 session I take a VPN remote-desktop-connection to a PC on a client's site running also Windows-7. From there I take a remote connection to a physical server running a virtualized Windows -server. In that remote Windows Server -session I run a Java virtual machine.

A remote-desktop-connection is not usually considered a "virtual machine" but it kind of is, conceptually. It effectively  transforms my physical PC to look and behave like a machine that seems to virtually exist on it.  From my point of view it is a virtual machine, running on my physical (OR virtual) machine.

What about JavaVM? Is it really a virtual machine? Yes, it's name is officially Java Virtual Machine. It is one, it just doesn't typically run an OS. It just runs applications. Imagine that your PC would run just one or two applications on it's BARE METAL, no OS in between. That would make those applications  run and start fast. JavaVM is a virtual version of that scenario.  A Virtual Machine is not the same thing as an Operating System. An OS needs a machine, virtual or physical, to run on. But note, there is something called JavaOS.

If instead of Java I would develop on something like Pharo Smalltalk it would be even clearer that I was developing applications for a virtual machine ON a virtual machine. Pharo-VM runs its own virtual desktop and has the ability to save "snapshots" of the state of that VM on disk, and keep multiple copies of them around.

So, I have multiple layers of virtual machines running on virtual machines. And it all works great. Diagrammatically my configuration looks like this:

-> Windows Vista
-> Windows-8
-> Windows-7
-> Windows-7
-> Windows Server
-> Java Virtual Machine

You could think that having all those layers would affect performance negatively. But there are actually four physical machines involved whose combined processing power helps to make performance good. A fast network is needed of course as well.

One more benefit of this setup: Running different things on different machines which are more or less isolated from each other, and which can be restored to an earlier version if needed, improves security.

The main points of this article: If virtual machines are good, then it's probably also good to run them inside a virtual machine, at least in some cases. If "bare metal" is good, then it's probably also good to virtualize the good aspects of it, as exemplified by Java Virtual Machine. If something is good, then probably also a virtualized version of it is.

 © 2014 Panu Viljamaa. All rights reserved