Should Haskell be rebranded away from "Pure Functional Programming"

The problem is, Haskell implicitly has support for multi-paradigm programming via both do notation, object libraries, and even logic programming via monads. Pure in the sense that the core language is functional, and that multi-paradigm programming is done through a functional programming layer, creates some level of confusion, and makes Haskell not seem “pragmatic”, when it is very pragmatic, it just avoids compromising by providing first-class support for multi-paradigm programming and resorts to different hacks to preserve its non-strict and functional-first nature.

1 Like

There are a couple of sides to the issue

  1. The technical definition of “pure”. That’s what Richard, gilmi and I have been discussing.
  2. Regardless of the technical definition, the impression it gives to the outside world. I think this is the main thrust of your original post, William.

I agree with you, William. In so many online discussions in general programming fora I see comments of the following sort:

Haskell is a pure language, that means it can’t have state or side effects, but modifying state and causing side effects are essential in a real-world system, therefore Haskell is useless in the real world.

My mind always boggled how such commenters could believe what they are saying. Do massive corporations like Facebook and Standard Chartered really use Haskell despite it being useless in the real world?! But the point remains: people do seem to think this.

I’m with gilmi and (I think, you): not only does “pure” (in the programming language sense, let alone the moral sense) give the wrong connotations, it’s not even what we value at all! We value referential transparency. The notion of “purity” is a poorly-defined approximation to referential transparency.

Here’s a challenge to folks who like the notion that “Haskell is a pure language”: please explain what benefit you get from Haskell’s “purity” that is not also a benefit of Haskell’s referential transparency.

3 Likes

@tomjaguarpaw, is the following URL yours?

http://h2.jaguarpaw.co.uk/posts/impure-lazy-language

Yes!!!

[Exclamation marks added because Discourse requires that posts must be at least 20 characters]

[EDIT: intriguingly, although I wrote 17 exclamation marks, Discourse only shows 3]

3 Likes

Honestly, I think we could save pure by saying that Haskell is a language with “purely functional semantics”, then pick some kind of marketing buzzword to refer to referential transparency or a pure-impure separation. Purely functional semantics → is what Haskell actually is, since do notation etc is just syntax that converts down to functional code.

The idea is, for people who understand what purity means, purely functional semantics, or a similar term, is equivalent to purity, whereas for bean-counters / language warriors, they have no bleeding clue what it means. It’s a dog-whistle, except for academics instead of reprobates.

So what we’d do would be to describe Haskell as a ___ language, with purely functional semantics, a very strong type system, and non-strict evaluation.

On the top level, then, we find some other term to describe Haskell, its benefits, and utility. Because, after all, the language designers were busier working on the language design than the marketing (see: “Cute, fuzzy things”). But that’s what Haskell Foundation is for, right? HF handles the business and marketing side, GHC Committee handles the language itself.

===

Yeah, and I’m skirting the issue. Referential transparency is a good academic term, but a bad marketing term. If you were Sun, preparing to blow hundreds of millions on Java’s marketing budget, and were all of a sudden forced to blow hundreds of millions on Haskell’s marketing budget, how would you describe Haskell?

1 Like

13 posts were split to a new topic: What is a good formal definition of purity?

What a surprise: it’s a question about I/O in Haskell - I’m assuming none of these helped. Let’s try something different and see how Agda performs I/O:

Haskell 2010 almost permits a similar "outsourcing" of I/O:

-- the I/O ADT...
data IO a
foreign import "primUnitIO" unitIO :: a -> IO a
foreign import "primBindIO" bindIO :: IO a -> (a -> IO b) -> IO b

instance Monad IO where
    return  = unitIO 
    (>>=)   = bindIO 

Main.main can be dealt with in similar fashion, so:

module Main(main) where

main :: IO ()
        ⋮

would be translated into:

module Main() where
foreign export "hs_Main_main" main :: IO ()

main :: IO ()
        ⋮

So after all that, what does evaluating main entail?

{- Haskell I/O outsourced: nothing to see here... -}

