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

2004-11-08 Thread Lennart Augustsson
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 a global variable.
I incredibly suspicious about code that needs it.  Having a global
variable almost always you have a single copy of some data structure;
there is no way to create two of them.  I claim that the right way
is to have a handle to your object and pass that around.  (But I
can also be persuaded that there might be exceptions.  (I've written
a few lines of Haskell and I have used a global variable once, I
think.))
-- Lennart
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


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

2004-11-08 Thread Lennart Augustsson
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.  Of course you need some state
associated with the handle, but that state does not
have to be a unique global things.  You are passing
that state around via the IO monad, and there could
be multiple versions of it.  GHC chooses to implement
it differently, but that's a choice.
-- Lennart
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


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

2004-11-08 Thread Lennart Augustsson
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 real world
example of why this is necessary then. Even your
example of real world hardware that must be
initialised once fails! (What if I start two copies
of the program?)
Indeed.  With hardware the solution is to do
hdl - openDevice
which will succeed the first time and then return
busy until closed.  Any access to the device must
use the hdl.  Trying to do without the handle is just
shooting yourself in the foot.  It might look good at
first, but it doesn't scale.
-- Lennart
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


RE: [Haskell-cafe] Making MVar and Chan Instances of Typeable

2004-11-08 Thread Simon Peyton-Jones
 
| instance Typeable a = Typeable (MVar a) where
|   typeOf x =
| mkAppTy (mkTyCon Control.Concurrent.MVar.MVar) [typeOf
(undefined::a)]

As I think you now know, the above declaration is fine if you use
-fglasgow-exts.  Haskell 98 does not support lexically scoped type
variables, but GHC -fglasgow-exts does.  You can read about it in the
GHC user manual.  

Type variables are bound by instance declarations, as above, but you can
also bind them in patterns.  So as others have said an alternative is

| instance Typeable a = Typeable (MVar a) where
|   typeOf (x::MVar b) =
| mkAppTy (mkTyCon Control.Concurrent.MVar.MVar) [typeOf
(undefined::b)]

But that's not legal in Haskell 98 either, and since 'a' is already in
scope with -fglasgow-exts, the extra binding for 'b' seems less nice.

The best Haskell 98 solution is the one Remi gives:

instance Typeable a = Typeable (MVar a) where
typeOf v= mkAppTy (mkTyCon Control.Concurrent.MVar.MVar)
[typeOf (t v)]
where
t   :: a b - b
t   = undefined

Simon

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


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

2004-11-08 Thread Jules Bean
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 Int.  So stdin is no more a global
variable than 0.  Of course you need some state
associated with the handle, but that state does not
have to be a unique global things.  You are passing
that state around via the IO monad, and there could
be multiple versions of it.  GHC chooses to implement
it differently, but that's a choice.
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...

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


Re: [Haskell-cafe] Dynamic Type Contruction

2004-11-08 Thread Ralf Laemmel
Vitor,
That's amazing!!! Your question is very timely! :-)
You know ... someone just challenged me with this question,
and I added the corresponding function to the boilerplate testsuite.
However, it is much more typeful than you propose.
I call it the typeful reflection benchmark.
http://www.cs.vu.nl/boilerplate/#suite
http://www.cs.vu.nl/boilerplate/testsuite/getC.hs
So you actually can write isC Circle some term.
No string encoding!
No possible confusion of different term types.
Ralf
Oops: I leave it as an exercise to implement this boilerplate pearl in 
Strafunski :-)

Vitor Rodrigues wrote:
I'm trying to create a library to querying XML data using Strafunski. 
I'm also using DrIFT to generate the instances of Typeable and Term of 
my Datatypes to be used inside Strafunski.
 
Supose i've this datatypes:
 
data Shape = Circle Float (Float,Float) | Triangle (Float, Float) 
(Float, Float) (Float, Float)
 
then DrIFT, among other things, creates the functions:
 
isCircle (Circle _ _ ) = True
isCircle _ = False
isTriangle (Triangle _ _ _) = True
isTriangle _ = False
 
what i'd like to have is as a generic isFoo function, with the type:
 
is :: String - DataType - Bool
 
that when running will act like this:
 
is Circle (Circle 3.4 (3.0,3.1)) = True
is Triangle (Circle 3.4 (3.0,3.1)) = False
is Circle 2 = False
 
I was looking on TyCon constructor and mkTyCon function, but i didn't 
understood it well.
Can anyone tell me how can i create this is Foo function?
 
I was thinking about create a dynamic type with mkTyCon and then see 
if it matches with the DataType receiveid as function parameter.
 
Regards,
Vitor Rodrigues
 


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


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


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

2004-11-08 Thread Keith Wansbrough
[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 style, or whatever..
 
 Please show me a concrete alternative in real Haskell code, other

I'm mystified as to why you are insisting others provide real examples when you 
are not.  Can you give one concrete example of an intended application of 
oneShot, so that we can either propose a concrete Haskell implementation of 
it, or agree that global variables really are necessary.

Hoping to increase the light / heat ratio in this discussion...

Cheers,

--KW 8-)

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


[Haskell-cafe] Currying and errors

2004-11-08 Thread Graham Klyne
I just found myself writing a function that looked like this:
 isSubsumedByWith  :: TBox c - c - c - Bool
 isSubsumedByWith [] c d = isALSubsumedBy c d
 isSubsumedByWith _  _ _ = error TBox reasoning not supported for AL
and immediately noticed that I might also write this:
 isSubsumedByWith  :: TBox c - c - c - Bool
 isSubsumedByWith [] = isALSubsumedBy
 isSubsumedByWith _  = error TBox reasoning not supported for AL
which led me to thinking about the difference between these two functions 
(I reason there must be a difference, because the call of 'error' is 
required to fulfil (terminology?) values of different types).

I think it is this:  Suppose I evaluate an expression:
   let s = isSubsumedByWith [foo] in seq s e
then I think the first case will return a legitimate function, albeit one 
that returns error when it is applied, and the second will cause an error 
to be returned immediately.  Am I right?  Is this all?

#g

Graham Klyne
For email:
http://www.ninebynine.org/#Contact
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] FiniteMap-like module for unordered keys?

2004-11-08 Thread Graham Klyne
Is there a module that provides functionality similar to that of 
Data.FiniteMap for keys that do not have a defined ordering relation?

(I looked at Data.HashTable, but I couldn't figure why it needs to be 
implemented in the IO monad, except to optimize the internal 
implementation.  Also, it's not clear to me how it behaves when a key is 
inserted that already exists.)

#g

Graham Klyne
For email:
http://www.ninebynine.org/#Contact
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


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

2004-11-08 Thread Adrian Hey
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 arguments about this kind of thing
  being unnecessary, bad programming style, or whatever..
 
  Please show me a concrete alternative in real Haskell code, other

 I'm mystified as to why you are insisting others provide real examples when
 you are not.

Maybe you should read the whole thread. AFAIK I am the only person who
has provided a concrete example of anything, and I did so in direct response
to a request to do so from Keaan IIRC.

Unfortunately my own requests for counter examples showing that there are
safer (easier, more elegant or whatever) solutions have been ignored (not
that I'm in the least bit surprised by this). Instead all I get is repeated 
denial of the reality of this problem.

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 application
 of oneShot, so that we can either propose a concrete Haskell
 implementation of it, or agree that global variables really are necessary.

Any C library which requires an explicit initialisation call before anything
in that library can be used (common enough IME). Accidental re-initialisation
(e.g. by two independent modules/libraries) will destroy any state currently
be used by the libraries existing clients.

The need to do this may or may not indicate bad design on the part of the
library author. But so what? It just happens to be a fact that must be dealt
with from Haskell (in a safe manner preferably).

Regards
--
Adrian Hey

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


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

2004-11-08 Thread Keean Schupke
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 copies of
the executable at once... or wven sequentially!
Keean.
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


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

2004-11-08 Thread Keith Wansbrough
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 application
  of oneShot, so that we can either propose a concrete Haskell
  implementation of it, or agree that global variables really are necessary.
 
 Any C library which requires an explicit initialisation call before anything
 in that library can be used (common enough IME). Accidental re-initialisation
 (e.g. by two independent modules/libraries) will destroy any state currently
 be used by the libraries existing clients.

Great, thanks, that's just what I was hoping for - I now see the
problem you're trying to address.

--KW 8-)

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


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

2004-11-08 Thread Robert Dockins
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 variable:

void doInit()
{
static int doneInit = 0;
if( !doneInit ) {
   reallyInit();
   doneInit = 1;
}
}
Then your haskell libs can call doInit any number of times, and
reallyInit will be called at most once.
Since your committed to FFI anyway (calling a C lib is the premise), the 
wrapper seems a small price to pay.  For Haskell-only code, something 
else would be nice.

Keith Wansbrough wrote:
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 application
of oneShot, so that we can either propose a concrete Haskell
implementation of it, or agree that global variables really are necessary.
Any C library which requires an explicit initialisation call before anything
in that library can be used (common enough IME). Accidental re-initialisation
(e.g. by two independent modules/libraries) will destroy any state currently
be used by the libraries existing clients.

Great, thanks, that's just what I was hoping for - I now see the
problem you're trying to address.
--KW 8-)
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Currying and errors

2004-11-08 Thread Marcin 'Qrczak' Kowalczyk
Graham Klyne [EMAIL PROTECTED] writes:

   isSubsumedByWith  :: TBox c - c - c - Bool
   isSubsumedByWith [] c d = isALSubsumedBy c d
   isSubsumedByWith _  _ _ = error TBox reasoning not supported for AL

 and immediately noticed that I might also write this:

   isSubsumedByWith  :: TBox c - c - c - Bool
   isSubsumedByWith [] = isALSubsumedBy
   isSubsumedByWith _  = error TBox reasoning not supported for AL

A difference is that you can generally assume that:

   let x = isSubsumedByWith [] 0 in
   x 0  x 1

will evaluate 'isALSubsumedBy 0' only once, so if it has some work to
do before waiting for the second argument, the work will be shared for
both arguments. They will give the same result anyway, but may need
different amounts of work to do.

OTOH if isALSubsumedBy does not have any shared the work to do, but is
itself defined with two arguments, then applying it to both arguments
at once is more efficient (has less overhead). Manually lifting a
partial application is valuable only when we expect that it shares
some real work.

An optimizing compiler can change the effect it in either direction.
The above is not a formal guarantee, only some expectation which might
be useful for tuning performance.

 I think it is this:  Suppose I evaluate an expression:

 let s = isSubsumedByWith [foo] in seq s e

 then I think the first case will return a legitimate function, albeit
 one that returns error when it is applied, and the second will cause
 an error to be returned immediately.  Am I right?

Yes. And this time an optimizing compiler can't exchange that. While
program termination is a part of the language semantics, the amount
of recomputation and sharing is not formally specified, and you can at
most hope that the compiler would do no worse than the obvious naive
implementation would do (i.e. that its optimizations will not become
pessimizations).

-- 
   __( Marcin Kowalczyk
   \__/   [EMAIL PROTECTED]
^^ http://qrnik.knm.org.pl/~qrczak/
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] IO and State (was Re: [Haskell] Re: Global Variables and IO initializers)

2004-11-08 Thread Iavor S. Diatchki
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:

   type IO = ST RealWorld
   type IORef a = Ref RealWorld a
   type STRef s a = Ref s a
   


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 state.
On the other hand, the state of the RealWorld can change on its own,
without anything in the program affecting it.
I guess this is similar to volatile state in C.
For example, one might expect the following rule in a state monad:

do x - readSTRef r
y - readSTRef r
f x y
=
do x - readSTRef r
f x x
But this is not true for the IO monad, as for example reading a file 
twice does not guarantee
that you will get the same result, even if no part of the program ever 
wrote to the file.

Now the above law already doesn't hold when all GHC extensions are used,
as when concurrency is present we cannot assume that nobody modified the 
state concurrently.
As a result all pointers in GHC probably behave as if they were 
volatile, which is not very nice.

I think that inherently there are two concepts here, and I see no point 
in mixing them
(even though they are already a bit mixed up, because of stToIO).
The one is the usual sequential state that we know and love (and I think 
we use that a lot of the time).
In the sequential state the above optimization is one of the laws 
specifying the monad.
The other concept is that of volatile or concurrent state, and then 
the law doesn't hold.

The two monads have a very similar inetrafce (reading and wrinting 
pointers, and creating new pointers)
but the laws that the operations satisfy are different.

-Iavor




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


[Haskell-cafe] Hal Daume III's NewBinary now ghc6ized, cabalized, debianize, darcsized.

2004-11-08 Thread Jeremy Shaw
Hello,

I am quite interested in having better Binary support in Haskell --
especially support for reading and writing binary files and protocols
that have fields smaller than 8-bits and non-byte alignment.

As a first step, I have republished Hal Daume III's NewBinary package
in hopes that it will inspire some forward movement on it. I have made
the following 'improvements':

 ~ ghc6ized

cd /tmp/NewBinary/
diff  /tmp/Binary.hs /tmp/NewBinary/NewBinary/Binary.hs
81c81,82
 import GHC.Handle ( openFileEx, IOModeEx(..) )
---
 import GHC.Handle 
 import IOExts ( openFileEx, IOModeEx(..) )

