What I wish someone had told me...

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

What I wish someone had told me...

John Lato-2
I was just thinking about what I wish someone had told me when I
started working with Haskell (not that long ago).  It would have saved
me a great deal of trouble.

The Difference Between Interfaces and Type Classes.

Many "Introduction to Haskell for the OOper" style tutorials claim
that type classes are like Interfaces (for languages with that
feature).  I now think that, although this is technically true, it's
fundamentally misleading.  Here's a simple example demonstrating my
line of thought:

In C# (and presumably Java), this sort of function is common:
public IList GetListOfData()

In Haskell, a similar function may be
GetListOfData :: (Foldable a, Indexable a) => IO a

In C#, it doesn't matter what the actual type returned by
GetListOfData is, as long is it supports the IList interface.  It's
not uncommon for GetListOfData to make a choice between several
different implementations, depending on the nature of the data to be
returned.  The following code is perfectly reasonable in C# :

// List and MyList are different classes
if (something) { return new List(); }
else { return new MyList(); }

The equivalent won't compile in Haskell, because the actual return
type does matter, and *is determined by the calling code*.  Our
fictional GetListOfData can't return a List or a Mylist depending on
some conditional, in fact it can't explicitly return either one at
all, because the actual type of the result, as determined by the
caller, could be either one, or something else entirely (ignoring the
IO bit for the time being).

So I've come to the conclusion that stating type classes are like
interfaces is misleading to newcomers to Haskell, because it leads
people to think they should use type classes for the same sorts of
problems OO-languages solve with interfaces.  In turn this means new
programmers are encouraged to use OO-style architecture in programs,
reassured that they're in a "functional" idiom because they're using
the "functionally-approved" feature of type classes.  I think that if
I had understood this earlier, I would have embraced functional idioms
more quickly.

Incidentally, I'm still horrible at designing functional APIs and
modules, but at least now I know it, and I'm no longer trying to force
OO interfaces into Haskell.  So I've made progress.
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: What I wish someone had told me...

Alexey Romanov
Well, they act like interfaces in argument types, just not variable or
return types.

Yours, Alexey Romanov



On Tue, Oct 14, 2008 at 4:11 PM, John Lato <[hidden email]> wrote:

> I was just thinking about what I wish someone had told me when I
> started working with Haskell (not that long ago).  It would have saved
> me a great deal of trouble.
>
> The Difference Between Interfaces and Type Classes.
>
> Many "Introduction to Haskell for the OOper" style tutorials claim
> that type classes are like Interfaces (for languages with that
> feature).  I now think that, although this is technically true, it's
> fundamentally misleading.  Here's a simple example demonstrating my
> line of thought:
>
> In C# (and presumably Java), this sort of function is common:
> public IList GetListOfData()
>
> In Haskell, a similar function may be
> GetListOfData :: (Foldable a, Indexable a) => IO a
>
> In C#, it doesn't matter what the actual type returned by
> GetListOfData is, as long is it supports the IList interface.  It's
> not uncommon for GetListOfData to make a choice between several
> different implementations, depending on the nature of the data to be
> returned.  The following code is perfectly reasonable in C# :
>
> // List and MyList are different classes
> if (something) { return new List(); }
> else { return new MyList(); }
>
> The equivalent won't compile in Haskell, because the actual return
> type does matter, and *is determined by the calling code*.  Our
> fictional GetListOfData can't return a List or a Mylist depending on
> some conditional, in fact it can't explicitly return either one at
> all, because the actual type of the result, as determined by the
> caller, could be either one, or something else entirely (ignoring the
> IO bit for the time being).
>
> So I've come to the conclusion that stating type classes are like
> interfaces is misleading to newcomers to Haskell, because it leads
> people to think they should use type classes for the same sorts of
> problems OO-languages solve with interfaces.  In turn this means new
> programmers are encouraged to use OO-style architecture in programs,
> reassured that they're in a "functional" idiom because they're using
> the "functionally-approved" feature of type classes.  I think that if
> I had understood this earlier, I would have embraced functional idioms
> more quickly.
>
> Incidentally, I'm still horrible at designing functional APIs and
> modules, but at least now I know it, and I'm no longer trying to force
> OO interfaces into Haskell.  So I've made progress.
> _______________________________________________
> Haskell-Cafe mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: What I wish someone had told me...

John Lato-2
In reply to this post by John Lato-2
While this may be true, it's missing the point.  The claim that type
classes are like interfaces (the usual argument is that they define an
interface, but not an implementation) misleads OO-grounded programmers
into thinking of type classes in terms of an already-familiar concept.
 This is bad because said programmers then attempt to apply familiar
OO-styles, when they would be better off abandoning most of what they
already know about design.  I don't mean in the sense of "abstraction
good, separation of processing good, repetition bad", but rather how
to develop a useful/stable API, how to divide up the different
processing the module should do, etc.  In short, how to approach API
design, which is very different in Haskell than the practice that most
OO disciples are familiar with.

IMHO, stating that type classes act like interfaces in argument types,
but not return types, is too complicated a relationship to be useful
to somebody's first introduction to FP.  Better to avoid the whole
issue completely.

