@mkunikow: It depends a little on your definition of ‘functional purity’. There are some implementations, most notably Nock/Urbit comes to mind, that simply says ‘as far as code on our platform is concerned, there is nothing outside of the platform. Therefore, all function calls can be considered pure, and data structures can be made persistent.’
Other languages, like Haskell, that are basically syntactic sugar around the mathematical lambda calculus (which is pure by definition) preserve purity when dealing with side-effects by returning an object that represents a changed state of the world (It’s basically a reminder stating ‘Look! This was the second time I did a change!’). These values, which are of type IO in Haskell, can be used to chain multiple side-effectful operations together in a fixed order. This is necessary because there otherwise is no way to know in what order the functions are called, as this happens lazily. (more information on the Haskell wiki)
Can this be considered pure? Most people think yes, but of course this is subjective.
It is an interesting fact that the operations used for ‘passing the IO baton’ around together form a Monad, but you do not need to know how monads work in order to use side effects in Haskell.
If people want I can write a little introduction to how Monads work. Of course, it is very easy to fall for the ‘Monads are like Tacos’ fallacy: It is a very abstract concept, and an explanation that worked for me might not work for you.
Nevertheless, I think I can make a stab at it, using some great analogies with Fruit Salads and cooking that have their origins in the fun_land package.
He is a bit of a “rebel for the static strongly typed pure functional cause” - and even though he makes some good arguments that isn’t going to stop me from referring to work like that from Pierre-Yves Saumont if I should find myself trapped in Java-land (for whatever reason) anytime in the future.
I would argue that “functional tactics” in imperative languages are ultimately more effectively wielded by developers with experience with “real functional languages” - but never(, ever, and not even close) to the full effect and impact of actually using a “real functional language” for the task at hand (which ultimately is one of the points that Erik Meijer is making).
[quote=“mkunikow, post:20, topic:1771”]
You will always need to deal with state and side effects. But there should be clear separation in code: pure functions vs rest.[/quote]
In the Clojure community it is often said that good functional design “pushes the [impure aspects] to the edges of the system”‡ - leaving the core logic pure and minimally “complected”.
‡I seem to recall David Nolen using that phrase fairly regularly in his communications.
Now I am very confused about what is functional programming. I feel, none languages out there support pure functional and a language can never be 100% perfect.
So close the eyes, do something greet with elixir, I really love the language.
And elixir contributors, your guys do amazing work, thanks so much.
Interpret that timeline whichever way you seem fit - but he always struck me as a person who can be pragmatic when it suits him - at the same time he never seems to lay off his “learn Haskell” campaign (and that the type system needs to identify side-effects). So he may not be an “evangelist” but he has never been afraid to voice his strong opinions.
Open your eyes and watch the Scott Wlaschin video I linked to above - you’ll likely need to watch it in pieces and multiple times because he covers a lot of ground in that hour.
Lots of her videos are available on the Web but you may find this one helpful to start with:
Jessica Kerr: Functional Principles for Object-Oriented Development (GOTO 2014)
@vasspilka already made a good start for you on the “purity” aspect but as simple as it may seem on the surface, the implications go quite deep. The programming language you choose is like a carpenter’s toolbox - even if it is stocked with the best tools available there is no guarantee that you will be crafting only “top of the line”, “world class” cabinets - that part is ultimately up to you and your (developing) skill.
Elixir can’t stop you from writing Spaghetti Code - that responsibility ultimately rests with you.
A lot of that depends on how one defines “pure”. If a program did exactly the same thing every time it was run there wouldn’t be much point in running it more than once would there? A program has to have some side-effect to be useful. Side-effects aren’t inherently bad; uncontrolled or accidental side-effects are the problem.
Stop looking for absolutes. Few things in life are always right or always wrong.
There is no true 100% pure language (that works and is used in practice; Lambda Calculus itself is pure, but you directly run it on hardware), if only that the languages that for the most part are pure, have some ways to cheat (for Haskell: unsafePerformIO).
Haskell, for instance, archieves purity by allowing programmers to pass on the ‘IO baton’ from one side-effectful action to the next. This ‘IO baton’ can therefore be considered ‘the state of the whole von Neumann computer this program runs on, as a whole’. In this way, one can still consider these side-effectfull actions to be pure, from the viewpoint of the programmer (and of the language).
Of course, what happens behind the scenes is not important in this case, as long as the end result is that we can show ‘look! when you would call this function again with the same input, you would indeed get exactly the same output’.
In the style of Joe Armstrong, I’m going to bring physics into the discussion. “Pure” computation exists only as a thought experiment. Once you execute on a physical computing device, you cannot ignore physics. Hardware fails; a cosmic ray may flip a bit it memory, etc. However rare these may be, they are non-zero probabilities. A “pure” computation run on physical hardware may return a different result when run again.
This bit of brilliance led to supervisors for when you need truly robust systems. And IMHO is a core bit of the difference between computer science and software engineering.
That said, it is still wise to isolate side effects to one/few places in code. The IO monad is one way of doing that. It’s one that appeals to the theoretician more than the practitioner though.
You hit the nail right on the head! I couldn’t agree more with what you’ve said. It was i believe last friday when an interesting exploit on Android phones was published, which alters the state of the software by exploiting a physical hardware peculiarly.