Re: The future of Haskell discussion
Alastair David Reid <reid@cs.utah.edu> writes:
In the case of the Draw monad (which is identical to the IO monad except that it carries a "device context" around as an implicit parameter), the different feel comes from aggressive use of continuations (actually, they're not quite continuations but I don't have a better word for them). For example, you might normally write code like this:
do old_color <- selectColor blue old_font <- selectFont helvetica write_text "Hello World" selectFont old_font selectColor old_color
(Reselecting the old color and font at the end is recommended Win32 programming style.)
In the HGL, you instead write:
setPicture window (withColor blue (withFont helvetica (text "Hello World")))
you can achieve the same in many langage such as c++. I dont really see what is haskell specific in your code. pseudo code (i dont remember exactly c++ :) ): class Draw { Color color; Font font; Widget wid; Draw(Widget w) { wid = w } draw(window) { Color old; Font old; oldc = setColor color; oldf = setFont font; wid.draw(window); setColor oldc; setFont oldf; } withColor (Color c) {color = c} withFont (Font f) {font = f} } new Draw(new textWidget("Hello World"))->withColor(blue)->withFont("helvetica")->draw(window) there are plenty of way to achieve what you do.
or, equivalently but allegedly easier to read,
setPicture window $ withColor blue $ withFont helvetica $ text "Hello World"
where withColor and withFont are defined like this:
withColor :: Color -> Draw a -> Draw a withColor c m = do{ old <- selectColor c; a <- m; selectColor old; return a }
withFont :: Font -> Draw a -> Draw a withFont f m = do{ old <- selectFont f; a <- m; selectFont old; return a }
and setPicture exploits the fact that an object of type "Draw a" is a first class object which can be stored in the window state and executed when appropriate (e.g., when the window is uniconified).
What I'm saying is that Haskell's standard abstraction facilities mean that even in the IO monad your programming experience can significantly better than that of a C programmer. (Of course your experience can also be worse if you don't or can't bring Haskell's strengths to bear on your problem.)
-- Yoann Padioleau, INSA de Rennes, France, http://www.irisa.fr/prive/padiolea Opinions expressed here are only mine. Je n'écris qu'à titre personnel. **____ Get Free. Be Smart. Simply use Linux and Free Software. ____**
Hello Yoann, Monday, September 17, 2001, 7:12:42 PM, you wrote:
In the case of the Draw monad (which is identical to the IO monad except that it carries a "device context" around as an [skip] setPicture window (withColor blue (withFont helvetica (text "Hello World")))
YP> you can achieve the same in many langage such as c++. YP> I dont really see what is haskell specific in your code. YP> pseudo code (i dont remember exactly c++ :) ): You made some mistakes here. ^^^^^^^^^^^^^^^ YP> class Draw { YP> Color color; YP> Font font; YP> Widget wid; YP> Draw(Widget w) { wid = w } YP> draw(window) { Color old; Font old; YP> oldc = setColor color; oldf = setFont font; YP> wid.draw(window); YP> setColor oldc; setFont oldf; YP> } YP> withColor (Color c) {color = c} You should always return references to 'this' in every method, which may be used during "glued" calls, so: Draw& withColor (Color c) {color = c; return *this;} Draw& withFont (Font f) {font = f; return *this;} It was one of the sources of resistance by B.Stroustrup to include "named" parameters in function calls, for ex: withColor(c=blue) And the technique shown was similar with mentioned above. I think that this is a bit pervertive. YP> new Draw(new textWidget("Hello World"))->withColor(blue)->withFont("helvetica")->draw(window) YP> there are plenty of way to achieve what you do. I just clarified some moments in shown C++ example. Not more. -- Best regards, hw mailto:hw@ksue.kharkov.ukrtel.net
participants (2)
-
hw -
Yoann Padioleau