Re: [Haskell-cafe] Language support for imperative code. Was: Re: monad subexpressions

2007-08-09 Thread Jules Bean

Brian Hulley wrote:
Haskell is designed so 
that any attempt at abstracting mutable local state will infect the 
entire program (modulo use of a highly dangerous function whose 
semantics is entirely unclear, depending on the vagaries of evaluation 
strategy of the particular compiler) 


(Your email message is long and very interesting, and it does an a 
considerable injustice to take one sentence out of context, but...)


This echoes a misconception that I see here on haskell-cafe quite often.

Mutable local state *really* doesn't need to infect the whole program, 
and haskell is certainly not designed so it must.


We have all kinds of techniques for ensuring that the pure parts of your 
code can remain pure, and only the impure parts get 'infected' with an 
IO signature.


Additionally, if it's just refs, you can use ST, which is totally pure.

If it's literally just state, you can use the techniques of the State 
monad and the Reader monad: but you don't necessarily have to use them 
explicitly with those names. Sometimes it is actually simpler just to 
use the types s - (a,s) and s - a directly; only in certain 
circumstances is the extra plumbing useful.


Often different parts of your program have different needs; some parts 
actually need the ability to make fresh names (and so need STRefs) other 
parts merely read the state (and can use Reader techniques) and other 
parts alter it (and can use State techniques). You need some plumbing to 
connect the different parts together, but fortunately haskell has 
powerful abstraction and it's quite easy to slap together the 
higher-order functions (combinators!) to do this.


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


[Haskell-cafe] Language support for imperative code. Was: Re: monad subexpressions

2007-08-08 Thread Brian Hulley

apfelmus wrote:

However, most genuinely imperative things are often just a building
block for a higher level functional model. The ByteString library is a
good example: the interface is purely functional, the internals are
explicit memory control. It's a bad idea to let the internal memory
control leak out and pollute an otherwise purely functional program with
IO-types.
  

Hi Apfelmus,

This is a really interesting discussion that touches on issues I'm 
currently working with (I'm designing a strict version of Haskell to 
explore various ideas about modules, namespace management, and how to 
get really efficient machine code but without losing the convenience of 
accurate garbage collection etc, but I'm having difficulties deciding 
between the monadic path and the impure path), so I've forked this new 
thread.


Regarding the quote above, if the API must hide explicit memory control 
from the user the only way I can see of doing this would be to use 
(unsafePerformIO), which really is unsafe since Haskell relies on the 
fact that mutable operations can't escape from the IO monad in order to 
get away with not having to impose a value restriction as in ML.


If you don't use (unsafePerformIO), then the slightest need for mutable 
data structures pollutes the entire interface. For example in the 
excellent paper you quoted


 N. Ramsey and J. Dias.
 An Applicative Control-Flow Graph Based on Huet's Zipper
 http://www.eecs.harvard.edu/~nr/pubs/zipcfg-abstract.html 
http://www.eecs.harvard.edu/%7Enr/pubs/zipcfg-abstract.html


the authors are pleased to have found an Applicative solution, and 
indeed their solution has many useful and instructive aspects. However 
on page 111, hidden away in the definition of their API function to 
create a label, is a call to (ref 0)  ;-) The equivalent 
implementation in Haskell would completely destroy all hope of using 
this in a pure context and force all use of the API into the IO monad.


Haskell and ML seem to stand at opposite poles. Haskell is designed so 
that any attempt at abstracting mutable local state will infect the 
entire program (modulo use of a highly dangerous function whose 
semantics is entirely unclear, depending on the vagaries of evaluation 
strategy of the particular compiler) whereas people have been struggling 
in the ML community for at least 15 years to try and find a way to hide 
the fact that mutable storage is being used (cf attempts to find a 
proper solution to the unsoundness introduced by polymorphism and ref 
without having to use imperative/weak type variables etc).


Meanwhile, C++, C#, and Java programmers get a type system (thinking 
only about static methods using generics/templates) that seems to me no 
less powerful than that of the prenex polymorphism of ML, yet without 
any of the unsoundness problems, and therefore without the need of a 
value restriction (afaiu this is because their template/generic 
definitions stand in for an infinite family of monomorphic bindings 
instead of ML which tries unsuccessfully to make one piece of memory 
represent each element of an infinite family of values simultaneously).


Not only this, but there seems to me to be many problems for which it is 
natural to think in terms of objects with identity and mutable state. I 
can readily discard the concepts of deep inheritance hierarchies and 
open recursion but this still leaves the problem of identity and 
localised mutability.


For example consider a simple GUI with 2 edit widgets, a splitter, and a 
single buffer that contains the text being edited. The idea is that you 
should be able to use either edit widget to interact with the same 
buffer eg to edit at different locations in the buffer. A simple 
imperative solution might be something like:


   main = do
   buffer - createBuffer
   edit1 - createEdit buffer
   edit2 - createEdit buffer
   splitter - createSplitter (wrapWidget edit1) (wrapWidget edit2)
   runMessageLoopWith splitter

Here it's really clear what's happening, and different objects in the 
program correspond exactly to how I think about what I'm trying to do ie 
I want to  create individual objects with identity and then plug them 
together. I don't want to have to bother about passing state around, or 
having to define a new data type every time I want a different 
configuration of widgets. Thus the ability to abstract mutable state 
gives to my mind by far the best solution.


In contrast, all the pure functional GUIs that I've seen are just 
wrappers around someone else's imperative code, and moreover, they 
exchange the simplicity of the object oriented imperative API for a 
veritable mindstorm of unbelievably heavy, clunky, slow, inefficient, 
inextensible, hard to understand encodings that seem to me to have the 
effect of turning a high level language into some kind of circuit board 
(I'm thinking of arrows etc).


Indeed everyone seems to be using either WxWidgets or 

Re: [Haskell-cafe] Language support for imperative code. Was: Re: monad subexpressions

2007-08-08 Thread Martin Percossi

Brian Hulley wrote:

hidden away in the definition of their API function to create a label, 
is a call to (ref 0)  ;-) The equivalent implementation in Haskell 
would completely destroy all hope of using this in a pure context and 
force all use of the API into the IO monad.


Really? I would have thought this is a job for the ST monad, in which 
case the API can be wrapped up in a runST or similar; no need for 
leaking IO monads.


Or am I missing something?

Regards,
Martin

My music: http://www.youtube.com/user/thetonegrove (please visit!)
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Language support for imperative code. Was: Re: monad subexpressions

2007-08-08 Thread Hugh Perkins
On 8/8/07, Brian Hulley [EMAIL PROTECTED] wrote:

 In contrast, all the pure functional GUIs that I've seen are just
 wrappers around someone else's imperative code, and moreover, they
 exchange the simplicity of the object oriented imperative API for a
 veritable mindstorm of unbelievably heavy, clunky, slow, inefficient,
 inextensible, hard to understand encodings that seem to me to have the
 effect of turning a high level language into some kind of circuit board
 (I'm thinking of arrows etc).

 In defense of Haskell (wow!), note that imperative languages are not
without problems in GUIs.  In a multithreaded environment, typically only
one thread is allowed to manage the GUI, and then you typically need to set
up some sort of message-passing system to communicate between this thread
and the others AFAIK?  This is a total PITA, so if someone has a solution
for this that would rock :-)

Question: to what extent do the Haskell wrappers around gtk and wxWidgets
suffer from this problem?  I mean, I havent tried them, so it's a genuine
question.

(Note: off the top of my head, in an imperative language, I guess one could
use some sort of generator to take an interface and generate the message
classes, and marshalling classes automatically)

(Disclaimer: I havent really searched very hard for ways to handle threading
in GUIs in imperative languages, since mostly I either use web pages as the
visual interface, which avoids around the problem, or use a single thread,
which also avoids the problem)
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Language support for imperative code. Was: Re: monad subexpressions

2007-08-08 Thread Corey O'Connor
On 8/8/07, Brian Hulley [EMAIL PROTECTED] wrote:

 Regarding the quote above, if the API must hide explicit memory control
 from the user the only way I can see of doing this would be to use
 (unsafePerformIO), which really is unsafe since Haskell relies on the
 fact that mutable operations can't escape from the IO monad in order to
 get away with not having to impose a value restriction as in ML.


My theory is weak. Can somebody point me the way to educate myself about the
value restriction in ML?
Thanks!
-Corey


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


Re: [Haskell-cafe] Language support for imperative code. Was: Re: monad subexpressions

2007-08-08 Thread Brian Hulley

Martin Percossi wrote:

Brian Hulley wrote:

hidden away in the definition of their API function to create a 
label, is a call to (ref 0)  ;-) The equivalent implementation in 
Haskell would completely destroy all hope of using this in a pure 
context and force all use of the API into the IO monad.


Really? I would have thought this is a job for the ST monad, in which 
case the API can be wrapped up in a runST or similar; no need for 
leaking IO monads.


Or am I missing something?


Well I agree you're right on this particular use of a Ref, since their 
program is only dealing with a mapping from input to output so once 
they're finished using the data structure there is no longer any need 
for the ref and so the result can be returned to the rest of the program.


However there are 2 problems with this approach in general afaics:

1) All code that uses this data structure ie that participates in the 
implementation of the transformations by using the API functions will 
have to be in a monad (ST or IO, it really doesn't matter in terms of 
all the perceived burdensomeness of do notation relative to normal 
applicative code).


2) The example doesn't transfer to an interactive situation, where we 
would need to keep the data structure around and use it forever - 
because we would be forever trapped inside the ST monad otherwise we'd 
lose that particular STRef which we were hoping to use to efficiently 
update the output in the face of a delta in the input.




Corey -
I found this page helpful to get an understanding of the value 
restriction in ML:


http://www.smlnj.org/doc/Conversion/types.html

The restriction was proposed by Andrew Wright in 1995:

Simple Imperative Polymorphism by Wright
http://citeseer.ist.psu.edu/wright95simple.html

Some other related papers are:

The Type and effect discipline by Talpin and Jouvelot 1992
Standard ML-NJ weak polymorphism and imperative constructs by Hoang, 
Mitchell, and Viswanathan

Weak polymorphism can be sound by Greiner 1993

and more recently (2003)

Relaxing the value restriction by Garrigue
http://citeseer.ist.psu.edu/garrigue03relaxing.html

(Note that even now there is still no real solution to it.)


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


Re: [Haskell-cafe] Language support for imperative code. Was: Re: monad subexpressions

2007-08-08 Thread Brian Hulley

Hugh Perkins wrote:
On 8/8/07, *Brian Hulley* [EMAIL PROTECTED] 
mailto:[EMAIL PROTECTED] wrote:


In contrast, all the pure functional GUIs that I've seen...

In defense of Haskell (wow!), note that imperative languages are not 
without problems in GUIs.  In a multithreaded environment,
If you're using multiple threads you'd need to be in the IO monad to 
create/manipulate the MVars or TVars or whatever. (In contrast to eg 
AliceML where you could easily use a synchronising logic variable 
without having to leave all the familiar applicative coding comforts 
behind to brave the fiercesome lonely toil of Monadia ;-))


typically only one thread is allowed to manage the GUI, and then you 
typically need to set up some sort of message-passing system to 
communicate between this thread and the others AFAIK?  This is a total 
PITA, so if someone has a solution for this that would rock :-)
 
Question: to what extent do the Haskell wrappers around gtk and 
wxWidgets suffer from this problem?  I mean, I havent tried them, so 
it's a genuine question.
I don't know though I seem to recall some info on this on the website of 
Gtk2Hs.


 
(Note: off the top of my head, in an imperative language, I guess one 
could use some sort of generator to take an interface and generate the 
message classes, and marshalling classes automatically)
 
(Disclaimer: I havent really searched very hard for ways to handle 
threading in GUIs in imperative languages, since mostly I either use 
web pages as the visual interface, which avoids around the problem, or 
use a single thread, which also avoids the problem)


So far I've always managed to get away with just using a single threaded 
GUI. I think you run into problems with XLib and OpenGL (on GNU/Linux at 
least) if you try to call into those APIs from multiple threads and also 
it seems better to separate concerns by having all rendering code, 
including cacheing of geometry etc, in the same thread since it's easy 
enough to spawn new threads to do calculations and set a flag in the 
relevant widget when the result is complete...


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


Re: [Haskell-cafe] Language support for imperative code. Was: Re: monad subexpressions

2007-08-08 Thread Donald Bruce Stewart
brianh:
 Hugh Perkins wrote:
 On 8/8/07, *Brian Hulley* [EMAIL PROTECTED] 
 mailto:[EMAIL PROTECTED] wrote:
 
 In contrast, all the pure functional GUIs that I've seen...
 
 In defense of Haskell (wow!), note that imperative languages are not 
 without problems in GUIs.  In a multithreaded environment,
 If you're using multiple threads you'd need to be in the IO monad to 
 create/manipulate the MVars or TVars or whatever. (In contrast to eg 
 AliceML where you could easily use a synchronising logic variable 
 without having to leave all the familiar applicative coding comforts 
 behind to brave the fiercesome lonely toil of Monadia ;-))

Or use purely functional channels (Chan).

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