EduHaskell

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

EduHaskell

erwig
Dear Haskell aficionados,

We will be using Haskell in an introductory course to computer science for college freshmen. From my past experience in using Haskell for students, the biggest hurdle and source of frustration is the type checker, or more precisely, the error messages generated. I see three major kinds of errors that get in the way of a smoother programming experience:

* Errors resulting from overloading
* Errors due to undefined type class instances (specifically, Eq and Show)
* Errors in the context of parametric polymorphism

While these problems are not unsurmountable, having to talk about these errors is a distraction from the major goal of explaining basics of (functional) programming. It would be great to have a Haskell compiler that offers the following features (and maybe others):

* Type classes and overloading could be turned off
* Eq and Show (and maybe Ord) instances would be automatically defined for any data type definition (when type classes are enabled)

My questions are:

(1) Does there exist a good solution to this problem already?

Should one use Helium? I haven't checked lately, but it used to avoid type classes. This might have the disadvantage of having to switch to GHC in case one wants to use overloading. (I have used Helium in the past, and while I admire the effort, I am not sure it's the best option.)

Are there versions of the Prelude available that accomplish some of this?

(2) Are there other Haskellers out there who also want a simpler, more educationally suited version of GHCi?

(3) If the answer to (1) is NO and to (2) is YES, is there any interest in forming a group for creating something like "EduHaskell"?


I'd be grateful for any comments or suggestions!


Thanks,
Martin

_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: EduHaskell

Simon Hafner
Hello Erwig

From what I understand, you want a Haskell without typeclasses. Elm
[1] would fit that bill nicely.

> * Type classes and overloading could be turned off
These don't exist in Elm.

> * Eq and Show (and maybe Ord) instances would be automatically defined for any data type definition (when type classes are enabled)
Eq and Show are implemented by compiler magic, no Ord though.

You could later move the students towards Haskell, after you spoiled
them with the Elm compiler messages :-)

Cheers,
Simon

[1] http://elm-lang.org/examples

2017-09-24 3:02 GMT+02:00 erwig <[hidden email]>:

> Dear Haskell aficionados,
>
> We will be using Haskell in an introductory course to computer science for college freshmen. From my past experience in using Haskell for students, the biggest hurdle and source of frustration is the type checker, or more precisely, the error messages generated. I see three major kinds of errors that get in the way of a smoother programming experience:
>
> * Errors resulting from overloading
> * Errors due to undefined type class instances (specifically, Eq and Show)
> * Errors in the context of parametric polymorphism
>
> While these problems are not unsurmountable, having to talk about these errors is a distraction from the major goal of explaining basics of (functional) programming. It would be great to have a Haskell compiler that offers the following features (and maybe others):
>
> * Type classes and overloading could be turned off
> * Eq and Show (and maybe Ord) instances would be automatically defined for any data type definition (when type classes are enabled)
>
> My questions are:
>
> (1) Does there exist a good solution to this problem already?
>
> Should one use Helium? I haven't checked lately, but it used to avoid type classes. This might have the disadvantage of having to switch to GHC in case one wants to use overloading. (I have used Helium in the past, and while I admire the effort, I am not sure it's the best option.)
>
> Are there versions of the Prelude available that accomplish some of this?
>
> (2) Are there other Haskellers out there who also want a simpler, more educationally suited version of GHCi?
>
> (3) If the answer to (1) is NO and to (2) is YES, is there any interest in forming a group for creating something like "EduHaskell"?
>
>
> I'd be grateful for any comments or suggestions!
>
>
> Thanks,
> Martin
>
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.
_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: EduHaskell

Chris Smith-31
In reply to this post by erwig
Hi!

For some of your ideas, let me suggest looking at CodeWorld, at http://code.world.  I use it to teach middle school students, ages around 11 to 14.  It has some of the properties you are looking for.  Notably:

- No type classes are defined in the standard library.
- It offers a fully polymorphic equality operator, with no type class constraint.  (This is implemented with runtime-aware logic specific to GHCJS.)
- It avoids the need for many other type classes by simplifying the available types.  For instance, there is one Number type so that math operators are monomorphic.  Comparison operators only work on Number, and there are separate monomorphic "Show"-like functions for different types.
- The prelude is uncurried, because accidentally partially applying a function is another mistake that new programmers make that can lead to poor error messages.
- A pre-compile step enforces that function application should use parentheses around arguments.  CodeWorld is designed to be used with a math-like notation -- such as "f(x)" -- rather than just "f x".
- There are post-processing rules that rewrite some error messages to be beginner-friendly.

This is likely not *exactly* what you want.  For instance, there is no REPL at all, and programs are designed to be run in a web browser panel (and soon exported to Android) rather than used from the command line.  But it might be a source of ideas for what is possible to accomplish on top of GHC.

