Re: [Haskell-cafe] Deriving class instances using DrIFT

2006-10-30 Thread Einar Karttunen
On 29.10 19:56, John Meacham wrote:
 Since DrIFT can only understand haskell source code, it can't derive
 instances for anything you don't have the original source to. such as
 things in the pre-compiled libraries that come with ghc. you will likely
 have to write out those instances by hand. 
 
 Another possibility is that you could replicate just the data
 declarations by hand, and use DrIFT -r to just spit out the derivations
 and put those in a file on their own.

How about using Template Haskell for getting the definition and then
giving that to DrIFT?

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


Re: ghc-6.6 candidate Win32 installer

2006-10-14 Thread Einar Karttunen
On 14.10 10:20, Ross Paterson wrote:
 On Fri, Oct 13, 2006 at 04:05:49PM -0700, Sigbjorn Finne wrote:
  Afraid I have to disappoint you (again :-( ) wrt OpenAL/ALUT. A bit
  too late, but _if_ there's a wider agreement that including a
  package such as this would be generally useful, I'd be happy to
  do something about it the next time around.
  
  cabal-get + hackage.haskell.org really ought to be the distribution
  channel for not-quite(-yet?)-mainstream packages though.
 
 That would be fine for pure Haskell packages (when hackage is ready),
 but Cabal can't handle packages that require non-trivial configuration
 (like OpenAL and ALUT) on Windows without MSYS.

If people are interested I have NSIS scripts that make it trivial to
create windows binary installers for many Haskell packages (for GHC).

I would be interested in creating a repository of windows binary
packages but I lack the space for hosting such a thing.

- Einar Karttunen
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: [Haskell-cafe] source code for haskell web server?

2006-09-28 Thread Einar Karttunen
On 27.09 13:03, Pasqualino 'Titto' Assini wrote:
 There is also the HAppS application server and the HaskellNet library.
 
 Would not be possible to merge the protocol-handling parts of all these
 libraries into a generic Internet Haskell server that could then be expanded
 to support CGIs, transactions, etc.?


It would be very nice to have a common format.

Historically HAppS has used ByteStrings in HTTP, while most other
libraries have used Strings.

The HAppS format is:
http://happs.org/auto/apidoc/HAppS-Protocols-HTTP-LowLevel.html#t%3ARequest

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


[Haskell-cafe] Re: [Haskell] BitSyntax for Haskell

2006-09-28 Thread Einar Karttunen
On 26.09 10:01, Adam Langley wrote:
 For the decoding part:
 * Provide a monadic interface
 
 Are you suggesting a monad to pass in the input around, or that it
 returns mzero on error? The latter makes more sense to me.

Yes. Also make it possible for user supplied functions to fail
in better ways than to produce Either or use error.

 * Add a test part to ReadType:
 Test :: ReadType a - (a - Bool) - ReadType Test
 (or a - m ()) in the monadic case.
 
 Again, I'm not clear what you are thinking of here?

In some protocols I am using there are some fixed bytes
which I want to ignore (no Haskell value produced), but
check that they are valid in the data stream.

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


[Haskell-cafe] Eager global IO actions (per module initialization)

2006-09-28 Thread Einar Karttunen
Hello

I am needing a way to run initializers defined in various modules 
in an eager fashion before main. I am doing this to load
deserialization functions for a Typeable function.

Basically I have code like:

$(inferDecoderAndRegisterItOnStartup ''MyType)

which defines a class instance, but additionally I want to
call 'registerDecoderForType MyType decodeMyType' automatically
on startup.

Calling registerDecodeForType for all types in main gets very tedious
and error-prone when doing things by hand. Thus an automated solution
would be very nice.

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


Re: [Haskell-cafe] source code for haskell web server?

2006-09-28 Thread Einar Karttunen
On 28.09 15:33, Bulat Ziganshin wrote:
 Hello Einar,
 
 Thursday, September 28, 2006, 1:25:55 PM, you wrote:
 
  Historically HAppS has used ByteStrings in HTTP, while most other
  libraries have used Strings.
 
 why not use StringLike class here? you can find implementation at
 darcs get --partial http://darcs.haskell.org/SoC/fps-soc/

http://darcs.haskell.org/SoC/fps-soc/Data/Stringable.hs ?

1) Because it didn't exist at the time
2) Lots of code would need even more type parameters
3) Would still need specialize pragmas to get acceptable performance
4) No easy way of adding ByteStrings without unpacking first which is slow
5) One can already easily write functions that handle setting anything
string-like as the body.

But moving from [ByteString] into a lazy ByteString makes sense.

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


[Haskell] ANN: HAppS version 0.8.2

2006-09-25 Thread Einar Karttunen
We are pleased to announce HAppS -- Haskell Application Server version 0.8.2.

HAppS is a Haskell web application server for building industrial strength
Internet applications safely, quickly, and easily. With HAppS you focus
entirely on application functionality implemented in your favorite language
and you don't have to worry about making sure all sorts of server subsystems
are functioning properly.

This release has the following highlights:

* Switch to BSD3 license.
* Support for new ByteString.
* Support GHC 6.6 (using the HAppS.cabal.ghc66)
* Good support for cookies.
* Revise HAppS.DNS and make it easier to access from the outside.
* Much faster URI parsing.
* Many internal changes to HTTP and Saver implementations.
* Add new examples: cookie, dns, http.

HAppS can be obtained from http://happs.org/ or directly from:

* http://happs.org/auto/HAppS-0.8.2.tar.gz
* darcs get --partial --tag=HAppS-0.8.2  http://happs.org/HAppS


Einar Karttunen, Alex Jacobson, David Himmelstrup
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


[Haskell-cafe] Re: [Haskell] BitSyntax for Haskell

2006-09-25 Thread Einar Karttunen
On 23.09 15:00, Adam Langley wrote:
 Erlang's bit syntax[1] is a great for building and breaking up binary
 structures. I've knocked up something similar (although a little
 clumsy) for Haskell:
 
 http://www.imperialviolet.org/binary/bitsyntax/
 http://www.imperialviolet.org/binary/bitsyntax/BitSyntax.hs
 
 I'm sure that this isn't the best possible way to do this, but it
 suffices at this stage for many problems.

This looks very nice.

Here are some feature wishes:

BitBlock: add a way to encode length prefixed ByteStrings.

For the decoding part:
* Provide a monadic interface
* Add a test part to ReadType: 
Test :: ReadType a - (a - Bool) - ReadType Test
(or a - m ()) in the monadic case.
* Add a way to limit the size of a LengthPrefixed:
e.g. [Unsigned 4, LengthPrefixed] is very unsafe, the app should
have a way to control the maximum length.

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


Re: small errors in ghc 6.6

2006-09-20 Thread Einar Karttunen
On 19.09 21:28, Tomasz Zielonka wrote:
 On Tue, Sep 19, 2006 at 09:13:56PM +0200, Rene de Visser wrote:
  I would suggest -fforce-recomp for force recompilation.
 

-frecompile-all

- Einar Karttunen
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: [Haskell-cafe] Serialising types with existential data constructors

2006-09-13 Thread Einar Karttunen
On 12.09 15:28, Misha Aizatulin wrote:
   I've been using existentially quantified data constructors like
 
  data Box = forall a. Cxt a = Box a

If you can include Typeable into the mix then serializing works.

Serialize the value as name of type value.

When deserializing use a Map name of type decoder-function
and get the appropriate decoder from there for the type in question.

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


[Haskell-cafe] Traversing a graph in STM

2006-09-13 Thread Einar Karttunen
Hello

Is there an elegant way of traversing a directed graph in STM?

type Node  nt et = TVar (NodeT nt et)
type Edge  et= TVar et
data NodeT nt et = NodeT nt [(Node nt et, Edge et)]

type MyGraph = Node String Int

When implementing a simple depth first search we need a way to
mark nodes (= TVars) as visited. In addition multiple concurrent
searches should be possible.

Is it possible to avoid passing around an explicit Set of visited
nodes? And is there a better way of getting TVar identity than
StableNames?

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


Re: [Haskell-cafe] Traversing a graph in STM

2006-09-13 Thread Einar Karttunen
On 13.09 08:48, Chris Kuklewicz wrote:
 And the concurrent searches are isolated from each other?  Or are you 
 performing a single search using many threads?

Isolated from each other. Mainly dreaming of the per-transaction
variables attached to the nodes :-)

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


Re: Replacement for GMP: Update

2006-08-10 Thread Einar Karttunen
On 10.08 11:16, Peter Tanski wrote:
 Paragraph 6 of the OpenSSL (1998-2005) license states that:
 
  * 6. Redistributions of any form whatsoever must retain the following
 *acknowledgment:
 *This product includes software developed by the OpenSSL Project
 *for use in the OpenSSL Toolkit (http://www.openssl.org/).
 
 All developers would have to do is include the acknowledgment stated  
 above.

I think this is not bad for specific applications, but forcing this
upon all code compiled by GHC would be bad. I think the compiler
should not link applications by default to things that force
license related things. 

I think this is one reason GMP is being replaced.

ps. personally I don't think the advertising clause is bad, but
I think it is bad to force it on other users.

- Einar Karttunen
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: [Haskell] thread-local variables

2006-08-08 Thread Einar Karttunen
 was pretty fast under GHC.

Threads are quite cheap. But with using a pool we can guarantee things
about the number of threads and don't run to situations with 1
extra threads just because forking always is fun. The other point
is to use a background thread which talks to blocking C API and
executed callbacks upon receiving events from the C side.

- Einar Karttunen

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


Re: [Haskell] thread-local variables

2006-08-06 Thread Einar Karttunen
On 06.08 04:23, Frederik Eaton wrote:
 I also forgot to mention that if you hold on to a ThreadId, it
 apparently causes the whole thread to be retained. Simon Marlow
 explained this on 2005/10/18:

Actually this problem does not exist in the code.
The problem is encountered if children are tied to their parents,
that is they contain the ThreadId of the parent thread. In my
code this problem should not occur.

- Einar Karttunen
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] thread-local variables

2006-08-06 Thread Einar Karttunen
On 06.08 02:41, Frederik Eaton wrote:
 Also, note that my proposal differs in that thread local variables are
 not writable, but can only be changed by calling (e.g. in my API)
 'withIOParam'. This is still just as general, because an IORef can be
 stored in a thread-local variable, but it makes it easier to reason
 about the more common use case where TLS is used to make IO a Reader;
 and it makes it easier to share modifiable state across more than one
 thread. I.e. if modifiable state is stored as 'IOParam (IORef a)' then
 the default is for the stored 'IORef a' to be shared across all
 threads; it can only be changed locally for a specified action and
 any sub-threads using 'withIOParam'; and if some library I use decides
 to fork a thread behind the scenes, it won't change my program's
 behavior.

Perhaps a function like this would solve all our problems:

-- | Tie all TLS references in the IO action to the current
-- environment rather than the environment it will actually
-- be executed.
tieToCurrentTLS :: IO a - IO (IO a)


 I think it is a good idea to have stdin, cwd, etc. be thread-local.

How would this work together with the FFI?

 I don't understand why the 'TL' monad is necessary, but I haven't read
 the proposal very carefully.

The TL monad is necessary to make initialization order problems go
away.

- Einar Karttunen
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] thread-local variables

2006-08-06 Thread Einar Karttunen
On 05.08 19:56, Frederik Eaton wrote:
 That doesn't answer the question: What if my application has a need
 for several different sets of parameters - what if it doesn't make
 sense to combine them into a single monad? What if there are 'n'
 layers? Is it incorrect to say that the monadic approach requires code
 size O(n^2)?

