Re: [Haskell-cafe] global variables for foreign C functions

2008-12-02 Thread Andrea Rossato
On Mon, Dec 01, 2008 at 05:30:33PM -0800, Judah Jacobson wrote:
 You can limit the size of that stub file using:
 
 foreign import ccall progname progname :: Ptr (Ptr CChar)
 
 which lets you access that global variable and write the
 getters/setters in Haskell rather than C.

this solves my problems quite nicely indeed, but I still cannot figure
how to write a setter function that actually works.

That is to say, after:
newCString new_name = poke progname

this:
putStrLn . show = peekCString = peek progname

would return new_name, but the library, which is using progname to
produce some debugging messages, doesn't seem to get it correctly: the
original bits are gone, but instead of new_name I get some garbage.

Thanks to everyone for the interesting and useful hints.

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


Re: [Haskell-cafe] global variables for foreign C functions

2008-12-01 Thread Evan Laforge
On Mon, Dec 1, 2008 at 4:39 PM, Andrea Rossato
[EMAIL PROTECTED] wrote:
 Hello,

 I'm writing the bindings to a C library which uses, in some functions,
 global variables.

 To make it clearer, those functions need a global variable to be
 defined. A C program using my_function, one of the library functions,
 would look like:

I don't think you can use the FFI to declare symbols for C.  One
not-so-pretty but effective way to do it is create a stub.c with the
variables declared along with setting functions, then bind those
functions like any other.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] global variables for foreign C functions

2008-12-01 Thread Judah Jacobson
On Mon, Dec 1, 2008 at 4:55 PM, Evan Laforge [EMAIL PROTECTED] wrote:
 On Mon, Dec 1, 2008 at 4:39 PM, Andrea Rossato
 [EMAIL PROTECTED] wrote:
 Hello,

 I'm writing the bindings to a C library which uses, in some functions,
 global variables.

 To make it clearer, those functions need a global variable to be
 defined. A C program using my_function, one of the library functions,
 would look like:

 I don't think you can use the FFI to declare symbols for C.  One
 not-so-pretty but effective way to do it is create a stub.c with the
 variables declared along with setting functions, then bind those
 functions like any other.

You can limit the size of that stub file using:

foreign import ccall progname progname :: Ptr (Ptr CChar)

which lets you access that global variable and write the
getters/setters in Haskell rather than C.

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


Re: [Haskell-cafe] global variables for foreign C functions

2008-12-01 Thread John Meacham
On Mon, Dec 01, 2008 at 04:55:14PM -0800, Evan Laforge wrote:
 On Mon, Dec 1, 2008 at 4:39 PM, Andrea Rossato
 [EMAIL PROTECTED] wrote:
  Hello,
 
  I'm writing the bindings to a C library which uses, in some functions,
  global variables.
 
  To make it clearer, those functions need a global variable to be
  defined. A C program using my_function, one of the library functions,
  would look like:
 
 I don't think you can use the FFI to declare symbols for C.  One
 not-so-pretty but effective way to do it is create a stub.c with the
 variables declared along with setting functions, then bind those
 functions like any other.

Yes, it is unfortunate this is the case. my ForeignData proposal was
meant to address this:

http://hackage.haskell.org/trac/haskell-prime/wiki/ForeignData

I am not entirely sure about the proposal as described, but I think
something like it should be done.

John

-- 
John Meacham - ⑆repetae.net⑆john⑈
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] global variables for foreign C functions

2008-12-01 Thread John Van Enk
I would find a ForeignData extension incredibly helpful. This will be
crucial if Haskell ever wants to target out of the ordinary systems.

/jve


On Mon, Dec 1, 2008 at 8:38 PM, John Meacham [EMAIL PROTECTED] wrote:

 On Mon, Dec 01, 2008 at 04:55:14PM -0800, Evan Laforge wrote:
  On Mon, Dec 1, 2008 at 4:39 PM, Andrea Rossato
  [EMAIL PROTECTED] wrote:
   Hello,
  
   I'm writing the bindings to a C library which uses, in some functions,
   global variables.
  
   To make it clearer, those functions need a global variable to be
   defined. A C program using my_function, one of the library functions,
   would look like:
 
  I don't think you can use the FFI to declare symbols for C.  One
  not-so-pretty but effective way to do it is create a stub.c with the
  variables declared along with setting functions, then bind those
  functions like any other.

 Yes, it is unfortunate this is the case. my ForeignData proposal was
 meant to address this:

 http://hackage.haskell.org/trac/haskell-prime/wiki/ForeignData

 I am not entirely sure about the proposal as described, but I think
 something like it should be done.

John

 --
 John Meacham - ⑆repetae.net⑆john⑈
 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe

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


Re: [Haskell-cafe] global variables

2007-05-24 Thread Adrian Hey

Taral wrote:

On 5/23/07, Adrian Hey [EMAIL PROTECTED] wrote:

I think I still prefer..

var :: IORef Int
var - newIORef 3


So do I. For one very good reason: this syntax could be defined as a
constructor syntax and guaranteed to run before main.


Or even at compile time (which is why I think it's reasonable to
regard operations like newIORef etc.. as not really being IO
operations at all). But anyway, the constraints of the ACIO monad
allow creation to occur at any time before the first attempt to
read or write the IORef.


The other syntaxes proposed don't strike me as sufficiently rigorous.


Me neither. It's always been a great source of puzzlement to me why this
very simple and IMO conservative proposal should be so controversial.
Unless someone can point out some severe semantic difficulty or suggest
something better it seems like a no-brainer to me.

Regards
--
Adrian Hey



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


Re: [Haskell-cafe] global variables

2007-05-24 Thread Taral

On 5/24/07, Adrian Hey [EMAIL PROTECTED] wrote:

Taral wrote:
 The other syntaxes proposed don't strike me as sufficiently rigorous.

Me neither. It's always been a great source of puzzlement to me why this
very simple and IMO conservative proposal should be so controversial.
Unless someone can point out some severe semantic difficulty or suggest
something better it seems like a no-brainer to me.


I think it lacks implementation. I don't have time, or I'd look into
hacking this into GHC.

--
Taral [EMAIL PROTECTED]
Please let me know if there's any further trouble I can give you.
   -- Unknown
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] global variables

2007-05-24 Thread Simon Marlow

Adrian Hey wrote:

Taral wrote:

On 5/23/07, Adrian Hey [EMAIL PROTECTED] wrote:

I think I still prefer..

var :: IORef Int
var - newIORef 3


So do I. For one very good reason: this syntax could be defined as a
constructor syntax and guaranteed to run before main.


Or even at compile time (which is why I think it's reasonable to
regard operations like newIORef etc.. as not really being IO
operations at all). But anyway, the constraints of the ACIO monad
allow creation to occur at any time before the first attempt to
read or write the IORef.


The other syntaxes proposed don't strike me as sufficiently rigorous.


Me neither. It's always been a great source of puzzlement to me why this
very simple and IMO conservative proposal should be so controversial.
Unless someone can point out some severe semantic difficulty or suggest
something better it seems like a no-brainer to me.


This is going to be highly subjective, but to me it still doesn't feel like it 
falls under the bar for implementation cost given its usefulness.


The new syntax requires additions all the way through the front end of the 
compiler: parser, abstract syntax, renamer, type checker, desugarer, for 
something that is rarely used.  It's a first-class language construct (a new 
top-level binding form, no less), and it has to pay its way.  Also you want to 
add the ACIO monad as a built-in to the language.


Not that my gut feeling should in any way be considered the final word on the 
subject, but I thought I should say something about why we're not running to 
implement this right now.  To me it seems like we should let it simmer some more.


Cheers,
Simon

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


Re: [Haskell-cafe] global variables

2007-05-24 Thread David House

On 24/05/07, Adrian Hey [EMAIL PROTECTED] wrote:

Or even at compile time (which is why I think it's reasonable to
regard operations like newIORef etc.. as not really being IO
operations at all).


You can allocate heap space at compile time? (Well, I guess you could,
but that wouldn't still be usable at run time...) I imagine newIORef
as mallocing() some room, then returning a pointer to that memory.
That doesn't seem like something that could be done at compile time.

--
-David House, [EMAIL PROTECTED]
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] global variables

2007-05-24 Thread Adrian Hey

David House wrote:

On 24/05/07, Adrian Hey [EMAIL PROTECTED] wrote:

Or even at compile time (which is why I think it's reasonable to
regard operations like newIORef etc.. as not really being IO
operations at all).


You can allocate heap space at compile time? (Well, I guess you could,
but that wouldn't still be usable at run time...) I imagine newIORef
as mallocing() some room, then returning a pointer to that memory.
That doesn't seem like something that could be done at compile time.


There seems to be quite a few implicit (and incorrect) assumptions in
your argument, which is fallacious IMO. The logic of your argument
would imply that *no* top level expression can be evaluated at compile
time. This might be the case with ghc, though I doubt it (and even if
it was this would just be a ghc problem).

BTW, the Haskell standard says nothing about any kind of heap, let
alone a C style malloc.

Regards
--
Adrian Hey




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


Re: [Haskell-cafe] global variables

2007-05-24 Thread Aaron Denney
On 2007-05-24, David House wrote:
 On 24/05/07, Adrian Hey [EMAIL PROTECTED] wrote:
 Or even at compile time (which is why I think it's reasonable to
 regard operations like newIORef etc.. as not really being IO
 operations at all).

 You can allocate heap space at compile time? (Well, I guess you could,
 but that wouldn't still be usable at run time...) I imagine newIORef
 as mallocing() some room, then returning a pointer to that memory.
 That doesn't seem like something that could be done at compile time.

You can allocate bss or data space at compile time for the executable
you are compiling.  (Well, if you read compile as compile and link.
It's a bit fuzzy.)

-- 
Aaron Denney
--

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


Re: [Haskell-cafe] global variables

2007-05-24 Thread Adrian Hey

Aaron Denney wrote:

On 2007-05-24, David House wrote:

On 24/05/07, Adrian Hey [EMAIL PROTECTED] wrote:

Or even at compile time (which is why I think it's reasonable to
regard operations like newIORef etc.. as not really being IO
operations at all).

You can allocate heap space at compile time? (Well, I guess you could,
but that wouldn't still be usable at run time...) I imagine newIORef
as mallocing() some room, then returning a pointer to that memory.
That doesn't seem like something that could be done at compile time.


You can allocate bss or data space at compile time for the executable
you are compiling.  (Well, if you read compile as compile and link.
It's a bit fuzzy.)


Well we don't need to get too bogged down with the details of how
any particular compiler/linker/rts might work. The point being that
with any..

myIORef - newIORef initialExpression

whether or not it's at the top level, the only information needed
to create the IORef is the initialExpression, and if it's at the
top level then this is available at compile time (it doesn't even
have to be evaluated at compile time in order to create the IORef).

But it doesn't require any information from, nor should it have
any effect on, the outside world that an executing program is
interacting with. It is conceivable that for some newIORef
implementations this would not be true, but in that case it's
difficult to see how such implementations could safely put
their newIORef in the ACIO monad anyway.

Regards
--
Adrian Hey





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


Re: [Haskell-cafe] global variables

2007-05-23 Thread Adrian Hey

Isaac Dupree wrote:


var :: IORef Int
var = {-# EVALUATE_THIS_TEXT_ONLY_ONCE #-} (unsafePerformIO (newIORef 3))


I think I still prefer..

var :: IORef Int
var - newIORef 3

or, more likely..

var :: IORef Int
var - ACIO.newIORef 3

The - syntax should make the intended semantics clear and unambiguous,
so it becomes the problem of individual implementors (not standards
writers) to make sure that whatever optimisations or transformations
that may be appropriate for their implementation preserve those
semantics. (IOW there's no need to worry about what a pragma really
means in operational terms, AFAICS).

The ACIO monad also restricts what programmers may use on the rhs of
the -.

But if you want a good name for the pragma how about this..


var :: IORef Int
var = {-# - #-} (unsafePerformIO (newIORef 3))


:-)

Regards
--
Adrian Hey








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


Re: [Haskell-cafe] global variables

2007-05-23 Thread Taral

On 5/23/07, Adrian Hey [EMAIL PROTECTED] wrote:

I think I still prefer..

var :: IORef Int
var - newIORef 3


So do I. For one very good reason: this syntax could be defined as a
constructor syntax and guaranteed to run before main.

The other syntaxes proposed don't strike me as sufficiently rigorous.

--
Taral [EMAIL PROTECTED]
Please let me know if there's any further trouble I can give you.
   -- Unknown
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] global variables

2007-05-22 Thread Isaac Dupree
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Isaac Dupree wrote:
 Maybe some sort of ISOLATE, DON'T_OPTIMIZE (but CAF), or
 USED_AS_GLOBAL_VARIABLE pragma instead of just the insufficient NOINLINE
 would be a good first step... if successful it would remove the
 occasional need for -fno-cse for a whole module in GHC, at least.

ISOLATE, DON'T_OPTIMIZE are actually bad names for the whole effect,
which requires persistent CAF semantics.  An implementation that doesn't
make top-level definitions be CAFs, or even one that is willing to
garbage-collect them when memory is tight such that they need
recalculation later, would need a special case for global variables to
make them work.

i.e. I'm not sure if there exists a reasonable pragma while the code
still uses unsafePerformIO.

Hmm

How about

so,
{-# NOINLINE var #-}
var :: IORef Int
var = unsafePerformIO (newIORef 3)

- --

var :: IORef Int
var = {-# EVALUATE_THIS_TEXT_ONLY_ONCE #-} (unsafePerformIO (newIORef 3))

to capture the desired semantics: text-based uniqueness, no duplication,
no sharing of the IORefs (sharing the pure contents is fine), and no
need to actually evaluate it any times at all. {-#
EVALUATE_THIS_TEXT_ONLY_ONCE #-} is syntactically like a (special)
function.  Clearly it is an impossible demand for polymorphic things, so
the compiler could complain (at least a warning) if the (var :: IORef
Int) line was left off, for example. I guess it would also complain
about non-type(class) argument dependencies too such as (f x =
(unsafePerformIO (newIORef (x::Int))) )...

Food for thought :-)


Isaac
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGU02YHgcxvIWYTTURAoCaAKCkDH7Pd7JbNt0TmNig9j7ujiUV9ACZAevI
QOjdmMbrPfVrKBafZshCh7c=
=9/5v
-END PGP SIGNATURE-
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


RE: [Haskell-cafe] global variables

2007-05-21 Thread Simon Peyton-Jones

| I see no need two answer this again I believe I have already made my
| views perfectly clear already and provided ample evidence to justify
| them. Surely I don't need to do it again?

Is there a Wiki page about this somewhere?  Often email gets into a loop 
because not everyone reads everything on Haskell Cafe. (There's just too much 
of it.)  When that happens, a good thing do to is to summarise the various 
positions on a Wiki page, so the debate can progress by refining text rather 
than by repeating it.  There is the additional advantage that someone coming 
along later can still make sense of the debate.

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


Re: [Haskell-cafe] global variables

2007-05-21 Thread Arthur van Leeuwen


On 21-mei-2007, at 9:31, Simon Peyton-Jones wrote:



| I see no need two answer this again I believe I have already made my
| views perfectly clear already and provided ample evidence to justify
| them. Surely I don't need to do it again?

Is there a Wiki page about this somewhere?  Often email gets into a  
loop because not everyone reads everything on Haskell Cafe.  
(There's just too much of it.)  When that happens, a good thing do  
to is to summarise the various positions on a Wiki page, so the  
debate can progress by refining text rather than by repeating it.   
There is the additional advantage that someone coming along later  
can still make sense of the debate.


As I am sure Adrian would tell you were he awake:

http://www.haskell.org/haskellwiki/Top_level_mutable_state

With regards, Arthur van Leeuwen

--

  /\/ |   [EMAIL PROTECTED]   | Work like you don't need  
the money
/__\  /  | A friend is someone with whom | Love like you have never  
been hurt
/\/__ | you can dare to be yourself   | Dance like there's nobody  
watching




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


Re: [Haskell-cafe] global variables

2007-05-20 Thread Adrian Hey

Jules Bean wrote:

I've pretty much convinced it's wrong. There should be one and only
one main from which all subsequent IO activity derives. But creating
internal state in the form of mutable data structures is not an IO
activity. It just so happens that at the moment the only way to do this
is newIORef :: a - IO(IORef a), but this need not be so (readIORef and
writeIORef are IO activities, but newIORef isn't).



I find this point rather slippery. 'newIORef' is a unique-name-provider, 
but 'unique over what'? When a module is imported twice, should it not 
create new unique names?


No, it's just binding a name to a value, same as any other binding.
The difference is unlike normal top level bindings, that name is not
equal to any other expression. It just is, if you get what I mean
(I'm sure you do). That's why the proposed syntax borrows the - from
do expressions.


If it's necessary that there is only one libWhateverState to preserve
safety properties (because the state must be kept in sync with what's
really being done to the world, of which there is also only one) then
what's the point of making it a parameter (the lib is not truly
parameterisable by that state).


A slightly irrational point of concern in my mind is that by encouraging 
this practice, we encourage lazy library design.


Yes, this is slightly irrational :-)


A large proportion of
libraries in fact *can* be written as reentrant in this sense, and
truly are parameterisable by their state.


I can't help being sceptical about this. AFAICS it doesn't matter how
many explicit state handles you tack on to the left of the
- IO Whatever, the fact that the whole lot ends in - IO Whatever
means there's almost certainly some state left unaccounted for and
unparameterised (calls the OS are missing an OS state handle for
example).

Also, I don't really understand what you mean by reentrant in this
context. Are you talking about thread safety? (I guess not) Are you
implying that APIs of IO libs that mutate Haskell global state are
some how different from other IO APIs which mutate other global state
(such as OS state or world state)? Are they deficient in some way?
If so, how can you tell the difference?

Regards
--
Adrian Hey







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


Re: [Haskell-cafe] global variables

2007-05-20 Thread Jules Bean

Adrian Hey wrote:

Jules Bean wrote:

I've pretty much convinced it's wrong. There should be one and only
one main from which all subsequent IO activity derives. But creating
internal state in the form of mutable data structures is not an IO
activity. It just so happens that at the moment the only way to do this
is newIORef :: a - IO(IORef a), but this need not be so (readIORef and
writeIORef are IO activities, but newIORef isn't).



I find this point rather slippery. 'newIORef' is a 
unique-name-provider, but 'unique over what'? When a module is 
imported twice, should it not create new unique names?


No, it's just binding a name to a value, same as any other binding.
The difference is unlike normal top level bindings, that name is not
equal to any other expression. It just is, if you get what I mean
(I'm sure you do). That's why the proposed syntax borrows the - from
do expressions.



That's not my point. newIORef creates unique names (references). The 
whole job of newIORef is to create unique names; unique names which 
refer to little tiny bits of state parcelled up somewhere in that 
mysterious IO monad. It is the scope of this uniqueness I'm talking 
about: do libraries need these unique names to be unique over each 
importer, over each thread, over each subprocess: consider a haskell 
application server or a haskell OS... what is the correct domain of 
uniqueness?




A large proportion of
libraries in fact *can* be written as reentrant in this sense, and
truly are parameterisable by their state.


I can't help being sceptical about this. AFAICS it doesn't matter how
many explicit state handles you tack on to the left of the
- IO Whatever, the fact that the whole lot ends in - IO Whatever
means there's almost certainly some state left unaccounted for and
unparameterised (calls the OS are missing an OS state handle for
example).

Also, I don't really understand what you mean by reentrant in this
context. Are you talking about thread safety? (I guess not) Are you
implying that APIs of IO libs that mutate Haskell global state are
some how different from other IO APIs which mutate other global state
(such as OS state or world state)? Are they deficient in some way?
If so, how can you tell the difference?



'reentrant' is not the right word, although it's a related notion. I was 
talking about libraries which can safely be initialised more than once, 
for multiple clients, and they keep around 'separate' state for each 
client/each time they are initialised. This kind of design is often a 
precondition for being thread-safe; and it's often plain good design, 
unless some external 'real world' uniqueness makes it impossible.


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


Re: [Haskell-cafe] global variables

2007-05-20 Thread Adrian Hey

[cc'ing HPrime]

Isaac Dupree wrote:

The unsafePerformIO hack being used is not very satisfactory given how
many optimizations make it difficult to use safely in practice.  This
hack is also used many places.  I would be happier if that situation
were not true, and I suspect there's something like a consensus on
_that_. (maybe not as strong as _needs_ a solution in the short-to-mid
term future)


Considering the value that the Haskell community normally places on
sound semantics, reliance on such an appalling hack seems pretty bad to
me. If a solution doesn't find it's way into H' then how many more years
is it going to be with us? It's just embarrassing :-)

Also, I don't know if the OP was a noob, but telling people (especially
noobs) that if they can't figure out how to solve a problem without
using a global variable then that must be down to inexperience and
general cluelessness on their part just seems wrong to me. It simply
isn't true.

(Anyone who disagrees with this should feel free to submit the patches
needed to fix up the base package :-)

Regards
--
Adrian Hey

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


Re: [Haskell-cafe] global variables

2007-05-20 Thread Isaac Dupree
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Adrian Hey wrote:
 [cc'ing HPrime]
 
 Isaac Dupree wrote:
 The unsafePerformIO hack being used is not very satisfactory given how
 many optimizations make it difficult to use safely in practice.  This
 hack is also used many places.  I would be happier if that situation
 were not true, and I suspect there's something like a consensus on
 _that_. (maybe not as strong as _needs_ a solution in the short-to-mid
 term future)
 
 Considering the value that the Haskell community normally places on
 sound semantics, reliance on such an appalling hack seems pretty bad to
 me. If a solution doesn't find it's way into H' then how many more years
 is it going to be with us? It's just embarrassing :-)

Yes, also it places value on REALLY EXTREMELY (excessively?) SOUND
semantics, and on the modularity of the language even more than the
modularity of its uses (or something like that :-)

Maybe some sort of ISOLATE, DON'T_OPTIMIZE (but CAF), or
USED_AS_GLOBAL_VARIABLE pragma instead of just the insufficient NOINLINE
would be a good first step... if successful it would remove the
occasional need for -fno-cse for a whole module in GHC, at least.

Isaac
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGUF4yHgcxvIWYTTURAvqWAJ46eFRt5LK1lUwqr2BmHVSrHljxzwCfYGJB
x5ivAFEw5vYKbxTPIg+PrIU=
=0xVK
-END PGP SIGNATURE-
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] global variables

2007-05-20 Thread Adrian Hey

Isaac Dupree wrote:

Maybe some sort of ISOLATE, DON'T_OPTIMIZE (but CAF), or
USED_AS_GLOBAL_VARIABLE pragma instead of just the insufficient NOINLINE
would be a good first step... if successful it would remove the
occasional need for -fno-cse for a whole module in GHC, at least.


I have a hard time trying to understand why anyone would prefer
this to the simple and clear - syntax that's been proposed. As
for the ACIO monad itself, this is utterly trivial and requires
no language change. It's just a library.

Maybe the first pragma you propose might have other uses to control
optimisations, so I'm not totally anti this. But generally I
dislike pragmas (I always find myself wondering what's wrong
with the language design that makes the pragma necessary).

So pragmas that influence optimisation are something I can
live with. But using pragmas to influence *semantics* really
is an evil practice IMO and is something that should be
discouraged, not made an unavoidable necessity.

But yes, if this problem isn't going to be properly addressed
then at the very least the -fno-cse flag or something similar
needs standardising (NOINLINE already is I think). Or we port
all existing unsafePerfomIO hacked code to use Johm Meachams
variant of the hack (uses types to ensure the compiler doesn't
see common sub-expressions).

Regards
--
Adrian Hey



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


Re: [Haskell-cafe] global variables

2007-05-20 Thread Albert Y. C. Lai

Adrian Hey wrote:

Also, I don't know if the OP was a noob, but telling people (especially
noobs) that if they can't figure out how to solve a problem without
using a global variable then that must be down to inexperience and
general cluelessness on their part just seems wrong to me. It simply
isn't true.


Then what is right and what is true?

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


Re: [Haskell-cafe] global variables

2007-05-20 Thread Adrian Hey

Jules Bean wrote:
That's not my point. newIORef creates unique names (references). The 
whole job of newIORef is to create unique names; unique names which 
refer to little tiny bits of state parcelled up somewhere in that 
mysterious IO monad. It is the scope of this uniqueness I'm talking 
about: do libraries need these unique names to be unique over each 
importer, over each thread, over each subprocess: consider a haskell 
application server or a haskell OS... what is the correct domain of 
uniqueness?


The scoping rules are exactly the same as for any other top level
identifier, whether or not exported or imported. There's no reason why
an importing module should know or care that one or more of the
identifiers it's importing is the result of a - binding.

Should every module that imports the prelude get a different stdout?
(they currently don't of course)

'reentrant' is not the right word, although it's a related notion. I was 
talking about libraries which can safely be initialised more than once, 
for multiple clients, and they keep around 'separate' state for each 
client/each time they are initialised. This kind of design is often a 
precondition for being thread-safe; and it's often plain good design, 
unless some external 'real world' uniqueness makes it impossible.


I don't see a problem here. The fact that an IO lib presents some
controlled interface one or more to real world resources (I.E.
resources where you can't simply conjour up a new ones by using
a newResource constructor) should not stop it being able to service
multiple clients or sessions. The socket API and indeed the OS itself
seem to be obvious examples of this (or even something really simple
like Data.Unique).

Or take a look at the hypothetical embedded device driver API I put
on the wiki. This makes a clear distinction between DeviceHandles and
DeviceSessionHandles (which will wrap the correspnding DeviceHandle).
Users cannot create new DeviceHandles but are free to create as many
DeviceSessionHandles with a particular device as they like.

Regards
--
Adrian Hey




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


Re: [Haskell-cafe] global variables

2007-05-20 Thread Adrian Hey

Albert Y. C. Lai wrote:

Adrian Hey wrote:

Also, I don't know if the OP was a noob, but telling people (especially
noobs) that if they can't figure out how to solve a problem without
using a global variable then that must be down to inexperience and
general cluelessness on their part just seems wrong to me. It simply
isn't true.


Then what is right and what is true?


I see no need two answer this again I believe I have already made my
views perfectly clear already and provided ample evidence to justify
them. Surely I don't need to do it again?

If you disagree with any of them then feel free to explain why.

Regards
--
Adrian Hey

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


RE: [Haskell-cafe] global variables

2007-05-18 Thread Simon Peyton-Jones
|  and (at worst) are evil. These people are quite simply wrong and
|  should be ignored :-)
| 
|  Adrian Hey is not only wrong, but actually evil. He should be ignored. :-)
|
| I am right, I might well be evil, and if past experience is anything to
| go by I already know that I will be ignored. We've been talking about
| this problem for years, but nothing is ever done about it

I know that Jules preceded his remarks by saying that they were lighthearted, 
but I'd like to urge moderation in language.  One of the best things about the 
Haskell community is that politeness is pretty much universal.  Email is too 
fragile a medium to sustain the wry smile that can accompany an in-person 
conversation.

Also Adrian, you may feel ignored, but I don't think that's really so.  For 
example, I was looking back at your ACIO mail a couple of months ago, when I 
was thinking about concurrency.

Not immediately achieving a critical mass behind a language change is not the 
same as being ignored.  One of the good things about Haskell is that we put up 
with woefully inadequate situations (such as the total lack of sensible I/O in 
early lazy languages) because we can't yet find a solution that feels 
satisfying.  To say that nothing is ever done about it implies that there are 
clear things that could be done, but I don't think that is so (yet).  And 
sometimes people don't reply because they are just busy, or because they don't 
have anything useful to say.

In short, don't be discouraged.  Keep identifying problems, suggesting 
solutions, maintaining Wiki pages that summarise both, and so on.  There are 
lots of bright people on this mailing list, and sooner or later an aha moment 
will happen.

Simon

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


Re: [Haskell-cafe] global variables

2007-05-18 Thread Henning Thielemann

On Thu, 17 May 2007, Jules Bean wrote:

 Eric wrote:
  H|i,
 
  Does anyone know of a simple and straightforward way to use global
  variables in Haskell?

 (Perhaps annoyingly) the answer to this question, like so many other
 questions on this list, is a question. What are you trying to do?.

I've put your answer to the FAQ category on Haskell-Wiki:
 http://haskell.org/haskellwiki/Global_variables
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] global variables

2007-05-18 Thread Jules Bean

[I agree with your points, but...]

Adrian Hey wrote:


I've pretty much convinced it's wrong. There should be one and only
one main from which all subsequent IO activity derives. But creating
internal state in the form of mutable data structures is not an IO
activity. It just so happens that at the moment the only way to do this
is newIORef :: a - IO(IORef a), but this need not be so (readIORef and
writeIORef are IO activities, but newIORef isn't).



I find this point rather slippery. 'newIORef' is a unique-name-provider, 
but 'unique over what'? When a module is imported twice, should it not 
create new unique names?




Indeed they do, unfortunately. In fact it was this very problem that
lead me to conclude the top level mutable state is not only not evil,
but is a necessity. Having to call explicit initialisation code is
a big problem in complex systems. Exactly who is responsible for
initialising what? and in what order?


Maybe I'm being old-fashioned here, but isn't that a *fundamental* 
problem, that can't be automatically solved? Isn't it just a fact that 
in a complex system you, the programmer, have to make some decisions 
about who is responsible for acquiring resources?



If it's necessary that there is only one libWhateverState to preserve
safety properties (because the state must be kept in sync with what's
really being done to the world, of which there is also only one) then
what's the point of making it a parameter (the lib is not truly
parameterisable by that state).


A slightly irrational point of concern in my mind is that by encouraging 
this practice, we encourage lazy library design. A large proportion of 
libraries in fact *can* be written as reentrant in this sense, and 
truly are parameterisable by their state.


Only a few are not: those which actually manage connections to some 
real entity which is in fact unique.


Of course that doesn't mean the problem doesn't exist.

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


Re: [Haskell-cafe] global variables

2007-05-18 Thread Adrian Hey

Jules Bean wrote:

main = do
  sockstate - initSocks
  graphstate - initGraphics
  ...
  disposeGraphics graphstate
  disposeSocks sockstate
  exit


Voila. Mutable state which persists for our entire program.

Arguably it's a pain passing around the state explicitly. Alternatively, 
you can argue that passing this stuff around explicitly makes code much 
easier to reason about. And we know a dozen tricks to hide this stuff 
(reader monads, state monads, withSocketsDo-style bracket constructs).


So I don't think this is really the issue, is it?


Have you ever wondered why our IO API's don't look like this? I think
there are many problems with this approach. What are the consequences
of this philosophy for issues such safety, platform independence,
maintainance of stable APIs?

As I understood it, the issue was more about whether or not *library* 
modules should be allowed to some 'set up' initialisation code to run at 
the beginning of 'main' to start up their own global state. I was never 
convinced this was a nice idea (I don't like the thought than an 
'import' alone can add hidden IO actions to main).


I agree, which is why I'm not keen on the top level mdo proposal.
But addressing this issue is the point of the ACIO monad proposal.

Mind you, I'm not 
convinced it's wrong, either. I think it's a hard one.


I've pretty much convinced it's wrong. There should be one and only
one main from which all subsequent IO activity derives. But creating
internal state in the form of mutable data structures is not an IO
activity. It just so happens that at the moment the only way to do this
is newIORef :: a - IO(IORef a), but this need not be so (readIORef and
writeIORef are IO activities, but newIORef isn't).


I wouldn't dispute the assertion that at the level of complete programs
or processes, implementations that don't use global variables are
possible. But this does not hold at the level of individual IO library
API's. If we want to keep our software *modular* (I take we do), then
we need top level mutable state.


That's assuming you feel having an explicit 'init' command and a 
'withLibXYZDo' construct breaks modularity. It doesn't feel like a 
terrible modularity break to me. (Plenty of C libraries I've used 
require explicit init calls).


Indeed they do, unfortunately. In fact it was this very problem that
lead me to conclude the top level mutable state is not only not evil,
but is a necessity. Having to call explicit initialisation code is
a big problem in complex systems. Exactly who is responsible for
initialising what? and in what order?

You could make it the users responsibility to do it right at the
begining of main. But this places a heavy burden on the user to
fully understand the dependencies of their hardware and the
software that controls it.

Or you could make it the users responsibility to initialise whatever
APIs they actually make use of, in no particular order. Those APIs
then initialise whatever sub-systems they actually use as part of
their own initialisation. But what happens if the same sub-system is
used (and initialised) by two different higher level IO libs?
(The second will initialisation will destroy any state that the first
may have set up.)

Of course it's perfectly straight forward to avoid accidental
re-initialisation, but only by making use of..you know what.


Is it the use of global variables?
Or is it the use of the unsafePerformIO hack to create them?



The latter is definitely a problem.


Yes.


The former, I'm not sure. My gut feeling is that it is, too.


If it's necessary that there is only one libWhateverState to preserve
safety properties (because the state must be kept in sync with what's
really being done to the world, of which there is also only one) then
what's the point of making it a parameter (the lib is not truly
parameterisable by that state).

Furthermore, if it is going to take this state handle as an explicit
argument then you need to provide some way for users to get this
state handle. This could be by..
 1 - Making it an argument of main.
 2 - Exposing a newLibWhateverState constructor
 3 - Exposing a getLibWhateverState getter.

Problems..
 1 Requires the type of main to depend on what IO libs are used.
   Also the Boot code that invokes main must get this state handle
   from somewhere.
 2 Potentially permits 2 or more libWhateverStates to be created
   (in which case all bets are off re. the safety proprties I was
talking about).
 3 Can't be implemented without making use of..you know what.

Regards
--
Adrian Hey


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


Re: [Haskell-cafe] global variables

2007-05-18 Thread Adrian Hey

Simon Peyton-Jones wrote:

For example, I was looking back at your ACIO mail a couple of months ago,

 when I was thinking about concurrency.

Actually, this is Ian Starks proposal..

 http://www.haskell.org/pipermail/haskell-cafe/2004-November/007664.html

..but is one with which I agree. I just wrote some stuff on the wiki
about this actually solved some currently insoluble problems.


Not immediately achieving a critical mass behind a language change is not the

 same as being ignored.

Unfortunately the situation seems worse than this. AFAICT we haven't
even got a consensus that that there is a real problem here that needs
any kind of solution :-)

Regards
--
Adrian Hey


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


Re: [Haskell-cafe] global variables

2007-05-18 Thread Isaac Dupree
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Adrian Hey wrote:
 Furthermore, if it is going to take this state handle as an explicit
 argument then you need to provide some way for users to get this
 state handle. This could be by..
  1 - Making it an argument of main.
  2 - Exposing a newLibWhateverState constructor
  3 - Exposing a getLibWhateverState getter.
 
 Problems..
  1 Requires the type of main to depend on what IO libs are used.
Also the Boot code that invokes main must get this state handle
from somewhere.
  2 Potentially permits 2 or more libWhateverStates to be created
(in which case all bets are off re. the safety proprties I was
 talking about).
  3 Can't be implemented without making use of..you know what.

Making it an argument of main (1) is somewhat the same as doing (3) -
consider getArgs.  What bothers me is the IO-state in the Haskell
standard (arguments, random state...) which is a set not extensible
without the hack.  (It bothers me that there _are_ so many things in
that set, somewhat ad-hoc-ly it seems :)


 Unfortunately the situation seems worse than this. AFAICT we haven't
 even got a consensus that that there is a real problem here that needs
 any kind of solution :-)

The unsafePerformIO hack being used is not very satisfactory given how
many optimizations make it difficult to use safely in practice.  This
hack is also used many places.  I would be happier if that situation
were not true, and I suspect there's something like a consensus on
_that_. (maybe not as strong as _needs_ a solution in the short-to-mid
term future)

Isaac


-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGTg2+HgcxvIWYTTURAvWfAKC36q24IKTX5YQOVi+A4gNYLzBMMACePwkL
dwnAlZh++e2EqiFKvJEmn1M=
=NBHG
-END PGP SIGNATURE-
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] global variables

2007-05-18 Thread John Meacham
On Thu, May 17, 2007 at 07:25:03PM +0100, Adrian Hey wrote:
 The above hack is not actually Haskell. It's a hack, and it depends on 
 the particular implementation characteristics of GHC. It is not 
 unreasonable to imagine that a future GHC might contain different 
 compilation techniques (I hesitate to use the word 'optimisations' 
 because that sounds like something easy to turn off) which invalidate 
 the technique in other ways or make it dangerous.
 
 Well of course, that's why something needs to be done about this. Just
 being in a state of complete denial regarding the reality of this
 problem won't make it go away.

Indeed, I made a proposal a while ago to allow top level IO actions,

foo - newIORef foo

which are quite straigtforward, and would not even be inconsistant in
the view of the type system, as - bindings are always monomorphic
anyway.

Others pointed out that if we allow arbitrary IO actions, it could cause
undesirable things like causing importing a mobule to change program
behavior, or expose implementatino details, like when these are
executed, right away or lazily.

The solution was to have a special restricted version of IO containing
only those actions that are safe. like newMVar etc.. where safe means
more or less commutative and omittable.

this doesn't require any special support, just a

newtype ACIO a = ACIO (IO a)
deriving(Monad,Functor)

and then have a module only export the trusted things in the ACIO monad.

John

-- 
John Meacham - ⑆repetae.net⑆john⑈
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] global variables

2007-05-18 Thread John Meacham
On Thu, May 17, 2007 at 11:00:18PM +0100, Jules Bean wrote:
 I'm not sure that's quite to the point. Clearly we can set up state at 
 the top of our main action:
 
 main = do
   sockstate - initSocks
   graphstate - initGraphics
   ...
   disposeGraphics graphstate
   disposeSocks sockstate
   exit
 
 
 Voila. Mutable state which persists for our entire program.
 
 Arguably it's a pain passing around the state explicitly. Alternatively, 
 you can argue that passing this stuff around explicitly makes code much 
 easier to reason about. And we know a dozen tricks to hide this stuff 
 (reader monads, state monads, withSocketsDo-style bracket constructs).
 
 So I don't think this is really the issue, is it?
 
 As I understood it, the issue was more about whether or not *library* 
 modules should be allowed to some 'set up' initialisation code to run at 
 the beginning of 'main' to start up their own global state. I was never 
 convinced this was a nice idea (I don't like the thought than an 
 'import' alone can add hidden IO actions to main). Mind you, I'm not 
 convinced it's wrong, either. I think it's a hard one.

indeed. the whole issue is libraries. global state need not be visible
to users, but is certainly useful when hidden inside librarys to provide
efficient purely functional veneers for internal algorithms. 

I think restricting the actions to ones that don't have externally
visible effects is the way to go here for a couple reasons. 

 * I would very much hate for 'import' to have effects in and of itself.
 * it would disallow (or expose) the obvious 'lazy' approach to
   top-level IO, where you don't actually perform the IO until the first
   time the value is needed, then memoize it.

so, some sort of restricted ACIO monad is in order.

Also, there is the somewhat related 'ForeignData' proposal of mine, the
syntax is pretty much off the top of my head, but I think something like
this needs to go into the haskell FFI, 

http://hackage.haskell.org/trac/haskell-prime/wiki/ForeignData

especially since it will sever the last need for C, allowing fully native
haskellp programs with the full power of C code. (plus, lots of
optimizatuons are available to the compiler when it sees the definitions
like this and it is really easy to implement)

John

 

-- 
John Meacham - ⑆repetae.net⑆john⑈
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] global variables

2007-05-17 Thread Donald Bruce Stewart
eeoam:
 H|i,
 
 Does anyone know of a simple and straightforward way to use global 
 variables in Haskell?
 
 E.

The usual way is to run the code that needs a global variable in a State monad.

The next answer is: you don't really need global variables, since you
don't have mutable variables anyway :-)

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


Re: [Haskell-cafe] global variables

2007-05-17 Thread Dougal Stanton

On 17/05/07, Eric [EMAIL PROTECTED] wrote:

H|i,

Does anyone know of a simple and straightforward way to use global
variables in Haskell?



You can pass around an environment with the State or Reader monads
(read/write and read-only respectively). If you want to do IO with the
data you'll probably need the transformer equivalents: StateT or
ReaderT.

I think there are some hackish ways of making IO variables but I don't
know how that's done. I'd imagine it's frowned on from a stylistic
point of view, too...

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


Re: [Haskell-cafe] global variables

2007-05-17 Thread Tom Harper

You can also use mutable variables (MVars) found in Control.Concurrent.MVar

http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Concurrent-MVar.html

They might work depending on your implementation.  The reading and
writing of MVars returns IO actions.

On 5/17/07, Dougal Stanton [EMAIL PROTECTED] wrote:

On 17/05/07, Eric [EMAIL PROTECTED] wrote:
 H|i,

 Does anyone know of a simple and straightforward way to use global
 variables in Haskell?


You can pass around an environment with the State or Reader monads
(read/write and read-only respectively). If you want to do IO with the
data you'll probably need the transformer equivalents: StateT or
ReaderT.

I think there are some hackish ways of making IO variables but I don't
know how that's done. I'd imagine it's frowned on from a stylistic
point of view, too...

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




--
Tom Harper
Computer Science Major '07
Syracuse University
+1 949 235 0185
Public Key: http://aftereternity.co.uk/rth.asc
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] global variables

2007-05-17 Thread Robin Green
On Thu, 17 May 2007 14:41:33 +0100
Eric [EMAIL PROTECTED] wrote:

 H|i,
 
 Does anyone know of a simple and straightforward way to use global 
 variables in Haskell?
 
 E.

Another alternative, for write-once variables, is implicit parameters.

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


Re: [Haskell-cafe] global variables

2007-05-17 Thread Stefan O'Rear
On Thu, May 17, 2007 at 02:41:33PM +0100, Eric wrote:
 Does anyone know of a simple and straightforward way to use global 
 variables in Haskell?

Just declare them at the top level, as a function but without
arguments:

===

x = 2

main = print x

===

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


Re: [Haskell-cafe] global variables

2007-05-17 Thread Jules Bean

Eric wrote:

H|i,

Does anyone know of a simple and straightforward way to use global 
variables in Haskell?


(Perhaps annoyingly) the answer to this question, like so many other 
questions on this list, is a question. What are you trying to do?.


The reason for this is that haskell's abstractions are different from 
those of the mainstream imperative languages, and the mapping isn't 1-1. 
So for a particular 'C' feature, there may be 3 or 4 haskell features 
which achieve similar effects, and the correct choice depends on the 
detailed context.


So, in particular, all those tasks which you use global variables for in 
C, can be achieved in haskell, but which solution depends what you are 
trying to do:


1. If you have some globals which are constant, then just define them at 
the top level. No problem.  pi = 3.14; progname = MyCoolApp.


2. If you have a global environment, which various functions read from 
(and you might, for example, initialise from a configuration file) then 
you should thread that as a parameter to your functions (after having, 
very likely, set it up in your 'main' action). If the explicit parameter 
passing annoys you, then you can 'hide' it with a monad.


3. If you have a need to store some global state which various of your 
functions modify, then you have a design issue. This style of design is 
frowned upon in C as well! The correct solution in C is to pass a 
'bundle' of appropriate parameters (you might call it an environment) to 
those functions which need it. In C++, perl or python you'd very likely 
make this bundle an object. In haskell this bundle will be a data value 
in some custom type; and using Monads you can 'hide the details' of 
passing it around, if you wish.


Hope that helps a bit,


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


Re: [Haskell-cafe] global variables

2007-05-17 Thread Adrian Hey

Eric wrote:

H|i,

Does anyone know of a simple and straightforward way to use global 
variables in Haskell?


I assume what you're looking for is to be able to have IORefs,MVars
Chans etc at the top level. The standard (for want of a better word)
way to do this is known commonly known as the unsafePerformIO hack.

myTopLevelFlag :: IORef Bool
{-# NOINLINE myTopLevelFlag #-}
myTopLevelFlag = unsafePerformIO (newIORef False)

With ghc you should also compile which make use of the unsafePerformIO
hack using the -fno-cse flag (to inhibit common sub-expression elemination).

Use something like this at the top of the module..
{-# OPTIONS_GHC -fno-cse #-}

BTW, this is the commonly the subject of flame wars on the Haskell
mailing lists because there appear to be many who passionately believe
and assert that so called global variables are (at best) unnecessary
and (at worst) are evil. These people are quite simply wrong and
should be ignored :-)

They are necessary because they are the only way to ensure important
safety properties of many IO APIs.

I ported the old wiki page about this to the new wiki..
  http://www.haskell.org/haskellwiki/Top_level_mutable_state

If you want to see more examples of the use of the unsafePerformIO
hack you need only look at the source code of the current base
package (you'll find a dozen or so uses of this hack to create
top level mutable state).

Regards
--
Adrian Hey

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


Re: [Haskell-cafe] global variables

2007-05-17 Thread Jules Bean
Please take this message in the fashion that is intended. My criticism 
is light hearted, as I believe yours is.


Adrian Hey wrote:

[hack snipped]


BTW, this is the commonly the subject of flame wars on the Haskell
mailing lists because there appear to be many who passionately believe
and assert that so called global variables are (at best) unnecessary
and (at worst) are evil. These people are quite simply wrong and
should be ignored :-)


