[Haskell-cafe] Re: [Haskell] Re: Global Variables and IO initializers
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
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
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
| 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
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
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
[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
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?
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
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
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
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
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
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)
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.
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
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
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?=
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?=
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
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
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?=
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
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
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
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?=
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
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