Live data from Hacker News

“Mostly functional” programming does not work

queue.acm.org

91–100 of 205 posts

Re: “Mostly functional” programming does not work

#91
post #77

Earlier quoted context omitted.

> And its going to fail for the same reasons that C++ failed C++ "failed"? > the OO and functional features don't interact well How don't they? Before C++ had lambdas, programmers would define a class with overloaded operator() and use that instead, every time. Now the language provides a way to easily generate the class with its members and constructor and operator() automatically - which is basically what functiona…

For instance, in Haskell a value is a value. If I have a value of type Integer then it definitely exists; if I want to say that it might not exist then I use the type "Maybe Integer", which expresses that idea precisely. Same goes for a value of type Employee; if I might or might not have an Employee (for instance, if the lookup function doesn't find someone with that employee number) then I have to use Maybe Employe…

>For instance, in Haskell a value is a value. If I have a value of type Integer then it definitely exists;

    x,y::Integer
    x = x + 1
    y = undefined

Re: “Mostly functional” programming does not work

#92
post #54

I think that "Mostly functional" is actually the sweet spot. Going to any extreme makes some things horribly difficult and going to another does the same for other things. So, optimally, multiple paradigms coexist in the single codebase, applied where they're most useful. Functional programming with as many immutable bits as possible is definitely a good start. I generally do that for whatever problem I'm solving: I…

Please note that this is pretty much how you model Haskell programs as well: Keep as much of your logic as possible in pure code and interface/drive that with imperatively written stateful code. Purely functional languages (e.g. Haskell) do not remove your ability to code imperatively, they rather augment it so that you can better reason with it while doing it. Things like first class IO actions (that you can pass ar…

I agree whole heartedly, people write some pretty impressive shared state concurrent programs in haskell, precisely because they know how much state is shared.

Re: “Mostly functional” programming does not work

#93
post #45
post #36

Earlier quoted context omitted.

Of course C++ didn't fail in the sense that it would lack popularity; I think the parent meant that C++ is a complex, horrible mess and that it failed in the "beauty contest" sense. It also failed in the sense that it didn't eliminate all competition.

Yes, that is what I meant. Thanks for the clarification, although I think the term "beauty contest" trivialises the issue. Its not about beauty, its about buggy software.

Its not about beauty, its about buggy software.

Right. But until we have a comparable body of production software written in pure functional code -- and by comparable, I mean closer to the volume of code written in today's mainstream languages and by average developers, not a few applications written by elite developers -- we can't say for sure whether the pure functional approach does in fact prevent buggy software, or whether it simply leads to different kinds of bugs.

A lot of advocacy for functional programming and languages like Haskell makes claims about being safer because certain types of programmer error are prevented. However, relatively little commentary also highlights downsides like the need for accumulating parameters and strictness annotations just to achieve acceptable performance, or the maintenance hazards of having both monadic and non-monadic implementations of algorithms. Until someone finds a way to prove that a large-scale lazy functional program can't exceed the available system resources with an explosion of thunks, any claim that this approach is inherently safe seems rather premature.

Re: “Mostly functional” programming does not work

#94
post #65

The notion that functional programming is somehow better than imperative or object-oriented is completely and utterly wrong. It has its benefits. In some situations, it's the best approach. But in most real-world projects I've come across, a mix of different paradigms is optimal.

The trouble starts when you try to get your mixed paradigms to fit well together. The original article was making the point that the cost of mixing functional with imperative code means that the functional code is crippled. And I've never seen a project where a mix of paradigms was optimal. Any project, and any part of a project, can be tackled in a functional or OO paradigm.

The original article was about strictly side-effect free FP, wasn't it? Yeah, that obviously mixes badly with programming styles that use side-effects.

Most situations I come across are solvable with a reasonably elegant mix of programming styles.

Re: “Mostly functional” programming does not work

#95

Earlier quoted context omitted.

Have you completely switched to haskell now?

I've written an Elasticsearch client in Haskell just so I can port a project from Clojure. I'm moving everything over that I can. Some legacy Clojure at work I'll have to leave alone for now, but going forward it's Haskell wherever I can.

Have you found any drawback so far?

What is your take on the "you have to write clever, complicated code to make haskell work" (1). I've read that a lot of the code use for the language shootout is far from idiomatic haskell, but just plain clever, in order to get decent performance...

(1): http://jxyzabc.blogspot.ca/2009/03/haskell-vs-ocaml-or-ravin...

Re: “Mostly functional” programming does not work

#96
C functions are really procedures, except when they have no side effects on global variables. Indeed, a C function can be regarded as pure even if it contains imperative state changing code provided that all the mutable variables involved are local temporaries that only exist for the duration of the function call. Provided that f(x) always returns the same result for the same value of x it shouldn't matter how it is implemented.

APL element-wise operators are pure functions in an imperative language that has destructive assignment. However, it is also well suited to being used to implement GPGPU parallelism with local temporaries inside imperative procedures that appear to be pure functions from the outside.

Another form of parallelism arises from pipelined dataflow where tasks can simultaneously work on different parts of the whole linear computation so that those waiting for the results (further down the 'conveyor belt') receive more data from a potentially unlimited input stream 'just in time' whilst they consume more new data from their supplier or the source.

Taking things in the opposite direction a purely functional program can be seen as being a frozen moment in time that is subject to extrinsically defined constraints. Much like a spreadsheet these values can transition between epochs so they become ordinary mutable variables in a high-frequency event loop. This is the basis of exploratory "live" programming as an interpreter 'reacts' to dynamic changes in its source. It is also a facility provided by Mathematica where it permits the user to manipulate a graph of some complex function through recalculations based on new values of some sliders.

Every technique has its proper place and the latency incurred by Erlang mailboxes in the pursuit of fault tolerance and convenient hot-swapping of distributed modules is less of a performance issue when there would be a delay anyway given that the code is running over a network of computers. Erlang solves every significant problem of concurrency and it is highly reliable, unlike C# or Visual BASIC for which he is responsible. He really isn't in a position to criticise.

Both FP and OOP are extremes. Really, you can get by with Prototypes and have something type-oriented rather than class-based like Barbara Liskov's CLU. These can be given the capability of operating like Actors to simply take advantage of multicore / multiprocessor / multicomputer architectures. It helps your clarity of purpose if your language encapsulates persistent state in these Prototypal Actors without silly workarounds like C++'s friend function to make it go faster. A lot of your global state can live 'outside' of the program only to be seen from within as a set of global constants that change every 1/60th of a second when the runtime is reborn as if run from scratch with a slightly edited source. This may mean that apart from the output pipe of your dataflow that you can only put stuff IN to the BLACK BOX and must trust it to create its own views as to its current epochal value, just as a videogame renders a new frame of animation. All of the proponents of FP and OOP and for that matter Actors seek to prove that all programs can be written just using only their newly hyped paradigm. This is typical of ivory tower academia unsullied by the necessary pragmatism of the workplace. If you admit that there is something good about Actors then you don't have to learn Monads. If you admit that 'cloning' is a cleaner solution than the often abused (for the sake of convenience) 'implementation inheritance' and come to realize you can easily recreate classes / interfaces as abstract prototypes (i.e. they are just a pattern) you can jettison a whole lot of distracting OOP terminology and inscrutable UML diagrams as the work of self-promoting "architecture astronauts". Yet, if you embrace symbolic programming as seen in Mathematica you get to optimise your algorithms whilst not losing an insight into how their individual terms are transformed in your super-accessible declarative 'executable specification', at which point you realise that a symbol with an unknown value (i.e. a conventional mathematical variable) which can only become attached to a value once (per epoch) can be viewed as awaiting dataflow from a pipeline without any extra syntax obscuring your intent - you just call a variadic function and let the receiver await a finite list of arguments and then if there are more in the stream waiting beyond those it has already taken it awaits the same number of parameters again.

Really, the whole is greater than the sum of its parts - especially when those parts (paradigms) are dovetailed nicely.

I've been working on my own multiparadigm programming language for many years and Erik Meijer just seems too damn bleak.

Re: “Mostly functional” programming does not work

#97
I am going to take the apparently unique position here (after 90 comments) that Erik is correct, at least about pure functional programming (the more modern sense of "functional" rather than the older one that is "merely" about first-class function objects). The value of pure functional programming comes from creating programs out of very mathematically-small pieces... a function of Int -> Int can only do so many things to the output Int, as compared to a function in an impure language which may be only able to do so many things to the output Int but may also arbitrarily manipulate the world in uncontrollable ways. The pure-functional function is exponentially "smaller" than the the impure version. Much of the study of the Haskell world right now comes in how to use these much simpler pieces to still build real-world programs.

If you "pragmatically" say, "Oh, but this is so hard, let's just let ourselves use a little bit of arbitrary-world-manipulation in our functions", you've basically returned back to the original world of programming with exponentially-complicated pieces again. As he points out in the article, even with a tiny crack in the wall, the compiler is back to being unable to assume purity. Programs must once again function as if an Int -> Int closure might read from the disk or hit the network. You're really back in the world of OO + old-school functional addons. I'm a bit more pragmatic and will agree that's a nice and useful paradigm, especially if you've learned discipline from time in the pure-functional world, but it is not the pure-functional world, and you will not reap the benefits.

(Which A: yes, they do exist and B: no, they aren't necessarily "mandatory" or the "only way to program". But still, see A. Personally I'd keep pure functional around for either applications that need high quality assurance without breaking the development budget, or programs of high complexity where the state space is big enough even before you start using horrifically unconstrained pieces to try to build your solution.)

I'd rephrase the title a bit... Mostly functional programming is not pure functional programming, and whereas I think "pure OO" didn't have a sweet spot where you insist everything is 100% OO, pure functional programming does. It isn't the only sweet spot. I think careful use of a very-not-pure language like Go, where one merely uses convention to avoid shared state (a very "pure" idea), can still be a sweet spot on its own. But there is another, where you go "purely pure", and for that one, you really do have to go purely pure, or you're not using it... and if you've never done it yourself, because you've only used impurely pure languages, you don't really have an opinion yourself because you've never tried it. Very nearly the only practical way to try it right now is Haskell.

Re: “Mostly functional” programming does not work

#98
post #77

Earlier quoted context omitted.

> And its going to fail for the same reasons that C++ failed C++ "failed"? > the OO and functional features don't interact well How don't they? Before C++ had lambdas, programmers would define a class with overloaded operator() and use that instead, every time. Now the language provides a way to easily generate the class with its members and constructor and operator() automatically - which is basically what functiona…

For instance, in Haskell a value is a value. If I have a value of type Integer then it definitely exists; if I want to say that it might not exist then I use the type "Maybe Integer", which expresses that idea precisely. Same goes for a value of type Employee; if I might or might not have an Employee (for instance, if the lookup function doesn't find someone with that employee number) then I have to use Maybe Employe…

> in Haskell a value is a value

The same is true of C++. Values and references in C++ can't be null. Pointers can be null, but that's a lower-level feature that doesn't have an equivalent in idiomatic Haskell.

Re: “Mostly functional” programming does not work

#99
post #56
post #18

Earlier quoted context omitted.

And just what makes you think making a purely functional language 'lambdacious' will not a few years later result in a book 'Industrial strength lambdacious'? You're falling for the trap of thinking that pursuing a theoretically pure discipline will result in a language with less flaws; in reality, even theoretically pure concepts have issues and can be superior and inferior to other theoretical concepts/constructs […

Quote: "You call 'Aversion to Extremes' a cognitive bias [... but] the more extreme a language pursues a theoretical concepts, the less used it typically ends up being in practice." Yes, people use languages with solid theoretical foundations less because they perceive them to be extreme. That was my point. Quote: "I can't imagine [... any measure that] makes these 'purity-oriented' languages appear to "work better i…

They use them less because they are less practical and due to their purity are unable to fulfill peoples (real, rather than theoretical) requirements.

Measuring LOC required to implement a task is meaningless. If you implement a task in python in fewer LOCs than what I need in C, that doesn't necessarily mean anything, because my code might fit on an 8-bit microcontroller, run faster, ... or meet any other number of imaginary or real additional requirements I might think of (and people always have lots of those!) "Have 10% fewer lines of code" is pretty much never a given requirement, though.

Sure, erlang is a "uncompromisingly pure implementation of the actor model", but then python is an uncompromisingly pure implementation of the python model, and C is an uncompromisingly pure implementation of the C model, so that's hardly an interesting argument. Erlang is pretty much what popularized the actor model as we consider it nowadays in mainstream programming, so that's tautological.

The point (which you have not actually argued against) is that erlang is also a functional language, but not a pure one; it allows side-effects, it allows sending messages, it allows storing data in your (destructibly updatable) process dictionary, et cetera.

That means erlang benefits from the features it inherits from the functional languages, even though it doesn't go "full functional" in the sense some other languages do.

If you don't think there are programs that are difficult to write in haskell, agda, miranda, ML, ..., I have to doubt that you have done a substantial amount of them, and/or that you have applied it to any actual real-world task.

Re: “Mostly functional” programming does not work

#100
post #77

Earlier quoted context omitted.

> And its going to fail for the same reasons that C++ failed C++ "failed"? > the OO and functional features don't interact well How don't they? Before C++ had lambdas, programmers would define a class with overloaded operator() and use that instead, every time. Now the language provides a way to easily generate the class with its members and constructor and operator() automatically - which is basically what functiona…

For instance, in Haskell a value is a value. If I have a value of type Integer then it definitely exists; if I want to say that it might not exist then I use the type "Maybe Integer", which expresses that idea precisely. Same goes for a value of type Employee; if I might or might not have an Employee (for instance, if the lookup function doesn't find someone with that employee number) then I have to use Maybe Employe…

It's worth noting that `Option(null)` is `None`. And while it's possible for any reference to be assigned `null`, it rarely happens in Scala code as a) it's well known to be bad form, and b) the IDE's can be configured to yell at you about it. Practically speaking (from the middle), it's not a problem.
Post reply on HN