Well designed monadic approach does not require O(n^2). But if you
want to design code in a way that requires O(n^2) code size you
can do it.

Parallel layers require O(layers).
Nested layers hiding the lower layer need O(layers).

This is not a problem in practice and makes refactoring very easy.


  And don't have any static guarantees that you have done all the proper
  initialization calls before you use them.
 
 Well, there are a lot of things I don't have static guarantees for. 
 For instance, sometimes I call the function 'head', and the compiler
 isn't able to verify that the argument isn't an empty list. If I
 initialize my TLS to 'undefined' then I'll get a similar error
 message, at run time. For another example, I don't use monadic regions
 when I do file IO. I can live with that.

The problem is with refactoring and taking a piece of code and
reusing it somewhere else - and trying to figure out what does
it need.

  ... Also if we have two pieces of the same per-thread state that we
  wish to use in one thread (e.g. db-connections) then the TLS
  approach becomes quite hard.
 
 No harder than the monadic approach, in my opinion.

In the monadic approach adding a second db connection would involve:
1) add a line to the state record
2) add a db2query = withPart db2 . flip query
3) no changes elsewhere

If the DB API uses a TLS parameter of type Proxy DBH how would
you implement this in a nice manner for the TLS case?

 You've redefined 'fork'. If I want a library which works with other
 libraries, that will not be an option. The original purpose of my
 posting to this thread was to ask for two standard functions which
 would let me define thread-local variables in a way which is
 interoperable with other libraries, to the same extent as 'withArgs'
 and 'withProgName' are.

All libraries which may fork may use a preallocated thread pool.
Thus they might not work with TLS. withArgs and withProgName are
global and not very thread-friendly.

- Einar Karttunen
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] thread-local variables

2006-08-05 Thread Einar Karttunen
On 05.08 14:32, Frederik Eaton wrote:
  If it is documented maybe it could be done at the level of an
  implicit parameter?
 
 Do you think implicit parameters are better than TLS?


Implicit parameters are explicit and the type checker
guards that they are not undefined (and thus are safe
in the presence of callbacks). I haven't used implicit
parameters extensively because I prefer the monadic
approach.

  I don't consider these very different:
  1) use one thread from a pre-allocated pool to do a task
  2) fork a new thread to do the task
  
  With TLS they are vastly different.
 
 If you don't consider them different, then you can start using (2)
 instead of (1).

Performance reasons or access to a shared resources. Also 2) would
mean in many cases making currently local state global which is
not nice.

 Can you give the API for your library? I have a hard time imagining
 how it could not be obvious that a thread pool is being used.

e.g. various

withFooResource :: (Foo - IO a) - IO a

can use worker threads.

  As said before the monadic approach can be quite clean. I haven't used
  implicit parameters that much, so I won't comment on them.
 
 Perhaps you can give an example? As I said, a single monad won't
 suffice for me, because different libraries only know about different
 parts of the state. With TLS, one can delimit the scope of parameters
 by making the references to them module-internal, for instance.
 
 With monads, I imagine that I'll need for each parameter
 
 (1) a MonadX class, with a liftX member
 (2) a catchX function
 (3) a MonadY instance, for each wrapped monad Y (thus the number of
 such instances will be O(n^2) where n is the number of parameters)

That is usually the wrong approach. Newtype something like
StateT AppState IO. Use something like:

runWithPart :: (AppState - c) - (c - IO a) - AppM a

to define nice actions for different parts of the libraries.

Usually this is very easy if one uses combinators and high level
constructs and messier if it is hard to find the right combinators.

If you look at the various web frameworks in Haskell you will notice
that most of them live happily with one monad and don't suffer from
problems because of that.

 With TLS, I need
 
 (1) a declaration x = unsafePerformIO $ newIOParam ...

And don't have any static guarantees that you have done all the proper
initialization calls before you use them.

In the previous example we were using a lot of libraries using hidden
state. How do we guarantee that they have valid values in TLS?
Also if we have two pieces of the same per-thread state that
we wish to use in one thread (e.g. db-connections) then the TLS
approach becomes quite hard.

Here is a naive and dirty implementation. The largest problem is that
TypeRep is not in  Ord. An alternative approach using Dynamic would be
possible, but I like the connection between the key 
and the associated type.

http://www.cs.helsinki.fi/u/ekarttun/haskell/TLS/

Not optimized for performance at all.

- Einar Karttunen

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


Re: [Haskell] thread-local variables

2006-08-04 Thread Einar Karttunen
.

As said before the monadic approach can be quite clean. I haven't used
implicit parameters that much, so I won't comment on them.

  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.

I think we can agree to disagree on whether they are a good idea :-)

Mainly I am concerned with the ability to share and reuse code
between different Haskell projects. We really don't want to make
it hard to combine libraries because one uses much threading 
and the other one TLS. I think this is the most important
issue.

 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.

There is nothing stopping you from implementing them.


To make it type-safe maybe something like:

data Proxy a = Proxy
class TLSVar name ty | name - ty
getTLS  :: TLSVar name ty = Proxy name - IO ty
withTLS :: TLSVar name ty = Proxy name - ty - IO a - IO a

But I don't have strong feelings about the API as I would
probably not use it.


- Einar Karttunen
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] thread-local variables

2006-08-01 Thread Einar Karttunen
On 31.07 23:53, Adrian Hey wrote:
 Frederik Eaton wrote:
 On Mon, Jul 31, 2006 at 03:09:59PM +0300, Einar Karttunen wrote:
 On 31.07 03:18, Frederik Eaton wrote:
 4) the library runs the callback code in Tw where the TLS state is
invalid. This is even worse than a global variable in this case.
 
 If you have threads, and you have something which needs to be
 different among different threads, then it is hard for me to see how
 thread-local variables could be worse than global variables in any
 case at all.
 
 I haven't been following the technicalities of the particular
 scenario that's under discussion so I don't know exactly
 what either of you mean by (even) worse than global variables.
 
 I just want to point out that, as I (and a few others) see it at
 least, top level mutable state (aka global variables) is
 absolutely necessary sometimes for _SAFETY_ reasons.

I agree that global variables are sometimes the best solution.
My point in the quote was that in the example described
TLS would cause more trouble than global mutable state.

 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, 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).

I have to agree to this. It would be very nice to see good examples
of thread local state in action that would teach us (the sceptics)
why TLS is a good idea in Haskell - and maybe we would learn to
write better code with it. Something more than simply avoiding
a Reader monad / implicit parameters would be nice.

ps. Should we move this discussion to haskell-cafe?

- Einar Karttunen
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell-cafe] The difficulty of designing a sequence class

2006-08-01 Thread Einar Karttunen
On 31.07 16:27, Brian Hulley wrote:
 None of the above type classes would be compatible with Data.ByteString! 
 (You mentioned this issue before wrt Data.Edison.Seq but it just clicked 
 with me now for the above refactoring.) For compatibility, the element type 
 would need to appear also thus:
 
   class Foldable f_a a | f_a - a where
fold :: (a - b - b) - b - f_a - b
 

With the new System FC (when it is merged) we could make these classes
nicer.

class ElementType c a | c - a

instance ElementType [a] a
instance ElementType ByteString Char
instance IArray a e = ElementType (a i e) e

class Foldable c where
  fold :: ElementType c a = (a - b - b) - b - c - b

This won't work at the moment due to limitations in GHC, but seems
like a cleaner solution.

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


Re: [Haskell] thread-local variables (was: Re: Implicit Parameters)

2006-07-31 Thread Einar Karttunen
On 31.07 03:18, Frederik Eaton wrote:
 I don't think it's necessarily such a big deal. Presumably the library
 with the worker threads will have to be invoked somewhere. One should
 just make sure that it is invoked in the appropriate environment, for
 instance with the database connection already properly initialized.
 
 (*) One might even want to change the environment a little within each
 thread, for instance so that errors get logged to a thread-specific
 log file.

So we have the following:
1) the library is initialized and spawns worker thread Tw
2) application initializes the database connection and it
   is associated with the current thread Tc and all the children
   it will have (unless changed)
3) the application calls the library in Tc passing an IO action
   to it. The IO action refers to the TLS thinking it is in
   Tc where it is valid.
4) the library runs the callback code in Tw where the TLS state is
   invalid. This is even worse than a global variable in this case.

Of course one can argue that the application should first initialize
the database handle. But if the app uses worker threads (spawned
before library initialization) then things will break if a library
uses TLS and callbacks and they end up running in threads created
before the library initialization.

- Einar Karttunen

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


Re: [Haskell] thread-local variables (was: Re: Implicit Parameters)

2006-07-31 Thread Einar Karttunen
On 31.07 14:03, Thomas Conway wrote:
 This is why I believe transaction-local variables are a more useful concept.
 You are garanteed that there is only one thread accessing them, and
 they behave just like ordinary TVars except that each transaction has
 its own copy.

This seems like it could be useful. E.g. marking graph nodes while
traversing them.

 The argument to newLVar is an initial value that is used at the start
 of each transaction.  Note that this means that the value in an LVar
 does not persist between transaction. I agree that this limits their
 use, but simplifies them immensely, and doesn't stand in the way their
 being useful for solving a bunch of problems.

I think that them reverting to the initial value is more useful
than persisting behavior.

- Einar Karttunen
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] thread-local variables (was: Re: Implicit Parameters)

2006-07-30 Thread Einar Karttunen
On 29.07 13:25, Frederik Eaton wrote:
 I think support for thread-local variables is something which is
 urgently needed. It's very frustrating that using concurrency in
 Haskell is so easy and nice, yet when it comes to IORefs there is no
 way to get thread-local behavior. Furthermore, that one can make
 certain things thread-local (e.g. with withArgs, withProgName) makes
 the solution seem close at hand (although I can appreciate that it may
 not be). Yet isn't it just a matter of making a Map with existentially
 quantified values part of the state of each thread, just as the
 program name and arguments are also part of that state?

Are thread local variables really a good idea in Haskell?

If variables are thread local how would this combinator work:

withTimeOut :: Int - IO a - IO a
withTimeOut tout op = mdo
  mv - newEmptyMVar
  wt - forkIO $ do try op = tryPutMVar mv  killThread kt
  kt - forkIO $ do threadDelay tout
e - tryPutMVar mv $ Left $ DynException $ toDyn 
TimeOutException
if e then killThread wt else return ()
  either throw return = takeMVar mv


Would it change the semantics of the action as it is run in a
different thread (this is a must if there are potentially blocking FFI
calls). Now if the action changes the thread local state then
it behaves differently. Do we really want that?

Usually one can just add a monad that wraps IO/STM and provides the
variables one needs. This has the good side of making scoping
explicit.

- Einar Karttunen
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] thread-local variables (was: Re: Implicit Parameters)

2006-07-30 Thread Einar Karttunen
On 30.07 11:49, Frederik Eaton wrote:
 No, because the thread in which it runs inherits any thread-local
 state from its parent.


So we have different threads modifying the thread-local state?
If it is a copy then updates are not propagated.

What about a design with 10 worker threads taking requests
from a Chan (IO ()) and running them (this occurs in real code).
To get things right they should use the TLS-context relevant
to each IO () rather than the thread.
 
  Now if the action changes the thread local state then
  it behaves differently. Do we really want that?
 
 I'm not sure what you're suggesting. The API I proposed actually
 doesn't let users discover when their actions are running in
 sub-threads. (Can you write an example using that API?) However, even
 if it did, I don't see a problem. Do you think that we should get rid
 of 'myThreadId', for instance? I don't.

