Re: [Haskell-cafe] Current situation regarding global IORefs

2006-04-24 Thread Adrian Hey

Lennart Augustsson wrote:

I think global mutable variables should be regarded with utmost
suspicion.  There are very few situations where they are the
right solution.


Well IMO even the use of the term global mutable variable causes
muddled thinking on this and I wish people would stop it. There's no
reason to regard top level things with identity (call them TWIs
or objects or whatever) with any more suspicion than top level IO
actions themselves.

One thing I never could fathom about the position of the nay-sayers
in this debate is what exactly is it that they object to?
Is it existence of top level TWIs and of IO operations that
reference them *in principle*?
Or are they content with their existence but just don't want to
allow people to use Haskell to define them?

If it's the former then we should be purging the IO libraries of
all such horrors, though I can't see much remaining of them (well
anything actually). But I guess an IO incapable language might
still have some niche uses.

If it's the latter then we are advocating a language which cannot
be used to implement many demonstrably useful IO modules and libraries,
*by design*. If so, the claim that Haskell is a general purpose
programming language seems quite bogus and should be removed from
the haskell.org home page IMO.

Regards
--
Adrian Hey




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


Re: [Haskell-cafe] Current situation regarding global IORefs

2006-04-24 Thread Cale Gibbard
On 24/04/06, Adrian Hey [EMAIL PROTECTED] wrote:
 Lennart Augustsson wrote:
  I think global mutable variables should be regarded with utmost
  suspicion.  There are very few situations where they are the
  right solution.

 Well IMO even the use of the term global mutable variable causes
 muddled thinking on this and I wish people would stop it. There's no
 reason to regard top level things with identity (call them TWIs
 or objects or whatever) with any more suspicion than top level IO
 actions themselves.

What do you mean by top level IO action? If you mean something like
'getLine', then there is a huge difference. If you mean actions which
execute automatically in any program which imports the given module,
then I'd contend that Haskell doesn't really even have those (apart
from possibly 'main', if you count that at all).

In the latter case, you might have disconnected components which all
must run, but since they do IO, are potentially noncommutative. With
the ability to mark actions as automatically executing without some
way to control the order of that execution, program behaviour is
unpredictable in general. At least, I wouldn't want the language to
allow that. However, putting an explicit ordering on their execution
is essentially equivalent to defining a new IO action which executes
each of them in a given sequence, obviating the need for such a
feature in the first place.

While only allowing the definition of top-level IORefs (i.e. not
unrestricted IO) wouldn't cause quite as much harm, it's still
questionable as to whether it's ever actually necessary. One can get
computation-global IORefs easily using something along the lines of
ReaderT IORef IO. By newtyping the monad, one could exert even more
control over how the IORef was used.

One problem with real top-level IORefs is that it leaves no way for
the module user to reset things in general. As a library designer, you
might think that the users of your library will only ever want to
initialise things once, but this is being a little bit overly forceful
-- what if the program has reloaded its configuration while running
and wants to restart the functionality your module provides? If you
haven't explicitly provided a way to reset the IORefs, there's no way
for the module user to reliably do so.

There are plenty of other nice ways to enforce things such as
particular actions only running once and so on. For one, you could use
a new monad, which would give extremely fine control over what actions
were permitted, but even with just IO, there are plenty of things one
can do -- just not globally.

We can relatively easily create a context which provides an IO action
that will only run once in that context, and return the same value as
the first time without repeating the execution thereafter:

singletonRegion :: IO a - (IO a - IO b) - IO b
singletonRegion action region = do
r - newIORef Nothing
let action' = do
t - readIORef r
case t of
Nothing - do v - action
  writeIORef r (Just v)
  return v
Just v  - return v
region action'

test1 = singletonRegion (putStrLn Hello) $ \greet - do
greet -- only this one will actually have any effect.
greet
greet

With a custom monad, this sort of setup would be built into the run
function which transforms the action back into IO, and so would be
even more transparent, while still not creating irrevocable
program-global state.

 One thing I never could fathom about the position of the nay-sayers
 in this debate is what exactly is it that they object to?
 Is it existence of top level TWIs and of IO operations that
 reference them *in principle*?
 Or are they content with their existence but just don't want to
 allow people to use Haskell to define them?

 If it's the former then we should be purging the IO libraries of
 all such horrors, though I can't see much remaining of them (well
 anything actually). But I guess an IO incapable language might
 still have some niche uses.

 If it's the latter then we are advocating a language which cannot
 be used to implement many demonstrably useful IO modules and libraries,
 *by design*. If so, the claim that Haskell is a general purpose
 programming language seems quite bogus and should be removed from
 the haskell.org home page IMO.

This argument sounds quite a lot like the ones used by those arguing
against the removal of GOTO from programming languages. Sometimes, by
explicitly not providing some feature, you're also making code in
general easier to comprehend (especially when that feature has
invisible global effects on programs, where you'd need to look
carefully at the source of all modules involved in order to determine
what was actually happening in the presence of its use). It can also
prevent certain classes of design problems from ever cropping up. The
more state which one has to reconstruct in order to test an arbitrary

[Haskell-cafe] Re: The case of the missing module

2006-04-24 Thread Simon Marlow

Neil Mitchell wrote:



import Paths_haddock( getDataDir )



Haddock requires to be built with Cabal (which generates this module),
and as far as I can remember, its a Cabal that isn't released
anywhere. When I did some work on haddock I commented this out, and
made getDataDir return an empty list and then made sure to set the -l
flag (I think) and was able to work around this.

Of course, the solution is to get Cabal working. I broke Cabal long
ago, but you might have more luck.


Haddock builds fine with the Cabal included in GHC 6.4.2, BTW.

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


[Haskell-cafe] Re: How to get Haddock to generate docs for a directory tree of modules

2006-04-24 Thread Simon Marlow

Brian Hulley wrote:

I've been looking at the docs for Haddock at 
http://haskell.org/haddock/haddock-html-0.7/index.html but I can't seem 
to find any option to recursively traverse a directory generating 
hyperlinked docs for all modules anywhere in the directory or any sub 
directory etc.


Is there a simple undocumented flag I'm missing?


Haddock doesn't do this on its own, but Cabal can do it (./setup 
haddock).  You do have to specify all the modules in the .cabal file 
though, so it's not really traversing a directory.


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


[Haskell-cafe] Re: Haddock seems to generate wrong types in newtype deriving

2006-04-24 Thread Simon Marlow

Brian Hulley wrote:

Hi -
I have the following code:

data MState = MState -- details omitted
type MonadStateMState = MonadState MState -- necessary for Haddock
newtype ManagerM a =
ManagerM (StateT MState IO a)
deriving (Monad, MonadIO, MonadStateMState)

which means that ManagerM is an instance of Monad, MonadIO, and 
MonadState MState.

However, the Haddock docs look like:

data ManagerM a
Instances
??? a = Monad (ManagerM a)
??? a = MonadIO (ManagerM a)
??? a = MonadStateMState (ManagerM a)

which doesn't seem at all right to me. I'd have thought it should say:

data ManagerM a
Instances
Monad ManagerM
MonadIO ManagerM
MonadStateMState ManagerM

Is this just a bug in Haddock or am I misunderstanding something about 
Haskell?


It's a bug / missing feature in Haddock.  Haddock is basically pretty 
dumb when it comes to understanding Haskell code; it knows about the 
syntax and the module system, and that's about all.  It makes a 
half-hearted attempt to figure out what instances you get from deriving 
clauses, but it's not complete, and you've encountered a case it doesn't 
handle.


One day Haddock will be built on top of the GHC API, and all this will 
be fixed...


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


Re: [Haskell-cafe] Advice needed on best way to simulate an STL vector

2006-04-24 Thread Ross Paterson
On Wed, Apr 19, 2006 at 09:32:19PM +0200, Udo Stenzel wrote:
 We don't have an implementation of Ropes (yet?).  I think, a Finger Tree
 of Fast Packed Strings might be the closest thing.  I'd even implement
 it this way, if the low performance of raw Strings finally overcame my
 inertia...

Sounds like a good idea.  I've placed the general annotated finger tree
structure from our paper on the webpage

http://www.soi.city.ac.uk/~ross/papers/FingerTree.html

It might be useful if anyone would like to attempt this.

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


[Haskell-cafe] Re: Haddock seems to generate wrong types in newtype deriving

2006-04-24 Thread Brian Hulley

Simon Marlow wrote:

Brian Hulley wrote:

Hi -
I have the following code:


[snip]

Is this just a bug in Haddock or am I misunderstanding something
about Haskell?


It's a bug / missing feature in Haddock.  Haddock is basically pretty
dumb when it comes to understanding Haskell code; it knows about the
syntax and the module system, and that's about all.  It makes a
half-hearted attempt to figure out what instances you get from
deriving clauses, but it's not complete, and you've encountered a
case it doesn't handle.

One day Haddock will be built on top of the GHC API, and all this will
be fixed...


Thanks - I'm glad it's not just me!
In the meantime, I found a better workaround (since the type decl using a 
class name is not legal Haskell) is just to use -cpp to preprocess for both 
ghc and haddock so that haddock sees explicitly defined dummy instances 
instead of a newtype deriving clause, then perfect results are obtained... 
:-)


Regards, Brian. 


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


[Haskell-cafe] Re: How to get Haddock to generate docs for a directory tree of modules

2006-04-24 Thread Brian Hulley

Simon Marlow wrote:

Brian Hulley wrote:


I've been looking at the docs for Haddock at
http://haskell.org/haddock/haddock-html-0.7/index.html but I can't
seem to find any option to recursively traverse a directory
generating hyperlinked docs for all modules anywhere in the
directory or any sub directory etc.

Is there a simple undocumented flag I'm missing?


Haddock doesn't do this on its own, but Cabal can do it (./setup
haddock).  You do have to specify all the modules in the .cabal file
though, so it's not really traversing a directory.


Thanks for this suggestion. I've also got things to work quite well by using 
the following makefile on a Windows command shell (using a Win32 port of gnu 
make and based on a helpful example makefile received offlist):


# Makefile for Haddock docs
GHCFLAGS = -fglasgow-exts -fffi
API_FILES := $(wildcard *.hs)

# preprocess for Haddock
%.haddock:%.hs
   ghc $(GHCFLAGS) -cpp -E -optP-P -D__HADDOCK__ $^ -o docs/$@
# generate docs
docs: $(patsubst %.hs,%.haddock,$(API_FILES))
   haddock -o docs -h $(addprefix docs/, $^)

This works as long as all the subdirectories containing modules are 
explicitly listed in API_FILES, and the whole directory tree (including the 
docs directory) is manually created (for Windows, since Windows doesn't 
automatically create directories that don't exist when it tries to open a 
file for writing when the filename contains a path) - not a big problem 
since the directory tree only needs to be created once.


Regards, Brian. 


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


Re: [Haskell-cafe] Current situation regarding global IORefs

2006-04-24 Thread Lennart Augustsson

Adrian Hey wrote:
.

I was going to respond, but Cale very eloquently said most
of what I was thinking.

Let me just add one thing.  Sometimes you hear the argument
I need a global IORef here because it's to track the use of my
single screen (or keyboard, or elevator, or some some
other gizmo in th real world).
I think such decisions are just generally poor design, and
it should not be done in any language.  The number of physical
resources that a program can control should never be assumed
to be one; things change.

-- Lennart

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


Re: [Haskell-cafe] Re: Control.Exceptions and MonadIO

2006-04-24 Thread Brian Hulley

Brian Hulley wrote:

I've started work on a module to replace Control.Exception by
wrapping all the original Control.Exception functions in more general
monadic functions and using two type classes as follows:

class MonadIO m = MonadException m where
catch :: m a - (Exception - m a) - m a
catchDyn :: Typeable exception = m a - (exception - m a) - m a
catchJust :: (Exception - Maybe b) - m a - (b - m a) - m a
try :: m a - m (Either Exception a)
tryJust :: (Exception - Maybe b) - m a - m (Either b a)

and

class MonadIO m = MonadIOU m where
   getUnliftIO :: m (m a - IO a)

All the other functions can be implemented just using MonadIO or
MonadIOU or MonadException in place of IO (depending on the function
eg bracket needs MonadIOU) - just in case anyone is interested.


After more thought, it seems that it *should* be possible to implement block 
and unblock for StateT monads under certain conditions, using a different 
unlift function to return IO (a,s) instead of just IO a. Therefore I've 
changed things around, and also by looking at the source code for the 
current Control.Exception module, arrived at the following revised design 
(I've implemented all the other functions in terms of the classes below)


   class MonadIO m = MonadException m where
   catch :: m a - (Exception - m a) - m a
   catchDyn :: Typeable exception = m a - (exception - m a) - m a
   block, unblock :: MonadException m = m a - m a

  class MonadIO m = MonadIOU m where
   getUnliftIO :: m (m a - IO a)

However I then want to say that any instance of MonadIOU is also an instance 
of MonadException. I tried:


   instance MonadIOU m = MonadException m where
   catch action e_m = do
unliftIOa - getUnliftIO
unliftIOb - getUnliftIO
liftIO $ C.catch (unliftIOa action) (\e - unliftIOb(e_m e))
   -- etc

but this only compiles with -fallow-undecidable-instances. I'm puzzled at 
why there is a problem with such a simple instance declaration, and also 
don't know if this means my design is fatally flawed.
The highlight of the above design is that all that's needed for many monads 
such as MonadIOU m = ReaderT r m is a definition of the one unlifting 
function, but it also allows instances of MonadException to be declared 
where the monad (eg a StateT s m) doesn't support this particular operation.


Any ideas?

Thanks, Brian.

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


[Haskell-cafe] Google Summer of Code 2006

2006-04-24 Thread Paolo Martini

Hello,

Haskell.org is going to partecipate as mentoring organization to the 
Google Summer of Code programme of this year.


We have formed a group of volunteers taking care of the administrative 
work as well as the mentoring part. The group is listed here: 
http://haskell.org/haskellwiki/Summer_of_Code:_People.


We are now looking for projects, and mentors.  We've reached number 24 
but we are happily going to add more, Haskell Open Source paid work for 
the summer!


If you run some active open source program you might want to mentor some 
student who will be working on your code, for example.  Either just add 
your ideas here: 
http://haskell.org/haskellwiki/Summer_of_Code:_Project_suggestions (as 
well as your informations on the People's page) or contact me for details.


I am also looking for students, I'd like to ear from them if they are 
going to partecipate with Haskell projects, last year I was alone! (I 
did write the bindings to the Cairo vector graphics library and 
integrated them in Gtk2Hs.)


Details about the programme itself can be found on the official webpage:
http://code.google.com/summerofcode.html

Hoping you like the idea as much as me,
Paolo.
--
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Current situation regarding global IORefs

2006-04-24 Thread Robert Dockins


On Apr 24, 2006, at 2:42 AM, Adrian Hey wrote:

Lennart Augustsson wrote:

I think global mutable variables should be regarded with utmost
suspicion.  There are very few situations where they are the
right solution.


Well IMO even the use of the term global mutable variable causes
muddled thinking on this and I wish people would stop it. There's no
reason to regard top level things with identity (call them TWIs
or objects or whatever) with any more suspicion than top level IO
actions themselves.


Sure there is.  TWI's are just the object-oriented singleton pattern  
warmed over, and the singleton pattern is much maligned in some  
circles (for good reason, IMO).



One thing I never could fathom about the position of the nay-sayers
in this debate is what exactly is it that they object to?
Is it existence of top level TWIs and of IO operations that
reference them *in principle*?
Or are they content with their existence but just don't want to
allow people to use Haskell to define them?


The former, in my case.  As I stated in an earlier message, the  
problem is primarily one of defining the dynamic scope of the thing.   
If you look back in the archives, you'll notice I proposed a thread- 
local state mechanism because I felt it placed the scope boundary in  
an appropriate place, where it could be manipulated and reasoned  
about by programmers, and where it has a reasonable semantic  
interpretation.  Presumably, runtime models will have to deal somehow  
with the notion of a thread of execution (even if just to say there  
is only ever one) and will thus fix the dynamic scope of thread local  
state.


I additionally think that thread-local state (and similar mechanisms)  
can be abused to create difficult-to-maintain and buggy code, but  
that's a somewhat separate issue.



If it's the former then we should be purging the IO libraries of
all such horrors, though I can't see much remaining of them (well
anything actually). But I guess an IO incapable language might
still have some niche uses.


Argument by straw-man: there are important differences between  
regular IO actions and TWI's, AKA singletons.  The former is  
referentially transparent, while the latter is referentially opaque,  
for starters.  There's also the scoping issue: the properties of the  
IO monad bound the dynamic scope of regular IO actions, but not so  
for singletons.



If it's the latter then we are advocating a language which cannot
be used to implement many demonstrably useful IO modules and  
libraries,

*by design*. If so, the claim that Haskell is a general purpose
programming language seems quite bogus and should be removed from
the haskell.org home page IMO.


You presuppose that a language which cannot be used to implement  
many demonstrably useful IO modules and libraries is not general  
purpose.  I claim that is silly.  If we take that argument to its  
logical conclusion, then we should throw out static typing,  
referential transparency and most of the things that make Haskell  
what it is.  I think that what a programming language keeps you from  
doing is as least as important as what it lets you do.  If you don't  
believe that at least to some extent, then your first exposure to  
Haskell probably made your head explode.


That said, I also disagree with the premise.  I don't know of any  
stateful library designs that can't be pretty straightforwardly  
refactored using explicit initialization and ReaderT-over-IO monads.   
Furthermore, I believe that a library so structured is actually  
_more_ useful than the library with implicit state.



Regards
--
Adrian Hey



Rob Dockins

Speak softly and drive a Sherman tank.
Laugh hard; it's a long way to the bank.
  -- TMBG


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