> As for the subject under discussion (thread local state), I am > personally sceptical about it. Why do we need it? Are we talking > about safety or just convenience/API elegance? I've never > encountered a situation where I've needed thread local state, > (but this does not necessarily make it evil:-)
OK. What if all Haskell processes, all over the world, were made into threads in the same large process? There are a lot of things that are currently "global" state - as in, process-global - which would have to become non-global in some way - pretty much all interaction with the world: file IO, networking, command line arguments, system environment, etc. You, Einar, and others seem to be arguing that the only way to make these things non-global should be to either make them explicit arguments to functions, or to have them appear explicitly in the type of the application's primary monad. For instance, this simple program: main :: IO () main = do putStrLn "Hello world" might, in Adrian Hey and Einar Karttunen's world, become: newMain host environment program_args network_config locale terminal_settings stdin stdout stderr = do hPutStrLn stdout (defaultEncoding locale) "Hello world" Now, some people might find this second version delightfully explicit, but I'd have doubts about whether such people are actually trying to get things done, or whether they see the language as an end in itself. As for me, I prefer the first version - it saves reading and typing, and is perfectly clear, and I have work to do. Maybe I'm misunderstanding your position - maybe you think that I should use lots of different processes to segregate global state into separate contexts? Well, that's nice, but I'd rather not. For instance, I'm writing a server - and it's just not efficient to use a separate process for each request. And there are some things such as database connections, current user id, log files, various profiling data, etc., that I would like to be thread-global but not process-global. Or maybe you think that certain types of global state should be privileged - for instance, that all of the things which are arguments to 'newMain' above are OK to have as global state, but that anything else should be passed as function arguments, thus making thread-localization moot. I disagree with this - I am a proponent of extensibility, and think that the language should make as few things as possible "built-in". I want to define my own application-specific global state, and, additionally, I want to have it thread-global, not process-global. You asked for an example, but, because of the nature of this topic, it would have to be a very large example to prove my point. Thread-local variables are things that only become really useful in large programs. Instead, I've asked you to put yourself in my shoes - what if the bits of context that you already take for granted in your programs had to be thread-local? How would you cope, without thread-local variables, in such a situation? > But I would say that I think I would find having to know what thread > a particular bit of code was running in in order to "grok it" very > strange, I agree that it is important to have code which is easy to understand. Usually, functions run in the same thread as their caller, unless they are passed to something with the word 'fork' in the name. That's a good rule of thumb that is in fact sufficient to let you understand the code I write. Also, if that's too much to remember, then since I'm only proposing and using non-mutable thread-local state (i.e. it behaves like a MonadReader), and since I'm not passing actions between threads as Einar is, then you can forget about the 'fork' caveat. I think the code would in fact be more difficult to "grok", if all of the things which I want to be thread-local were instead passed around as parameters, a la 'newMain'. This is simply because, in that scenario, there would much more code to read, and it would be very repetitive. If I used special monads for my state, then the situation would be only slightly better - a single monad would not suffice, and I'd be faced with a plethora of 'lift' functions and redefinitions of 'catch', as well as long type signatures and a crowded namespace. > unless there was some obvious technical reason why the > thread local state needed to be thread local (can't think of any > such reason right now). Some things are not immediately obvious. If you don't like to think of reasons, then just take my word for it that it would help me. A facility for thread-local variables would be just another of many facilities that programmers could choose from when designing their code. I'm not asking you to change the way you program - I don't care how other people program. I trust them to know what is best for their particular application. It's none of my business, anyway. Since Simon Marlow said that he had been considering a thread-local variable facility, I merely wanted to voice my support: http://www.mail-archive.com/haskell@haskell.org/msg18398.html It seems that there are enough resources to implement one. The discussion should not be about "do we allow this" but rather "what should the API be". Frederik -- http://ofb.net/~frederik/ _______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell