Hacker News new | ask | show | jobs
by rprospero 4353 days ago
You can do a pure function that reads files or does IO. Heraclitus solved the algorithm millenia ago. You just need to include the right parameters.

Instead of

    readFile(file_name)
You just do

    readFile(file_name,complete_description_of_the_universe)
If you change the value of complete_description_of_the_universe, then you've changed the input to your function, and of course you're going to get a different result back.

Granted, a full complete_description_of_the_universe is rather space consuming. I don't even think it would fit on a floppy. Maybe a Zip drive?

Thankfully, you don't need the COMPLETE description. You only need the parts that your computer can access. There's no reason to store the amount of gas in the bowels of every elephant in India, unless you actually have an elephant gas sensor. So our function is really

    readFile(file_name,complete_description_of_everything_the_computer_measure)
Of course, that still means that the second parameter contains the contents of every bit on the hard drive, since the GMR sensor can measure those bits. Some lousy manufacturers are now selling computers that don't even have enough memory to hold their entire hard drive contents. Thankfully, we can use another optimization.

Since, by definition, the computer can measure the value of complete_description_of_everything_the_computer_measure, there's no reason to store it in memory at all. We just measure it when it's needed. Granted, it's a little slow to read the hard drive, versus having the entire drive stored in memory, but premature optimization and all that.

It's still completely functional, though. We still pass the function two parameters. The first parameter is a set of bytes in memory with a EBCDIC representation of the name of the file. The second parameter is a physical computer that can perform the measurements. As long as you pass the exact same computer to the readFile function, you'll get the same result every time.

Same thing for writeFile. We pass in a physical computer and the function returns to us a new, physical computer that's similar to the one that we passed in, except that this computer has some different magnetic spin arrangements on its hard drive and its system clock is reading a different value.

Granted, carrying all of these physical computers around gets tiring, plus people start giving you guff about conservation of mass or whatever whenever you make a new computer. Thankfully, the functional compiler guys have found ways to optimize the code so that you can destroy the unneeded computers very rapidly. In fact, it's faster than the human eye can detect. Without careful measurement, you'd think that it was just one computer the whole time.

1 comments

In practice, you don't actually need to return a new universe at all, because of course, that would be quite costly. Instead, the runtime can modify the existing universe and return it with a new unique identity - the reason we can do IO and remain referentially transparent is because every time we perform a side-effect, we do so on a unique universe - there is no way to duplicate a universe.

Haskell actually models the real universe better than any other languages - in the real world, we have the concept of now - some state of the current universe until an event elapses, when we have a new now, and we have a concept of the past, but in fact, this past does not exist anywhere - it was transient - we can't go back and modify this old universe to cause a change in the future, unless we introduce theories of parallel universes. the only thing that ever exists is the now, as you might learn from a Buddhist.

A Haskell function which does IO is just an event which causes a change from an old now in the universe to a current now, and the old one, the past, no longer exists.