I do consider using myThreadId bad form for most purposes.
It is nice to have for debugging output - and occasionally
for sending other threads a handle for asynchronous exceptions,
but this can lead to problems when changing threading patterns.

Usually nice code does not care in which thread it is run.

 
  Usually one can just add a monad that wraps IO/STM and provides the
  variables one needs. This has the good side of making scoping
  explicit.
 
 That's easier said than done. Sometimes I take that route. But
 sometimes I don't want 5 different monads wrapping each other, each
 with its own 'lift' and 'catch' functions, making error messages
 indecipherable and code difficult to read and debug. Do you propose
 creating a special monad for file operations? For network operations? 
 No? Then I don't see why I should have to make a special monad for
 database operations. Or, if the answer was yes, then fine: obfuscate
 your own code, but please don't ask me to do the same. Let's support
 both ways of doing things, and we can be different.

Usually I just define one custom monad for the application which
wraps the stack of monad transformers. Thus changing the monad stack
does not affect the application code. A quite clean and efficient
solution.

My main objection to the TLS is that it looks like normal IO,
but changing the thread that evaluates it can break things in ways
that are hard to debug. E.g. we have an application that uses
TLS and passes an IO action to a library that happens to use
a pool of worker threads that invisible to the application. 
Or the same with the role of the application and library reversed.

Offering it up as a separate library should be ok as it would
be very easy to spot and take extra care not to cause problems.

- Einar Karttunen
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell-cafe] Serializing Functions and Actions for Distributed Programming

2006-07-30 Thread Einar Karttunen
On 29.07 14:07, Brian Sniffen wrote:
 I'm very excited by the ability to pass functions or IO actions
 between threads of the same program.  But I don't see any language or
 library support for doing so between programs, or between sessions
 with the same program.  OCaml provides a partial solution:
 
 http://caml.inria.fr/pub/docs/manual-ocaml/libref/Marshal.html
 
 Though all it's really sending is an address and a hash of the binary
 program.  Even SerTH doesn't help with functional types.  I seek the
 knowledge of the Haskell Cafe: is there a reasonable way of addressing
 this problem?

There is sadly no real good way of doing it on top of GHC. If both
sides are running an identical executable image one can hack it to
work (see parallel Haskell for the code to do it). But in general
I don't think it is worth the trouble. The problem is:

1) versioning (I like being able to upgrade applications while keeping 
serialized state)
2) trust (GHC does not have sandboxing)

YHC may have an answer for YHC users.

I have some code which allows one to register functions and call them
transparently over a network - even supporting callbacks. Thus code
does not move, but code location is quite transparent.

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


Re: [Haskell-cafe] Serializing Functions and Actions for Distributed Programming

2006-07-30 Thread Einar Karttunen
On 30.07 12:12, Jason Dagit wrote:
 Depending on the type of sandboxing that you need/want #2 might be
 possible with GHC.  Take lambdabot for example.  lambdabot has made it
 safe to allow arbitrary expression evaluation by disallowing IO and
 not importing unsafePerformIO and similar unsafe functions.


This is possible as lambdabot has the source code rather than
an arbitrary Haskell expression at runtime.

Basically how does one differentiate between:

(\x - unsafePerformIO somethingNasty `seq` (x+1))
and
(\x - x + 1)

at runtime.

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


[Haskell-cafe] Still not dead

2006-07-21 Thread Einar Karttunen
Hello

As many of you may have noticed I have been away for some months.
This has been due to health problems which have unfortunately
kept me unable to work on Haskell projects.

I am not dead and will be working on resolving the backlog
of messages (will probably take a week). I will be slowly
back to hacking things when I get everything fixed.

- Einar Karttunen

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


Re: [Haskell-cafe] Existentially-quantified constructors: Hugs is fine, GHC is not?

2006-05-10 Thread Einar Karttunen
On 10.05 13:27, Otakar Smrz wrote:
data ... = ... | forall b . FMap (b - a) (Mapper s b)
 
... where FMap qf qc = stripFMap f q
 
 the GHC compiler as well as GHCi (6.4.2 and earlier) issue an error
 
 My brain just exploded.
 I can't handle pattern bindings for existentially-quantified
 constructors.

You can rewrite the code in a way that GHC accepts it. Just
avoid pattern binding your variables. I had the same problem
in HAppS code and needed to lift some code to the top
level to solve it.

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


Re: Building ghc-6.4 on Solaris x86

2006-04-29 Thread Einar Karttunen
On 29.04 17:47, Georg Sauthoff wrote:
 Hi,
 
 I am trying to build ghc-6.4.2 under solaris x86 (10.0).

Hello

A few months ago physrules ported GHC 6.4.1 to solaris x86.
There were a few problems (and the tarball does not have
the install target fixed), but the binary should work.

Hopefully this can help you further. No guarantees.

http://www.cs.helsinki.fi/u/ekarttun/physrules/ghc-6.4.1-i386-unknown-solaris2.tar.bz2

- Einar Karttunen
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: [Haskell-cafe] GetOpt

2006-04-27 Thread Einar Karttunen
On 27.04 12:32, Mirko Rahn wrote:
 So it would be much better to define the options in the library and to 
 provide this definitions to the user program somehow. I tought about 
 this topic several times and came up with a solution that works for me 
 but is far from being perfect. It uses existentials and a main 
 disadvantage is the need of explicit traversing. Moreover some new 
 boilerplate code is necessary.

HAppS has a typeclass for this kind of thing also:

http://test.happs.org/auto/apidoc/HAppS-Util-StdMain-Config.html
http://test.happs.org/HAppS/src/HAppS/Util/StdMain/Config.hs

and for an example instance see:

http://test.happs.org/HAppS/src/HAppS/Protocols/SimpleHTTP.hs

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


Re: [Haskell-cafe] GetOpt

2006-04-26 Thread Einar Karttunen
On 26.04 11:29, Anton Kulchitsky wrote:
 I just started to study Haskell and it is my almost first big experience 
 with functional languages (except Emacs Lisp and Python). I enjoyed all 
 small exercises and started a bigger business writing a general utility. 
 However, I have a problem from the beginning. The utility get some file 
 and convert it to another format. It is a kind of small compiler. It 
 also accepts many parameters and behaves depending on them. The problem 
 is how to do this neat! How should I write my program to accept and 
 neatly work with options

One solution is to have a datatype for configuration:

 data Config = Config { mode:: Mode,
infile  :: Maybe FilePath,
outfile :: Maybe FilePath
  }
 nullConfig = Config Normal - -
 data Mode   = Normal | Version | Help

and handle options as functions from Config to Config:

 Option ['i']   [input]   (ReqArg (\x c - c { infile = Just x }) file) 
 input file name

and then handle the parsed options like:

 case conf of
   Config Normal (Just i) (Just o) - ...
   Config Normal __- both input and output must be specified
   Config Help   __- help message

- Einar Karttunen

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


GHC6.5 + TH + Profiling

2006-04-23 Thread Einar Karttunen
Hello

I am having problems combining TH and profiling with ghc-6.5.20060420. GHC 
seems to die
when loading the object file for TH execution and failing to notice that it 
should
load profiling symbols. The exact error is:

Loading package base-1.0 ... linking ... done.
Loading package template-haskell-1.0 ... linking ... done.
Loading package mtl-1.0 ... linking ... done.
Loading package stm-1.0 ... linking ... done.
ghc-6.5.20060420: 
.haskell_cache/http_searchpath.org-default.map.cache//HAppS/Util/StdMain/StartStateTH.o:
 unknown symbol `entering_PAP'

I can create a simpler example of this if needed.

- Einar Karttunen
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: using ghc with make

2006-04-20 Thread Einar Karttunen
On 20.04 12:06, Bulat Ziganshin wrote:
 my Streams library mainly consists of two parts - Streams and
 AltBinary. The streams part implements Handle-like interface
 (including such functions as vGetChar, vGetByte, vPutBuf, vSeek and so
 on) for various data sources - files, memory buffers, pipes, strings.
 m/m files support is planned but now has just preliminary
 implementation

Having these as separate would be very nice. I think that a separately
packaged AltBinary would be much easier to use for many people rather
than force a dependency on the rest of Streams.

- Einar Karttunen

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: GHC 6.5 error? Illegal polymorphic or qualified type

2006-04-16 Thread Einar Karttunen
Hello

Here is a short example of the GHC 6.5 problem:

type AnyE a = forall err. Either err a
foo :: Monad m = AnyE (m t)
foo = undefined

Works with older versions of GHC 6.5, but newer versions
fail with the:

Illegal polymorphic or qualified type: forall err. Either err (m t)
In the type signature for `foo':
  foo :: (Monad m) = AnyE (m t)


- Einar Karttunen
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


[Haskell] ANNOUNCE: HAppS 0.8

2006-04-13 Thread Einar Karttunen
Hello,

HAppS - Haskell Application Server version 0.8 has been released and
contains a complete rewrite of the ACID and HTTP functionalities.

Features include:

* MACID - Monadic framework for ACID transactions:
  Write apps as a set of simple state transformers. MACID write-ahead
  logging and checkpointing make it easy for you to guarantee
  application integrity in the face of unplanned outages. MACID even
  guarantees that your side effects will be executed at-least-once if
  they can complete within a timelimit you define.
* HTTP Server:
  Performs better than Apache/PHP in our informal benchmarks (thanks to
  Data.FastPackedString), handles serving both large (video) files and
  lazy (javascript) streaming, supports HTTP-Auth, and more.
* SMTP Server
  Handle incoming email in your application without worrying about
  .procmail or other user level inbound mail configuration hackery. Just
  have the HAppS.SMTP listen on port 25 or have the system mail server
  SMTP forward mail for your app to some internal port.
* Mail delivery agent
  Stop worrying about making sure a separate local mail server or DNS is
  up and running to deliver your mail. HAppS takes care of making sure
  your mail is delivered as long as your application itself is running
  and makes sure no outbound mail is lost even with unplanned restarts.
* DNS resolver in pure Haskell
  For resolving MX records and concurrent queries. Can use an upstream
  DNS server or root servers directly.
* XML and XSLT
  Separate application logic from presentation using XML/XSLT. With
  HAppS, you can have your application output XML (via HTTP or SMTP) and
  handle style/presentation via separate XSLT files at runtime. HAppS
  takes care of doing server side XSLT for outbound mail and HTTP
  user-agents that don't support it client side.
* Sessions and much more!

Where to get?

http://happs.org/
darcs get http://happs.org/HAppS

--
Einar Karttunen
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


[Haskell-cafe] Re: request for code review

2006-03-12 Thread Einar Karttunen
On 12.03 01:47, Shannon -jj Behrens wrote:
 monad.  Perhaps controversially, I've continued to use | in a bunch
 of places that the monad didn't get rid of because I think it's more
 readable, but I'm still open for argument on this topic.  Using the

What about using () from Control.Arrow?

 -- For convenience:
 currTokType :: ParseContext - TokenType
 currTokType ctx = ctx | currTok | tokenType

currTokType = currTok  tokenType

 currTokValue :: ParseContext - String
 currTokValue ctx = ctx | currTok | tokenValue

currTokValue = currTok  tokenValue

 -- Create the final output string given a ParseContext.
 consolidateOutput :: ParseContext - String
 consolidateOutput ctx =
   ctx | output | reverse | concat

consolidateOutput = output  reverse  concat

and so on.

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


Re: [Haskell-cafe] More STUArray questions

2006-03-12 Thread Einar Karttunen
On 12.03 18:44, Martin Percossi wrote:
 However, just out of curiosity, I'm still curious at how I could do the
 runSTMatrix, which would really be the icing on the cake in terms of client
 usability.

You might want to look at the definition of Data.Array.ST
(at http://darcs.haskell.org/packages/base/Data/Array/ST.hs)
runSTUArray is defined as follows:

runSTUArray :: (Ix i)
   = (forall s . ST s (STUArray s i e))
   - UArray i e
runSTUArray st = runST (st = unsafeFreezeSTUArray)

A similar way should work for matrixes.

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


[Haskell-cafe] Looking for an efficient tree in STM

2006-03-08 Thread Einar Karttunen
Hello

Does anyone have an efficient tree implemented in STM that
supports concurrent updates in an efficient fashion? This
seems suprisingly hard to implement - a normal binary
tree with links as TVar is very slow and does not scale
very well.

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


[Haskell-cafe] getChar + System.Cmd.system + threads causes hangups

2006-02-20 Thread Einar Karttunen
Hello

Using system or any variant of it from System.Process
seems broken in multithreaded environments. This
example will fail with and without -threaded.

When run the program will print hello: start and
then freeze. After pressing enter (the first getChar)
System.Cmd.system will complete, but without that
it will freeze for all eternity.

What is the best way to fix this? I could use System.Posix,
but that would lose windows portablity which is needed.


import Control.Concurrent
import System.Cmd

main = do forkIO (threadDelay 10  hello)
  getChar
  getChar

hello = do putStrLn hello: start
   system echo hello world!
   putStrLn hello: done


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


Re: [Haskell-cafe] getChar + System.Cmd.system + threads causes hangups

2006-02-20 Thread Einar Karttunen
Here is a version that works fine:


myRawSystem cmd args = do 
(inP, outP, errP, pid) - runInteractiveProcess cmd args Nothing Nothing
hClose inP
os - pGetContents outP
es - pGetContents errP
ec - waitForProcess pid
case ec of
  ExitSuccess   - return ()
  ExitFailure e -
  do hPutStrLn stderr (Running process ++unwords (cmd:args)++ FAILED 
(++show e++))
 hPutStrLn stderr os
 hPutStrLn stderr es
 hPutStrLn stderr (Raising error...)
 fail Running external command failed

pGetContents h = do
mv - newEmptyMVar
let put [] = putMVar mv []
put xs = last xs `seq` putMVar mv xs
forkIO (hGetContents h = put)
takeMVar mv

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


Pragmas for FFI imports

2006-02-16 Thread Einar Karttunen
Hello

I would like to propose two pragmas to be included in Haskell'
for use with FFI. One for specifying the include file defining
the foreign import (INCLUDE in ghc) and an another for defining
a library that the foreign import depends on, called FFI_LIB
(not implemented at the moment). These changes would not break
any existing code.

- Einar Karttunen
___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://haskell.org/mailman/listinfo/haskell-prime


Re: [Haskell-cafe] standard poll/select interface

2006-02-09 Thread Einar Karttunen
On 09.02 22:24, Bulat Ziganshin wrote:
 as i understand this idea, transformer implementing async i/o should
 intercept vGetBuf/vPutBuf calls for the FDs, start the appropriate
 async operation, and then switch to another Haskell threads. the I/O
 manager thread should run select() in cycle and when the request is
 finished, wake up the appropriate thread. what's all. if you will ever
 need, this implementation can then be used to extend GHC's System.IO
 internals with the support for new async i/o managers (as i
 understand, select() is now supported by GHC, but poll(), kqueue() is
 not supported?). the only difference that my lib gives an opportunity
 to test this implementation without modifying GHC I/O internals, what
 is somewhat simpler. so, interface for async vGetBuf/vPutBuf routines
 should be the same as for read/write:
 
 type FD = Int
 vGetBuf_async :: FD - Ptr a - Int - IO Int
 vPutBuf_async :: FD - Ptr a - Int - IO Int

Please don't fix FD = Int, this is not true on some systems,
and when implementing efficient sockets one usually wants
to hold more complex state.

 JM Don't take the absence of a feature in jhc to mean I don't like or want
 JM that feature. There are a lot of things I don't have but that I'd
 JM definitly want to see in the language simply because I was only shooting
 JM for H98 to begin with and was more interested in a lot of the back end
 JM stuff. You should figure out the nicest design that uses just the
 JM extensions needed for the design you want. it could help us decide what
 JM goes into haskell-prime to know what is absolutely needed for good
 JM design and what is just nice to have.
 
 this simply means that the Streams library cannot be used with JHC,
 what is bad news, because it is even more rich than GHC's System.IO.
 jhc had chance to get modern I/O library. but it lost that chance :)

I think it is more like all haskell-prime programs. Seriously,
if we design a new IO subsystem it would be quite nice to be
able to use it from standard conforming programs.

Maybe things can be reformulated in a way that will be compatible
with haskell-prime.

 please look. at this moment Sreams library lacks only a few important
 features, already implemented in GHC's System.IO: sockets, line
 buffering and async i/o. moreover, i don't have an experience in
 implementing the async i/o, so foreign help is really necessary

If you want I can look at getting network-alt to implement the
interface.

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


Re: new i/o library

2006-01-27 Thread Einar Karttunen
On 27.01 13:10, Bulat Ziganshin wrote:
 i'm now write some sort of new i/o library. one area where i currently
 lacks in comparision to the existing Handles implementation in GHC, is
 the asynchronous i/o operations. can you please briefly describe how
 this is done in GHC and partially - why the multiple buffers are used?

One simple optimization is that you can omit all buffering with
unbuffered operation. Then simply add the buffer (which is ok
because Handles are mutable) if the user ever calls hLookAhead.

 moreover, i have an idea how to implement async i/o without complex
 burecreacy: use mmapped files, may be together with miltiple buffers.
 for example, we can allocate four 16kb buffers. when one buffer is
 filled with written data, the program unmaps it and switches to use
 the next buffer. i don't tested it, but OS can guess that unmapped
 buffer now should be asynchronously written to disk. the same for
 reading - when we completely read one buffer, we can unmap it, switch
 to the second buffer and map the third so that the OS can
 asynchronously fill the third buffer while we are reading second.
 should this work, at least on the main desktop OSes?

Please no. There are multiple reasons to avoid mmapped files.
1) They make very few performance guarantees for reading
   (i.e. a Haskell thread touches memory which has not yet
been read from the file causing IO and all the other
Haskell threads are blocked too)
2) The time of writes is unpredictable making implementing a
   hFlush harder? (not sure about this)
3) Not all file descriptors will support it - i.e. we will
   need the read/write path in any case.
4) Mmap cannot be used for random access for arbitrary files
   since they may be larger than the address space. This means
   some kind of window needs to be implemented - and this is
   easily done with read/write.

- Einar Karttunen
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: [Haskell] Re: page names on the new Haskell wiki

2006-01-27 Thread Einar Karttunen
On 27.01 21:13, Wolfgang Jeltsch wrote:
  I don't mind people creating hierarchies such as Simon M's performance
  resource. It may not be appropriate for a pure encyclopedia like
  Wikipedia, but HaskellWiki will be replacing the haskell.org site
  (shortly) and a more hierarchical structure may be appropriate for some
  content.
 
 Maybe we should allow using slashes for specifying hierarchy.  But 
 nevertheless I think that page names shouldn't be mnemonic, so I would, for 
 example, use Books and tutorials instead of Books.

Short and nice URLs without too many %20 are a nice thing to have.
Please consider at least leaving shorter names as alternatives
with redirection if you must use long names for some reason.

- Einar Karttunen
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


[Haskell-cafe] Re: Shootout favoring imperative code

2006-01-11 Thread Einar Karttunen
On 09.01 11:32, Simon Marlow wrote:
 Sebastian Sylvan wrote:
 
 It would be neat if the PackedString library contained functions such
 as hGetLine etc. It does have a function for reading from a buffer,
 but it won't stop at a newline...
 But yeah, fast string manipulation is difficult when using a
 linked-list representation...
 
 My version of the packed string library does have an hGetLine.  Don 
 Stewart was merging my version with his fps at some point, Don - any 
 news on that?