John Lato

Alexey Romanov wrote:
>
> Well, they act like interfaces in argument types, just not variable or
> return types.
>
> Yours, Alexey Romanov
>
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: What I wish someone had told me...

Lennart Augustsson
In reply to this post by John Lato-2
You can do equivalent of
// List and MyList are different classes
if (something) { return new List(); }
else { return new MyList(); }
in Haskell as well.  But to do that you have to introduce an
existential wrapper in the return type.
In OO languages the existential wrapper is built in to OO constructs,
but in Haskell you have smaller building blocks that you have to
assemble to make the thing you want.

So to extend your example, you can do
data IList = forall a . (Foldable a, Indexable a) => IList a
getListOfData :: IO IList
and now you can return different kinds of types from getListOfData
depending on circumstances.

  -- Lennart

On Tue, Oct 14, 2008 at 1:11 PM, John Lato <[hidden email]> wrote:

> I was just thinking about what I wish someone had told me when I
> started working with Haskell (not that long ago).  It would have saved
> me a great deal of trouble.
>
> The Difference Between Interfaces and Type Classes.
>
> Many "Introduction to Haskell for the OOper" style tutorials claim
> that type classes are like Interfaces (for languages with that
> feature).  I now think that, although this is technically true, it's
> fundamentally misleading.  Here's a simple example demonstrating my
> line of thought:
>
> In C# (and presumably Java), this sort of function is common:
> public IList GetListOfData()
>
> In Haskell, a similar function may be
> GetListOfData :: (Foldable a, Indexable a) => IO a
>
> In C#, it doesn't matter what the actual type returned by
> GetListOfData is, as long is it supports the IList interface.  It's
> not uncommon for GetListOfData to make a choice between several
> different implementations, depending on the nature of the data to be
> returned.  The following code is perfectly reasonable in C# :
>
> // List and MyList are different classes
> if (something) { return new List(); }
> else { return new MyList(); }
>
> The equivalent won't compile in Haskell, because the actual return
> type does matter, and *is determined by the calling code*.  Our
> fictional GetListOfData can't return a List or a Mylist depending on
> some conditional, in fact it can't explicitly return either one at
> all, because the actual type of the result, as determined by the
> caller, could be either one, or something else entirely (ignoring the
> IO bit for the time being).
>
> So I've come to the conclusion that stating type classes are like
> interfaces is misleading to newcomers to Haskell, because it leads
> people to think they should use type classes for the same sorts of
> problems OO-languages solve with interfaces.  In turn this means new
> programmers are encouraged to use OO-style architecture in programs,
> reassured that they're in a "functional" idiom because they're using
> the "functionally-approved" feature of type classes.  I think that if
> I had understood this earlier, I would have embraced functional idioms
> more quickly.
>
> Incidentally, I'm still horrible at designing functional APIs and
> modules, but at least now I know it, and I'm no longer trying to force
> OO interfaces into Haskell.  So I've made progress.
> _______________________________________________
> Haskell-Cafe mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: What I wish someone had told me...

John Lato-2
Are you advocating introducing existential types to beginning
Haskellers?  I think something with the scary name "existential
quantification" would greatly increase the head'splodin' on the
learnin' slope.  Certainly there's a place for them, but I wouldn't
want to see new Haskell programmers habitually approach problems with
a "first create a type class, then make an existential wrapper"
mentality.  Which is exactly what I fear is the current situation.

Although my list example is far to shallow to make this point, it
seems to me that it's fairly likely that somebody faced with this
problem has had something go severely wrong at some earlier time.

Existentials are certainly useful, but isn't it also possible that,
for many cases, an alternative design exists which fits a functional
idiom better and doesn't face this issue at all?

John

On Tue, Oct 14, 2008 at 5:03 PM, Lennart Augustsson
<[hidden email]> wrote:

