RE: [Haskell-cafe] RE: Re[4]: [Haskell] Dynamic binding

2005-06-24 Thread Ralf Lammel
I guess we just need to agree that we disagree.

Of course, you are right that I am just a newbie when it comes to
Haskell.

How did you know that I am actually a Cobol programmer?
Did you google?
http://www.google.com/search?biw=1003&hl=en&q=Ralf+Cobol

Seriously (?):

1.

I never intended to impose any particular OO style on Haskeller's.
Its more about the *intellectual* question whether we can take
C++/C#/Java
code and do a structure-preserving conversion to Haskell without
starting to argue on paradigm conversion.

Or as Alistair Bayley  argues (Alistair, thanks for helping out!)

http://www.haskell.org/tmrwiki/FpVsOo

"... it might be that you need to interface with external OO code, or
you are porting an existing program and need to remain faithful to the
original design, if only because you don't understand it well enough to
convert it to a functional design. ..."

Bulat, why not read all of this? Also see the end of that Wiki page,
where a reference to a paper is given, which seems to solve all these
problems, but my brain is to small to really be sure. ;-)

2.

No matter how much you try, the code that you showed
was not very close to a faithful Shapes implementation.
If you dare to read the spec:

http://onestepback.org/articles/poly/ 
http://www.angelfire.com/tx4/cus/shapes/

You made two proposals that don't solve the problem no matter of
*style*:

1st proposal of Bulat:

> just create list of draw functions itself:
> 
> [drawCircle (10,10) 5, drawSquare (20,20) 10]
>
> you are not expected that this problem can be solved with one line of
code? :)

My reply: you are not building a list of objects.
You are not organizing a loop whose body iterates over a list and
executes functionality.


2nd proposal of Bulat:

> for more complex tasks - declare interface as a structure:
> 
> data ShapeInterface = Shape { draw :: IO (),
>   moveTo :: Point -> IO (),
>   calcArea :: Float
> }
> 
> 
> and return this structures from "constructor" functions:
> 
> circle x y r = Shape { draw = drawCircle center r,
>moveTo newCenter = ,
>calcArea = pi*r*r
>  }
>where center = Point x y
> 
> square x y size = Shape { draw = ,
>   moveTo newCenter = ,
>   calcArea = size*szie
> }
> 
> figures = [circle 1 2 3, square 4 5 6, circle 7 8 9]

The tragedy here is that this stops to work once circles and squares
do have different interfaces. You solution does not scale. Subtyping
allows for interface extension, and the actual benchmark exploits
this, but your code avoids it.

Anyway the solution is trivial: ex. quantification, you didn't propose
that.

Cheers,
Ralf (back to Cobol)


> -Original Message-
> From: Bulat Ziganshin [mailto:[EMAIL PROTECTED]
> Sent: Thursday, June 23, 2005 11:37 PM
> To: Ralf Lammel
> Cc: Pal-Kristian Engstad; haskell-cafe@haskell.org
> Subject: Re: [Haskell-cafe] RE: Re[4]: [Haskell] Dynamic binding
> 
> Hello Ralf,
> 
> Thursday, June 23, 2005, 11:40:13 PM, you wrote:
> 
> RL> a) building (i) a list of data is fundamentally different
> RL> from building (ii) a list of anticipated results of each datum.
> RL> I would be surprised to hear that this counts as a valid
technique.
> RL> BTW, you can do the *same* in a lazy OO language. (No lazy OO
language
> RL> at hand -- well lazyness can be simulated.)
> 
> sorry, "valid" technique is technique that work :)  i use in my own
> program all the three ways i mentioned to solve problems of different
> complexity
> 
> afair, you are relatively new to Haskell (relatively to my 1-year
> experience :) and, i think, you are not share FP thinking style. when
> programming in Haskell, i think in terms "what thing i will need in
> this point of program?". if i need, for example, a possibility to
check
> string against regular expression, then i will pass a function which
> does this check, not original RE. if i need a possibility to
> draw a shape, i will pass action which draws this shape. if i need
> several functions, i just combine them in a tuple
> 
> there is one interesting example in my program. i have a list of
> wildcards and list of filenames and for each filename i need to know
> number of first wildcard to which this filename matched. in early
> stages of my program development i just passed list of wildcards to
> file-finding routine (as [Wildcard]). then, i changed list of
wildcards
> to list of functions which check match against each wildcard
> ([Filename->Bool]). and after that, i changed this to one fun

Re: [Haskell-cafe] RE: Re[4]: [Haskell] Dynamic binding

2005-06-24 Thread Bulat Ziganshin
Hello Ralf,

Thursday, June 23, 2005, 11:40:13 PM, you wrote:

RL> a) building (i) a list of data is fundamentally different
RL> from building (ii) a list of anticipated results of each datum.
RL> I would be surprised to hear that this counts as a valid technique.
RL> BTW, you can do the *same* in a lazy OO language. (No lazy OO language
RL> at hand -- well lazyness can be simulated.)

sorry, "valid" technique is technique that work :)  i use in my own
program all the three ways i mentioned to solve problems of different
complexity

afair, you are relatively new to Haskell (relatively to my 1-year
experience :) and, i think, you are not share FP thinking style. when
programming in Haskell, i think in terms "what thing i will need in
this point of program?". if i need, for example, a possibility to check
string against regular expression, then i will pass a function which
does this check, not original RE. if i need a possibility to
draw a shape, i will pass action which draws this shape. if i need
several functions, i just combine them in a tuple

there is one interesting example in my program. i have a list of
wildcards and list of filenames and for each filename i need to know
number of first wildcard to which this filename matched. in early
stages of my program development i just passed list of wildcards to
file-finding routine (as [Wildcard]). then, i changed list of wildcards
to list of functions which check match against each wildcard
([Filename->Bool]). and after that, i changed this to one function which
just finds first True answer (Filename->Int). it was also more
effective to compute this function only one time (it was something compiled
on moment of computing and worked as fast as hand-written analyzer for
given set of wildcards)

as you see, i slowly migrated from traditional way of solving this
problem to perfectly functional way and it was required several months

RL> a) building (i) a list of data is fundamentally different
RL> from building (ii) a list of anticipated results of each datum.

i think that you don't have "Haskell brain" ;)  and therefore don't
"trust" functions, which are passed as parameters, collected in lists,
saved in data structures and so on. you are prefer to "put hands on"
some data, preferably an object, which can be manipulated with any
method declared in his interface. i'm right? ;)

FP encourage another way - passing functions which will then be applied to
some additional arguments, as in my program, where file-finding
function absolutely don't need list of wildcards. it just need to map
filename to wildcard number, so a Filename->Int parameter is just
enough

in the draw example, each elment in a list was an action (having type
IO() ), so i don't create list of anticipated results, i created list
of actions which can be performed, for example, by sequence_


RL> Anyway, even if people end up coding as you propose,
RL> it won't work in general. Think of mutation methods that
RL> change the state but preserve the type. Then your list will
RL> still be heterogonous. NO?

my second example was just of this type. it uses IORefs to hold
current state, but this IORefs don't need to appear in interface

see method moveTo, which changes state variable center, and method
draw, which uses this variable 

>> this state is just don't need to appear in interface definition :)
>> circle x y r

RL> You are not talking about state but constructor arguments.

"interface definition" is a structure ShapeInterface, which have only
fields for exposed object methods. so it supports any figures in
universe :)

RL> In OO, mutable state tends to leak to the interface,
RL> perhaps not as public fields, perhaps not even as public

only in C++ and other languages which need to calculate object size :)
declaration of _non-public_ fields in _interface_ is something strange
;)

>> this state is just don't need to appear in interface definition :)
>> 
>> if you need to maintain mutable state, this is also not a problem:
>> 
>> data ShapeInterface = Shape { draw :: IO (),
>>   moveTo :: (Int,Int) -> IO (),
>>   calcArea :: Float
>> }
>> circle x y r = do
>>   center <- ref (x,y)
>>   return Shape { draw = val center >>= drawCircle r
>>, moveTo   = (center=:)
>>, calcArea = pi*r*r
>>}
>> main = do
>>   figures <- sequence [circle 1 2 3, square 4 5 6, circle 7 8 9]
>>   mapM_ draw figures
>>   mapM_ (moveTo (0,0)) figures
>>   mapM_ draw figures
>> 
>> ref=newIORef
>> val=readIORef
>> (=:)=writeIORef



-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] RE: Re[4]: [Haskell] Dynamic binding

2005-06-23 Thread Ralf Lammel
Bulat,

