[Haskell-cafe] New type of ($) operator in GHC 8.0 is problematic

David Turner dct25-561bs at mythic-beasts.com
Sat Feb 6 19:33:53 UTC 2016


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 at gmail.com> wrote:

> On Sat, Feb 6, 2016 at 12:42 PM, Edward Kmett <ekmett at 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 at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20160206/8341e7e5/attachment.html>


More information about the Haskell-Cafe mailing list