…just as Agda outsources I/O - and not a real faux world in sight! It just requires some FFI extensions. It would also help to make abundantly clear that the monadic interface is actually relatively boring e.g:

 -- "alternate" I/O ADT!
data IO a
type Await a = IO a -> a
foreign import "primAsyncIO" asyncIO :: ((forall a . Await a) -> b) -> IO b

instance Monad IO where
    return x = asyncIO $ \ await -> x
    m >>= k  = asyncIO $ \ await -> let !x = await m in
                                    let !y = await (k x) in
                                    y

I don’t want to delve into the theoretical intricacies of CS concepts, but I think this entire thread started on the wrong (semantic) foot: to say that Haskell is pure simply means that most Haskell functions do most of their work consuming/producing all and only the values instantiating the types mentioned in their signature. Exceptions, UnsafeIO, Traces and other niceties provided by the runtime are, of course, not (always) part of these.

Most functions… most of their work… that’s a tell-tale indicator that purity is, in fact, a concept that admits of degrees, and whose meaning is to be determined against a host of background conditions (just like, for example, the use of the word “pure” in chemistry that means something like “made of only one substance”; in this context there are background conditions meant to specify, among other things, the “scale” at which substance is individuated, so as to not include, say, exchanges of subatomic particles with other parts of the system within which the allegedly pure substance is considered).

For this reason I think it makes completely sense to not drop “pure” in “Haskell is a pure, lazy, functional programming language” simply because once we specify the relevant background conditions, one of two things:

  • either there is no other language which, relative to this specification of the background conditions, will be considered to be pure in the first place; or
  • Haskell will come out as part of the first-tier of all contenders ordered by purity, relative to this specification.

But my main argument for keeping “pure” is because it gives a super nice vibe to the slogan, a vibe that resonates with the ego craving for virtue-signalling opportunities of many folks, and I think it is not necessary to deprive them from this pleasure.

2 Likes

In my pedestrian view Haskell being pure is demonstrated by the following snippet:

mainLines :: [IO ()]
mainLines = [ putStrLn "hi", putStrLn "see you at runtime" ]

main = print $ length mainLines -- XXX: no, you wouldn't

Sure, in other languages you can wrap that into lambdas or whatever so the effects wouldn’t be triggered. But in Haskell “IO” (the concept, not the type) is just an ordinary value you pass around. And so are other effects. You have to entangle yourself explicitly with the effect to reach for its “result”.

Well … ever tried to talk about “total functions” in a german user-group? Raises some eyebrows :laughing:

1 Like

The key term is “rebranded”, i.e, the notion of branding.

The objection to the term pure isn’t simply that it isn’t true in some sense, but that it implies a lack of pragmatism, first, when Haskell is reputed to be very effective in industry settings, and second, it implies a moralism that can make Haskell offensive to others or more difficult to learn.

In Scala-land, for instance, I’m told that many shops write their Scala as “a better Java”, instead of as an FP / OOP hybrid. This is fine; Scala has multiple times the adoption of Haskell, and eventually Scalators move toward greater FP and even to Haskell (the Hascalator).

Haskell, in theory, can just function as a better C / Python (and there are people who use Haskell as a scripting / glue language). The ST monad exists, so does IORef, etc. Now, this should sound horrifying to all true Haskellers, but in reality, I’ve read that there’s a 3-month onboarding experience at many shops in order for a non-Haskeller to be prepared to work on a Haskell codebase.

The high cost of on-boarding makes Haskell unattractive to businesses simply because you’re putting a person up for 3 months while you get zero productivity out of it. Treating Haskell as simply pure means that there’s no way around it, but if you’re willing to break purity, you can potentially put the trainees on imperative Haskell / Haskell gluecode while you train them, thus getting productivity out of Haskell trainees.

But as long as Haskell is marketed as pure, as opposed to “with purely functional semantics” using a different top-level label, people are less likely to try this, because purity is not merely a language trait, it’s also a matter of language culture.

===

And once again, remember that I’m not technically violating “avoid $ success at all costs”. This is about attitudes and branding, not the language compromising itself to support (more than it already has) imperative or OOP constructs.

2 Likes

Can you give an example of what you mean by “break purity”?

I disagree with:

  • “implies a lack of pragmatism”
  • “implies a moralism”
  • can just function as a better C

But that’s not very important. The more important objectionable bit is this inference:

  • treating Haskell as simply pure means that there is no way around [purity], which is one important factor contributing to difficulties that shops run into when taking Haskell trainees.

I think think it’s a very exotic claim to say the least, that Haskell’s branding in terms of purity makes the life of trainees / shop more difficult – borderline outlandish in fact. The more reasonable claim in the vicinity was perhaps that Haskell’s purity might require some adjustment in the programming habits of development teams if they are only familiar with more mainstream approaches, but I don’t think this is what you wanted to say because it has nothing to do with branding.

But Okay, in the spirit of making something useful out of this, how about reaching out to the HF to survey shops that did take Haskell trainees, and ask them if the branding made things more difficult? From there you could extract a profile of Haskell shops sometimes taking trainees and perhaps even get in touch with shops that don’t take trainees, so as to have a contrastive case for the stats. Then you can back up your claim that branding is misguided.

If the request is to reach out to HF, it might simply make more sense to ask the HF to survey companies that considered using Haskell, and from companies that both considered and selected Haskell, as well as companies that considered and rejected Haskell, to determine what is the most effective branding for Haskell that is still honest.

This would be an enlargement in scope from the simple “Haskell is misbranded as pure” notion that I’m playing around with right now to a more comprehensive “Haskell is probably misbranded” notion.

And we can generalize further from that; i.e, beyond Haskell simply being misbranded, what misconceptions about Haskell do people have that prevent its use in production? How can we ameliorate these misconceptions?

===

Thinking in this vein, one big opportunity is probably “do Notation”, in the context of “purely functional semantics”. An advertisement for do Notation would simply be “get the benefits of functional programming while having your code look traditional / imperative!” And given that do Notation ultimately desugars to a series of binds, this isn’t false.

1 Like

My suggestion was to try to turn the “your playing around with a (technically complex) notion” into a valuable action item. But whatever you do, please have common sense; it does not make sense to call for a rebrand (practical task with lots of implications) if in fact you’re mostly playing around with a notion; and if you are serious about a rebrand, do bring forth evidence backing up your claims.

I’m calling for a brand analysis at this point; i.e, does the brand serve the Haskell Foundation and the Haskell community’s needs? In what ways does it do so? In what ways is it lacking? In the event that it’s lacking, how might adjusting the brand better serve HF / Haskellers?

Yeah well 99% of folks around here are volunteers and you just don’t “summon up” volunteers to do work. Instead you create something like a working group that you yourself are going to lead and you try to build a meaningful, actionable project out of it. If you do it well and with a bit of luck others may want to merge in turn and contribute. Else you move on.

Well, I apologize for being too presumptuous, but I was just responding to your comments that “pure branding is not a problem”. It does make sense, however, to research Haskell’s image among its users and potential users, and see to what extent it impacts its selection choice as a programming language. If you want me to conduct informal surveys, I can try to do so.

Before you do, try reading A History of Haskell first - it will provide some context (and maybe inspiration) for what you’re contemplating.

I agree in a sense but I think it should be in regards to functional programming as a whole. When you say “there are no mutable variables, no side effects and no loops” people think “then you can’t do anything” which is correct, which is why we actually don’t have these restrictions. It confused me a lot in the beginning and made things harder because whenever I would see these things I would think “something is wrong because I’ve heard these are not allowed so whatever this is, it isn’t functional programming”.

I think I like the Robert Martin put it: Functional programming impose discipline on mutation and side effects the same way structured programming imposed discipline on control flow or how OO imposes discipline on state. (I don’t know if the last one is fair but I suspect I’m incapable of being fair to OO)

2 Likes