(hrm, I probably don't need to import GHC.Handle anymore either...)

 ~ cabalized

To build, you need the Cabal libraries installed. Then do something
like this:

ghc -package Setup.lhs -o setup
./setup configure
./setup build
./setup install
./setup register (? maybe not needed ?)

 ~ debianized

You should be able to build and install it like any other debian
package:

dpkg-buildpackage  debi 

 ~ darcsized

darcs get http://www.n-heptane.com/nhlab/repos/NewBinary

I hope I am not stepping on anyone's toes or duplicating efforts.

Jeremy Shaw.

ps. The original is available at:

http://www.isi.edu/~hdaume/haskell/NewBinary/
--

This message contains information which may be confidential and privileged. 
Unless you are the 
addressee (or authorized to receive for the addressee), you may not use, copy 
or disclose to anyone 
the message or any information contained in the message. If you have received 
the message in error, 
please advise the sender and delete the message.  Thank you.
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


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

2004-11-08 Thread Keean Schupke
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 
extreemly
hard) to write such librarys. Haskell libraries tend to allow multiple
concurrent independent threads of access. Allowing global vars into
Haskell would make it easy for coders moving to Haskell from C to carry
on coding in a bad style. It seems correcting the problem outside of
Haskell and in C is the right approach - as it does not involve making
these 'bad' things easier to do in Haskell.

Keean.
Keean Schupke wrote:

Any C library which requires an explicit initialisation call before 
anything
in that library can be used (common enough IME). Accidental 
re-initialisation
(e.g. by two independent modules/libraries) will destroy any state 
currently
be used by the libraries existing clients.

The need to do this may or may not indicate bad design on the part 
of the
library author. But so what? It just happens to be a fact that must 
be dealt
with from Haskell (in a safe manner preferably).
 

You are right, the C library that works like this is bad design...
any library should really be reentrant, an preferably state free.
An example of a well designed C library is the ODBC database
connection library, where all the state is stored in opaque
handles returned to the user.
For 'broken' libraries that cannot support multiple simultaneous
contexts, it would be better to use the 'C' FFI based solution
suggested by another poster. Ideally you would want to find
a library with a better interface - If you tell me the library you
wish to use I may be able to suggest a better alternative.
   Keean.
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe

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


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

2004-11-08 Thread Adrian Hey
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 *very*, *very* few times you need a global variable.

*very*, *very* few times is not the same as never.

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


Re: [Haskell-cafe] Re: [Haskell] Re: Global Variables and =?iso-8859-1?q?IO initializers?=

2004-11-08 Thread Adrian Hey
On Monday 08 Nov 2004 10:37 am, 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 real world
 example of why this is necessary then.

Because it is irrelevant, unless you think I'm lying.
It is suffices merely to state the problem.

If you want an answer see my reply to Keith.

Regards
--
Adrian Hey


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


Re: [Haskell-cafe] Re: [Haskell] Re: Global Variables =?iso-8859-1?q?and IO initializers?=

2004-11-08 Thread Adrian Hey
On Monday 08 Nov 2004 12:26 pm, Lennart Augustsson wrote:
 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 real world
  example of why this is necessary then. Even your
  example of real world hardware that must be
  initialised once fails! (What if I start two copies
  of the program?)

 Indeed.  With hardware the solution is to do
   hdl - openDevice
 which will succeed the first time and then return
 busy until closed.

How will it know it's busy? Please show me the
code for your hypothetical openDevice.

Regards
--
Adrian Hey

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


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

2004-11-08 Thread Peter Simons
Adrian Hey writes:

  I don't see any value in problems that are
  specifically designed so that they can be solved
  only with a global entity.

  Even if it was true that I had specifically
  designed this problem, it's existance is of some
  interest I think.

Perhaps my choice of words wasn't really good. I am
sorry. What I meant to say is that I have never once
_needed_ a global variable yet. Never. On the other
hand, there were plenty of occasions where I had
trouble with global variables in other people's code.
I'll readily admit that a safe way to implement them in
Haskell is probably an interesting research subject,
but I honestly don't expect to be using that feature
any time soon. It's a completely abstract concept for
me; I associate no practical value with it.


  [Creating top level things with identity is] what
  many in this thread assert is bad code, yourself
  included it seems. Yet this is widely used in many
  programs and libraries, even in ghc itself I
  believe. Not to mention stdin etc.. (again).

Right, but it is by no means _necessary_ to have a
global 'stdin'. It could equally well be defined as

  stdin :: IO Handle

and it would work just the same. The fact that it isn't
implemented this way is for historical reasons, IMHO,
not because it's a good idea.


  Because code like that is very hard to get right
  and very hard to maintain, and I don't want to use
  library code that uses this technique if I can
  avoid it.

  This is dogma I think.

Yes, you are right. Nonetheless, it is a dogma that's
not just arbitrary; it is motivated by experience with
real-life code. Just ask the C++ folks about the
wonders of global variables that are actually complex
classes with a constructor and a destructor. You
wouldn't believe through what kind of hoops you have to
jump if you want to write reliable code that has to
deal with this. For instance: Where do you catch
exceptions a constructor throws that is executed before
your main() routine is? How do you deal with exceptions
that are thrown after your main routine has _ended_?

The effect is that the language is full of strange and
very counter-intuitive mechanisms, just so that they
can implement something which -- in _my_ opinion -- is
completely useless to begin with!


  There are many libraries you will need to try to
  avoid using if this is really your position.

Let's say ... I try to compromise rarely, but I do have
to compromise, unfortunately. In fact, I have to admit
that my own Haskell code contains unsafePerformIO at
the occasion, too. Not that I'd need it, but I am too
damn lazy as well. :-)

Peter

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


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

2004-11-08 Thread jeff
Quoting Peter Simons [EMAIL PROTECTED]:

 Just ask the C++ folks about the
 wonders of global variables that are actually complex
 classes with a constructor and a destructor.

You can't use that as an argument against global variables
in other languages.

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


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

2004-11-08 Thread Keean Schupke
Yes I didn't read your specification accurately... However I would argue
such a constraint on the problem domain is artificial as operating 
systems exist.
At the end of the day it is the job of the OS to manage such one-shot 
hardware
inits, not application code. (As the OS is the only thing that can 
manage resources
accross multiple programs)...

What did you think of the code example given where the one-shot nature is
provided by a 'C' wrapper around the FFI function. I think this is the best
solution...
   Keean.
Adrian Hey wrote:
On Monday 08 Nov 2004 6:48 pm, Keean Schupke wrote:
 

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 copies of
the executable at once... or wven sequentially!
   

Read what I wrote :-)
Regards
--
Adrian Hey
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe
 

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


RE: [Haskell-cafe] Re: Processing of large files

2004-11-08 Thread Simon Marlow

John Goerzen writes:
 
 Yes it does.  If you don't set block buffering, GHC will call 
 read() separately for *every* single character.  (I've 
 straced stuff!)  This is a huge performance penalty for large 
 files.  It's a lot more efficient if you set block buffering 
 in your input, even if you are using interact and lines or 
 words to process it.

That shouldn't be the case.  GHC's IO library checks whether a Handle
refers to a TTY, and enables line buffering if it does.  Otherwise,
block buffering is the default.

Could you isolate the test case and submit a bug report?

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


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

2004-11-08 Thread jeff
Quoting Peter Simons [EMAIL PROTECTED]:

 jeff  writes:

   Just ask the C++ folks about the wonders of global
   variables that are actually complex classes with a
   constructor and a destructor.

   You can't use that as an argument against global
   variables in other languages.

 Why not?

So what if there are problems with globals that are actually
complex classes etc in C++?

Why should that matter to anyone using any other language?

 Does the creation of global variables never fail in
 Haskell?

That's a different argument, not based on C++.

 Besides, my main point is that they are
 _unnecessary_ in my experience,

Ok, but that's again not the C++ argument (which was all that
I was addressing).

-- Jeff
___
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


Re: [Haskell-cafe] Re: [Haskell] Re: Global Variables and whatever

2004-11-08 Thread Adrian Hey
On Monday 08 Nov 2004 9:53 pm, Keean Schupke wrote:
 What did you think of the code example given where the one-shot nature is
 provided by a 'C' wrapper around the FFI function. I think this is the best
 solution...

As a pragmatic solution to this (and only this) particular problem it's OK.

But let's not pretend the real problem has gone way (or just doesn't exist)
as a result of this. There are many reasons why people might need top-level
TWIs. You asked for a simple example and I provided one, that's all.

Also note that Roberts solution still requires the use of a top level
mutable variable. I take it the position of those who object to such
things is not..

 Top level mutable variables are a very very bad thing and
  should never ever be used (Errm..well unless they're really
  necessary, in which case you should use C).

Now that would be strange. I would call that militant denial.

As a side note (not specifically directed at you) I would also
like folk to take note that the mutable variable used in Roberts
solution is top level, but is NOT global.

As I have observed in an earlier post, the thread title
chosen by the OP is a rather unfortunate choice of words IMO.
I wish people stop talking about global variables. Nobody is
advocating the use of global mutable variables. I sure hope I'm
not going to have to repeat this (yet again!).

Actually, I know I'm not going to have to repeat this yet again
because I'm going to make this is my last post on this thread.

Regards
--
Adrian Hey

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