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

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:bulatz@HotPOP.com] 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, Bulat mailto:bulatz@HotPOP.com

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, Bulat mailto:bulatz@HotPOP.com
participants (2)
-
Bulat Ziganshin
-
Ralf Lammel