Getting a fast FastPackedString will solve the problems with many
benchmarks. A similar thing for arrays would be nice - although
this is more about inteface:

 module Data.Array.UnsafeOps where

 import Data.Array.Base hiding((!))

 {-# INLINE (!) #-}
 (!) :: MArray a e m = a Int e - Int - m e
 (!) = unsafeRead

 {-# INLINE set #-}
 set :: MArray a e m = a Int e - Int - e - m ()
 set = unsafeWrite

 {-# INLINE swap #-}
 swap :: MArray a e m = a Int e - Int - Int - m ()
 swap arr x y = do xv - arr ! x
   yv - arr ! y
   set arr x yv
   set arr y xv

 {-# INLINE combineTo #-}
 combineTo :: MArray a e m = a Int e - Int - (e - e - e) - a Int e - 
 Int - m ()
 combineTo a0 i0 f a1 i1 = do v0 - a0 ! i0
  v1 - a1 ! i1
  set a0 i0 $! f v0 v1

and so forth. Usually imperative solutions have something like
a[i] += b[i], which currently is quite tedious and ugly to
translate to MArrays. Now it would become combineTo a i (+) b i.

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


Re: [Haskell-cafe] I/O and utf8

2006-01-11 Thread Einar Karttunen
On 10.01 10:25, Bulat Ziganshin wrote:
 i have the question about this issue - i also want to provide
 autodetection mechanism, which relies on first bytes of text files to
 set proper encoding. what is the standard rules to encode utf8/utf16
 encoding used for text in file in these first bytes?

The BOM is used to mark the encoding
(http://en.wikipedia.org/wiki/Byte_Order_Mark), but most
UTF-8 streams lack it. I have not seen it used in UTF-8 files either.

Do you plan on supporting things like HTTP where the character set
is only known in the middle of the parsing?

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


Re: [Haskell-cafe] In for a penny, in for a pound.

2006-01-09 Thread Einar Karttunen
On 09.01 12:56, Donald Bruce Stewart wrote:
 Entries that may currently be worth submitting:
takfp - http://www.haskell.org/hawiki/TakfpEntry

Committed.

pidigits (currently 2nd!) - http://www.haskell.org/hawiki/PidigitsEntry 

Committed.

mandelbrot- http://www.haskell.org/hawiki/MandelbrotEntry

Committed.

harmonic  - http://www.haskell.org/hawiki/HarmonicEntry

Already present in the CVS.

fannkuch (pure and impure) - http://www.haskell.org/hawiki/FannkuchEntry

I think these could do with some work. Optimizing the impure one
at least.

I took the liberty of submitting some of these. Please keep in future
the comment lines in the entries, because Shootout wants the names
of the contributers.

- Einar Karttunen

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


Re: [Haskell-cafe] binary IO

2005-12-28 Thread Einar Karttunen
On 27.12 07:00, Tomasz Zielonka wrote:
 Some time ago I was playing with DNS too. I have a library that can
 construct and interpret DNS packets, but it's a bit incomplete right
 now. It reads packets as Strings, but it should be quite straightforward
 to make it read and interpret FastPackedStrings.
 
 http://www.uncurry.com/repos/TzDNS


Nice, here is my shot at DNS - 
http://cs.helsinki.fi/u/ekarttun/haskell/hdnsd-20051227.tar.bz2
feel free to take bits if you are interested. The serialization/deserialization
uses Ptrs.

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


Re: storing highly shared data structures

2005-12-22 Thread Einar Karttunen
On 22.12 14:43, Christian Maeder wrote:
 How can I detect this sharing in order to avoid traversing the very
 same symbol table for every symbol?

By using System.Mem.StableName
SerTH (http://cs.helsinki.fi/u/ekarttun/SerTH/) implements this,
so you can look at the source for pointers.

 I've tried to use a Map (Ptr ()) ShATerm. So before traversing an
 object I look up its address and check if is was traversed before (if
 not I traverse it and store it in my map for future lookups).

GHC can move the objects in memory.

 2.) A single Map (Ptr ()) ShATerm does not work! It seems that
 sometimes objects are shared that have different types (as tests
 revealed). This seems obvious for newtypes but also happens (I think)
 without newtype declarations.

Yes, this is quite evil. For example the empty list can be shared
across type boundaries. Also phantom types can share the same
address. In addition you have to worry about libraries using
unsafeCoerce#

 So, I'm now thinking if I should try using the type of my data as key
 as well, i.e. using Map (TypeRep, Ptr ()) ShATerm to avoid duplicate
 traversals.

TypeRep is not Ord iirc, which makes this harder. Of course you can
show it and then use that.

- Einar

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


[Haskell-cafe] Re: [Haskell] A simple server (or how to do io).

2005-12-21 Thread Einar Karttunen
On 21.12 01:13, Pupeno wrote:
 So, I install a signal handler with installHandler... and then ? how do I 
 prevent the program for quiting ? am I missing some kind of event loop here ?
 

Here is a small server program:

main = performForkWithUnixySessionStuff work

-- this is just for testing, replace with real implementation
performForkWithUnixySessionStuff x = x

work = do s1 - runStreamServer ...
  s2 - runDgramServer ...
  mv - newEmptyMVar
  installHandler someSignal (Catch (putMVar mv ())) Nothing
  takeMVar mv
  someCleanupActions
  killServer s1
  killServer s2

For simple testing you might want to just use getLine to wait for the right
time to exit.

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


Re: [Haskell] A simple server (or how to do io).

2005-12-20 Thread Einar Karttunen
On 20.12 21:52, Pupeno wrote:
 It works, but I have the following problems:
 When I run server 10013 from ghci, the prompt returns immediately and if I 
 do a query to that port I don't get anything, until I go and press enter on 
 ghci and the daytime is sent to the client. Like if the prompt was blocking 
 all IO or something like that.
 The other problem is that I tried to make a program, so I made 
 DaytimeServer.hs:

Your problem is that the ghci prompt *is* blocking everything. ghci is
builded non-threaded. Ghci uses a blocking call to read the lines
which means that all other computations are stopped.

 I compile it and run it. It returns immediately and the server of course, is 
 not running.

It spawns the server threads and returns immediately.

 I think what I am missing is that server, after running runStreamServer 
 should 
 block and be able to reply to all the queries (in the final version I'll also 
 have runDgramServer as well) and be able to receive a signal, upon which it 
 should close the socket and finish. How can do that ? Any help will be 
 appreciated.

Catch the signal and kill the listening threads. If you
are using the new 0.3.1 release then you can use the
killServer call.

ps. I think it may be best to continue on haskell-cafe@ rather 
than the main list.


- Einar Karttunen
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Preferred way of submitting patches

2005-12-17 Thread Einar Karttunen
Hello

What is the preferred way of submitting patches at the moment?
I tried using Trac but it seems that users without an account
on haskell.org cannot attach files... Is using Trac and
linking to the patch hosted externally the way to go?

- Einar Karttunen
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: [Haskell-cafe] Optimizing a high-traffic network architecture

2005-12-16 Thread Einar Karttunen
On 16.12 07:03, Tomasz Zielonka wrote:
 On 12/16/05, Einar Karttunen ekarttun@cs.helsinki.fi wrote:
  To matters nontrivial all the *nix variants use a different
  more efficient replacement for poll.
 
 So we should find a library that offers a unified
 interface for all of them, or implement one ourselves.
 
 I am pretty sure such a library exists. It should fall back to select()
 or poll() on platforms that don't have better alternatives.

network-alt has select(2), epoll, blocking and very experimental kqueue
(the last one is not yet committed but I can suply patches
if someone is interested.

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


Re: [Haskell-cafe] Optimizing a high-traffic network architecture

2005-12-15 Thread Einar Karttunen
On 15.12 17:14, John Meacham wrote:
 On Thu, Dec 15, 2005 at 02:02:02PM -, Simon Marlow wrote:
  With 2k connections the overhead of select() is going to start to be a
  problem.  You would notice the system time going up.  -threaded may help
  with this, because it calls select() less often.
 
 we should be using /dev/poll on systems that support it. it cuts down on
 the overhead a whole lot. 'poll(2)' is also mostly portable and usually
 better than select since there is no arbitrary file descriptor limit and
 it doesn't have to traverse the whole bitset. a few #ifdefs should let
 us choose the optimum one available on any given system.

To matters nontrivial all the *nix variants use a different
more efficient replacement for poll.

Solaris has /dev/poll
*BSD (and OS X) has kqueue
Linux has epoll

Also on linux NPTL+blocking calls can actually be very fast
with a suitable scenario. An additional problem is that
these mechanisms depend on the version of the kernel
running on the machine... Thus e.g. not all linux machines
will have epoll.

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


Re: [Haskell-cafe] Optimizing a high-traffic network architecture

2005-12-14 Thread Einar Karttunen
On 14.12 23:07, Joel Reymont wrote:
 Something like this? Comments are welcome!

 timeout :: Int
 timeout = 500 -- 1 second

Is that correct?

 {-# NOINLINE timers #-}
 timers :: MVar Timers
 timers = unsafePerformIO $ newMVar M.empty
 
 --- Call this first
 initTimers :: IO ()
 initTimers =
 do forkIO $ block checkTimers
return ()

Here is a nice trick for you:

{-# NOINLINE timers #-}
timers :: MVar Timers
timers = unsafePerformIO $ do mv - newMVar M.empty
  forkIO $ block checkTimers
  return mv


initTimers goes thus away.

 --- Not sure if this is the most efficient way to do it
 startTimer :: String - Int - (IO ()) - IO ()
 startTimer name delay io =
 do stopTimer name
now - getClockTime
let plus = TimeDiff 0 0 0 0 0 delay 0
future = addToClockTime plus now
block $ do t - takeMVar timers
   putMVar timers $ M.insert (future, name) io t

I had code which used a global IORef containing
the current time. It was updated once by a second
by a dedicated thread, but reading it was practically
free. Depends how common getClockTime calls are.

 --- The filter expression is kind of long...
 stopTimer :: String - IO ()
 stopTimer name =
 block $ do t - takeMVar timers
putMVar timers $
M.filterWithKey (\(_, k) _ - k /= name) t

And slow. This is O(size_of_map)

 --- Tried to take care of exceptions here
 --- but the code looks kind of ugly

Is there a reason you need block for checkTimers?
What you certainly want to do is ignore exceptions
from the timer actions.


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


Re: [Haskell-cafe] Opening the same file multiple times

2005-12-12 Thread Einar Karttunen
On 12.12 12:06, Duncan Coutts wrote:
 It states in the Haskell Report 21.2.3:
 
 http://haskell.org/onlinereport/io.html

Thanks, for the pointer, but am looking for an extension
in the non-haskell98 API to do it.

It seems that things are quite problematic:

1) Use openFile or GHC.Handle.openFd

Works in Hugs, fails as the standard mandates in GHC
due to locking. This is fine.

2) Use openFile + handleToFd + unlockFile

This seems like a good plan. Except handleToFd will close the Handle.

3) Using System.Posix.IO

Using the fd{Read,Close,Write} functions from System.Posix.IO
could solve the problem - except that there is no way to
write binary buffers (Ptr Word8) with the API. Thus no
solution.

4) Use System.Posix.IO.openFd + fdToHandle

This appears to be nice on surface. Except fdToHandle locks
the file, thus back to drawing board.

5) Use System.Posix.IO.openFd + fdToHandle + unlockFile

Thus we have:

* lock mutex - otherwise there is a race condition
* System.Posix.IO.openFd - open the file emulating openFile
* fdToHandle - convert the file to Handle locking it
* unlockFile (fromIntegral fd) - now unlock the original fd
* unlock mutex

Is this really the most simple way of doing things?
Most of the operations will also hit the disk, and
be slow (safe) FFI calls.

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


[Haskell-cafe] Opening the same file multiple times

2005-12-11 Thread Einar Karttunen
Hello

It seems that opening the same file multiple times (one writer
and multiple readers) is not supported at least on *nix with
GHC. I want to use one Handle to use append data till the
end of the file while other Handles perform random access
IO with seeks on the file.

Sharing the same Handle for all the threads is not possible
since they perform seeks and may thus mess each other up.
Hiding the Handle behind a mutex would limit concurrency
more than I like.

Thus I wanted to open multiple Handles to the file, but
this seems quite hard. My best guess is to create a function 
like:

#ifdef mingw32_HOST_OS
openUnlocked fn mode = openBinaryFile fn mode
#else
openUnlocked fn mode = withMVar mutex $ do
  h  - openBinaryFile fn mode
  fd - handleToFd h
  unlockFile $ fromIntegral fd
  return h

{-# NOINLINE mutes #-}
mutex = unsafePerformIO $ newMVar ()
#endif

Is there really no simpler solution?

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


Re: [Haskell-cafe] Opening the same file multiple times

2005-12-11 Thread Einar Karttunen
On 11.12 22:26, Donn Cave wrote:
 Quoth Einar Karttunen ekarttun@cs.helsinki.fi:
 | It seems that opening the same file multiple times (one writer
 | and multiple readers) is not supported at least on *nix with
 | GHC. I want to use one Handle to use append data till the
 | end of the file while other Handles perform random access
 | IO with seeks on the file.
 
 How is it not supported?  What happens with something like this

Try the same in ghc / ghci:

[EMAIL PROTECTED]:~$ ghci
   ___ ___ _
  / _ \ /\  /\/ __(_)
 / /_\// /_/ / /  | |  GHC Interactive, version 6.4.1, for Haskell 98.
/ /_\\/ __  / /___| |  http://www.haskell.org/ghc/
\/\/ /_/\/|_|  Type :? for help.

Loading package base-1.0 ... linking ... done.
Prelude :m IO
Prelude IO af - openFile z AppendMode
Prelude IO sf - openFile z ReadMode
*** Exception: z: openFile: resource busy (file is locked)
Prelude IO 

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


Re: [Haskell-cafe] STM and `orElse` on a few thousand TMVars

2005-12-06 Thread Einar Karttunen
On 06.12 20:57, Tomasz Zielonka wrote:
 On Tue, Dec 06, 2005 at 02:52:03PM +, Joel Reymont wrote:
  Well, I do need to have access to all those thread handles.

Since thread creation is inside IO anyways you might want to
look at Control.Concurrent.QSem which solves this in an
easy fashion. If you want to use STM then a global 
TVar Int should work fine.

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


[Haskell-cafe] STM commit hooks

2005-11-29 Thread Einar Karttunen
Hello

I have been playing with STM and want to log transactions to disk. 
Defining a logging function like:

log h act = unsafeIOToSTM $ hPrint h act

works most the time. Aborts can be handled with:

abort h = log h Abort  retry
atomic' h act = atomically (act `orElse` abort h)

But is it possible to handle a commit?

commit h = unsafeIOToSTM (hPrint h Commit  hSync h)
atomically2 h act = atomically ((act  commit h) `orElse` abort h)

This won't work because the transaction is validated and 
maybe aborted after the commit is logged to disk.

Another alternative would be:

atomically3 h act = atomically (act `orElse` abort h)  atomically (commit h)

But this does not work either. Given Trx1 and Trx2, the following may occur:

1) Trx1 commits
thread switch
2) Trx2 commits (and depends on Trx1)
3) Trx2 commit is logged to disk
system crash

This means that the log would be inconsistent. Is there a way to implement
the commit that works?

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


Re: [Haskell-cafe] Haskell GUI on top of Xlib?

2005-11-28 Thread Einar Karttunen
On 26.11 22:00, Dimitry Golubovsky wrote:
 Thanks Duncan for this link: a very interesting reading.
 
 Duncan Coutts wrote:
 
 Are you aware of the XCB library:
 http://xcb.freedesktop.org/


I managed to parse the XCB XML protocol descriptions to
Haskell data structures, next I'll try to emit some
nice code from that. If it works well the end result
should be a pure Haskell X library.

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


[Haskell-cafe] throwDyn typing fun

2005-11-11 Thread Einar Karttunen
Hello

It seems that the type of throwDyn and throwDynTo are dangerously close.
ThrowDyn works in with any of the arguments of throwDynTo, which can
cause evil situations.

throwDyn :: Typeable exception = exception - b

Which means e.g. throwDyn someThreadId SomeException will work 
when you wanted to say throwDynTo someThreadId SomeException
and they both have types which unify with IO ().

I think using a
class Typeable = DynamicException a where ...
and throwDyn :: DynamicException a = a - b
could make more sense.

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


ghc-6.4.1: panic - Prelude.last: empty list

2005-10-30 Thread Einar Karttunen
Hello

I am having problems with GHC 6.4.1 dying with the message:

ghc-6.4.1: panic! (the `impossible' happened, GHC version 6.4.1):
Prelude.last: empty list

The source is nontrivial and contains template haskell. The error
seems to appear after byte code generation.

The log of the compile with -v9 is at the address below:
http://cs.helsinki.fi/u/ekarttun/haskell/log.txt

Is there anything else I should do to isolate the error better?

- Einar Karttunen
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: [Haskell] Paper: The essence of dataflow programming

2005-09-26 Thread Einar Karttunen
On 26.09 01:01, David Menendez wrote:
 We'll also define the injection combinator from Kieburtz's paper[1]:
 
  (.) :: Functor d = d a - b - d b
  d . a = fmap (const a) d

We add some nice combinators:


(-) :: Comonad co = (co a - co b) - (co b - co c) - co a - co c
a - b = b . a
infixr -

(--) :: Comonad co = (co a - co b) - (b - co b - co c) - co a - co c
a -- b = \co - let x = a co in b (counit x) x
infixr --

coreturn v = cobind (const v)


And define the simple state comonad:


data StateC st a = StateC (st - a) st

instance Comonad (StateC st) where
  counit (StateC f v) = f v
  cobind fun (StateC f v) = StateC (\v - fun (StateC f v)) v

get :: StateC st a - StateC st st
get (StateC _ st) = StateC id st

set :: st - StateC st a - StateC st a
set new (StateC fun _) = StateC fun new

modify :: (c - c) - StateC c a - StateC c a
modify mutator (StateC fun st) = StateC fun $ mutator st

runStateC fun v0 = let StateC a b = fun (StateC id v0) in (a b,b)


Now we can write comonadic code like monadic code:

foobar = get -- \x - coreturn (3*x)

test3 = get -- \x -
set 15  -
foobar  -- \y -
set x   -
coreturn (show y)


This looks very much like monadic code written with  and =.

A general Functor instance is easy (but non-haskell98):


instance Comonad w = Functor w where
  fmap f = cobind (f . counit)


- Einar Karttunen
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] Mixing monadic and non-monadic functions

2005-09-15 Thread Einar Karttunen
On 15.09 23:40, Bulat Ziganshin wrote:
 of course
 
 class Ref c a where
   new :: a - IO (c a)
   get :: c a - IO a
   set :: c a - a - IO ()

Maybe even:

class Ref m t where
  new :: a - m (t a)
  get :: t a - m a
  set :: t a - a - m ()

Or if you want to support things like FastMutInts

class Ref m t v where
  new :: v - m t
  get :: t - v - m a
  set :: t - v - m ()

That would even support an evil IOArray instance:

instance Ref IO (IOArray Int v, Int) v where
  new iv= newArray_ (0,iv)
  get (arr,idx) = readArray arr idx
  set (arr,idx) val = writeArray arr idx val

- Einar Karttunen
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell-cafe] Binary parser combinators and pretty printing

2005-09-15 Thread Einar Karttunen
On 13.09 23:31, Tomasz Zielonka wrote:
 How about all these points together?:
 
 a) Simple monadic interface

I think I already have this - minus packaging and documentation.

 b) Using better combinators

This is lacking.

 c) Using TH to generate code for the simple cases

I have TH for generating code, but that is not yet general 
purpose (the code comes from SerTH).

 d) Using type-classes

As most real-world protocols will need customization I cannot 
see much improvement here. Keeping the types of the serialized
data explicit makes sense. Otherwise changing an innocent Haskell
data declaration would cause on-wire data mismatch rather than
compile-time type errors.

 I've played with such frameworks a couple of times and I feel it's time
 to make a library useful for others. If you're interested, we could
 cooperate.
 

I would be interested in cooperation and getting an usefull library released. 
Currently my parsers just use [FastString] (thus support lazy IO), peek and 
poke.

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


Re: [Haskell-cafe] Binary parser combinators and pretty printing

2005-09-15 Thread Einar Karttunen
On 15.09 21:53, Bulat Ziganshin wrote:
 EK data Packet = Packet Word32 Word32 Word32 [FastString]
 
 well. you can see my own BinaryStream package at http://freearc.narod.ru
 
 class BinaryData a where
   read :: ...
   write :: ...

I don't think this is a very good solution. Keeping the on-wire datatypes 
explicit makes sense to me. Also things like endianess will need to be 
taken into account. If the encoding is derived automatically then 
changing the Haskell datatype will change the on-wire representation.
This is not wanted when interfacing with external protocols.

For typeclasses I would rather have:
getWord32BE :: Num a = MyMonad a
than
get :: MyClass a = MyMonad a

Note the difference between the Haskell type determining the on-wire 
type and it being explicit. I already have working TH code for the 
case where I want to derive automatic binary serialization for 
Haskell datatypes (SerTH).

 EK Maybe even the tuple could be eliminated by using a little of TH.
 
 it may be eliminated even without TH! :+: and :*: should work,
 although i don't tried this

I don't know how generics work in newer versions of GHC, but 
it may be worth investigating.

- Einar Karttunen

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


[Haskell-cafe] Binary parser combinators and pretty printing

2005-09-13 Thread Einar Karttunen
Hello

I am trying to figure out the best interface to binary parser
and pretty printing combinators for network protocols. 

I am trying to find the most natural syntax to express
these parsers in Haskell and would like opinions and
new ideas.

As an example I will use a protocol with the following packet structure:
0  message-id
4  sender-id
8  receiver-id
12 number of parameters
16 parameters. Each parameter is prefixed by 32bit length followed by 
   the data.

We will use the following Haskell datatype:

data Packet = Packet Word32 Word32 Word32 [FastString]

1) Simple monadic interface

getPacket = do mid - getWord32BE
   sid - getWord32BE
   rid - getWord32BE
   nmsg- getWord32BE
   vars- replicateM (fromIntegral nmsg) (getWord32BE = getBytes)
   return $ Packet mid sid rid nmsg vars

putPacket (Packet mid sid rid vars) = do
  mapM_ putWord32BE [mid, sid, rid, length vars]
  mapM_ (\fs - putWord32BE (length fs)  putBytes fs) vars


This works but writing the code gets tedious and dull. 

2) Using better combinators

packet = w32be  w32be  w32be  lengthPrefixList w32be (lengthPrefixList 
w32be bytes)
getPacket = let (mid,sid,rid,vars)  = getter packet in Packet mid sid rid vars
putPacket (Packet mid sid rid vars) = setter packet mid sid rid vars

Maybe even the tuple could be eliminated by using a little of TH.
Has anyone used combinators like this before and how did it work?

3) Using TH entirely

$(getAndPut 'Packet w32 w32 w32 lengthPrefixList (w32 bytes))

Is this better than the combinators in 2)? Also what sort of 
syntax would be best for expressing nontrivial dependencies - 
e.g. a checksum calculated from other fields.

4) Using a syntax extension

Erlang does this with the bit syntax 
(http://erlang.se/doc/doc-5.4.8/doc/programming_examples/bit_syntax.html)
and it is very nifty for some purposes. 

getPacket = do  mid:32, sid:32, rid:32, len:32 rest:len/binary 
   ...

The list of lists gets nontrivial here too...


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


Re: [Haskell-cafe] Using unsafePerformIO

2005-08-01 Thread Einar Karttunen
Dinh Tien Tuan Anh [EMAIL PROTECTED] writes:
 will be written without unsafePerformIO:
co' (x:xs) = do
   c1 - co' xs
   c- f (x:xs)
   if (c==1)
   then return 1:c1
   else return 0:c1


You might want to use unsafeInterleaveIO :: IO a - IO a. 
It allows IO computation to be deferred lazily.

In the particular example 
co' (x:xs) = do c1 - unsafeInterleaveIO (co' xs)
c  - f (x:xs)
if (c==1) then return (1:c1) else return (0:c1)


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


Bug in placing _stub.o files with HEAD

2005-07-29 Thread Einar Karttunen
Hello

I noticed the following behaviour using GHC 6.5.20050728:
If compiling a Cabal package containing hs-source-dirs it 
places the _stub.o under dist/build/source-dir/path/to/Module
when Cabal expects it in dist/build/path/to/Module. Things
appear to work without hs-source-dirs. 

For example with hs-source-dirs: src
Network/GnuTLS/IOWrap.hs contains foreign export declarations.
runnning Setup build creates the files:
dist/build/src/Network/GnuTLS/IOWrap_stub.o
src/Network/GnuTLS/IOWrap_stub.h
src/Network/GnuTLS/IOWrap_stub.c

But Cabal fails to include the IOWrap_stub.o as it is 
expected as dist/build/Network/GnuTLS/IOWrap_stub.o

- Einar Karttunen
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: [Haskell-cafe] ForeignPtrs with liveness dependencies

2005-07-26 Thread Einar Karttunen
Simon Marlow [EMAIL PROTECTED] writes:
 You might be able to find more information on this in the mailing list
 archives.  It's true that touchForeignPtr isn't enough to enforce an
 ordering on the running of finalizers, but it *can* be used to express a
 liveness relationship between one ForeignPtr and another (ForeignPtr A
 is alive if ForeignPtr B is alive).  This should be enough if you're
 dealing with pointer relationships between memory objects, for example,
 where it doesn't matter which one gets freed first when they're both
 unreferenced.

The order of the cleanup functions is significant in this case,
so that does not unfortunately help.

 If you really do need ordering, maybe it would be possible to use
 reference counting in your case?

I ended up using the following design, which seems to work fine:
data Foo = Foo (ForeignPtr Foo) (IORef [IO ()])
Each ForeignPtr Foo has a single finalizer which first calls the C-side
cleanup function for Foo and then executes all the IO-actions inside the 
IORef. 

Now the association becomes
associate (Foo _ ref) bar = 
  atomicModifyIORef ref (\lst - (touchForeignPtr bar : lst, ()))

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


Re: [Haskell-cafe] ForeignPtrs with liveness dependencies

2005-07-26 Thread Einar Karttunen
Simon Marlow [EMAIL PROTECTED] writes:
 No, unfortunately not.  You have foo's finalizer which refers to bar via
 a touchForeignPtr.  If both foo and bar are unreachable (references from
 finalizers don't count), then both foo and bar's finalizers will be
 started together, and may run in any order.

I didn't realize the references from finalizers don't count rule.
What would happen if the finalizer of foo would resurrect bar after 
bar's finalizer has been run?

 So touchForeignPtr does only one thing: it expresses the precise
 relationship bar is alive if foo is alive.  If both are not alive,
 then both finalizers can run, in any order.

So reference counting the objects is the solution?

 I realise this is very subtle.  By all means suggest improvements to the
 docs.

Mentioning that references from finalizers don't count could help
someone not to repeat my mistakes.

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


[Haskell-cafe] ForeignPtrs with liveness dependencies

2005-07-25 Thread Einar Karttunen
Hello

What is the correct way to express liveness dependencies for
ForeignPtrs? I am wrapping a C library and need a way to keep 
ForeignPtrs alive until the finalizer for an another ForeignPtr 
has been executed. 

Basically I have two types, ForeignPtr A and ForeignPtr B and a function
associate :: ForeignPtr A - ForeignPtr B - IO (). I want to keep all
of the ForeignPtr Bs associated with a given ForeignPtr A alive until its
finalizer has been run. The relationship is M:N - each ForeignPtr A may
be associated with multiple ForeignPtr B and each ForeignPtr B may be
associated with multiple ForeignPtr A.

GHC documentation tells that touchForeignPtr is not enough as it makes
no guarantees about when the finalizers are run. If it helps the
finalizers are C functions which neither block nor perform callbacks
into Haskell. 

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


Re: [Haskell-cafe] weired

2005-07-16 Thread Einar Karttunen
wenduan [EMAIL PROTECTED] writes:
 The following function which converts a number represents a sum of money 
 in pence didn't work as expected and the result didn't make any sense to me:

 penceToString :: Price - String
 penceToString  p  =
   let  str  =  show p
len  =  length str
   in
 if len ==1 then 0.0 ++ str else
  if len ==2 then 0. ++ str else (take (len-2) str) ++ . ++ 
 (drop (len - 2) str )

 *Main penceToString 234566678786
 -6710990.94

You are encountering the fact the Int is a fixed size type (32 bits on
many common architectures). Thus 

*Main 234566678786 :: Int
-671099094

Which explains the result. 

To make the program work use Integer instead of Int.


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


[Haskell-cafe] Functional dependencies and type inference

2005-07-15 Thread Einar Karttunen
Hello

I am having problems with GHC infering functional dependencies related
types in a too conservative fashion.

 class Imp2 a b | a - b
 instance Imp2 (Foo a) (Wrap a)


 newtype Wrap a = Wrap { unWrap :: a }
 data Foo a = Foo
 data Proxy (cxt :: * - *)

 foo :: Imp2 (ctx c) d = Proxy ctx - (forall a b. (Imp2 (ctx a) b) = a - 
 b) - c - d
 foo p f x = f x

The type of foo (undefined :: Proxy Foo) is inferred as
forall c. (forall a b. (Imp2 (Foo a) b) = a - b) - c - Wrap c
which shows the outmost functional dependence is working fine. ctx
is carried to the inner Imp2. 

However foo (undefined :: Proxy Foo) Wrap will fail complaining that 

Couldn't match the rigid variable `b' against `Wrap a'
  `b' is bound by the polymorphic type `forall a b. (Imp2 (ctx a) b) = a 
- b'
at interactive:1:0-32
  Expected type: a - b
  Inferred type: a - Wrap a
In the second argument of `foo', namely `Wrap'

My guess is that GHC cannot see that the functional dependency
guarantees that there are no instances which make the inferred 
type invalid. Any solutions to this problem?


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


Re: [Haskell] Re: Existing Haskell IPv6 Code

2005-05-12 Thread Einar Karttunen
Peter Simons [EMAIL PROTECTED] writes:
 Judging from a quick glance, the code seems to marshal the
 POSIX API:

   type SockAddrLen   = Int
   data SockAddrT
   type SockAddr  = ForeignPtr SockAddrT
   data SocketAddress = SA !SockAddr !SockAddrLen

 I'm not sure whether that's a useful representation. It
 works, of course, but it appears that an address is
 essentially opaque (unless you want to do more FFI things).
 It doesn't really unify different types of network addresses
 either. Note, for example, that you can't pass such an
 address to the 'connectTCP' function.

That is one of the few working representations.
The user of the library is not aware how the socket addresses
are represented internally, so it is not a problem. 

Lifting the information to Haskell level seems quite pointless,
as it is usually just fed back to the C functions. Also IPv6
addresses sometimes need scopes - lifting this would make 
things even more messy.

The current way is to ignore adress families as much as possible
while still supporting multiple ones. E.g. the following works
with both IPv4 and IPv6 in network-alt:

googleMainPage = do
  h - connectTCP www.google.com http
  hPutStr h GET / HTTP/1.0\r\n\r\n
  hFlush h
  hGetContents h = print
  hClose h


- Einar Karttunen
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] Re: Existing Haskell IPv6 Code

2005-05-12 Thread Einar Karttunen
Peter Simons [EMAIL PROTECTED] writes:
   Lifting [network address information] to Haskell level
   seems quite pointless, as it is usually just fed back to
   the C functions.

 Well, I certainly _do_ need it.

You can certainly get it:
getHost mySocketAddress niNumerichost
getServ mySocketAddress niNumericserv

 That's true. However, it doesn't work with anything _but_
 IPv4 and IPv6. I think it is unsatisfactory that you need a
 different function to connect to a TCP target than to
 connect to a Unix stream socket.

Having a separate TCP connect function is just for
niceness - of course one can use an aproach to go from
URIs to sockets having a case statement for each scheme.

But what URI should represent e.g. unix datagram sockets?
Having an URI connection function would be nice, but having
it as the primary alternative would not be very nice.

- Einar Karttunen
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] URLs in haskell module namespace

2005-03-23 Thread Einar Karttunen
Hello

Here are some problems I see with the scheme:

1) No easy way of seing the dependencies of a single package.
Currently I can just look at the Cabal file and know what packages are
required. In the new scheme I would need to grep all the source files.
Not a very good improvement in  my opinion.

2) What about machines without an easy http connection out?
These machines are not as uncommon as you may think. Some companies have
internal networks not connected to the rest of the net (and internet
connected machines separate) - and even home I would like to use Haskell
even if there is a network outage.

3) Package versions
You cannot have to modules with the same name in your application. This
is a limit in GHC afaik, not the current import syntax. To handle
versioning you should plan ahead and make new versions support the
serialization syntax of older versions. So there would be no real
advantage. Also if we use an url like http://package/newest then 
we don't have control when we start using a new version of library
(while usually one wants to test that) and if we use
http://package/version then we have to perform the update
in all the source files which use the package (and if we support 
multiple versions then missing one will have fun results).

4) Does not help for nontrivial packages
Most nontrivial packages are a lot more than simple haskell source files
scattered somewhere. They may have C-sources, need configuration when
build or use alex, happy, cpphs or somesuch. 

- Einar Karttunen
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell-cafe] invalid character encoding

2005-03-19 Thread Einar Karttunen
Wolfgang Thaller [EMAIL PROTECTED] writes:
 In what way is ISO-2022 non-reversible? Is it possible that a ISO-2022 
 file name that is converted to Unicode cannot be converted back any 
 more (assuming you know for sure that it was ISO-2022 in the first 
 place)?

I am no expert on ISO-2022 so the following may contain errors,
please correct if it is wrong.

ISO-2022 - Unicode is always possible.
Also Unicode - ISO-2022 should be always possible, but is a relation
not a function. This means there are an infinite? ways of encoding a
particular unicode string in ISO-2022.

ISO-2022 works by providing escape sequences to switch between different
character sets. One can freely use these escapes in almost any way you
wish. Also ISO-2022 makes a difference between the same character in
japanese/chinese/korean - which unicode does not do.

See here for more info on the topic:
http://www.ecma-international.org/publications/files/ecma-st/ECMA-035.pdf


Also trusting system locale for everything is problematic and makes
things quite unbearable for I18N. e.g. on my desktop 95% of things run
with iso-8859-1, 3% of things use utf-8 and a few apps use EUC-JP...

Using filenames as opaque blobs causes the least problems. If the
program wishes to display them in a graphical environment then they have
to be converted to a string, but very many apps never display the
filenames...

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


Re: schedule: re-entered unsafely - with heavy concurrent load

2005-02-19 Thread Einar Karttunen
Simon Marlow [EMAIL PROTECTED] writes:
 I fixed a bug that might cause this in the last couple of days.  Could
 you try again with a fresh build and let us know if the problem still
 occurs?

Seems to work without problems on 6.4.20050218. GHC seems to improve
faster than one can spot problems :-)

- Einar Karttunen
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


schedule: re-entered unsafely - with heavy concurrent load

2005-02-18 Thread Einar Karttunen
Hello

I am having problems with the threaded rts (6.5.20050207)
dying with 'schedule: re-entered unsafely'. The same code 
seems to work with 6.2.2 with threaded rts.

The exact error message is:
foo: schedule: re-entered unsafely.
   Perhaps a 'foreign import unsafe' should be 'safe'?

I originally notices the problem with networking code which 
didn't use any of Network (nor threadWaitX). However the error 
appeared even with the standard libraries tipping in the direction 
of a bug in the rts.

The code works most of the time, but has a small probability of 
failing when load is high. The test case implements a dummy web 
server which can be tried with e.g. apache benchmark (ab),
/usr/sbin/ab2 -c 1000 -n 5000 127.0.0.1:8080/foo
usually crashes the code when run a few times.
The code should be compiled and run as 
ghc --make -threaded foo.hs -o foo  ./foo 8080

import Network
import Control.Concurrent
import qualified Control.Exception as E
import System
import System.IO

main = do [port] - getArgs
  server port

server port = do
  s - listenOn $ PortNumber $ fromIntegral $ read port
  acceptLoop s

acceptLoop sock = do
  (csock,_,_) - accept sock
  forkIO (handle csock `E.catch` print)
  acceptLoop sock

handle sock = do
  hPutStr sock HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\n
  hPutStr sock (This is the body for the request to\n++hope you like 
this.\n\nnow garbage:\n)
  hClose sock


- Einar Karttunen

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Newbie question

2005-01-09 Thread Einar Karttunen
Dmitri Pissarenko [EMAIL PROTECTED] writes:
 a) asking the user to enter several numbers (while the end of the sequence is
 indicated by entering 0)
 b) calculate the sum of those numbers.

 ...
 

Here is a corrected version:

 module Main where

 import IO

Delete this.

 main = do
   hSetBuffering stdin LineBuffering

This is extraneous - stdin should be line buffered by default.

   words - askForNumbers
   printWords words
   map read words
   putStrLn The sum is
   foldl (+) 0 words

Here you map read over words and discard the result.
Then you wold over the words and produce an interger,
whereas you should produce an IO value from the do block.

Here is a complete implementation (untested):

main = do 
   words - askForNumbers
   mapM_ putStrLn words
   putStrLn EOL
   let nums = map read words
   print nums
   putStrLn The sum is
   print (foldl (+) 0 nums)

- Einar Karttunen
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


[Haskell-cafe] Implementing computations with timeout

2005-01-07 Thread Einar Karttunen
Hello

What is the best way of doing an computation with a timeout?

A naive implementation using two threads is easy to create - but 
what is the preferred solution?

withTimeout :: forall a. Int - IO a - IO (Maybe a)
withTimeout time fun =
  do mv - newEmptyMVar
 tid - forkIO (fun  = tryPutMVar mv . Just  return ())
 forkIO (threadDelay time   killThread tid  tryPutMVar mv Nothing  
return ())
 takeMVar mv 


btw How would I do the same with the new STM abstraction?

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


Re: [Haskell-cafe] Implementing computations with timeout

2005-01-07 Thread Einar Karttunen
Tomasz Zielonka [EMAIL PROTECTED] writes:
   import Control.Concurrent (forkIO, threadDelay)
   import Control.Concurrent.STM

   withTimeout :: Int - STM a - IO (Maybe a)
   withTimeout time fun = do
   mv - atomically newEmptyTMVar
   tid - forkIO $ do
   threadDelay time
   atomically (putTMVar mv ())
   x - atomically (fmap Just fun `orElse` (takeTMVar mv  return 
 Nothing))
   killThread tid
   return x

Isn't this buggy if fun just keeps working without throwing an exception
or using retry? I meant wholly inside STM - if we use IO as the
signature then using the TMVar has few advantages over using an MVar.

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


Terminal does not reset correctly with System.Console.SimpleLineEditor

2004-11-06 Thread Einar Karttunen
Hello

It appears that the console is not reset correctly with
System.Console.SimpleLineEditor. The terminal does not 
echo characters until it is reset. 

The following program demonstrates it:
import System.Console.SimpleLineEditor
main = initialise  getLineEdited prompt  = print  restore

This occurs with the Debian ghc package version 6.2.1 and the binary cvs 
snapshot of 20041017, both on i386 linux and in an xterm.

- Einar Karttunen
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


[Haskell-cafe] ArrowLoop examples?

2004-10-23 Thread Einar Karttunen
Hello

Are there any examples of using ArrowLoop outside the signal
functions? Instances are declared for ordinary functions and 
Kleisli arrows, but how should they be actually used?

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


[Haskell-cafe] Re: Seeking reference(s) relating to FP performance

2004-09-29 Thread Einar Karttunen
On 29.09 19:00, John Goerzen wrote:
 3. ghc doesn't seem to do very well in terms of performance, though it
 does at least beat out Java in many cases.

Please note that many of the GHC programs are not posed for
performance, but rather elegance. E.g. the nestedloop got
seven times faster with minor corrections (not reflected
on the website yet).

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


[Haskell-cafe] Strings - why [Char] is not nice

2004-09-20 Thread Einar Karttunen
Hello

Strings in haskell seem to be one major source of problems. I try 
to outline some of the problems I have faced and possible solutions.


Size

Handling large amounts of text as haskell strings is currently not
possible as the representation (list of chars) is very inefficient. 


Serialization

Most of the time when serializing a string, we want to handle it as an
array of Word8. With lists one has to account for cycles and infinite 
length which make the encoding much more verbose and slow. 

The problem is not that some strings may not be trivially
serializable, but rather that it is hard to find the easy
cases.


Typeclass instances

It is currently hard to define typeclass instances for strings as 
String ( = [Char]) overlaps with [a]. Implementations provide
solutions for this, but there should not be a need for workarounds
in the first place.


Show/Read

The current Show/Read implementation makes it impossible to use
with large strings. A read implementation needs to traverse the file 
looking for the terminating '' and handling escape codes. 

A better solution would be to have an efficient (size prefixed)
representation, maybe in a separate Serializable typeclass. But
this would need the ablity to derive Serializable instances for
algebraic datatypes automatically to avoid lots of useless code.


Possible solutions

The optimal solution should be compact and fast. A list of chunks
is one solution - it would make it possible to e.g. mmap files (modulo
encoding) and support fast concatenation. 

In addition one would need to support infinite and cyclic structures.
Adding an alternative which corresponds to the current string
abstraction would be sufficient.

type CharT = Word8

data Str = S [(Ptr CharT, Int)]
 | I [CharT]


A major problem is breaking old code. The main problem is that many
functions are defined only on lists which forces strings to be lists. 
Making the functions polymorphic would solve a lot of problems and 
not only for Strings. There should be no performance penalty (at least
in theory) when the compiler knows which instance is used at compile
time.

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


Re: [Haskell-cafe] Strings - why [Char] is not nice

2004-09-20 Thread Einar Karttunen
On 20.09 12:59, Henning Thielemann wrote:
  Handling large amounts of text as haskell strings is currently not
  possible as the representation (list of chars) is very inefficient. 
 
 Efficiency is always a reason to mess everything. But the inefficiency
 applies to lists of every data type, so why optimizing only Strings, why
 not optimizing Lists in general, or better all similar data structures, as
 far as possible? Why not doing it in a transparent way by an optimizer in
 the compiler? This is certainly the more complicated task, but the more
 promising target for the long term. I very like to apply List functions to
 Strings, so the definition String = [Char] seems to me the most natural
 definition. 

Optimizing all lists would be nice but choosing allways the correct
behaviour would be quite hard. Of course if such an optimization would
exists Strings would benefit from it. 

Making strings an abstract type would not preclude using such
optimizations. But Strings could be optimized even before the
optimization existed.

The list of chars seems natural when thinking in terms of
transformations, but it is not very natural when trying to interact
with external world.

  It is currently hard to define typeclass instances for strings as 
  String ( = [Char]) overlaps with [a]. Implementations provide
  solutions for this, but there should not be a need for workarounds
  in the first place.
 
 That's a problem, I also like to hear opinions about that. E.g. Show
 instance of String doesn't output ['b','l','a'] but bla. 
 

This is because Show has a special case for lists:

class Show
  showsPrec :: Int - a - ShowS
  show  :: a   - String
  showList  :: [a] - Shows

This is not very elegant and does not help when using a boilerplate style
traversal.

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


Re: [Haskell-cafe] Strings - why [Char] is not nice

2004-09-20 Thread Einar Karttunen
On 20.09 15:05, Dylan Thurston wrote:
 You know about the PackedString functions, right?
 
 http://www.haskell.org/ghc/docs/6.0/html/base/Data.PackedString.html

Yes, but they are quite broken. I am using FastPackedString from 
darcs for many purposes, which is like PackedString in many 
ways.

PackedStrings use full unicode codepoints (4*size in bytes), but
having a char  256 in them does not work if one wants to do IO.
This means essentially that the wasted space cannot be used in any
meaningfull way. 

Also concatenating PackedStrings is not very nice:
concatPS pss = packString (concat (map unpackPS pss))

And most important they need a conversion (unpackPS), before
using them with external libraries which expect Strings.

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


Re: [Haskell-cafe] Implementing tryReadMVar

2004-09-02 Thread Einar Karttunen
On 01.09 18:30, MR K P SCHUPKE wrote:
   while channel not empty
   read next event
   if event high priority process now
   else queue event in FIFO
   process first event in FIFO

That suffers from the same problem as I described.

do e - isEmptyChan ch -- is the channel empty?
   case e of
True - processFifo
False- readChan ch = highPriorityOrPush

Now there is danger of blocking on the readChan. (consider a case
where we create two similar server processes reading the same
channel). Now we create a tryReadChan, but we cannot implement
it with tryTakeMVar, as that would break dupChan. Rather we
need a tryReadMVar or a different channel abstraction.

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


Re: [Haskell-cafe] Implementing tryReadMVar

2004-09-02 Thread Einar Karttunen
On 01.09 13:09, Jan-Willem Maessen - Sun Labs East wrote:
 I was, however, curious what use you had in mind where writes were 
 racing, but where you nonetheless wanted to perform blind non-blocking 
 reads.  Such situations are generally fraught with peril.  In this 
 case, the peril is starvation of the debug thread---which you may or 
 may not actually care about.

I was trying to implement safe tryReadChan, which seems to be 
very simple with tryReadMVar, without it it seems to suffer
from various concurrency problems.

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


[Haskell-cafe] Implementing tryReadMVar

2004-09-01 Thread Einar Karttunen
Hello

Is it possible to implement an operation like 
tryReadMVar :: MVar a - IO (Maybe a)
in a good fashion? The semantics should be 
Read the value of the MVar without taking
it if it is filled, otherwise return Nothing.

There are several easy and flawed implementations:

tryReadMvar mv = do e - isEmptyMVar mv
case e of
 True - return Nothing
 False- readMVar mv = return . Just

This does not work because there can be a thread switch 
between the isEmpty and readMVar.

tryReadMVar mv = do mc - tryTakeMVar mv
case mc of
 Nothing - return mc
 Just v  - putMVar mv v  return mc

Now this can block on the putMVar if there was a thread switch 
and someone filled the MVar behind our back. 

Using tryPutMVar does not help much as it just creates another 
race condition:

tryReadMVar mv = do mc - tryTakeMVar mv
case mc of
 Nothing - return mc
 Just c  - tryPutMVar mv v  return mc

Consider what happens if the tryPutMVar fails:

-- read till we get the value with foobar in the middle
loopTill mv = do foobar 
 mc - tryReadMVar mv
 case mc of
  Nothing - loopTill mv
  Just v  - return v

maybe (loopTill mv) process (tryReadMVar mv)

error = do mv - newEmptyMVar
   forkIO (mapM_ (\i - putMVar mv i) [1..10])
   mapM_ (\_ - loopTill mv = print  takeMVar mv = print) [1..10]

If a tryPutMVar fails, then there will be less than ten values to 
read which will make the process block in takeMVar.

This seems quite straightforward in C with GHC (might be wrong
in the SMP case with locking?):

tryReadMVarzh_fast
{
W_ mvar, info;

/* args: R1 = MVar closure */
mvar = R1;
info = GET_INFO(mvar);

if (info == stg_EMPTY_MVAR_info) 
  RET_NP(0, stg_NO_FINALIZER_closure);

RET_NP(1, vStgMVar_value(mvar);
}

What is the best way to do this?

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


Re: [Haskell-cafe] Implementing tryReadMVar

2004-09-01 Thread Einar Karttunen
On 01.09 09:27, Jan-Willem Maessen - Sun Labs East wrote:
 Einar Karttunen wrote:
 Hello
 
 Is it possible to implement an operation like 
 tryReadMVar :: MVar a - IO (Maybe a)
 in a good fashion? The semantics should be 
 Read the value of the MVar without taking
 it if it is filled, otherwise return Nothing.
 
 There are several easy and flawed implementations:
 ...
 tryReadMVar mv = do mc - tryTakeMVar mv
 case mc of
  Nothing - return mc
  Just v  - putMVar mv v  return mc
 
 Now this can block on the putMVar if there was a thread switch 
 and someone filled the MVar behind our back. 
 
 This sets off alarm bells in my head.  What are you actually trying to 
 do, and why is correct for mutiple threads to race to putMVar?

There are several cases in which multiple threads racing putMVar is
correct. Consider e.g. a server thread encapsulating state, which 
needs to rate limit its clients. The server is put behind a MVar
to which all the clients putMVar and thus block until the server 
is ready e.g. 

plumbIn :: MVar SCoreT - HId - Handle - IO ()
plumbIn mv hid h = hGetContents h = loop
where loop s = let (m,r) = readInput s in putMVar mv (Msg m hid)  loop r

The server thread uses tryTakeMVar for its job. 

Now add a debug function:

debug :: MVar SCoreT - IO ()
debug mv = tryReadMVar mv = maybe (putStrLn Nothing) print

And suddenly we have a created a subtle bug in the code with 
flawed tryReadMVar implementation.

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