a) building (i) a list of data is fundamentally different
from building (ii) a list of anticipated results of each datum.
I would be surprised to hear that this counts as a valid technique.
BTW, you can do the *same* in a lazy OO language. (No lazy OO language
at hand -- well lazyness can be simulated.)

Anyway, even if people end up coding as you propose,
it won't work in general. Think of mutation methods that
change the state but preserve the type. Then your list will
still be heterogonous. NO?


b)

You wrote:

> this state is just don't need to appear in interface definition :)
> circle x y r

You are not talking about state but constructor arguments.

Please have a look here:

http://www.angelfire.com/tx4/cus/shapes/cpp.html

Circle Interface (Circle.h)

class Circle: public Shape {

public:
   Circle(int newx, int newy, int newradius);
   int getRadius();
   void setRadius(int newradius);
   void draw();

private:
   int radius;
};

[See getRadius and setRadius)

In OO, mutable state tends to leak to the interface,
perhaps not as public fields, perhaps not even as public
proxy properties (but in the shapes example, it *does*), but
then still as sublcass-specific interface member.

Anyway, I am happy to add your and Lennart's proposals
as appendices to the OOHaskell saga. 

And finally, Bulat, I agree with your point that 

> original exercise was about OO way to solve some problem. i want
> to say that in Haskell it's better in most cases to use another,
> functional way

Thanks,
Ralf (returning to his VB problem)



> -Original Message-
> From: Bulat Ziganshin [mailto:[EMAIL PROTECTED]
> Sent: Thursday, June 23, 2005 4:55 AM
> To: Ralf Lammel
> Cc: Andrew Ward; Pal-Kristian Engstad; haskell-cafe@haskell.org
> Subject: Re[4]: [Haskell] Dynamic binding
> 
> Hello Ralf,
> 
> Thursday, June 23, 2005, 11:36:20 AM, you wrote:
> 
> >> just create list of draw functions itself:
> >>
> >> [drawCircle (10,10) 5, drawSquare (20,20) 10]
> 
> RL> No! the exercise is about lists of shapes
> RL> not lists of results of drawing shapes.
> RL> This is clearly a major difference.
> 
> in cases where you need to call only one function on created objects,
> you can just insert in list calls to this functions (not their
results! i
> suppose
> that drawXXX functions has "... -> IO ()" type)
> 
> in cases where you need to call several functions for this object, you
> can insert in list tuple or structure for each object, as i do in next
> example. original exercise was about OO way to solve some problem. i
want
> to say that in Haskell it's better in most cases to use another,
> functional way
> 
> RL> Bulat wrote:
> 
> >> for more complex tasks - declare interface as a structure:
> >>
> >> data ShapeInterface = Shape { draw :: IO (),
> >>   moveTo :: Point -> IO (),
> >>   calcArea :: Float
> >> }
> 
> RL> No! You miss the point that the different shapes
> RL> differ regarding state types.
> RL> You don't have a chance when you use one datatype.
> 
> this state is just don't need to appear in interface definition :)
> 
> see for example:
> 
> data ShapeInterface = Shape { draw :: IO (),
>   calcArea :: Float
> }
> 
> circle x y r = Shape { draw = drawCircle x y r,
>calcArea = pi*r*r
>  }
> 
> square x y size = Shape { draw = drawSquare x y size,
>   calcArea = size*szie
> }
> 
> figures = [circle 1 2 3, square 4 5 6, circle 7 8 9]
> 
> 
> 
> 
> 
> if you need to maintain mutable state, this is also not a problem:
> 
> data ShapeInterface = Shape { draw :: IO (),
>   moveTo :: (Int,Int) -> IO (),
>   calcArea :: Float
> }
> circle x y r = do
>   center <- ref (x,y)
>   return Shape { draw = val center >>= drawCircle r
>, moveTo   = (center=:)
>, calcArea = pi*r*r
>}
> main = do
>   figures <- sequence [circle 1 2 3, square 4 5 6, circle 7 8 9]
>   mapM_ draw figures
>   mapM_ (moveTo (0,0)) figures
>   mapM_ draw figures
> 
> ref=newIORef
> val=readIORef
> (=:)=writeIORef
> 
> 
> RL> haskell-cafe?
> 
> as you wish :)
> 
> --
> Best regards,
>  Bulatmailto:[EMAIL PROTECTED]
> 
> 

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe