(indexing with TypeRep)
This is yet another incidence where Robert Will's ByMaps would be very useful
In fact GHC at least *already* generates a unique integer for each TypeRep.
A good idea, since it means comparisons can be done in unit time.
Thus indexing can be done trivially using this
On Monday 29 November 2004 11:35, George Russell wrote:
(indexing with TypeRep)
This is yet another incidence where Robert Will's ByMaps would be
very useful
In fact GHC at least *already* generates a unique integer for each
TypeRep. A good idea, since it means comparisons can be done
On Mon, Nov 29, 2004 at 11:57:31AM +0100, Benjamin Franksen wrote:
Can anyone think of a situation where adding a derived instance to an
abstract data type breaks one of its invariants?
Yes, I was thinking of this the other day,
newtype LessThan5 = LessThen5 Int
new x | x 5 = LessThen5 x
On Friday 26 November 2004 08:39, George Russell wrote:
Benjamin Franksen wrote (snipped):
What non-standard libraries have I used (that you don't)?
OK, but you have to test every element of the dictionary with fromDynamic
until you find one with the type you want, which is not a good idea
On Friday 26 November 2004 08:39, you wrote:
Benjamin Franksen wrote (snipped):
What non-standard libraries have I used (that you don't)?
OK, but you have to test every element of the dictionary with fromDynamic
until you find one with the type you want, which is not a good idea if the
[for the 4th time moving this discussion to cafe]
On Friday 26 November 2004 08:39, you wrote:
Benjamin Franksen wrote (snipped):
Doesn't that run contrary to Adrian Hey's oneShot example/requirement?
Remind me again what Adrian Hey's oneShot example/requirement is ...
On Friday 26 November 2004 14:12, Benjamin Franksen wrote:
I still can't see any reason why each single Haskell thread should have its
own searate dictionary. Contrary, since it is common to use forkIO quite
casually, and you expect your actions to do the same thing regardless of
which thread
This is funny. When I got no immediate reaction from you, I started
implementing it myself. I ended up with something similar. It has less
features but is also a lot simpler. This is the interface:
initGlobal :: Typeable a = a - IO ()
getGlobal :: Typeable a = IO a
Your implementation is
George Russell [EMAIL PROTECTED] writes:
Your implementation is probably much simpler than mine because
you don't implement withEmptyDict. I'm really quite keen about
withEmptyDict, because one of the MAJOR conceptual problems I have
with unsafePerformIO global variables is that you only get
On Thursday 25 November 2004 10:02, you wrote:
This is funny. When I got no immediate reaction from you, I started
implementing it myself. I ended up with something similar. It has less
features but is also a lot simpler. This is the interface:
initGlobal :: Typeable a = a - IO ()
Benjamin Franksen wrote (snipped):
Doesn't that run contrary to Adrian Hey's oneShot example/requirement?
Remind me again what Adrian Hey's oneShot example/requirement is ...
Well, that's indeed one major problems with global variables. Sure, you can
try to solve it with multiple dictionaries,
On Wed, Nov 24, 2004 at 08:53:47AM +0100, Lennart Augustsson wrote:
Well, I don't. unsafePerformIO is an extension that is very much
against the spirit of Haskell. Haskell with it does not have the
properties I want. So I don't use it. :)
I hope 'it' means unsafePerformIO, not Haskell :)
I
Tomasz wrote:
Without unsafePerformIO Haskell gives me many guarantees for free.
With unsafePerformIO, they are no longer for free, I have to think, prove,
etc. When I mistakenly give a pure function interface to an unpure
function, it can affect my program in most unexpected places.
I think
I wrote (snipped):
3) It needs no extensions to the Haskell language, and only fairly
standard hierarchical libraries like Data.IORef.
Lennart Augustsson wrote (snipped):
It uses unsafePerformIO which is very much an extension to Haskell. :)
Ben Rudiak-Gould wrote (snipped):
I think by Haskell
On 23 Nov 2004, at 11:53, George Russell wrote:
I wrote (snipped):
3) It needs no extensions to the Haskell language, and only fairly
standard hierarchical libraries like Data.IORef.
Lennart Augustsson wrote (snipped):
It uses unsafePerformIO which is very much an extension to Haskell.
:)
Ben
G'day all.
Quoting George Russell [EMAIL PROTECTED]:
No. I mean by the Haskell language what is described in
the Haskell 98 Report. unsafePerformIO is not part of the language,
it is a value defined by one of the standard hierarchical libraries.
unsafePerformIO is part of the FFI addendum
[EMAIL PROTECTED] wrote:
No. I mean by the Haskell language what is described in
the Haskell 98 Report. unsafePerformIO is not part of the language,
it is a value defined by one of the standard hierarchical libraries.
unsafePerformIO is part of the FFI addendum to the H98 report. So I
think
At 10:38 08/11/04 -0800, Iavor S. Diatchki wrote:
It is not (should not be?) the case that IO = ST RealWord, as IO is not a
state monad as we understand it.
In a state monad, the changes to the state are all in the program, i.e.
one can always
point to the part of the program that modified the
On Monday 08 Nov 2004 6:00 am, Peter Simons wrote:
Frankly, the idea that anyone would want to jump through
hoops to add them to a purely functional language sounds
bizarre to me.
The first step to solving a problem is to at least recognise
that it exists. What is bizarre is that so many folk
--- Ben Rudiak-Gould
[EMAIL PROTECTED] wrote:
This is solved by merging the IO and ST monads,
something that ought to
be done anyway:
type IO = ST RealWorld
type IORef a = Ref RealWorld a
type STRef s a = Ref s a
newRef :: a - ST s (Ref s a) -- replaces
newIORef and
However, turning Haskell into O'Haskell seems like a far more radical
suggestion than the (IMO) conservative language extension under
discussion. So I don't expect it to happen anytime soon. Maybe if
Haskell ever gets a better records/modules system things might look
a bit different. But there
Adrian Hey wrote:
The first step to solving a problem is to at least recognise
that it exists. What is bizarre is that so many folk seem
to be in denial over this. Perhaps you would like to show
me your solution to the oneShot problem.
Why are you unable to give a concrete real world
example of
Krasimir Angelov wrote:
Note that 2-rank type of runSTInit doesn't allow to
execute regular IO actions. Even that (ST s a) allows
actions like readRef and writeRef. This allows to
initialise local references but doesn't allow to
access other toplevel reverences since they are bound
to RealWorld
Note that 2-rank type of runSTInit doesn't allow to
execute regular IO actions. Even that (ST s a) allows
actions like readRef and writeRef. This allows to
initialise local references but doesn't allow to
access other toplevel reverences since they are bound
to RealWorld state.
Thinking about
--- Keean Schupke [EMAIL PROTECTED] wrote:
Note that 2-rank type of runSTInit doesn't allow
to
execute regular IO actions. Even that (ST s a)
allows
actions like readRef and writeRef. This allows to
initialise local references but doesn't allow to
access other toplevel reverences
Krasimir Angelov wrote:
ered on top of ST and the stToIO is
the lifting function. What does 'automatically be
lifted' mean?
Krasimir
For example with the state monad you can define:
instance (MonadState st m,MonadT t m) = MonadState st (t m) where
update = up . update
setState = up .
Adrian Hey wrote:
Why are top level IORefs any worse than other IORefs (for
example)?
Because global variables are just BAD. They have been considered
bad a long time, it's not a Haskell thing.
If you really grok the functional way of doing things there should
be *very*, *very* few times you need
Adrian Hey wrote:
4- They already exist (stdin,stout,stderr) and I don't
recall anybody ever complaining about this.
stdin, stdout, and stderr are not global variables.
They are just handles. One possible implementation
of handles is as an Int. So stdin is no more a global
variable than 0.
Keean Schupke wrote:
Adrian Hey wrote:
The first step to solving a problem is to at least recognise
that it exists. What is bizarre is that so many folk seem
to be in denial over this. Perhaps you would like to show
me your solution to the oneShot problem.
Why are you unable to give a concrete
On 8 Nov 2004, at 12:23, Lennart Augustsson wrote:
Adrian Hey wrote:
4- They already exist (stdin,stout,stderr) and I don't
recall anybody ever complaining about this.
stdin, stdout, and stderr are not global variables.
They are just handles. One possible implementation
of handles is as an
As I know the ST monad doesn't provide
getState/setState functions. In order to get this kind
of overloading we need to put all functions that deal
with references in type class:
class MonadRef m r where
readRef :: r a - m a
writeRef :: a - r a - m ()
I guess that this is an overkill
Jules Bean wrote:
Yes... a lot of the example we have seen here are 'just' handles.
newIORef creates handles. Something many programmers would like is the
ability to create fresh handles at the toplevel...
Yes, I hear what they want. That doesn't mean I think it's
a good idea. Top level
Krasimir Angelov [EMAIL PROTECTED] writes:
I guess that this is an overkill since we can just
define IO as
type IO a = ST RealWorld a
'instance MonadIO IO' would start to need some type system extensions.
--
__( Marcin Kowalczyk
\__/ [EMAIL PROTECTED]
^^
On Monday 08 Nov 2004 10:52 am, Keean Schupke wrote:
Krasimir Angelov wrote:
Note that 2-rank type of runSTInit doesn't allow to
execute regular IO actions. Even that (ST s a) allows
actions like readRef and writeRef. This allows to
initialise local references but doesn't allow to
access
On Monday 08 Nov 2004 12:23 pm, Lennart Augustsson wrote:
Adrian Hey wrote:
4- They already exist (stdin,stout,stderr) and I don't
recall anybody ever complaining about this.
stdin, stdout, and stderr are not global variables.
They are just handles.
Isn't an IORef just a handle for a
Adrian Hey wrote:
Why are top level IORefs any worse than other IORefs (for
example)?
Because global variables are just BAD. They have been considered
bad a long time, it's not a Haskell thing.
If you really grok the functional way of doing things there should
be *very*, *very* few times you need
Adrian Hey wrote:
4- They already exist (stdin,stout,stderr) and I don't
recall anybody ever complaining about this.
stdin, stdout, and stderr are not global variables.
They are just handles. One possible implementation
of handles is as an Int. So stdin is no more a global
variable than 0.
Keean Schupke wrote:
Adrian Hey wrote:
The first step to solving a problem is to at least recognise
that it exists. What is bizarre is that so many folk seem
to be in denial over this. Perhaps you would like to show
me your solution to the oneShot problem.
Why are you unable to give a concrete
On 8 Nov 2004, at 12:23, Lennart Augustsson wrote:
Adrian Hey wrote:
4- They already exist (stdin,stout,stderr) and I don't
recall anybody ever complaining about this.
stdin, stdout, and stderr are not global variables.
They are just handles. One possible implementation
of handles is as an
[posted to haskell-cafe per SLPJ's request]
Hi Adrian,
I can assure you that for the intended applications of oneShot it
is vital that realInit is executed once at most, but the user must
[..]
So please, no more handwaving arguments about this kind of thing
being unnecessary, bad programming
On Monday 08 Nov 2004 3:57 pm, Keith Wansbrough wrote:
[posted to haskell-cafe per SLPJ's request]
Hi Adrian,
I can assure you that for the intended applications of oneShot it
is vital that realInit is executed once at most, but the user must
[..]
So please, no more handwaving
Adrian Hey wrote:
The problem is simple enough to restate for anyone who's interested.
Provide a simple reliable mechanism to ensure that in a given
program run one particular top level IO operation cannot be executed
more than once.
No language can guarantee this - all I have to do is run 2
Adrian Hey writes:
The problem is simple enough to restate for anyone who's interested.
Provide a simple reliable mechanism to ensure that in a given
program run one particular top level IO operation cannot be executed
more than once.
Can you give one concrete example of an intended
As a purely practical matter, it seems like the easiest solution (to
this particular use case) is to write a small wrapper initializer in C
which is idempotent, then use FFI to call the wrapper, rather than
calling the initialization directly. This is easy enough to do with a
static local
Hello,
Just wanted to point out that the suggested idea is not quite correct.
(well that has to be quantiifed a bit, see bellow)
Krasimir Angelov wrote:
--- Ben Rudiak-Gould
[EMAIL PROTECTED] wrote:
This is solved by merging the IO and ST monads,
something that ought to
be done anyway:
Just to add a small point... you can see how the 'bad' single context
design affects the code that uses it. Because C allows global variables
it is possible to write libraries that require once-and-only-once
initialisation.
In Haskell (without global variables) it is impossible (or at least
On Monday 08 Nov 2004 12:14 pm, Lennart Augustsson wrote:
Adrian Hey wrote:
Why are top level IORefs any worse than other IORefs (for
example)?
Because global variables are just BAD.
Who said anything about global?
If you really grok the functional way of doing things there should
be
On Sunday 07 Nov 2004 3:16 am, Benjamin Franksen wrote:
Of course, the downside is that some of the functions (not many) now have
one or two additional arguments. OTOH one could argue that this is in fact
an advantage, as it makes all the dependencies crystal clear.
I wouldn't argue that :-)
Adrian Hey wrote:
I'm not at all convinced, having not seen or groked either the before or
after code. Perhaps you could show how this would work with an even simpler
example, the one that I posted concerning the use of oneShot to create a
top level (I.E. exportable) userInit.
AFAICS the only
On Sunday 07 November 2004 13:36, you wrote:
AFAICS the only alternative to..
userInit - oneShot realInit
is to export realInit, have users create their own userInit, and then pass
that around as an argument to everything that might make use of userInit.
Yes. For instance, user code
On Sunday 07 November 2004 16:18, you wrote:
Adrian Hey wrote:
I'm not at all convinced, having not seen or groked either the before or
after code. Perhaps you could show how this would work with an even
simpler example, the one that I posted concerning the use of oneShot to
create a top
On Sunday 07 Nov 2004 1:45 pm, Benjamin Franksen wrote:
It's a similar advantage as using the IO monad has over allowing arbitrary
side-effects in functions: The IO monad gives you a clear separation
between stuff that has (side-) effects (i.e. depends on the real word) and
pure functions
On Fri, Nov 05, 2004 at 07:03:06PM +, MR K P SCHUPKE wrote:
You don't want stdin/stdout/stderr?
Also these are only available in the IO monad...
No, they are available outside the IO monad, only you can't do
anything useful with them. Well, you can show them!
without breaking
Please, can we confine this discussion to just one mailing list:-)
It started out on [EMAIL PROTECTED] so that's where I'd like
to keep it (at least that's where I will be posting my responses
from now on).
On Sunday 07 Nov 2004 10:38 pm, Keean Schupke wrote:
I don't understand the relevance of
On Monday 08 Nov 2004 1:55 am, Benjamin Franksen wrote:
[moving to haskell-cafe]
Sorry for the long post.
[moving back to haskell]
Hope you'll exuse me if I don't respond to everything here, just
don't have the stamina. But maybe this..
Timber doesn't even have top-level IO actions, instead
I might really want to call the initialisation twice. If you use global
variables, the library can only be initialised once... but what if I
really want to use the library twice? With the state in a type passed
between functions, you can have multiple different states active
at once.
Keean.
On Sunday 07 November 2004 17:41, Keean wrote:
I might really want to call the initialisation twice. If you use global
variables, the library can only be initialised once... but what if I
really want to use the library twice? With the state in a type passed
between functions, you can have
On Sunday 07 Nov 2004 6:19 pm, Benjamin Franksen wrote:
On Sunday 07 November 2004 17:41, Keean wrote:
I might really want to call the initialisation twice. If you use global
variables, the library can only be initialised once... but what if I
really want to use the library twice? With the
Adrian Hey wrote:
Oh and while we're at it, perhaps one of you could explain what it is
you think is unsafe about the hypothetical top level - bindings we're
discussing (I've asked this before too, but no answer has been provided).
Are your objections dogmatic, aesthetic, or rational?
Do either of
On Friday 05 November 2004 22:07, Keean Schupke wrote:
myRef :: IORef Int
myRef = unsafePerformIO $ newIORef 0
This should always return the same reference, whereas:
myIORef :: IO (IORef Int)
myIORef = newIORef 0
Will return a new reference every time. I agree it would seem that
the
The problem I see here is how to proove the IO in safeIO is indeed
safe. Perhaps UnsafeIO is a better name, as infact the IO is still
unsafe - the compiler has to take special notice of this type and
not inline its definitions.
Your oneShot function has the same problem - if the compiler
inlines
Vincenzo Ciancia wrote:
Yes, but I guess everybody would like a solution where
myRef1 = unsafePerformIO $ newIORef 0
myRef2 = unsafePerformIO $ newIORef 0
are different variables. Also, it's not true that it's perfectly safe,
I don't understant this - they would be different variables with
Inling isn't the only optimization, which can lead to a wrong behavior,
let floating out and common subexpression elimination can also
change the behavior
of programs using unsafePerformIO.
Our research group has developed the calculus FUNDIO as a semantic basis:
It's a non-deterministic
Just been reading arround. According to ghc docs, the noinline
pragma is in the Haskell98 report. On that basis what is wrong
with using the following to initialise these top-level constants?
{-# NOINLINE newref #-}
newref :: IORef Int
newref = unsafePerformIO $ newIORef 0
Keean.
I hope this is not a stupid idea - but why not contribute the changes
as patches back to the main GHC development?
Keean.
David Sabel wrote:
Inling isn't the only optimization, which can lead to a wrong behavior,
let floating out and common subexpression elimination can also
change the
On 6 Nov 2004, at 13:07, Keean Schupke wrote:
Just been reading arround. According to ghc docs, the noinline
pragma is in the Haskell98 report. On that basis what is wrong
with using the following to initialise these top-level constants?
{-# NOINLINE newref #-}
newref :: IORef Int
newref
The main reason is: Nobody asks for it.
I conjecture, a problem is:
if you use FUNDIO as a semantics for Haskell, you have to give up
referential transparency in the strong sense. FUNDIO-programs are
only referential transparent with respect to the defined contextual
equivalence.
David
Keean
David Sabel wrote:
The main reason is: Nobody asks for it.
Actually I think Simon Marlow has talked in the past about wanting
to make GHC only do safe optimisations on unsafePerformIO.
I conjecture, a problem is:
if you use FUNDIO as a semantics for Haskell, you have to give up
referential
Keean Schupke wrote:
David Sabel wrote:
The main reason is: Nobody asks for it.
Actually I think Simon Marlow has talked in the past about wanting
to make GHC only do safe optimisations on unsafePerformIO.
I conjecture, a problem is:
if you use FUNDIO as a semantics for Haskell, you have to give
On Saturday 06 Nov 2004 12:27 pm, Keean Schupke wrote:
The problem I see here is how to proove the IO in safeIO is indeed
safe. Perhaps UnsafeIO is a better name, as infact the IO is still
unsafe -
I don't agree. All top level bindings currently have the property that
their value is
On Saturday 06 Nov 2004 1:07 pm, Keean Schupke wrote:
Just been reading arround. According to ghc docs, the noinline
pragma is in the Haskell98 report. On that basis what is wrong
with using the following to initialise these top-level constants?
{-# NOINLINE newref #-}
newref ::
As an experiment, I just finished to change the Haskell Web Server with
Plugins such that all global variables (unsafePerformIO-style) are replaced
by standard argument passing. It wasn't difficult. The main work was
(1) get it to compile with ghc-6.2.2
(2) understand how the code is organized
I don't quite understand this thread - There are already the equivalent of
IOrefs in the ST monad called STrefs. You can do newSTRef etc... you can use
stToIO to embed an ST operation in the IO monad and this is safe. You
can also
use the unsafe ioToST, provided you are careful. To me adding
Benjamin Franksen wrote:
| I think hiding the fact that certain objects are not
| constants but functions is a bad idea, because it will break
| sharing in a lazy implementation.
|
| You probably mean the case where the implicit parameter
| is the only one. I don't see why that would
On Friday 05 Nov 2004 1:23 pm, Marcin 'Qrczak' Kowalczyk wrote:
Keean Schupke [EMAIL PROTECTED] writes:
Why do want global variables?
Because they are more convenient than passing a state by hand.
They increase modularity by avoiding putting the fact that
a computation uses some global
You don't want stdin/stdout/stderr?
Also these are only available in the IO monad...
without breaking referential transparency
by use of unsafePerformIO hack.
I don't understand this still... how can it not break referntial transparancy.
For example consider if stdin were available outside the
Eiffel can dispense with global variables not least because objects contain
mutable state. And the methods cann access this state inside their object
without taking it as an argument.
All of which you can do in Haskell (including the objects) with no additional
extensions, see:
On 5 Nov 2004, at 19:03, MR K P SCHUPKE wrote:
You don't want stdin/stdout/stderr?
Also these are only available in the IO monad...
without breaking referential transparency
by use of unsafePerformIO hack.
I don't understand this still... how can it not break referntial
transparancy.
For example
Okay, now for the purposes of my understanding, let me explore this:
myRef :: IORef Int
myRef = unsafePerformIO $ newIORef 0
This should always return the same reference, whereas:
myIORef :: IO (IORef Int)
myIORef = newIORef 0
Will return a new reference every time. I agree it would seem that the
On Friday 05 November 2004 22:07, Keean Schupke wrote:
So what
we need is a way in the type system to tell the compiler the function
must have
a single unique definition... Something like:
myRef :: Unique (IORef Int)
myRef = uniquePerformIO $ newIORef 0
and then have:
runUnique ::
On Friday 05 Nov 2004 7:03 pm, MR K P SCHUPKE wrote:
Could someone give an example of what these things are that need to be
initialised and that are safe.
Here's a utility I've concocted for dealing with partial ordering
constraints on initialisation of foreign libraries..
oneShot :: IO a -
Benjamin Franksen wrote:
| 1) I strongly disagree with ideas to execute IO actions
| implicitly in whatever defined or undefined sequence
| before or during main for whatever reasons.
I agree with the objections you make. Having full IO actions
as initialization actions might be a bit too
Koen Claessen wrote:
Benjamin Franksen wrote:
| 1) I strongly disagree with ideas to execute IO actions
| implicitly in whatever defined or undefined sequence
| before or during main for whatever reasons.
I agree with the objections you make. Having full IO actions
as initialization actions
I've been meaning to get into this debate ...
Koen proposes:
Imagine a commutative monad, CIO. Commutative monads have
the property that it does not matter in what order actions
are performed, they will have the same effect. In other
words, for all m1 :: CIO A, m2 :: CIO B, k :: A - B -
On Thursday 04 November 2004 16:16, Koen Claessen wrote:
The problem with John's approach is that it breaks
modularity. It does this in two ways:
(1) Whenever a module uses an implicit parameter like that,
it has to have a name that is different from all implicit
parameters used by any other
John Peterson wrote (snipped):
The implementer of these functions has to guarantee that the
actions do not destroy the commutativity of the CIO monad.
Sorry, but several of my variable initialisation actions involve
things like starting up child processes or rapid exits from the program
if
On Thursday 04 November 2004 18:28, Koen Claessen wrote:
Ben Rudiak-Gould wrote:
| I think the OP is proposing the same thing, except
| without the ellipsis: i.e. we just write
|
| pretty :: Doc - String
|
| and the compiler infers pretty :: (?width :: Int) = Doc
| - String, or
On Thursday 04 November 2004 18:54, George Russell wrote:
John Peterson wrote (snipped):
The implementer of these functions has to guarantee that the
actions do not destroy the commutativity of the CIO monad.
Sorry, but several of my variable initialisation actions involve
things like
Benjamin Franksen wrote:
On Thursday 04 November 2004 17:20, Ben Rudiak-Gould wrote:
This is one of the several ways in which the current implementation of
implicit parameters is broken. Clearly they *should* belong to the
module namespace, and if we modify the implementation so that they do,
the
But I just realized that it will probably be necessary to declare (not
bind!) implicit parameters at the top level to avoid capture problems.
Yep, this is the way it would have to go.
--KW 8-)
___
Haskell mailing list
[EMAIL PROTECTED]
Jo'n Fairbairn wrote:
The idea is simply that we should provide a mechanism of
saying to a compiler this file (of data) is a module that
exports only the variable v. ...
So we tell the compilation system that file
/somewhere/contains-v contains the value of the variable
v::String, and that
Koen Claessen wrote:
Imagine a commutative monad, CIO. Commutative monads have
the property that it does not matter in what order actions
are performed, they will have the same effect. In other
words, for all m1 :: CIO A, m2 :: CIO B, k :: A - B - CIO
C, it should hold that:
do a - m1
Koen Claessen wrote:
Ben Rudiak-Gould wrote:
| I'm not convinced this is a problem either. All you have
| to do is use a single parameter (?MyModule.globals ::
| MyModule.Globals), where MyModule.Globals is an abstract
| type, and you've hidden your implementation as completely
| as if you
93 matches
Mail list logo