Adrian Hey is not only wrong, but actually evil. He should be ignored. :-)

The above hack is not actually Haskell. It's a hack, and it depends on 
the particular implementation characteristics of GHC. It is not 
unreasonable to imagine that a future GHC might contain different 
compilation techniques (I hesitate to use the word 'optimisations' 
because that sounds like something easy to turn off) which invalidate 
the technique in other ways or make it dangerous.



They are necessary because they are the only way to ensure important
safety properties of many IO APIs.


That's a bold claim. It's very hard to prove that things don't exist. 
(That is, that other ways to ensure these safety properties don't 
exist). In snipped text you comment that the problems are often in 
low-level FFI library code: this makes me wonder if the real culprit 
doesn't lie at the FFI-haskell boundary. Perhaps there are good ways to 
specify this kind of invariant there.



If you want to see more examples of the use of the unsafePerformIO
hack you need only look at the source code of the current base
package (you'll find a dozen or so uses of this hack to create
top level mutable state).


All of these are, in a sense, failings. Because unsafePerformIO is not 
haskell, and we'd like base to be a haskell library. Not a GHC library.


I'd be willing to take a sportsman's bet that the original poster
does not actually need to use this hack; I doubt his application falls 
into the categories you have outlined. I would discourage people from 
using this hack unless it is, in fact, the only feasible approach.


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


Re: [Haskell-cafe] global variables

2007-05-17 Thread Dougal Stanton

On 17/05/07, Jules Bean [EMAIL PROTECTED] wrote:


I'd be willing to take a sportsman's bet that the original poster
does not actually need to use this hack; I doubt his application falls
into the categories you have outlined. I would discourage people from
using this hack unless it is, in fact, the only feasible approach.


I find it amusing that questions like these elicit such a wide variety
of responses. The original poster probably thought they were asking a
fairly straightforward question and then... woosh :-) Everyone
responds to the question at the level that suits their own proficiency
in the subject, I suppose.

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


Re: [Haskell-cafe] global variables

2007-05-17 Thread Adrian Hey

Jules Bean wrote:

BTW, this is the commonly the subject of flame wars on the Haskell
mailing lists because there appear to be many who passionately believe
and assert that so called global variables are (at best) unnecessary
and (at worst) are evil. These people are quite simply wrong and
should be ignored :-)


Adrian Hey is not only wrong, but actually evil. He should be ignored. :-)


I am right, I might well be evil, and if past experience is anything to
go by I already know that I will be ignored. We've been talking about
this problem for years, but nothing is ever done about it (a solution to
this problem isn't even on the agenda for Haskell' AFIAK).

The above hack is not actually Haskell. It's a hack, and it depends on 
the particular implementation characteristics of GHC. It is not 
unreasonable to imagine that a future GHC might contain different 
compilation techniques (I hesitate to use the word 'optimisations' 
because that sounds like something easy to turn off) which invalidate 
the technique in other ways or make it dangerous.


Well of course, that's why something needs to be done about this. Just
being in a state of complete denial regarding the reality of this
problem won't make it go away.


They are necessary because they are the only way to ensure important
safety properties of many IO APIs.