Hope that helps,
Chris

On Sat, Sep 23, 2017 at 6:02 PM, erwig <[hidden email]> wrote:
Dear Haskell aficionados,

We will be using Haskell in an introductory course to computer science for college freshmen. From my past experience in using Haskell for students, the biggest hurdle and source of frustration is the type checker, or more precisely, the error messages generated. I see three major kinds of errors that get in the way of a smoother programming experience:

* Errors resulting from overloading
* Errors due to undefined type class instances (specifically, Eq and Show)
* Errors in the context of parametric polymorphism

While these problems are not unsurmountable, having to talk about these errors is a distraction from the major goal of explaining basics of (functional) programming. It would be great to have a Haskell compiler that offers the following features (and maybe others):

* Type classes and overloading could be turned off
* Eq and Show (and maybe Ord) instances would be automatically defined for any data type definition (when type classes are enabled)

My questions are:

(1) Does there exist a good solution to this problem already?

Should one use Helium? I haven't checked lately, but it used to avoid type classes. This might have the disadvantage of having to switch to GHC in case one wants to use overloading. (I have used Helium in the past, and while I admire the effort, I am not sure it's the best option.)

Are there versions of the Prelude available that accomplish some of this?

(2) Are there other Haskellers out there who also want a simpler, more educationally suited version of GHCi?

(3) If the answer to (1) is NO and to (2) is YES, is there any interest in forming a group for creating something like "EduHaskell"?


I'd be grateful for any comments or suggestions!


Thanks,
Martin

_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.


_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: EduHaskell

Ruben Astudillo
In reply to this post by erwig
I just have passing commentary on your issues. For the bigger questions at
the end of the mail I don't have good answers sadly, although just by
convenience on question from SO/reddit/web in general I would stay on
GHC/base so they can search their questions.

On 23/09/17 22:02, erwig wrote:
> * Errors resulting from overloading

On GHC 8.2.1 there is a new flag for `:type +d` which uses
type-defaulting for giving non-overloaded versions for functions.

    Prelude> :type +d foldr
      foldr :: (a -> b -> b) -> b -> [a] -> b
    Prelude> :type foldr
      foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b

That help to return some of the convenience from before Foldable was in
the Prelude. There also -XTypeApplications which lets you play with the
signatures

    Prelude> :set -XTypeApplications
    Prelude> import Data.Monoid
    Prelude> import Data.Set
    Prelude> :type +v foldMap
      foldMap :: Foldable t => forall m a. Monoid m => (a -> m) -> t a -> m
    Prelude> :type foldMap @Set
      foldMap @Set :: Monoid m => (a -> m) -> Set a -> m
    Prelude> :type foldMap @Set @(Sum _)
      foldMap @Set @(Sum _) :: Num w => (a -> Sum w) -> Set a -> Sum w
    Prelude> :type foldMap @Set @(Sum Int)
      foldMap @Set @(Sum Int) :: (a -> Sum Int) -> Set a -> Sum Int

type +v is to see the explicit forall and thus how the TypeApplications
get applied. Lastly there is more help to see what instances are
available in the form of link in the haddock pages of the classes.

> * Errors due to undefined type class instances (specifically, Eq and
    Show)

I would teach to define instances for those clases because they are easy
to do. They work on types of kind * thus are very down to earth. I
remember doing this with LYAH. That way they won't see them as magic and
actually understand why the compiler is barfing.

> * Errors in the context of parametric polymorphism

Those are actually hard. Classes of working on kinds * -> * are what
gives haskell the feeling that the class/instances are hard and magical.
Playing with them is the only to get comfortable though.

--
-- Ruben
-- pgp: 4EE9 28F7 932E F4AD
_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: EduHaskell

Johannes Waldmann-2
In reply to this post by erwig
Dear Martin,


I use Haskell for teaching as well (not for beginners) [1].
I do use ghci in lab classes. For the problems you mention,
I have these sort-of work-arounds:


> Errors resulting from overloading

numerical literals, arithmetical operators?
avoid built-in (Prelude) numbers and the Num class.

stuff that's been generalized from list to Foldable (e.g., length)?
avoid built-in (Prelude) lists [2]


> Errors due to undefined type class instances
> (specifically, Eq and Show)

I think these classes are somewhat easy to motivate -
at least Eq is (we need "==" to notate and test properties of programs,
not every type has decidable equality (functions have not),
so we need to mark the types that do)
For Show, it's not that nice (ghci uses "show" but implicitly -
then why do we need to write the Show instance explicitly)
Still, adding "deriving (Eq, Show)" after each data declaration
is not too much of a burden. I agree it is a distraction.


