Hacker News new | ask | show | jobs
by rujuladanh 2633 days ago
Yes, we all know how functional languages work; this is Y Combinator after all. However, that is a pedantic remark and missing OP's point.

It is clear OP meant a program as in an entire non-trivial system, not individual functions; even if they are programs themselves.

Regardless, when one talks about function purity, it is about the final evaluation, not about partial binding or lazyness.

1 comments

This is actually not at all pedantic but a very fundamental, if subtle at first glance, point about purity. Once you start doing more advanced monadic programming it stops being subtle at all. Many people, yes "even on HN", are totally fooled by do notation and the imperative nomenclature, but there is nothing similar.

You misunderstand it as well: it has nothing to do with evaluation mode. Idris is eagerly evaluated, for example, and _that function is still pure_! `f x = putStrLn x` gets "finally" evaluated and yes there is still no side effect. It is so evaluated that you can bind it to a variable and apply another function on it. Just like 2^100 is a pure expression, so is `putStrLn "hello"`.

> It is clear OP meant a program as in an entire non-trivial system, not individual functions; even if they are programs themselves.

It is not clear. Does he mean including the OS and hardware? Because no matter how complex, a pure program is still pure.

Yes, yes, of course. All my C programs are pure too!

They are a simple mapping of a tuple (hardware state, queue of world events) onto itself! Truly marvelous!

Vive la pureté!

PS. I am now working on abstracting this further, and I just realized the universe itself is pure too; but somehow I got some strange behaviors when I started to look into particles too closely... will report back soon.

You are really not getting this distinction, I'm not sure how much clearer I can make it. You can evaluate `putStrLn "hello"` a billion times without anything "happening" at all, because it is just a function. Maybe it has to be made clear that purity is a property of languages and language constructs, and how you can reason about them, if you model a physical system mathematically of course you will have a pure formal description of it, but that's not the domain where this concept applies. Even then, it can only be said of your _model_ that it is pure, and the point of pure languages is to allow for this mode of reasoning.

When you call a C function, you cannot know whether equational reasoning holds, whereas you can be sure when you're using a pure language. Therefore, when you're working on a project that is 100% in say Idris, you are in fact making a totally pure program. You could make an Idris compiler that inserts random perturbations in various functions, or you could look at crashes etc., but that is not where the concept of purity applies, it's a category error to think it does.

All right, but...

When I actually get output that says "hello", that isn't pure, is it? And there is some way for me to actually produce that output, isn't there? It may not be "evaluating putStrLn", but it's something.

And if that's all true, then rujuladanh is essentially correct: You're being pedantic in a way that misses the main point.

He has a point though. You can imagine that all c code lives implicitly in an io monad and define evaluation the same way Haskell does. Then c becomes pure by your own criteria.

If you say that c is impure you have to admit that any program with the io monad also is. That is, any working Haskell program, even if Haskell allows you to write part of this program out of the io monad.

Weren't all Java programs supposed to be "100% Pure" a while back? Whatever happened to Sun Microsystems' "100% Pure Java" [TM] Initiative?

https://www.oracle.com/technetwork/java/100percentpurejavaco...

>[...] 100% Pure Java, JavaStar, JavaPureCheck, [...] JavaSpin, HotJava, The Network Is The Computer, and JavaStation are trademarks or registered trademarks of Sun Microsystems, Inc. in the U.S. and certain other countries.

Registering purity as your trademark and insisting that all of your users rewrite every bit of their existing legacy code in your pure language, and never use or talk to any other languages ever again, always seemed like separatist linguistic supremacy to me.

Apparently, C#'s P/Invoke is an evil impure cross-language conspiracy to dilute our linguistic purity and sap our precious bodily fluids, breeding caravans of mongrel coders who will swarm across our open borders and steal our jobs. That's why JNI and NDK are only used by unpatriotic second class citizens with divided loyalties, so they don't deserve to be well supported or maintained.

https://www.zdnet.com/article/100-pure-java-initiative-wins-...

>"Keep Java pure" is the message behind Sun Microsystems' 100% Pure Java initiative which has already won support from 100 developers but will lock out programs such as Visual J++. The move is an attempt on behalf of the Californian firm to maintain integrity of Java code and build awareness.

https://www.cnet.com/news/100-pure-java-watered-down/

>Viewers of cable news network MSNBC may recently have seen a commercial for Sun Microsystems (SUNW) in which a man tells a priest that he's been thinking "pure" thoughts. When the beatific man exits the confessional, he passes a queue of anxious programmers--one wearing a Visual Basic shirt--ready to admit their sins.

>The commercial, which touts Sun's "100 percent pure Java" campaign, is not your usual television ad. But Sun has in many ways shown an almost religious determination to spread the gospel of Java to the far reaches of the globe, even sponsoring a worldwide educational tour for programmers with the support of Netscape Communications, IBM, and Novell.

It is being enjoyed every day by those of us that develop on Windows and deploy on JEE containers running somewhere, by uploading a JAR/WAR/EAR into them.
Ok so run up an embedded OS and application on a system with limited resources so that all the memory is being used. Now run your pure functional program. The system crashes. Using memory is a side effect. Consuming CPU time is a side effect. Heating up the environment and drawing power due to that CPU usage is a side effect[0]. These are not trivial either, actual real systems used for critical activities fall prey to this sort of thing all the time. It just depends on what you are willing to consider as a side effect.

[0]https://xkcd.com/1172/

That's not what purity refers to! We're talking about a mathematical property of the language itself.

The real issue is that people don't understand that `putStrLn "hello"` _is literally just as pure as `2*x`_. They are both like mathematical expressions in that they evaluate to a value and _nothing else_. The name "putStrLn" _suggests_ that this is similar to a print statement but it is emphatically not. You can evaluate it a billion times and nothing gets printed.

Hang on a minute.

The only difference is that the languages you are talking about have captured "doing I/O" as something that can be statically reasoned about, but not "consuming memory" (for example). From a mathematical perspective, one is part of the axioms while another is not.

One could imagine a language where all memory allocation must be done explicitly via a monad, just like how in Haskell all I/O is performed inside an IO monad. If that were the case, you could have additional static guarantees about how memory is used. That doesn't mean that languages which don't do this are somehow inherently "impure"; they are simply "pure with respect to a certain set of axioms" (which don't talk about memory usage).

"The system crashed" example is fun too. All pure functions must return a value, right? Well, that's obviously not gong to be the case if the computer blows up halfway through executing a pure function. "Blowing up" might not be something your type system talks about—Haskell does to some degree (with _|_ inhabiting every type), but Idris for example has total functions which at runtime could most definitely be interrupted by a sudden explosion. They are "total" only with respect to a set of axioms which imply an execution model where computers do not explode mid-program.

This can be done, for example ST in Idris which lets you reason about resources (check out linear types).

However, if you are thinking more in the direction of "you have to reason about where and how exactly your values and functions are stored", you're moving back to C, because the entire point is to disentangle the formal description of computation, from it's actual execution in the real world. If you want to deal with that, you have to do it explicitly and _by reasoning about it_ (with ST, for example). Which is what purity means.

> They are "total" only with respect to a set of axioms which imply an execution model where computers do not explode mid-program

"There is a chance that the computer blows up" is one of those things that have little bearing when reasoning about programs, it's just not in the domain of discourse. It certainly has no formal bearing on the notion of totality, mathematics just doesn't deal with cases such as "what if everyone who counted to 5 suddenly died", it deals with the counting itself. When the chance is actually high, for example radiation in space flipping bits, I'm pretty sure you want to handle that elsewhere.

It's not hard to imagine a fault-tolerance system gaining a lot from dependent types, however, with their ability to prove that your code follows a defined protocol.

Actually, the Moveable Feast Machine is a "Robust First" asynchronous distributed fault tolerant cellular-automata-like computer architecture that DOES reason about what might happen if computers randomly explode in mid-program!

(One of my favorite topics, that I've written about in other threads!)

https://news.ycombinator.com/item?id=15560845

Check out how the city seamlessly regrows after you nuke it:

https://www.youtube.com/watch?v=XkSXERxucPc

> Robust-first Computing: Distributed City Generation: A rough video demo of Trent R. Small's procedural city generation dynamics in the Movable Feast Machine simulator. See http://nm8.us/q for more information.

And here's a robust, self-healing membrane, that tolerates random failures (like tiny little exploding computers):

https://www.youtube.com/watch?v=oq0uvF4mm7Y

>To demonstrate the robustness of three membrane implementations in the MFM, an instance of each was placed side by side and subjected to a failure probability of 5e-5 per site per EPS. That is, each site is erased, on average, every 20,000 event cycles.

Intercellular Transport also demonstrates some robust chemical and biological programming metaphors:

https://www.youtube.com/watch?v=6YucCpYCWpY

>Two cells are interconnected by self-healing wire. The magenta substance is being passed from the cell in the west to the cell in the east. The black particles are an ectoplasm, allowing the membrane to identify sites outside of the cell. Similarly, the yellow and blue particles are an endoplasm specific to the cell in which they reside, allowing the membrane to identify sites inside of it.

Demon Horde Sort exemplifies the Robust First approach:

https://www.youtube.com/watch?v=helScS3coAE

Into functional programming? Here's a demo of programming the Movable Feast Machine with λ-Codons:

https://www.youtube.com/watch?v=DauJ51CTIq8

>λ-Codons provide a mechanism for describing arbitrary computations in the Movable Feast Machine (MFM). A collection of λ-Codon molecules describe the computation by a series of primitive functions. Evaluator particles carry along a stack of memory (which initially contains the input to the program) and visit the λ-Codons, which they interpret as functions and apply to their stacks. When the program completes, they transmute into output particles and carry the answer to the output terminals (left).

Yes we all know that, we're not stupid and the OP clearly knows that perfectly well too, but note his use of the word 'exist'. Real programs don't run on server farms located in Plato's Realm of Forms.
wow. I find it very sad that most people don't grok what pure means. The statement "no one writes pure functional programs. I mean, because they don't exist." is just wrong by any stretch of the imagination.

But at the same time, it's not that surprising, it's not something that comes to us humans naturally. The only way to learn it is to do it. This is something I highly recommend to everyone, you'll find the experience incredibly rewarding.