[Haskell-cafe] Monads aren't evil? I think they are.

2009-01-11 Thread Apfelmus, Heinrich
Ertugrul Soeylemez wrote:
> Let me tell you that usually 90% of my code is
> monadic and there is really nothing wrong with that.  I use especially
> State monads and StateT transformers very often, because they are
> convenient and are just a clean combinator frontend to what you would do
> manually without them:  passing state.

The insistence on avoiding monads by experienced Haskellers, in
particular on avoiding the IO monad, is motivated by the quest for elegance.

The IO and other monads make it easy to fall back to imperative
programming patterns to "get the job done". But do you really need to
pass state around? Or is there a more elegant solution, an abstraction
that makes everything fall into place automatically? Passing state is a
valid implementation tool, but it's not a design principle.


A good example is probably the HGL (Haskell Graphics Library), a small
vector graphics library which once shipped with Hugs. The core is the type

  Graphic

which represents a drawing and whose semantics are roughly

  Graphic = Pixel -> Color

There are primitive graphics like

  empty   :: Graphic
  polygon :: [Point] -> Graphic

and you can combine graphics by laying them on top of each other

  over:: Graphic -> Graphic -> Graphic

This is an elegant and pure interface for describing graphics.

After having constructed a graphic, you'll also want to draw it on
screen, which can be done with the function

  drawInWindow :: Graphic -> Window -> IO ()

This function is in the IO monad because it has the side-effect of
changing the current window contents. But just because drawing on a
screen involves IO does not mean that using it for describing graphics
is a good idea. However, using IO for *implementing* the graphics type
is fine

  type Graphics = Window -> IO ()

  empty  = \w -> return ()
  polygon (p:ps) = \w -> moveTo p w >> mapM_ (\p -> lineTo p w) ps
  over g1 g2 = \w -> g1 w >> g2 w
  drawInWindow   = id


Consciously excluding monads and restricting the design space to pure
functions is the basic tool of thought for finding such elegant
abstractions. As Paul Hudak said in his message "A regressive view of
support for imperative programming in Haskell"

   In my opinion one of the key principles in the design of Haskell has
   been the insistence on purity. It is arguably what led the Haskell
   designers to "discover" the monadic solution to IO, and is more
   generally what inspired many researchers to "discover" purely
   functional solutions to many seemingly imperative problems.

   http://article.gmane.org/gmane.comp.lang.haskell.cafe/27214

The philosophy of Haskell is that searching for purely functional
solution is well worth it.


Regards,
H. Apfelmus

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


Re: [Haskell-cafe] Monads aren't evil? I think they are.

2009-01-12 Thread Henning Thielemann
Apfelmus, Heinrich schrieb:
> Ertugrul Soeylemez wrote:
>> Let me tell you that usually 90% of my code is
>> monadic and there is really nothing wrong with that.  I use especially
>> State monads and StateT transformers very often, because they are
>> convenient and are just a clean combinator frontend to what you would do
>> manually without them:  passing state.
> 
> The insistence on avoiding monads by experienced Haskellers, in
> particular on avoiding the IO monad, is motivated by the quest for elegance.
> 
> The IO and other monads make it easy to fall back to imperative
> programming patterns to "get the job done". But do you really need to
> pass state around? Or is there a more elegant solution, an abstraction
> that makes everything fall into place automatically? Passing state is a
> valid implementation tool, but it's not a design principle.

I collected some hints, on how to avoid at least the IO monad:
  http://www.haskell.org/haskellwiki/Avoiding_IO

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


Re: [Haskell-cafe] Monads aren't evil? I think they are.

2009-01-12 Thread Philippa Cowderoy
On Sun, 2009-01-11 at 10:44 +0100, Apfelmus, Heinrich wrote:
> Ertugrul Soeylemez wrote:
> > Let me tell you that usually 90% of my code is
> > monadic and there is really nothing wrong with that.  I use especially
> > State monads and StateT transformers very often, because they are
> > convenient and are just a clean combinator frontend to what you would do
> > manually without them:  passing state.
> 
> The insistence on avoiding monads by experienced Haskellers, in
> particular on avoiding the IO monad, is motivated by the quest for elegance.
> 

By some experienced Haskellers. Others pile them on where they feel it's
appropriate, though avoiding IO where possible is still a good
principle.

I often find that less is essentially stateful than it looks. However, I
also find that as I decompose tasks - especially if I'm willing to
'de-fuse' things - then state-like dataflows crop up again in places
where they had been eliminated. Especially if I want to eg instrument or
quietly abstract some code. Spotting particular sub-cases like Reader
and Writer is a gain, of course!

> A good example is probably the HGL (Haskell Graphics Library), a small
> vector graphics library which once shipped with Hugs. The core is the type
> 
>   Graphic
> 
> which represents a drawing and whose semantics are roughly
> 
>   Graphic = Pixel -> Color



> After having constructed a graphic, you'll also want to draw it on
> screen, which can be done with the function
> 
>   drawInWindow :: Graphic -> Window -> IO ()
> 

Note that there are two different things going on here. The principle of
building up 'programs' in pure code to execute via IO is good - though
ironically enough, plenty of combinator libraries for such tasks form
monads themselves. Finding the right domain for DSL programs is also
important, but this is not necessarily as neatly functional. If you
start with a deep embedding rather than a shallow one then this isn't
much of a problem even if you find your first attempt was fatally flawed
- the DSL code's just another piece of data. 

-- 
Philippa Cowderoy 

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


Re: [Haskell-cafe] Monads aren't evil? I think they are.

2009-01-14 Thread Alberto G. Corona
The question of imperative versus pure declarative coding has brought to my
mind some may be off-topic speculations.  (so please don´t read it if you
have no time to waste):  I´m interested in the misterious relation bentween
mathematics, algoritms and reality (see
thisfor example).  Functional
programming is declarative, you can model the
entire world functionally with no concern for the order of calculations. The
world is mathematical. The laws of physics have no concern for sequencing.
But CPUs and communications are basically sequential.  Life is sequential,
and programs run along the time coordinate. Whenever you have to run a
program,  you or your compiler must sequence it.  The sequentiation  must be
done by you or your compiler or both. The functional declarative code can be
sequenced on-the-run by the compiler in the CPU by the runtime. but IO is
different.
You have to create, explicitly or implicitly the sequence of IO actions
because the external events in the external world  are not controlled by you
or the compiler. So you, the programmer are the responsible of sequencing
effects in coordination with the external world. so every language must give
you ways to express  sequencing of actions. that is why, to interact with
the external world you must think in terms of algorithms, that is ,
imperatively, no matter if you make the imperative-sequence  (relatively)
explicit with monads or if you make it trough pairs (state, value) or
unsafePerformIO or whatever. You have to think imperatively either way,
because yo HAVE TO construct a sequence. I think that the elegant option is
to recognize this different algorithmic nature of IO by using the IO monad.
In other terms, the appearance of input-output in a problem means that you
modelize just a part of the whole system. the interaction with the part of
the system that the program do not control appears as input output. if the
program includes the model of the environment that give the input output
(including perhaps a model of yourself), then, all the code may be side
effects free and unobservable. Thus, input output is a measure of the lack
of  a priori information.  Because this information is given and demanded at
precide points in the time dimension with a quantitative (real time) or
ordered (sequential) measure, then these impure considerations must be taken
into account in the program. However, the above is nonsensical, because if
you know everithing a priory, then you don´t have a problem, so you don´t
need a program. Because problem solving is to cope with unknow data that
appears AFTER the program has been created, in oder to produce output at the
corrrect time, then the program must have timing on it. has an algoritmic
nature, is not pure mathemathical. This applies indeed to all living beings,
that respond to the environment, and this creates the notion of time.


Concerning monadic code with no side effects, In mathematical terms,
 sequenced (monadic) code are mathematically different from declarative
code: A  function describes what in mathematics is called a  "manifold" with
a number of dimensions equal to the number of parameters.  In the other
side, a sequence describe a particular  trayectory in a manifold, a ordered
set of points in a wider manyfold surface. For this reason the latter must
be described algorithmically. The former can be said that include all
possible trajectories, and can be expressed declaratively. The latter is a
sequence  . You can use the former to construct the later, but you must
express the sequence because you are defining the concrete trajectory in the
general manifold that solve your concrete problem, not other infinite sets
of related problems. This essentially applies also to IO.

 Well this does not imply that you must use monads for it. For example, a
way to express a sequence is a list where each element is a function of the
previous.  The complier is forced to sequence it in the way you whant, but
this happens also with monad evaluation.

This can be exemplified with the laws of Newton: they are declarative. Like
any phisical formula. has no concern for sequencing. But when you need to
simulate the behaviour of a ballistic weapon, you must use a sequence of
instructions( that include the l newton laws). (well, in this case the
trajectory is continuous integrable and can be expressed in a single
function. In this case, the manifold includes a unique trajectory, but  this
is not the case in ordinary discrete problems,) . So any language need
declarative as well as imperative elements to program mathematical models as
well as algorithms.


Cheers
  Alberto.

2009/1/11 Apfelmus, Heinrich 

> Ertugrul Soeylemez wrote:
> > Let me tell you that usually 90% of my code is
> > monadic and there is really nothing wrong with that.  I use especially
> > State monads and StateT transformers very often, because they are
> > convenient and are just a clean combinator frontend to what y