> Errors in the context of parametric polymorphism

Well, it's an important concept to teach,
so it is natural that it takes some time and work.

(slightly tangential - I think it would already help
if it would be easier to declare types of identifiers -
to remove unwanted polymorphism.
E.g., "\ (x::Bool) (y::Bool) -> x || y" currently requires
a language pragma (!) whose name mentions type variables (!!) )


- Johannes.


[1] https://www.imn.htwk-leipzig.de/~waldmann/talk/17/wflp
[2]
https://www.imn.htwk-leipzig.de/~waldmann/etc/untutorial/list-or-not-list/
_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: EduHaskell

Stuart A. Kurtz
In reply to this post by erwig
Dear Martin,

I also teach Haskell to college freshmen, albeit in a self-selected "honors" class. My typical student has some programming background, and a high level of mathematical aptitude.

The first few weeks were a bit easier in the days before burning bridges, but my sense is the things are starting to improve again. Certainly, I think the benefits of the improved Prelude far outweigh the pedagogical costs imposed on the proud few, who like us, are crazy enough to teach Haskell to 18 year olds.

1. The error messages in ghc 8.2.1 strike me as clearer and more concise.
2. I'm changing the way I teach.

My experience in teaching Haskell is that have to introduce types early, and the only real question is "how early." We're experimenting with introducing types (including simple parametric types and typeclasses) in Lecture 1 (tomorrow) this year, in what my colleague Ravi Chugh and I refer to as the "types earliest" approach.

What we're aiming for in Lecture 1 is an overview, not a deep understanding of Haskell's type system. Still, we *are* introducing typeclasses (albeit without talking about how they're implemented), and we are sketching out how type inference works, so students can see how conflicts arise.

I'd send a URL, but it won't be stable until tomorrow.

Peace,

Stu

---------------

Stuart A. Kurtz
Professor, Department of Computer Science and the College
Director of Undergraduate Studies for Computer Science
The University of Chicago



_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: EduHaskell

Stuart A. Kurtz
In reply to this post by erwig
Dear Martin,

Here's the URL for our first lecture:

        http://cmsc-16100.cs.uchicago.edu/2017/Lectures/01/intro.php

It is idiosyncratic, but then, so am I ;-). My experience is that Chicago students love little bits of history that help contextualize what they're learning, and these notes reflect that.

We'll be putting up additional lectures as we go. It's pretty easy to find the 2016 version of the class, but it looks like we'll be reworking much of the material.

Peace,

Stu

---------------

Stuart A. Kurtz
Professor, Department of Computer Science and the College
Director of Undergraduate Studies for Computer Science
The University of Chicago

_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: EduHaskell

Jurriaan Hage
In reply to this post by erwig
Hi Martin,

Helium does support overloading, depending on your choice of flags.
If you turn it on,  it provides a number of built-in type classes, like Eq and Old. It is just that you cannot define
your own classes and instances (work is on the way in this respect). All instances are derived, as you ask.

I will be working on extending Helium this (course) year in various directions to make it
* suitable as a study object for a course on compiler construction
and
* adding code generation and type checking for type classes
* add import/export facilities (these are currently very straightforward)

Helium can be easily installed from Cabal for you to check out and play with. See the website
at http://foswiki.cs.uu.nl/foswiki/Helium/WebHome

As to your general question on EduHaskell, I’d be interested in such a group, and would like Helium to be that teaching-oriented
Haskell compiler.

best,
Jur

> On 24Sep, 2017, at 03:02, erwig <[hidden email]> wrote:
>
> Dear Haskell aficionados,
>
> We will be using Haskell in an introductory course to computer science for college freshmen. From my past experience in using Haskell for students, the biggest hurdle and source of frustration is the type checker, or more precisely, the error messages generated. I see three major kinds of errors that get in the way of a smoother programming experience:
>
> * Errors resulting from overloading
> * Errors due to undefined type class instances (specifically, Eq and Show)
> * Errors in the context of parametric polymorphism
>
> While these problems are not unsurmountable, having to talk about these errors is a distraction from the major goal of explaining basics of (functional) programming. It would be great to have a Haskell compiler that offers the following features (and maybe others):
>
> * Type classes and overloading could be turned off
> * Eq and Show (and maybe Ord) instances would be automatically defined for any data type definition (when type classes are enabled)
>
> My questions are:
>
> (1) Does there exist a good solution to this problem already?
>
> Should one use Helium? I haven't checked lately, but it used to avoid type classes. This might have the disadvantage of having to switch to GHC in case one wants to use overloading. (I have used Helium in the past, and while I admire the effort, I am not sure it's the best option.)
>
> Are there versions of the Prelude available that accomplish some of this?
>
> (2) Are there other Haskellers out there who also want a simpler, more educationally suited version of GHCi?
>
> (3) If the answer to (1) is NO and to (2) is YES, is there any interest in forming a group for creating something like "EduHaskell"?
>
>
> I'd be grateful for any comments or suggestions!
>
>
> Thanks,
> Martin
>
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.

_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: EduHaskell

erwig
In reply to this post by erwig
Thanks for all the useful hints and suggestions!

Maybe I should have explained the constraints (and where they come from) in more detail. First, the course is NOT an introduction to programming, but an introduction to computer science more generally and thus also discusses several topics not typically addressed by a programming course. Second, computing concepts are introduced with the help of stories, and programming will only take place in the second half of the course (more details about the approach can be found at web.engr.oregonstate.edu/~erwig/SBT). Thus the goal of minimizing the need for explaining advanced type system features. Also, we have already created Haskell code, so that's why Elm, although a really nice language, is currently not an option because of its different syntax. Code.world is also a cool system, but we do currently require a REPL. I definitely will take another look a Helium.

Again, thanks for all the responses so far! I'm still wondering which, if any, of the existing alternative preludes would potentially be a good substitute for educational purposes.

--
Martin



_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: EduHaskell

Viktor Dukhovni
On Mon, Sep 25, 2017 at 02:11:20PM -0700, erwig wrote:

> Again, thanks for all the responses so far! I'm still wondering
> which, if any, of the existing alternative preludes would potentially
> be a good substitute for educational purposes.

A small comment, for what it is worth:  as a still learning novice,
I find the error messages in GHC 8.2 to be significantly easier to
understand than in previous releases.  Perhaps students will also
find that to be the case.

As to having or not having "Eq" by default, I have a brief anecdote:

I just did some work to improve performance in the HDBC Sqlite
driver, and had to deal with bit-rot in the tests.  I moved the
time conversion tests from the deprecated System.Time interface to
the preferred Data.Time interface, but found an obstacle in that
ZonedTime has no Eq instance.  This makes sense, because equality
of time with a time zone is ambiguous, are two such times equal
when they refer to the same UTC time, or should the Time Zone name
and summer only flags also be required to be equal?  So choosing
a suitable Eq implementation can be a subtle issue.

For the purpose of the tests, full equality was previously chosen
for System.Time, and I let that stand, so I needed to define an
equivalent Eq instance for Data.Time's ZonedTIme, and wanted to
avoid compiler warnings from creation of orphan instances.  So I
wrapped ZonedTime in a newtype ZonedTimeEq and created an Eq instance
for that, but the tests also wanted this to be "Convertible" to
various related types.  So I engaged some rather fancy machinery:

    {-# LANGUAGE FlexibleContexts #-}
    {-# LANGUAGE FlexibleInstances #-}
    {-# LANGUAGE MultiParamTypeClasses #-}
    {-# LANGUAGE UndecidableInstances #-}

    newtype ZonedTimeEq = ZonedTimeEq { _zt :: ZonedTime }

    instance Show ZonedTimeEq where
        show = show . _zt

    instance Eq ZonedTimeEq where
        a == b = let a' = _zt a
                     b' = _zt b
                  in zonedTimeToUTC a' == zonedTimeToUTC b' &&
                     zonedTimeZone a' == zonedTimeZone b'

    instance (Convertible a ZonedTime) => (Convertible a ZonedTimeEq) where
        safeConvert v = ZonedTimeEq <$> (safeConvert v)
    instance (Convertible ZonedTime b) => (Convertible ZonedTimeEq b) where
        safeConvert (ZonedTimeEq v) = safeConvert v

I just wrote the definitions I wanted to write, and each time the
compiler produced warnings, it helpfully told me that the definitions
were illegal without an extension to make it go.   So it took three
iterations to add FlexibleInstances, MultiParamTypeClasses and
finally UndecidableInstances to make the compiler happy.

The moral of the story is that Eq can be subtle, and sometimes lack
of an Eq instance is not an oversight, but is a hint that there be
dragons with deciding equality for the type in question.  And it is
in such cases that the instance machinery comes into play to let one
make the appropriate choice for the problem at hand.

--
        Viktor.

P.S. Perhaps my ZonedTimeEq "solution" is suboptimal, if there's
a better way, please drop me a note.
_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: EduHaskell

Simon Michael
In reply to this post by Stuart A. Kurtz
On 9/24/17 5:19 PM, Stuart A. Kurtz wrote:
> Here's the URL for our first lecture:
>
> http://cmsc-16100.cs.uchicago.edu/2017/Lectures/01/intro.php
Enjoyed it! Thank you.


_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.