[Haskell] Dynamic binding

Lennart Augustsson lennart at augustsson.net
Thu Jun 23 16:55:31 EDT 2005


Yes, a) is a weakness, but usually I don't find it too restrictive.
I agree that extensible data types would be a very interesting
addition to Haskell, and I'd like to have it.

But the original question was how to do it in Haskell, and when I
hear Haskell i think Haskell-98 since it's the only standardized
version of Haskell.  So I tried to answer the question.
I wish Haskell-98 had existentials, but people didn't dare in
those days. :)  (Even though hbc had it implemented.)

	-- Lennart


Ralf Lammel wrote:
> Lennart,
> 
> from a textbook perspective I agree
> that this solution should be mentioned to make it easy
> for non-Haskellers to get into the subject.
> 
> However (as you of course know, but I just don't understand
> why you don't dare to mention the limitations a) and b) ...)
> 
> a)
> 
> Your constructor-based approach is not extensible.
> (Adding another form of shape requires touching existing code and
> recompilation.) I reckon that the (normal implied OO) point of
> the Shapes example, to a considerable extent, is also about the
> potential addition of new shapes.
> 
> Saying we can take a snapshot of shape "types"  and burn them
> into constructors of an algebraic type does not give me the
> impression of Haskell being ahead in type system and programming
> language arena.
> 
> b)
> 
> This "burn subtypes into constructors" leads me to a second
> weakness. By doing so, we have lost the precision of the
> original type dichotomy circle vs rectangle vs square since
> these guys are now all represented as terms of type.
> 
> Of course, you might say that we could define dedicated
> types for circle, rectangle and square so that we would use
> the shape type merely as a *sum* type. (So constructors
> only serve for embedding.) This way we could at least recover
> the typing precision of OO.
> 
> So I am willing to give in on b) 
> but I maintain a) 
> and I really miss extensible datatypes :-)
> 
> Ralf
> (doing too much C# these days I guess)
> 
> 
> 
>>-----Original Message-----
>>From: haskell-bounces at haskell.org [mailto:haskell-bounces at haskell.org]
> 
> On
> 
>>Behalf Of Lennart Augustsson
>>Sent: Thursday, June 23, 2005 7:30 AM
>>To: Andrew Ward
>>Cc: haskell at haskell.org
>>Subject: Re: [Haskell] Dynamic binding
>>
>>Andrew Ward wrote:
>>
>>>Hi All,
>>>In Simon Thompson's The Craft of Functional Programming Second
> 
> Edition,
> 
>>>page 226, it is mentioned that Laufer (1996) describes a Haskell
>>>extension to allow dynamic binding. I was wondering if this has been
>>>implemented as an extension in any of the haskell compilers, or
>>
>>variants?
>>
>>>I am a c++ programmer by trade, only dabbling in Haskell when I was
> 
> at
> 
>>>university, so it seems a disadvantage to me to not have dynamic
> 
> binding
> 
>>>in Haskell 98.
>>>What would be the normal way for a Haskell programmer to handle the
>>>typical shape example in beginner OO tutorials?
>>
>>
>>Unlike previous posters that have shown various ways to simulate
>>object oriented programming I'm going to try and answer the
>>question. :)
>>
>>Here is what I would do:
>>
>>----------------------
>>data Shape
>>	= Circle Point Radius
>>	| Square Point Size
>>
>>draw :: Shape -> Pict
>>draw (Circle p r) = drawCircle p r
>>draw (Square p s) = drawRectangle p s s
>>
>>moveTo :: Shape -> Point -> Shape
>>moveTo (Circle _ r) p = Circle p r
>>moveTo (Square _ s) p = Square p s
>>
>>shapes :: [Shape]
>>shapes = [Circle (0,0) 1, Square (1,1) 2]
>>
>>shapes' :: [Shape]
>>shapes' = map (moveTo (2,2)) shapes
>>----------------------
>>
>>This is in rather stark contrast to the object oriented way of doing
> 
> the
> 
>>same things.  For reference, here's how you could do it :
>>
>>----------------------
>>class IsShape shape where
>>     draw :: shape -> Pict
>>     moveTo :: Point -> shape -> shape
>>
>>data Shape = forall a . (IsShape a) => Shape a
>>
>>data Circle = Circle Point Radius
>>instance IsShape Circle where
>>     draw (Circle p r) = drawCircle p r
>>     moveTo p (Circle _ r) = Circle p r
>>
>>data Square = Square Point Size
>>instance IsShape Square where
>>     draw (Square p s) = drawRectangle p s s
>>     moveTo p (Square _ s) = Square p s
>>
>>shapes :: [Shape]
>>shapes = [Shape (Circle (0,0) 10), Shape (Square (1,1) 2)]
>>
>>shapes' :: [Shape]
>>shapes' = map (moveShapeTo (2,2)) shapes
>>   where moveShapeTo p (Shape s) = Shape (moveTo p s)
>>----------------------
>>
>>Both ways of doing it contains the same information, it's just that
>>it's organized in different ways.
>>
>>The "functional way" centers around the type Shape.  You can find out
>>all about what shapes exist by looking at the type definition.  For
>>each operation on shapes (draw & moveTo) you describe what they do for
>>the different shapes.
>>
>>The object oriented way centers more around the objects (surprise,
>>surprise).  For each kind of object you say that it's a shape and how
>>the shape operations work.
>>
>>
>>So, which is better?  I don't think you can say one is better than the
>>other.  They have different strengths.  With the object oriented way
> 
> it
> 
>>is easy to answer questions like "What is a Circle?", whereas with the
>>functional way it is easy to answer "How do you draw a Shape"?
>>Likewise, with the object oriented way it's easier to add a new kind
>>of shape and with the functional way it's easier to add a new
>>operation.
>>
>>To me it's a matter of taste.  I like the functional taste; my brain
>>has been warped over many years.
>>
>>	-- Lennart
>>_______________________________________________
>>Haskell mailing list
>>Haskell at haskell.org
>>http://www.haskell.org/mailman/listinfo/haskell
> 
> _______________________________________________
> Haskell mailing list
> Haskell at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell
> 



More information about the Haskell mailing list