That's a bold claim. It's very hard to prove that things don't exist. 
(That is, that other ways to ensure these safety properties don't 
exist). In snipped text you comment that the problems are often in 
low-level FFI library code: this makes me wonder if the real culprit 
doesn't lie at the FFI-haskell boundary. Perhaps there are good ways to 
specify this kind of invariant there.


No. Even if we stripped away all other code apart from the Haskell rts
itself (OS, device drivers etc) and performed your IO entirely in
Haskell (just using peek and poke on bare hardware), you'd still need
top level mutable state to implement common IO API's (e.g. The socket
API, does anybody really believe this is entirely stateless?).

I wouldn't dispute the assertion that at the level of complete programs
or processes, implementations that don't use global variables are
possible. But this does not hold at the level of individual IO library
API's. If we want to keep our software *modular* (I take we do), then
we need top level mutable state.


If you want to see more examples of the use of the unsafePerformIO
hack you need only look at the source code of the current base
package (you'll find a dozen or so uses of this hack to create
top level mutable state).


All of these are, in a sense, failings. Because unsafePerformIO is not 
haskell, and we'd like base to be a haskell library. Not a GHC library.


But what's the problem?
Is it the use of global variables?
Or is it the use of the unsafePerformIO hack to create them?

Regards
--
Adrian Hey

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


Re: [Haskell-cafe] global variables

2007-05-17 Thread Isaac Dupree
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Adrian Hey wrote:
 They are necessary because they are the only way to ensure important
 safety properties of many IO APIs.

 That's a bold claim. It's very hard to prove that things don't exist.
 (That is, that other ways to ensure these safety properties don't
 exist). In snipped text you comment that the problems are often in
 low-level FFI library code: this makes me wonder if the real culprit
 doesn't lie at the FFI-haskell boundary. Perhaps there are good ways
 to specify this kind of invariant there.
 
 No. Even if we stripped away all other code apart from the Haskell rts
 itself (OS, device drivers etc) and performed your IO entirely in
 Haskell (just using peek and poke on bare hardware), you'd still need
 top level mutable state to implement common IO API's (e.g. The socket
 API, does anybody really believe this is entirely stateless?).
 
 I wouldn't dispute the assertion that at the level of complete programs
 or processes, implementations that don't use global variables are
 possible. But this does not hold at the level of individual IO library
 API's. If we want to keep our software *modular* (I take we do), then
 we need top level mutable state.
 
 If you want to see more examples of the use of the unsafePerformIO
 hack you need only look at the source code of the current base
 package (you'll find a dozen or so uses of this hack to create
 top level mutable state).

 All of these are, in a sense, failings. Because unsafePerformIO is not
 haskell, and we'd like base to be a haskell library. Not a GHC library.
 
 But what's the problem?
 Is it the use of global variables?
 Or is it the use of the unsafePerformIO hack to create them?

It's only slightly the unsafePerformIO hack, IMHO - if that were all,
a mechanism not requiring it would have been implemented long ago.

Now I launch into a long discussion:

The difficult question is how global?. GHCi already has problems with
this (varying persistence of those global variables, and they never last
between separate invocations of ghci).  Obviously global variables to
truly be global should be shared with one persistent state across the
whole wide world forever :P - but then we get identity problems, e.g.
fancy-package:GlobalVariable.Fancy.nuclearMissilesLaunched :: IORef/MVar
MannerOfNuclearMissileLaunch
where one day or on one hacker's computer there is
type MannerOfNuclearMissileLaunch = Int --number launched already
and another,
data MannerOfNuclearMissileLaunch = NoMissilesLaunched | WorldDestroyed
| Unknown

The usual meaning relies on the size of a program invocation.  This is a
link to main:Main.main .  As you observe, this is like inserting a
wrapper over everywhere the IO monad is used.  Clearly this adds
modularity by not requiring main's code to be modified, and also
destroys modularity by forcing main's semantics to be modified.  A
Haskell program is notionally executed by running Main.main.  Consider:

 global foo (initial value: False)
 main1 = setGlobal foo True
 main2 = getGlobal foo = print

Compile with -main-is main1 to the binary 'main1' and with -main-is
main2 to the binary 'main2'.  Now consider two possible overall
definitions of main:

 main = main1  main2
or
 main = executeBinary main1  executeBinary main2

Basically, all existing operating systems require executing a binary to
be more than just running its IO monad; they set up a global
(process-specific) environment for the process, which is why the two
hypothetical example defintions of main give different results.

Note that operating systems also serve the root of filesystems / in
unix, and variables global to the root filesystem's sharedness can be
simulated in this way.  Operating systems could serve process-specific
spaces this way, as long as it is possible for them to define something
like getProcessID :: IO ProcessID.  Note that Haskell has ThreadID which
is usefully Eq-comparable in GHC, whereas Hugs chooses not to
distinguish the identity of threads.  It is a similar design tradeoff.


Hardware:
readHardware, writeHardware are IO specific to the hardware.
Kernels generally rely on storing information in RAM about the state of
the hardware, and they presume to have global variables whose scope is
the present run of the computer.  This is straightforward for monolithic
kernel designs.  Although, if you want persistent settings it is more
difficult, the system explicitly saving ALSA state to disk or whatever.

Operating systems:
I don't know sockets in particular, but indeed operating systems are
expected to provide some IO operations that don't do exactly the same
thing depending on which computer in the world the program is running on.

Kernel/OS design variation is certainly one area to look into for
further consideration of these issues.  There are non-monolithic kernels
(GNU Hurd...), systems that can run on multiple hardware-computers as a
cluster...

There is usually expected to be one name resolver (e.g. 

Re: [Haskell-cafe] global variables

2007-05-17 Thread Jules Bean

Adrian Hey wrote:

We've been talking about
this problem for years, but nothing is ever done about it (a solution to
this problem isn't even on the agenda for Haskell' AFIAK).


The problem needs talking about, it's important.

My objection was the implication that top-level mutable state was the 
right answer to the OP's question, which my strong hunch is it isn't. I 
don't deny the existence of a problem here.



No. Even if we stripped away all other code apart from the Haskell rts
itself (OS, device drivers etc) and performed your IO entirely in
Haskell (just using peek and poke on bare hardware), you'd still need
top level mutable state to implement common IO API's (e.g. The socket
API, does anybody really believe this is entirely stateless?).


I'm not sure that's quite to the point. Clearly we can set up state at 
the top of our main action:


main = do
  sockstate - initSocks
  graphstate - initGraphics
  ...
  disposeGraphics graphstate
  disposeSocks sockstate
  exit


Voila. Mutable state which persists for our entire program.

Arguably it's a pain passing around the state explicitly. Alternatively, 
you can argue that passing this stuff around explicitly makes code much 
easier to reason about. And we know a dozen tricks to hide this stuff 
(reader monads, state monads, withSocketsDo-style bracket constructs).


So I don't think this is really the issue, is it?

As I understood it, the issue was more about whether or not *library* 
modules should be allowed to some 'set up' initialisation code to run at 
the beginning of 'main' to start up their own global state. I was never 
convinced this was a nice idea (I don't like the thought than an 
'import' alone can add hidden IO actions to main). Mind you, I'm not 
convinced it's wrong, either. I think it's a hard one.



I wouldn't dispute the assertion that at the level of complete programs
or processes, implementations that don't use global variables are
possible. But this does not hold at the level of individual IO library
API's. If we want to keep our software *modular* (I take we do), then
we need top level mutable state.


That's assuming you feel having an explicit 'init' command and a 
'withLibXYZDo' construct breaks modularity. It doesn't feel like a 
terrible modularity break to me. (Plenty of C libraries I've used 
require explicit init calls).



Is it the use of global variables?
Or is it the use of the unsafePerformIO hack to create them?



The latter is definitely a problem.

The former, I'm not sure. My gut feeling is that it is, too.

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


Re: [Haskell-cafe] global variables

2007-05-17 Thread Adrian Hey

Albert Y. C. Lai wrote:
There is no reality about global variables. Global variables are 
syntactic sugar for local variables. That is the reality we need to 
think through. This syntactic sugar streamlines many practical programs 
and is indeed valuable.


I agree that the use of the term global variable is both inaccurate
an highly emotive, which is why I don't like it. But even the term
I use (top level mutable state) is not entirely accurate. The
mutable state is not at the top level, the mutable state is already
part of the world before main starts running.

What is top level are references to that state (IORefs, MVars etc).
As these are perfectly ordinary (I.E. *immutable*) Haskell values
there doesn't seem to be any obvious reason why they should not
exist at the top level. All that's missing is a semantically sound
mechanism to achieve this (such as the ACIO monad proposal).

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


Re: [Haskell-cafe] global variables

2007-05-17 Thread Jason Dagit

On 5/17/07, Adrian Hey [EMAIL PROTECTED] wrote:

Jules Bean wrote:
 BTW, this is the commonly the subject of flame wars on the Haskell
 mailing lists because there appear to be many who passionately believe
 and assert that so called global variables are (at best) unnecessary
 and (at worst) are evil. These people are quite simply wrong and
 should be ignored :-)

 Adrian Hey is not only wrong, but actually evil. He should be ignored. :-)

I am right, I might well be evil, and if past experience is anything to
go by I already know that I will be ignored. We've been talking about
this problem for years, but nothing is ever done about it (a solution to
this problem isn't even on the agenda for Haskell' AFIAK).

 The above hack is not actually Haskell. It's a hack, and it depends on
 the particular implementation characteristics of GHC. It is not
 unreasonable to imagine that a future GHC might contain different
 compilation techniques (I hesitate to use the word 'optimisations'
 because that sounds like something easy to turn off) which invalidate
 the technique in other ways or make it dangerous.

Well of course, that's why something needs to be done about this. Just
being in a state of complete denial regarding the reality of this
problem won't make it go away.

 They are necessary because they are the only way to ensure important
 safety properties of many IO APIs.

 That's a bold claim. It's very hard to prove that things don't exist.
 (That is, that other ways to ensure these safety properties don't
 exist). In snipped text you comment that the problems are often in
 low-level FFI library code: this makes me wonder if the real culprit
 doesn't lie at the FFI-haskell boundary. Perhaps there are good ways to
 specify this kind of invariant there.

No. Even if we stripped away all other code apart from the Haskell rts
itself (OS, device drivers etc) and performed your IO entirely in
Haskell (just using peek and poke on bare hardware), you'd still need
top level mutable state to implement common IO API's (e.g. The socket
API, does anybody really believe this is entirely stateless?).


At this point in the discussion I always think Haskell could probably
take a lesson from the evolution of object oriented programming.  As I
was taught, people starting to see modules as an important abstraction
(yay, Haskell has those).  Then people started to also realize that
instead of just modules it would be useful to have abstract data types
which could be instantiated many times and sort of encapsulate the
things (state) you might store in a module (yay, Haskell has ADTs).
Eventually, people put the two together, data types that also
encapsulated functionality.  Around this time, it was sort of like
having modules that could be instantiated many times instead of once
per program and objects were essentially born.

Well, it seems to me that Haskell modules are actually very similar to
singletons. Perhaps all these problems with modules having top level
mutable state could be solved if Haskell modules were parameterizable
at instantiation?  I'm not saying we should turn the Haskell module
system into an OO system, just that maybe it would be wise to borrow
some ideas from that paradigm.

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


Re: [Haskell-cafe] Global Variables and IO initializers

2004-11-09 Thread Malcolm Wallace
Benjamin Franksen [EMAIL PROTECTED] writes:

 We could reduce the pain of applying the C wrapper solution a bit by adding 
 some support in the FFI. I imagine a feature to allow writing small C 
 wrappers around imported foreign routines directly inside the Haskell
 module.

Such a facility is already available - the FFI pre-processor
`GreenCard' allows you to write in-line C code in your Haskell
module.

Regards,
Malcolm
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Global Variables and IO initializers

2004-11-09 Thread Keean Schupke

(stdin,stdout,stderr) seem to naturally have this scope (assuming you 
don't use freopen). There needs to be only one Handle created for each 
of these because otherwise the buffering won't work properly. Global 
- initializers seem like the right thing here.

I think I would rather have them passed to 'main' as arguments...
Afterall, what if somone calls hClose on one? The fact that a function
may fail (on a closed handle) due to an action taken in another function
(closing the handle) is not nice... Passing the handles explicitly might
make things more obvious. A more functional way would be to reference
count the handle, and only really close it then the last reference is closed
or goes out of scope. I guess you wouldn't want a huge number of arguments
to main, so a record would let you have all the 'environment' in one 
variable.

Are there any others?
The fact that the concept of 'one program' is artificial (created by the
loading process used by the OS), it would suggest that OS variables
associated with the process (IE process-ID, or anything stored in the
OS's process-table may have a natural lifetime of one process - although
these days most of these things tend to be associated with threads
instead (thread-id etc...) and many threads can start and end in the
life of a program.
I cannot think of any library that could not be written in a multiple
reference way - if it wasn't dependant on some legacy code. Even a
library to manage a single physical piece of hardware (say a special
encryption chip) would be better written allowing more than one
chip to be supported - even if current hardware does not allow this -
some future system might, and you don't want to have to change
the software-architecture because of this... Far better to allow
multiple threads to independantly open multiple devices - and limit
the number of devices to 1 for now. In this case the OS would need
to manage the device-counter.
A nice way to do this would be to use the FFI to get the operating
system to manage this. You could use an OS semaphore or a
unix-socket. If you use the PID as part of the socket name, then
only the first call to open-socket would succeed.
This suggests that a nice library to make this sort of thing easy
would be a 'namedChannel' library, where read and write
ends of a channel could be opened independantly and the address
would be an arbitrary string.
   Keean.
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Global Variables and IO initializers

2004-11-08 Thread Ben Rudiak-Gould
I think the broad issue is that there are many different levels of the 
system at which something can be global: a module, a thread, a process, 
a user, a computer, a network segment, the internet, the universe, etc.. 
If your model of a concept is more global than the concept itself, you 
lose flexibility. If your model is less global than the concept, you get 
cache-coherency problems.

The global variables we're talking about here are global to a single 
invocation of a Haskell program [*] [**]. The only concepts which are 
appropriately modeled by such globals are those whose natural scope is a 
single invocation of a Haskell program. Are there any?

Adrian Hey's example of a badly-written C library is one. But I agree 
with Robert Dockins that such cases are better solved in C than in Haskell.

(stdin,stdout,stderr) seem to naturally have this scope (assuming you 
don't use freopen). There needs to be only one Handle created for each 
of these because otherwise the buffering won't work properly. Global - 
initializers seem like the right thing here.

Are there any others?
-- Ben
[*] Adrian Hey has argued that global variables aren't really global. 
I think he's talking about hiding them through module scoping. What I 
mean by global is different: something is global at a particular level 
of the system if there's only one instance of it at that level.

[**] Wouldn't it make sense to support thread-local global state also, 
if we're going to support process-local global state?

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Global Variables and =?utf-8?q?IO=09initializers?=

2004-11-08 Thread Benjamin Franksen
On Tuesday 09 November 2004 03:18, Ben Rudiak-Gould wrote:
 Adrian Hey's example of a badly-written C library is one. But I agree
 with Robert Dockins that such cases are better solved in C than in Haskell.

Yes. Your code won't depend on compiler (dependent) flags to disable 
optimizations, which for my taste is just a little bit too obscure and is 
anyway non-portable.

What follows are very raw ideas. Please bear with me if you think it is 
nonsense.

We could reduce the pain of applying the C wrapper solution a bit by adding 
some support in the FFI. I imagine a feature to allow writing small C 
wrappers around imported foreign routines directly inside the Haskell module. 
Such code would need to be quoted properly (e.g. encoded as Haskell string, 
similar to the foreign entity names now). Eiffel has such a feature for its 
own variant of FFI and it has proven quite useful in practice.

I know of at least one other case where such a feature might be helpful, 
namely for APIs where C structures get passed by value. At the moment one has 
to either lie to the FFI (declare the routine as if teh structure fields were 
passed separately, after checking that this is ok with respect to argument 
order and alignment) or else write a C wrapper routine (which is somewhat 
safer and more portable).

The advantage of doing it through FFI support is that we avoid encouraging bad 
programming style by making global mutable variables an all too easily 
accessible and apparently safe feature.


I have some ideas how to handle stdxyz without using global state but they are 
not though out and it is too late now anyway.

Ben
-- 
Top level things with identity are evil.-- Lennart Augustsson
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe