Live data from Hacker News

Why Functional Programming Matters (1984) [pdf]

cse.chalmers.se

91–100 of 145 posts

Re: Why Functional Programming Matters (1984) [pdf]

#91

A lot of pleas for functional programming give a long list of convincing examples that work well with functional programming. You can do this with almost any language, and this is also quite deceptional, as this is often done to convince beginners to learn another language; "look at how simple it is to program this contrived example in !". In order to be able to use a programming language or paradigm well, it is espe…

NOTE: I agree with your comment as a whole but I want to give some counterpoints to some things you've said. These counterpoints all do require more "advanced" FP ability, but as FP becomes more popular, these techniques will become less "advanced."

> Functional programming does not work well in programs which handle a lot of states.

I've rewritten stateful, greedy, backtracking algorithms from Java to Scala. Scala (scalaz in particular) made this algorithms much simpler with no noticeable performance penalty. The backtracking in particular became trivial thanks to immutability and the State monad.

> It does not work well in programs which have high requirements for performance or memory.

There is a cost to immutability, but mostly it doesn't matter. When it does, FP has a lot of ability to encapsulate mutability/ugliness etc used for performance improved in different ways. Haskell in particular is great at this. It has ST for mutability, and rewrite rules/inline pragmas for performance gains. There still is a lot of room to improve here however.

> It does not work well for programs which have to do low-level stuff.

Haskell itself isn't ideal for low-level programming (low-level as in microcontrollers and FPGAs. Raspberry Pi isn't low-level and can handle Haskell fine). But Haskell has EDSLs that compile to C/VHDL/etc (C: Ivory, VHDL: Various Lava variants). With an EDSL approach, you end up using Haskell as a macro language for your low-level language. And unless the CPP, Haskell is a powerful and easy to reason about macro language!

Re: Why Functional Programming Matters (1984) [pdf]

#92

Earlier quoted context omitted.

My point is not that functional languages can't support mutation, I'm well aware of the whole gamut from State to F-Star, Eff, and Idris. My point is that you're going to spend almost all of your time explicitly mutating things, using whatever functional language as a "very fine imperative language." Yes, you can embed those semantics inside functional semantics, and even use the functional language to add more stati…

> My point is not that functional languages can't support mutation, I'm well aware of the whole gamut from State to F-Star, Eff, and Idris. My point is that you're going to spend almost all of your time explicitly mutating things, using whatever functional language as a "very fine imperative language." The difference being that this "very fine imperative language" has much stronger type safety guarantees. Maybe we ca…

> The difference being that this "very fine imperative language" has much stronger type safety guarantees.

Is that a result of the specific language, rather than FP?

That is: One could think about building a procedural language that had... well, I'm not sure it could have Hindley-Milner types, because I'm not sure it could have higher-kinded types, but it could come close, couldn't it?

And from the other side: Does FP require very strong types? Or can it be done with something equivalent to C/C++'s type system? Or Python's?

Re: Why Functional Programming Matters (1984) [pdf]

#93
post #38

Earlier quoted context omitted.

> There are plenty of tricks you can not write on pure monads This made me curious, could you list some?

Anything that needs rewriting a memory address without losing time by allocation and garbage collection. Handling IO exceptions and masking them as different errors. Thread, process, or machine coordination in parallel execution.

You don't need unsafePerformIO for any of these.

> Anything that needs rewriting a memory address without losing time by allocation and garbage collection.

ST gives you mutable references. Or just use IO.

Re: Why Functional Programming Matters (1984) [pdf]

#94

Earlier quoted context omitted.

A kernel spends most of it's time managing mutable state. Here's a table of processes. We want it to be an array, rather than a linked list, for efficiency reasons. When a new process is created, we don't want to copy the array, also for efficiency reasons. So we mutate the array. > So does every computer programmer though. Not really.

> A kernel spends most of it's time managing mutable state. Why do you think that FP doesn't have tools for this? Do you genuinely think that in 20+ years of research no one has thought of this? Have you investigated it? I don't know. If you think that things like ST aren't suitable please say why (other than the larger problems with monad transformers, of course).

I know that FP has tools for that. But if the problem is primarily managing mutable state, isn't a tools that lets you directly see what you're doing a better fit?

Are the FP tools as efficient as the direct, C-style approach? For an OS, that matters.

Are the FP tools as easy to reason about correctly (especially in a section you're not familiar with)? For an OS that's worked on by thousands of people, that matters.

In this context, what is "ST"? And, what are the larger problems with monad transformers?

Re: Why Functional Programming Matters (1984) [pdf]

#95
post #73
post #32

Earlier quoted context omitted.

Look, I fixed their code in so many ways: main = runConduitRes -- dealing with finite resources ( sourceFileBS "input.txt" -- read input.txt as binary data .| decodeC utf8 -- decode assuming UTF-8 .| linesC -- split into lines .| mapC parseList -- parse each line into list of text .| mapC (get 5) -- get sixth element of list .| catMaybeC -- discard lines with no sixth element .| encodeC utf8 -- encode as UTF-8 .| sin…

It seems to me that part of the problem he was having is that he didn't really understand how these methods were being implemented internally. I know that all languages inevitably have these problems but how do the amount of leaky abstractions compare in Haskell to other languages?

I don't think Haskell is worse than any other language in that regard. What perhaps sets it apart is how much of its functionality is implemented in third-party libraries, which may be difficult for a beginner to come to grips with. "Why should I download a library to use efficient arrays? Shouldn't they be built in, like in Python?"

I can come up with two explanations for this reliance on third-party libraries.

1) Haskell has always been a quickly evolving language attracting research-minded people which in turn go on to develop really cool libraries that are much better than conventional ways of doing things. The interpretation of this explanation is that it's simply not possible to keep the standard library up to date with the latest library developments.

It may also be the case that

2) Haskell has always been a really powerful language capable of offloading important tasks to libraries. What would need to be built-in functionality in other languages can be implemented as libraries with no sort of special treatment in Haskell, so people do it that way because they can, and because it keeps the base simple.

Re: Why Functional Programming Matters (1984) [pdf]

#96
post #95
post #73

Earlier quoted context omitted.

It seems to me that part of the problem he was having is that he didn't really understand how these methods were being implemented internally. I know that all languages inevitably have these problems but how do the amount of leaky abstractions compare in Haskell to other languages?

I don't think Haskell is worse than any other language in that regard. What perhaps sets it apart is how much of its functionality is implemented in third-party libraries, which may be difficult for a beginner to come to grips with. "Why should I download a library to use efficient arrays? Shouldn't they be built in, like in Python?" I can come up with two explanations for this reliance on third-party libraries. 1) H…

I'm leaning toward #2, largely because I know that's the Scheme approach, and I get the impression that Schemers and Haskellers have similar feelings about protecting the design purity of the language. By contrast, the Python community has always been pragmatic, arguably to a fault.

I can say that newcomers also seem to get a lot of advice that's directly at odds with how the Haskell community seems to think people should use the language. For example, Learn You A Haskell starts right off the bat by encouraging people to use the "list of characters" version of strings, even though that approach courts serious performance concerns.

Re: Why Functional Programming Matters (1984) [pdf]

#98

To me, this is the most important part of the text (p2, bottom): "The ways in which one can divide up the original problem dep end directly on the ways in which one can glue solutions together Therefore to increase ones ability to mo dularise a problem conceptually one must provide new kinds of glue in the programming language." Functional programming is great because it provides two (new) kinds of glue: function com…

> Functional programming is great because it provides two (new) kinds of glue: function composition and lazy evaluation. Certainly true for composition but laziness is more the exception than the rule in today's FP languages. And it's getting an increasingly bad reputation to the point that even Haskell is slowly (and reluctantly) being dragged in the strict direction (which it will never fully reach because so much…

There's one spot where I like laziness, and that's where it supports composition.

I'm gonna hop over to C# because that's where my favorite example lives: LINQ is a functional library that lets you describe queries on data that are executed lazily. The reason why the laziness is great in this scenario is that it lets you separate the tasks of constructing a data processing pipeline, and executing it.

The spot where it's tricky, though, is that it's a very leaky abstraction. It's easy to forget that these expressions might actually represent a lot of work, so if you get your lazy sequence object (IEnumerable in C# terms) and then check if it has any values in one expression, and calculate its sum in another, then you might end up accidentally round-tripping a database twice.

Because of those sorts of stumbling blocks, I think laziness is a power that needs to be handled with care. I'm pretty sure that means you most certainly should not make it the default behavior.

Re: Why Functional Programming Matters (1984) [pdf]

#99
post #95
post #73

Earlier quoted context omitted.

It seems to me that part of the problem he was having is that he didn't really understand how these methods were being implemented internally. I know that all languages inevitably have these problems but how do the amount of leaky abstractions compare in Haskell to other languages?

I don't think Haskell is worse than any other language in that regard. What perhaps sets it apart is how much of its functionality is implemented in third-party libraries, which may be difficult for a beginner to come to grips with. "Why should I download a library to use efficient arrays? Shouldn't they be built in, like in Python?" I can come up with two explanations for this reliance on third-party libraries. 1) H…

It might be simpler than that. Array syntax is not built in in Haskell therefore the array implementation needn't be built in.

Re: Why Functional Programming Matters (1984) [pdf]

#100

Earlier quoted context omitted.

A kernel spends most of it's time managing mutable state. Here's a table of processes. We want it to be an array, rather than a linked list, for efficiency reasons. When a new process is created, we don't want to copy the array, also for efficiency reasons. So we mutate the array. > So does every computer programmer though. Not really.

> Here's a table of processes. We want it to be an array, rather than a linked list, for efficiency reasons. At least in Linux, the table of processes is implemented as a (doubly) linked list.

I wasn't going to say anything but...
Post reply on HN