> You can do equivalent of
> // List and MyList are different classes
> if (something) { return new List(); }
> else { return new MyList(); }
> in Haskell as well.  But to do that you have to introduce an
> existential wrapper in the return type.
> In OO languages the existential wrapper is built in to OO constructs,
> but in Haskell you have smaller building blocks that you have to
> assemble to make the thing you want.
>
> So to extend your example, you can do
> data IList = forall a . (Foldable a, Indexable a) => IList a
> getListOfData :: IO IList
> and now you can return different kinds of types from getListOfData
> depending on circumstances.
>
>  -- Lennart
>
> On Tue, Oct 14, 2008 at 1:11 PM, John Lato <[hidden email]> wrote:
>> I was just thinking about what I wish someone had told me when I
>> started working with Haskell (not that long ago).  It would have saved
>> me a great deal of trouble.
>>
>> The Difference Between Interfaces and Type Classes.
>>
>> Many "Introduction to Haskell for the OOper" style tutorials claim
>> that type classes are like Interfaces (for languages with that
>> feature).  I now think that, although this is technically true, it's
>> fundamentally misleading.  Here's a simple example demonstrating my
>> line of thought:
>>
>> In C# (and presumably Java), this sort of function is common:
>> public IList GetListOfData()
>>
>> In Haskell, a similar function may be
>> GetListOfData :: (Foldable a, Indexable a) => IO a
>>
>> In C#, it doesn't matter what the actual type returned by
>> GetListOfData is, as long is it supports the IList interface.  It's
>> not uncommon for GetListOfData to make a choice between several
>> different implementations, depending on the nature of the data to be
>> returned.  The following code is perfectly reasonable in C# :
>>
>> // List and MyList are different classes
>> if (something) { return new List(); }
>> else { return new MyList(); }
>>
>> The equivalent won't compile in Haskell, because the actual return
>> type does matter, and *is determined by the calling code*.  Our
>> fictional GetListOfData can't return a List or a Mylist depending on
>> some conditional, in fact it can't explicitly return either one at
>> all, because the actual type of the result, as determined by the
>> caller, could be either one, or something else entirely (ignoring the
>> IO bit for the time being).
>>
>> So I've come to the conclusion that stating type classes are like
>> interfaces is misleading to newcomers to Haskell, because it leads
>> people to think they should use type classes for the same sorts of
>> problems OO-languages solve with interfaces.  In turn this means new
>> programmers are encouraged to use OO-style architecture in programs,
>> reassured that they're in a "functional" idiom because they're using
>> the "functionally-approved" feature of type classes.  I think that if
>> I had understood this earlier, I would have embraced functional idioms
>> more quickly.
>>
>> Incidentally, I'm still horrible at designing functional APIs and
>> modules, but at least now I know it, and I'm no longer trying to force
>> OO interfaces into Haskell.  So I've made progress.
>> _______________________________________________
>> Haskell-Cafe mailing list
>> [hidden email]
>> http://www.haskell.org/mailman/listinfo/haskell-cafe
>>
>
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: What I wish someone had told me...

Bugzilla from jonathanccast@fastmail.fm
On Tue, 2008-10-14 at 18:15 +0100, John Lato wrote:
> Are you advocating introducing existential types to beginning
> Haskellers?  I think something with the scary name

Invalid argument.

> "existential
> quantification" would greatly increase the head'splodin' on the
> learnin' slope.

Invalid argument.  Head explosion is the *goal* of teaching Haskell.

> Certainly there's a place for them, but I wouldn't
> want to see new Haskell programmers habitually approach problems with
> a "first create a type class, then make an existential wrapper"
> mentality.

Of course not.  That's just translating OO into Haskell.  Personally, I
would avoid comparing Haskell to other language at all (SOE I believe
takes this approach).

jcc


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: What I wish someone had told me...

Alexey Romanov
In reply to this post by John Lato-2
On Tue, Oct 14, 2008 at 9:15 PM, John Lato <[hidden email]> wrote:
> Are you advocating introducing existential types to beginning
> Haskellers?  I think something with the scary name "existential
> quantification" would greatly increase the head'splodin' on the
> learnin' slope.  Certainly there's a place for them, but I wouldn't
> want to see new Haskell programmers habitually approach problems with
> a "first create a type class, then make an existential wrapper"
> mentality.  Which is exactly what I fear is the current situation.

I don't think this is the current situation at all. For one, the
beginning Haskellers do
_not_ learn about existential types.

Yours, Alexey Romanov
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: What I wish someone had told me...

Alexey Romanov
In reply to this post by Bugzilla from jonathanccast@fastmail.fm
On Tue, Oct 14, 2008 at 9:14 PM, Jonathan Cast
<[hidden email]> wrote:

> On Tue, 2008-10-14 at 18:15 +0100, John Lato wrote:
>> Are you advocating introducing existential types to beginning
>> Haskellers?  I think something with the scary name
>
> Invalid argument.
>
>> "existential
>> quantification" would greatly increase the head'splodin' on the
>> learnin' slope.
>
> Invalid argument.  Head explosion is the *goal* of teaching Haskell.

Is it? I would certainly prefer my students to say "This is obvious. Why would
things work in any other way?" They don't, but I can dream.

>> Certainly there's a place for them, but I wouldn't
>> want to see new Haskell programmers habitually approach problems with
>> a "first create a type class, then make an existential wrapper"
>> mentality.
>
> Of course not.  That's just translating OO into Haskell.  Personally, I
> would avoid comparing Haskell to other language at all (SOE I believe
> takes this approach).
>
> jcc

I find such comparisons pretty useful.

Yours, Alexey Romanov
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: What I wish someone had told me...

Lennart Augustsson
In reply to this post by John Lato-2
I'm not advocating existential types in this case.  I rarely use them myself.
I was just pointing out that the mechanism for doing the OO thing
exists in Haskell too, albeit looking a little different.

I don't think there's anything weird about existential types, except
an unfamiliar name.

On Wed, Oct 15, 2008 at 1:15 AM, John Lato <[hidden email]> wrote:

> Are you advocating introducing existential types to beginning
> Haskellers?  I think something with the scary name "existential
> quantification" would greatly increase the head'splodin' on the
> learnin' slope.  Certainly there's a place for them, but I wouldn't
> want to see new Haskell programmers habitually approach problems with
> a "first create a type class, then make an existential wrapper"
> mentality.  Which is exactly what I fear is the current situation.
>
> Although my list example is far to shallow to make this point, it
> seems to me that it's fairly likely that somebody faced with this
> problem has had something go severely wrong at some earlier time.
>
> Existentials are certainly useful, but isn't it also possible that,
> for many cases, an alternative design exists which fits a functional
> idiom better and doesn't face this issue at all?
>
> John
>
> On Tue, Oct 14, 2008 at 5:03 PM, Lennart Augustsson
> <[hidden email]> wrote:
>> You can do equivalent of
>> // List and MyList are different classes
>> if (something) { return new List(); }
>> else { return new MyList(); }
>> in Haskell as well.  But to do that you have to introduce an
>> existential wrapper in the return type.
>> In OO languages the existential wrapper is built in to OO constructs,
>> but in Haskell you have smaller building blocks that you have to
>> assemble to make the thing you want.
>>
>> So to extend your example, you can do
>> data IList = forall a . (Foldable a, Indexable a) => IList a
>> getListOfData :: IO IList
>> and now you can return different kinds of types from getListOfData
>> depending on circumstances.
>>
>>  -- Lennart
>>
>> On Tue, Oct 14, 2008 at 1:11 PM, John Lato <[hidden email]> wrote:
>>> I was just thinking about what I wish someone had told me when I
>>> started working with Haskell (not that long ago).  It would have saved
>>> me a great deal of trouble.
>>>
>>> The Difference Between Interfaces and Type Classes.
>>>
>>> Many "Introduction to Haskell for the OOper" style tutorials claim
>>> that type classes are like Interfaces (for languages with that
>>> feature).  I now think that, although this is technically true, it's
>>> fundamentally misleading.  Here's a simple example demonstrating my
>>> line of thought:
>>>
>>> In C# (and presumably Java), this sort of function is common:
>>> public IList GetListOfData()
>>>
>>> In Haskell, a similar function may be
>>> GetListOfData :: (Foldable a, Indexable a) => IO a
>>>
>>> In C#, it doesn't matter what the actual type returned by
>>> GetListOfData is, as long is it supports the IList interface.  It's
>>> not uncommon for GetListOfData to make a choice between several
>>> different implementations, depending on the nature of the data to be
>>> returned.  The following code is perfectly reasonable in C# :
>>>
>>> // List and MyList are different classes
>>> if (something) { return new List(); }
>>> else { return new MyList(); }
>>>
>>> The equivalent won't compile in Haskell, because the actual return
>>> type does matter, and *is determined by the calling code*.  Our
>>> fictional GetListOfData can't return a List or a Mylist depending on
>>> some conditional, in fact it can't explicitly return either one at
>>> all, because the actual type of the result, as determined by the
>>> caller, could be either one, or something else entirely (ignoring the
>>> IO bit for the time being).
>>>
>>> So I've come to the conclusion that stating type classes are like
>>> interfaces is misleading to newcomers to Haskell, because it leads
>>> people to think they should use type classes for the same sorts of
>>> problems OO-languages solve with interfaces.  In turn this means new
>>> programmers are encouraged to use OO-style architecture in programs,
>>> reassured that they're in a "functional" idiom because they're using
>>> the "functionally-approved" feature of type classes.  I think that if
>>> I had understood this earlier, I would have embraced functional idioms
>>> more quickly.
>>>
>>> Incidentally, I'm still horrible at designing functional APIs and
>>> modules, but at least now I know it, and I'm no longer trying to force
>>> OO interfaces into Haskell.  So I've made progress.
>>> _______________________________________________
>>> Haskell-Cafe mailing list
>>> [hidden email]
>>> http://www.haskell.org/mailman/listinfo/haskell-cafe
>>>
>>
>
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: What I wish someone had told me...

Derek Elkins
In reply to this post by John Lato-2
On Tue, 2008-10-14 at 13:11 +0100, John Lato wrote:
> I was just thinking about what I wish someone had told me when I
> started working with Haskell (not that long ago).  It would have saved
> me a great deal of trouble.
>

A recent quote of mine from HWN:
    * ddarius: Here's the short guide to Haskell for OO programmers:
      Haskell isn't at all an OO language.

> The Difference Between Interfaces and Type Classes.
>
> Many "Introduction to Haskell for the OOper" style tutorials claim
> that type classes are like Interfaces (for languages with that
> feature).  I now think that, although this is technically true, it's
> fundamentally misleading.

It's not technically true.  Type classes and interfaces a la Java are
very fundamentally different neither is remotely capable of doing what
the other does.  As my quote above suggests, essentially nothing
transfers from OO programming to Haskell.  Haskell has absolutely no
support whatsoever for object-oriented programming.  At best, you can
try to encode objects.

