By way of a counterpoint to the "showing complicated things alienates beginners" argument, remember that to a beginner there are already very many things on the screen that they won't (and needn't immediately) understand. For instance, this is what a simple `stack ghci` in my home directory says to me:

$ stack ghci
Run from outside a project, using implicit global project config
Using resolver: lts-2.22 from implicit global project's config file: /home/linuxadmin/.stack/global/stack.yaml
Error parsing targets: The specified targets matched no packages.
Perhaps you need to run 'stack init'?
Warning: build failed, but optimistically launching GHCi anyway
Configuring GHCi with the following packages:
GHCi, version 7.8.4: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Ok, modules loaded: none.
Prelude>

There's a lot of stuff there you don't need as a beginner. The line beginning 'Error' is a bit scary, as is the 'Warning'. The advice to run 'stack init' is not good advice. The advice to use :? for help is probably the most beginner-useful thing in all that and it looks like line noise rather than a thing you might want to actually type!

My point is that beginners have to start out ignoring things they don't understand anyway - part of the process of learning a new language is coming to terms with what's important and what's not in any given context. I'm not saying I'm a big fan of the addition to the type sig of ($), and would definitely appreciate a flag to switch it off, but I don't think this'll make it significantly harder to teach my next victims.

Cheers,

David

On 6 February 2016 at 18:14, Manuel Gómez <targen@gmail.com> wrote:
On Sat, Feb 6, 2016 at 12:42 PM, Edward Kmett <ekmett@gmail.com> wrote:
> The primitives that GHC uses to implement arrays, references and the like
> live in #. We then wrap them in something in * before exposing them to the
> user, but you can shave a level of indirection by knowing what lives in #
> and what doesn't.

Yes!  Let’s not forget, of course, that these (or similar) have been
in GHC for many, many years, right in the Prelude:

```
> :i Int Char Float Double IO Integer
data Int = GHC.Types.I# GHC.Prim.Int#
data Char = GHC.Types.C# GHC.Prim.Char#
data Float = GHC.Types.F# GHC.Prim.Float#
data Double = GHC.Types.D# GHC.Prim.Double#
newtype IO a
  = GHC.Types.IO (GHC.Prim.State# GHC.Prim.RealWorld
                  -> (# GHC.Prim.State# GHC.Prim.RealWorld, a #))
data Integer
  = integer-gmp-1.0.0.0:GHC.Integer.Type.S# !GHC.Prim.Int#
  | integer-gmp-1.0.0.0:GHC.Integer.Type.Jp# {-# UNPACK
#-}integer-gmp-1.0.0.0:GHC.Integer.Type.BigNat
  | integer-gmp-1.0.0.0:GHC.Integer.Type.Jn# {-# UNPACK
#-}integer-gmp-1.0.0.0:GHC.Integer.Type.BigNat
```

Stepping outside the Prelude, yet well within beginner territory,
brings even more fun:

```
> :i Map Set
data Map k a
  = containers-0.5.6.2:Data.Map.Base.Bin {-# UNPACK
#-}containers-0.5.6.2:Data.Map.Base.Size
                                         !k
                                         a
                                         !(Map k a)
                                         !(Map k a)
  | containers-0.5.6.2:Data.Map.Base.Tip
data Set a
  = containers-0.5.6.2:Data.Set.Base.Bin {-# UNPACK
#-}containers-0.5.6.2:Data.Set.Base.Size
                                         !a
                                         !(Set a)
                                         !(Set a)
  | containers-0.5.6.2:Data.Set.Base.Tip
```

Unboxed types, the UNPACK pragma, references to GHC.Prim (which easily
lead to confusing exploration), unboxed tuples, an unboxed State
monad, RealWorld, bang patterns, unexported constructors,
implementation details for abstract types… all of them available right
from the prompt of the Prelude using the main tool for exploratory
learning that beginners rely on.

I’m not saying this is a good thing and I’m not saying this should be
fixed.  I’m not even saying this is comparable to the situation with $
and I’m likewise not saying presenting these concepts to beginners
should be thought of as comparable to presenting levity polymorphism
to beginners.  It is nonetheless relevant context to this discussion;
the Prelude has always had concepts unfriendly to beginners readily
available, and Haskell beginner teachers have always had to work
around these issues.  Students have always asked about these things.

> But even if you never care about #, Int, Double, etc. are of kind *,
> Functors are of kind * -> *, etc. so to talk about the type of types at all
> you need to be able to talk about these concepts at all with any rigor, and
> to understand why Maybe Maybe isn't a thing.

In my personal teaching experience, it is extremely helpful to discuss
kinds in the first introduction of type constructors, after covering
types with no parameters.  This is especially helpful in discussing
how the hierarchy leading to Monad works, and why things like
«instance Functor (Tree Int) where …» don’t make sense and why
«instance Functor Tree where …» must be parametric in the type of the
thing in the tree, which in turn motivates a lot more discussion.

Teaching kinds is teaching Haskell basics.  It is not an advanced
topic.  It ought to be covered near the very first lessons on Haskell
for absolute beginners.
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe