There’s currently a proposal to enable a set of warnings for code that uses punning. This is carefully not taking a position on whether punning is a Good/Bad Thing, but providing tools to help those who are making a stylistic choice to avoid puns.
I learnt Haskell from the ‘Gentle Introduction’. It introduces punning on [1,2,3] :: [Integer]; ('b',4) :: (Char,Integer)
without comment.
A little later (Section 2.2) it explains in an aside for user-defined data types/constructors
[Type constructors such as `Point` and data constructors such as `Pt` are in separate namespaces. This allows the same name to be used for both a type constructor and data constructor, as in the following:
data Point a = Point a a
While this may seem a little confusing at first, it serves to make the link between a type and its data constructor more obvious.]
And that’s all it says. (The word “pun/ning” doesn’t appear.)
Now there was plenty in that Intro that puzzled me; but punning didn’t; and “the link … more obvious” appealed to me. Yet (from that proposal and comments):
“Beginner confusion” [with link to a SO q; in which I don’t think the confusion is with the punning]
“I see students struggling with puns”
“… are extremely confusing to newbies. (…, I’ve seen 4 different classes of 2nd/3rd year university students getting confused by this)”
- A long straggly reddit thread that comes to no definite conclusion/has only anecdotal experiences, including teaching experiences.
So did I not suffer this (alleged) confusion because I taught myself Haskell/was not infected from getting taught by an academic who came with a prejudice that punning was confusing?
Did I not suffer because DataKinds
was not a thing at the time I was learning?
Perhaps DataKinds
should have a restriction [**] that it won’t promote data constructors that use punning(?) So the types typically used for kind-level programming would be unproblematic:
data Bool = False | True
data Either a b = Left a | Right b
data Nat = Zero | Succ Nat
data IntNat = 0 | 1 | 2 | ... | maxInt -- pseudodecl
data List a = Nil | Cons a (List a)
...
[**] Note DataKinds
already has a restriction that not all constructors are promotable.