>
> In C# (and presumably Java), this sort of function is common:
> public IList GetListOfData()
>
> In Haskell, a similar function may be
> GetListOfData :: (Foldable a, Indexable a) => IO a
>
> In C#, it doesn't matter what the actual type returned by
> GetListOfData is, as long is it supports the IList interface.  It's
> not uncommon for GetListOfData to make a choice between several
> different implementations, depending on the nature of the data to be
> returned.  The following code is perfectly reasonable in C# :
>
> // List and MyList are different classes
> if (something) { return new List(); }
> else { return new MyList(); }
>
> The equivalent won't compile in Haskell, because the actual return
> type does matter, and *is determined by the calling code*.  Our
> fictional GetListOfData can't return a List or a Mylist depending on
> some conditional, in fact it can't explicitly return either one at
> all, because the actual type of the result, as determined by the
> caller, could be either one, or something else entirely (ignoring the
> IO bit for the time being).
>
> So I've come to the conclusion that stating type classes are like
> interfaces is misleading to newcomers to Haskell, because it leads
> people to think they should use type classes for the same sorts of
> problems OO-languages solve with interfaces.  In turn this means new
> programmers are encouraged to use OO-style architecture in programs,
> reassured that they're in a "functional" idiom because they're using
> the "functionally-approved" feature of type classes.  I think that if
> I had understood this earlier, I would have embraced functional idioms
> more quickly.
>
> Incidentally, I'm still horrible at designing functional APIs and
> modules, but at least now I know it, and I'm no longer trying to force
> OO interfaces into Haskell.  So I've made progress.

I strongly agree with the thrust of your email.  This "type classes are
kinda like interfaces" meme is horrible.  The sooner newcomers realize
type classes have nothing to do with object oriented programming, or
likely anything they've seen before, the better.  Unfortunately, there
is a glut of crappy tutorials out there.  Good introductions tend to
deal with this much better and the best advice I can give is to simply
ignore most or all tutorials and read or steer others to more
comprehensive and better regarded/reviewed resources.  For example, this
is a line from RWH: "Typeclasses may look like the objects of
object-oriented programming, but they are truly quite different."  Also
later there is another sidebar along those lines.

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: What I wish someone had told me...

Bugzilla from jonathanccast@fastmail.fm
In reply to this post by Alexey Romanov
On Tue, 2008-10-14 at 22:28 +0400, Alexey Romanov wrote:

> On Tue, Oct 14, 2008 at 9:14 PM, Jonathan Cast
> <[hidden email]> wrote:
> > On Tue, 2008-10-14 at 18:15 +0100, John Lato wrote:
> >> Are you advocating introducing existential types to beginning
> >> Haskellers?  I think something with the scary name
> >
> > Invalid argument.
> >
> >> "existential
> >> quantification" would greatly increase the head'splodin' on the
> >> learnin' slope.
> >
> > Invalid argument.  Head explosion is the *goal* of teaching Haskell.
>
> Is it? I would certainly prefer my students to say "This is obvious. Why would
> things work in any other way?"

Sure.  But I see head explosion as a means to that end (in the finest
tradition of functional languages, from lisp onward).

> They don't, but I can dream.
>
> >> Certainly there's a place for them, but I wouldn't
> >> want to see new Haskell programmers habitually approach problems with
> >> a "first create a type class, then make an existential wrapper"
> >> mentality.
> >
> > Of course not.  That's just translating OO into Haskell.  Personally, I
> > would avoid comparing Haskell to other language at all (SOE I believe
> > takes this approach).

> I find such comparisons pretty useful.

What kind of comparisons?  Translations between languages or comparisons
of idioms (which usually involve quite different factorings)?  And
useful for getting students to be quiet, or useful for getting them to
produce idiomatic Haskell?

jcc


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: What I wish someone had told me...

Derek Elkins
In reply to this post by Lennart Augustsson
On Wed, 2008-10-15 at 05:39 +0800, Lennart Augustsson wrote:
> I'm not advocating existential types in this case.  I rarely use them myself.
> I was just pointing out that the mechanism for doing the OO thing
> exists in Haskell too, albeit looking a little different.

In general, to encode OO you need quite a bit more than existentials.
As you are probably aware, there was a cottage industry in the mid to
late '90s working on encodings of OO languages into System F + foo
calculi.  They just about gave up on a complete encoding until someone
figured one out.  'turns out all you needed was recursive bounded
existential quantification.  Of course, the encoding wasn't any fun to
use.  There are two morals that you can take out of this.  Either:
classes/objects are a conflation of ideas that might be more profitably
separated apart, or: OO is best approached on its own terms.

> I don't think there's anything weird about existential types, except
> an unfamiliar name.

Agreed.  I'm extremely tired of the "I haven't heard this term therefore
it must be 'scary' and complicated and beyond me" attitude.  Such people
need to stop acting like five year old children.

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: What I wish someone had told me...

Claus Reinke
In reply to this post by Lennart Augustsson
> I'm not advocating existential types in this case.  I rarely use them myself.
> I was just pointing out that the mechanism for doing the OO thing
> exists in Haskell too, albeit looking a little different.
>
> I don't think there's anything weird about existential types, except
> an unfamiliar name.

Perhaps, it helps to make Lennart's point about composable building
blocks made more explicit (simplifying slightly):

- a function 'f :: a -> IO a' has to accept any type 'a', so it can't know
    anything about those 'a's

- a function 'f :: Interface a => a -> IO a' only has to accept types 'a'
    that *at least* implement 'Interface', so there's a *lower bound* on the
    information required about those 'a's, and 'f' can't use any more than
    that (but since 'a' is exposed to 'f's calling context, it might be fixed there)

- a constructor of type '(forall a . Interface a => a) -> SomeType' can only
    be applied to objects of type 'a' that *at least* implement 'Interface',
    but if 'SomeType' doesn't mention 'a', the result *at most* implements
    'Interface' and 'a' itself gets hidden, so there's an *upper bound* on
    the information being provided

The reference that comes to mind

    On understanding types, data abstraction, and polymorphism.
    Luca Cardelli and Peter Wegner.
    ©1985  Computing Surveys, 17(4):471-522, 1985.
    http://lucacardelli.name/Bibliography.htm

predates Haskell, so any 'splodin' heads can't be blamed on Haskell!-)

I wouldn't expose beginning programmers to this level of detail about
types, but if you're going to talk about interfaces and types at all, and
about type classes in particular, to programmers who are beginning
their switch to Haskell, it can't hurt them much to read it. It might
even help, and if not, it is at least a concrete basis for more Haskell
specific explanations when they start running into those questions.

Claus

> On Wed, Oct 15, 2008 at 1:15 AM, John Lato <[hidden email]> wrote:
>> Are you advocating introducing existential types to beginning
>> Haskellers?  I think something with the scary name "existential
>> quantification" would greatly increase the head'splodin' on the
>> learnin' slope.  Certainly there's a place for them, but I wouldn't
>> want to see new Haskell programmers habitually approach problems with
>> a "first create a type class, then make an existential wrapper"
>> mentality.  Which is exactly what I fear is the current situation.
>>
>> Although my list example is far to shallow to make this point, it
>> seems to me that it's fairly likely that somebody faced with this
>> problem has had something go severely wrong at some earlier time.
>>
>> Existentials are certainly useful, but isn't it also possible that,
>> for many cases, an alternative design exists which fits a functional
>> idiom better and doesn't face this issue at all?
>>
>> John
>>
>> On Tue, Oct 14, 2008 at 5:03 PM, Lennart Augustsson
>> <[hidden email]> wrote:
>>> You can do equivalent of
>>> // List and MyList are different classes
>>> if (something) { return new List(); }
>>> else { return new MyList(); }
>>> in Haskell as well.  But to do that you have to introduce an
>>> existential wrapper in the return type.
>>> In OO languages the existential wrapper is built in to OO constructs,
>>> but in Haskell you have smaller building blocks that you have to
>>> assemble to make the thing you want.
>>>
>>> So to extend your example, you can do
>>> data IList = forall a . (Foldable a, Indexable a) => IList a
>>> getListOfData :: IO IList
>>> and now you can return different kinds of types from getListOfData
>>> depending on circumstances.
>>>
>>>  -- Lennart
>>>
>>> On Tue, Oct 14, 2008 at 1:11 PM, John Lato <[hidden email]> wrote:
>>>> I was just thinking about what I wish someone had told me when I
>>>> started working with Haskell (not that long ago).  It would have saved
>>>> me a great deal of trouble.
>>>>
>>>> The Difference Between Interfaces and Type Classes.
>>>>
>>>> Many "Introduction to Haskell for the OOper" style tutorials claim
>>>> that type classes are like Interfaces (for languages with that
>>>> feature).  I now think that, although this is technically true, it's
>>>> fundamentally misleading.  Here's a simple example demonstrating my
>>>> line of thought:
>>>>
>>>> In C# (and presumably Java), this sort of function is common:
>>>> public IList GetListOfData()
>>>>
>>>> In Haskell, a similar function may be
>>>> GetListOfData :: (Foldable a, Indexable a) => IO a
>>>>
>>>> In C#, it doesn't matter what the actual type returned by
>>>> GetListOfData is, as long is it supports the IList interface.  It's
>>>> not uncommon for GetListOfData to make a choice between several
>>>> different implementations, depending on the nature of the data to be
>>>> returned.  The following code is perfectly reasonable in C# :
>>>>
>>>> // List and MyList are different classes
>>>> if (something) { return new List(); }
>>>> else { return new MyList(); }
>>>>
>>>> The equivalent won't compile in Haskell, because the actual return
>>>> type does matter, and *is determined by the calling code*.  Our
>>>> fictional GetListOfData can't return a List or a Mylist depending on
>>>> some conditional, in fact it can't explicitly return either one at
>>>> all, because the actual type of the result, as determined by the
>>>> caller, could be either one, or something else entirely (ignoring the
>>>> IO bit for the time being).
>>>>
>>>> So I've come to the conclusion that stating type classes are like
>>>> interfaces is misleading to newcomers to Haskell, because it leads
>>>> people to think they should use type classes for the same sorts of
>>>> problems OO-languages solve with interfaces.  In turn this means new
>>>> programmers are encouraged to use OO-style architecture in programs,
>>>> reassured that they're in a "functional" idiom because they're using
>>>> the "functionally-approved" feature of type classes.  I think that if
>>>> I had understood this earlier, I would have embraced functional idioms
>>>> more quickly.
>>>>
>>>> Incidentally, I'm still horrible at designing functional APIs and
>>>> modules, but at least now I know it, and I'm no longer trying to force
>>>> OO interfaces into Haskell.  So I've made progress.
>>>> _______________________________________________
>>>> Haskell-Cafe mailing list
>>>> [hidden email]
>>>> http://www.haskell.org/mailman/listinfo/haskell-cafe
>>>>
>>>
>>
> _______________________________________________
> Haskell-Cafe mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/haskell-cafe 

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: What I wish someone had told me...

Daniel Fischer-4
In reply to this post by Derek Elkins
Am Mittwoch, 15. Oktober 2008 00:34 schrieb Derek Elkins:
> It's not technically true.  Type classes and interfaces a la Java are
> very fundamentally different neither is remotely capable of doing what
> the other does.  

Could you elaborate on that, please?
I always understood Java's interfaces to be somewhat similar to type classes
(and I learnt the bit of Java I know before I even knew the term "Functional
Programming", never really got the whole OO thing though).
An interface, I thought, is a contract stating that the classes implementing
that interface provide certain operations (obeying some rules). If there's
more to interfaces, I'm happily unaware of that :)
In what way is that "very fundamentally different" from type classes?

As the languages as a whole are fundamentally different, that similarity is of
course rather superficial, so I will not say that stressing it is beneficial,
but I'm not convinced it is detrimental either.

>
> I strongly agree with the thrust of your email.  This "type classes are
> kinda like interfaces" meme is horrible.  

Because of the tendency to confuse OO programmers learning Haskell, or is
there a deeper reason? (Answer to this question could be superfluous after
addressing the above)

>  For example, this
> is a line from RWH: "Typeclasses may look like the objects of
> object-oriented programming, but they are truly quite different."  Also
> later there is another sidebar along those lines.
>

Now that is something I wouldn't have dreamt of.
If anything, I would relate objects to values (except that objects tend to be
mutable).

Thanks,
Daniel

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: What I wish someone had told me...

Derek Elkins
On Wed, 2008-10-15 at 02:22 +0200, Daniel Fischer wrote:

> Am Mittwoch, 15. Oktober 2008 00:34 schrieb Derek Elkins:
> > It's not technically true.  Type classes and interfaces a la Java are
> > very fundamentally different neither is remotely capable of doing what
> > the other does.  
>
> Could you elaborate on that, please?
> I always understood Java's interfaces to be somewhat similar to type classes
> (and I learnt the bit of Java I know before I even knew the term "Functional
> Programming", never really got the whole OO thing though).
> An interface, I thought, is a contract stating that the classes implementing
> that interface provide certain operations (obeying some rules). If there's
> more to interfaces, I'm happily unaware of that :)
> In what way is that "very fundamentally different" from type classes?

There are a lot of difference, for example, interfaces are "types"
insofar as you can have a variable of type IList; type classes are not
types, there are no variables of type Eq.  The fundamental one, however,
comes down to what it means to be "object-oriented."  One defining
property of object-oriented programming is dynamic dispatch.  This is
the fundamental difference between interfaces and type classes.

The instance selection for an interface is done at run-time and this is
inherently necessary.  The instance (in a different sense) selection for
type classes is almost always resolvable statically.  In Haskell 98
there is only one case that can't be done simply because doing so would
result in infinite code.  That case is polymorphic recursion.  With
extensions we get another case, namely existentials.  With existentials
we do get something like dynamic dispatch.  Nevertheless, the equation:
interfaces = type classes + existentials
does both interfaces and type classes a huge disservice, and at any rate
it's the existential not the type class that results in the properties
with which OO programmers are familiar.  Indeed,
interfaces = existentials + record of functions
is a better equation in some respects.

Anyways, the examples do the talking:

void draw(IEnumerable<IDrawable> drawables) {
    foreach(IDrawable drawable in drawables)
        drawable.Draw();
}

draw(new IDrawable[] { new Circle(), new Square(), new Star() });

The original motivating example of type classes is Eq.  Exactly the
problem that type classes were -literally- designed to solve is the
usual example of the "binary method problem" in the OO literature.  You
can see this problem in action in the messy semantics and brokenness and
gotchas surrounding the Equals method in C# and Java.  Then there are
examples that just inherently make no sense in a dynamic dispatch world:
Bounded, Read, the showList method of Show.

You can, if you want, -encode- various OO things into Haskell including
interfaces and even use type classes to do the lifting, but the result
is definitely an encoding and it is definitely not as simple as
interfaces = type classes

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: What I wish someone had told me...

Albert Y. C. Lai
In reply to this post by John Lato-2
John Lato wrote:
> Are you advocating introducing existential types to beginning
> Haskellers?  I think something with the scary name "existential
> quantification" would greatly increase the head'splodin' on the
> learnin' slope.

OOP(*) advocates introducing existential types to beginning programmers.
Although it uses an easy name "object" and not a technical name
"existential", the easy-name honeymoon ends in a few minutes as soon as
the teacher demonstrates or the students discover the tricky behaviour
and semantics. It results in the same confusion and head explosion. The
learning curve is the same struggle struggle explosion struggle then click.

(*)Object Obfuscation Pomposity

The broken analogy between OOP interfaces and Haskell/Isabell type
classes is there because some people insist that all languages should be
like mainstream languages. You have heard it, even from reputable
leaders and pioneers: "if you know one language, picking up others
should be easy, they just differ in syntax".
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: What I wish someone had told me...

Janis Voigtlaender
In reply to this post by Derek Elkins
Derek Elkins wrote:
> On Wed, 2008-10-15 at 05:39 +0800, Lennart Augustsson wrote:
>>I don't think there's anything weird about existential types, except
>>an unfamiliar name.
>
>
> Agreed.  I'm extremely tired of the "I haven't heard this term therefore
> it must be 'scary' and complicated and beyond me" attitude.  Such people
> need to stop acting like five year old children.

Not that it has much to do with the debate, but the attitude you
complain about is the exact opposite of the attitude of any five year
old children that *I* know (well, my son primarily ;-).

--
Dr. Janis Voigtlaender
http://wwwtcs.inf.tu-dresden.de/~voigt/
mailto:[hidden email]

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: What I wish someone had told me...

Heinrich Apfelmus
Janis Voigtlaender wrote:
> Derek Elkins wrote:
>>
>> Agreed.  I'm extremely tired of the "I haven't heard this term therefore
>> it must be 'scary' and complicated and beyond me" attitude.  Such people
>> need to stop acting like five year old children.
>
> Not that it has much to do with the debate, but the attitude you
> complain about is the exact opposite of the attitude of any five year
> old children that *I* know (well, my son primarily ;-).

Derek probably meant kids that are three quarters through school ... and
thus no longer interesting in anything. :(


Regards,
apfelmus

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: What I wish someone had told me...

John Lato-2
In reply to this post by John Lato-2
> Albet Lai wrote:
> John Lato wrote:
>> Are you advocating introducing existential types to beginning
>> Haskellers?  I think something with the scary name "existential
>> quantification" would greatly increase the head'splodin' on the
>> learnin' slope.
>
> OOP(*) advocates introducing existential types to beginning programmers.

Yes, because they're required to get almost anything done in OOP
languages.  In general they are not required in Haskell.  I got a bit
carried away with rhetorical flourish, but my point wasn't so much
that beginners couldn't understand something as that something with
such specialized usage isn't necessary for new Haskellers, and is
likely to encourage bad habits from OOP-converts.

>
> The broken analogy between OOP interfaces and Haskell/Isabell type
> classes is there because some people insist that all languages should be
> like mainstream languages. You have heard it, even from reputable
> leaders and pioneers: "if you know one language, picking up others
> should be easy, they just differ in syntax".
>

I have heard it, and I used to believe it.  Now I think it's only true
provided the one language you know is suitably advanced (and currently
non-existent, I think).

John
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: What I wish someone had told me...

wren ng thornton
In reply to this post by John Lato-2
John Lato wrote:

> Are you advocating introducing existential types to beginning
> Haskellers?  I think something with the scary name "existential
> quantification" would greatly increase the head'splodin' on the
> learnin' slope.  Certainly there's a place for them, but I wouldn't
> want to see new Haskell programmers habitually approach problems with
> a "first create a type class, then make an existential wrapper"
> mentality.  Which is exactly what I fear is the current situation.
>
> Although my list example is far to shallow to make this point, it
> seems to me that it's fairly likely that somebody faced with this
> problem has had something go severely wrong at some earlier time.
>
> Existentials are certainly useful, but isn't it also possible that,
> for many cases, an alternative design exists which fits a functional
> idiom better and doesn't face this issue at all?
>
> John


I think one of the reasons more people don't highlight the differences
is that, with all due respect, the differences are often too subtle for
OOP programmers. That is, few OOP programmers are taught to think about
type theory as deeply as is necessary to see why they're so
different[1]. On the one hand, few programmers of any ilk are taught to
think deeply about type theory so that's unfair to OOP. But on the other
hand OO propaganda is rife with claims that the class/inheritance model
of types is The One True Way(tm). I'm not saying this to be rude; there
are many OO programmers who do know quite a bit about type theory.
However, tutorials for OOP are full of indoctrination about how OO type
systems are better than C. In my experience that tends to create
OO-programmers who don't question the class/inheritance model or think
about what other approaches would look like. Discussions where an OO
type system is not assumed typically lead to talking past one another,
as here[2]. The idea of defining allomorphic functions which don't use
dynamic dispatch and don't use inheritance is difficult to explain
without a lot of groundwork to undo OO assumptions.

That said, I agree it's a pernicious meme which does disservice to
everyone. Though I'm not sure showing people Oleg's handiwork is a
gentler introduction either ;)


[1] Consider, for example, the question of whether the arguments/value
of a function should be covariant or contravariant in subclasses. Java
got this wrong for arrays. Their answer seems intuitively right, but
this is one area where intuitions are suspect.

[2]
<http://www.reddit.com/r/programming/comments/6xerq/why_type_classes_are_interesting/c054u5u>

--
Live well,
~wren
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
123