Re: [Haskell-cafe] Monad Input/Output and Monad Transformers

2009-07-03 Thread Richard Kelsall

Gwern Branwen wrote:
...

 Ultimately, the problem with Haskell and ML for our purposes is that
the brightest and most aggressive programmers in those languages,
using the most aggressive optimization techniques known to the
research community, remain unable to write systems codes that compete
reasonably with C or C++. The most successful attempt to date is
probably the FoxNet TCP/IP protocol stack, which incurred a 10x
increase in system load and a 40x penalty in accessing external memory
relative to a conventional (and less aggressively optimized) C
implemenation. [ 4 ,6  ]

http://www.bitc-lang.org/docs/bitc/bitc-origins.html


Interesting paper.

Putting these remarks in context, in case anyone takes them as a current
critique of Haskell, they are apparently about ten years out-of-date and
apply to this SML program

http://www.cs.cmu.edu/~fox/foxnet.html

I wonder what would happen if the program was ported and benchmarked
in a recent version of GHC.


Richard.

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


[Haskell-cafe] Monad Input/Output and Monad Transformers

2009-07-02 Thread Maciej Piechotka
1. Learning haskell I discovered that I/O should be avoided nearly 'at
all costs'. The problem is that the IO monad is the only one which have
more interactive work flow. There is Reader/Writer monad but in fact
AFAIU first one is about the environment and second one is about
logging. Implementation of Writer can be defined in terms of handles but
it is rather limited (either non-full implementation which may be
confusing or need of caching the result for pass etc.).

I searched the hackage but I didn't find package with pure I/O. Such
package may look like:

class (Monad m, Monoid v) = MonadInput v m where
-- | Gets an element from input (line of text [with \n], 4096 bytes,
--   or something like that). mzero on end
getChunk :: m v
class (Monad m, Monoid v) = MonadOutput v m where
-- | Puts an element
putChunk :: v - m ()

In similar way filters (for example buffered input) can be defined:
class (MonadInput v m) = MonadBufferedInput m where
-- | If not whole chunk has been consumed at once (for example only
--   first 3 elements from list) rest can be returned. It will be 
--   returned as part of the input on next getChunk call.
returnChunk :: v - m ()
data (MonadInput v m, Monoid v) =
 BufferedInputT v m a = BufferedInputT a v

Also pipes may be defined (as far as I understand but I'm not 100% sure)
which probably will simplify the writing of network tests:

-- | Evaluates the first argument. If the getChunk is called the 
--   evaluation is passed to second argument until the putChunk is 
--   called, which argument is returned in the first argument
callPipeT :: (Monad m, Monoid v) =
 PipeInputT v m a - PipeOutputT v m b - m (a, b)

I've started some tests but I'd be grateful for comments (well -
probably I'm not the first who come to this idea so a) there is such
package or b) my level of Haskell does not allow me to see the
problems).

2. I find writing monad transformers annoying. 
Additionally if package defines transformer A and another transformer B
they need to be connected 'by hand'.

I find a simple solution which probably is incorrect as it hasn't been
used:

instance (MonadState s n, Monad (m n), MonadTrans m) =
 MonadState s (m n) where
get = lift get
put = lift . put

(requires FlexibleInstances MultiParamTypeClasses FlexibleContexts
UndecidableInstances - two last are not extensions used by mtl)

Regards

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


Re: [Haskell-cafe] Monad Input/Output and Monad Transformers

2009-07-02 Thread Bulat Ziganshin
Hello Maciej,

Thursday, July 2, 2009, 3:31:59 PM, you wrote:

 class (Monad m, Monoid v) = MonadInput v m where
 -- | Gets an element from input (line of text [with \n], 4096 bytes,
 --   or something like that). mzero on end
 getChunk :: m v
 class (Monad m, Monoid v) = MonadOutput v m where
 -- | Puts an element
 putChunk :: v - m ()

how about interact function?

-- 
Best regards,
 Bulatmailto:bulat.zigans...@gmail.com

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


Re: [Haskell-cafe] Monad Input/Output and Monad Transformers

2009-07-02 Thread Maciej Piechotka
On Thu, 2009-07-02 at 15:43 +0400, Bulat Ziganshin wrote:
 Hello Maciej,
 
 Thursday, July 2, 2009, 3:31:59 PM, you wrote:
 
  class (Monad m, Monoid v) = MonadInput v m where
  -- | Gets an element from input (line of text [with \n], 4096 bytes,
  --   or something like that). mzero on end
  getChunk :: m v
  class (Monad m, Monoid v) = MonadOutput v m where
  -- | Puts an element
  putChunk :: v - m ()
 
 how about interact function?
 

Well. As far as I know there is no way of using it with network.
Additionally there is hard to put monadic code in it:

myFunc :: (MonadInput i, MonadOutput o) =
  (String - m a) - MyMonad i o m [a]

If m == IO - which may be a case in normal code it requires
unsafePerformIO with all it's problems. In testing I can use pipes and
Identity simplifying the whole testing - allowing user to use it's own
monads.

The other problem is that the order sometimes matters. Consider:
main = interact (\x - What's your name?\n ++ Hello:\n ++ x)

For human being it is annoying but sometimes it is for example against
RFC.

Regards 

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


Re: [Haskell-cafe] Monad Input/Output and Monad Transformers

2009-07-02 Thread Luke Palmer
On Thu, Jul 2, 2009 at 5:31 AM, Maciej Piechotka uzytkown...@gmail.comwrote:

 2. I find writing monad transformers annoying.
 Additionally if package defines transformer A and another transformer B
 they need to be connected 'by hand'.


You have not given any concrete problems or examples, so it's hard for me to
comment.  But at first glance, I would conjecture that you are relying too
heavily on monads and sequential thinking.

Consider what your code would look like without a single monad.  Obviously
you cannot talk to the network without IO, but your program can still be *
modeled* purely, and then toss in IO at the last second to tie it to the
network.  This model may be difficult for you because it requires your brain
to be rewired; feel free to mail this list with concrete modeling problems
and we will help you out.

As for the pure model, throw away Reader, Writer, State -- everything, and
just use pure functions.  Then add monads back in *at small scopes* when
they clean things up.

I used to approach problems by designing a monad for my whole program, using
an appropriate stack of transformers.  I suspect such an approach led to the
claim that monads are not appropriate for large software systems in a
popular paper a few months ago.  As I have gained more experience, I found
that this is the *wrong* way to go about using them.  Now my primary use of
monads is within the scope of a single function, to tie together the helper
functions in the where clause.

Luke



 I find a simple solution which probably is incorrect as it hasn't been
 used:

 instance (MonadState s n, Monad (m n), MonadTrans m) =
 MonadState s (m n) where
get = lift get
put = lift . put

 (requires FlexibleInstances MultiParamTypeClasses FlexibleContexts
 UndecidableInstances - two last are not extensions used by mtl)

 Regards

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

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


Re: [Haskell-cafe] Monad Input/Output and Monad Transformers

2009-07-02 Thread Jason Dagit
On Thu, Jul 2, 2009 at 1:18 PM, Luke Palmer lrpal...@gmail.com wrote:



 I used to approach problems by designing a monad for my whole program,
 using an appropriate stack of transformers.  I suspect such an approach led
 to the claim that monads are not appropriate for large software systems in
 a popular paper a few months ago.


Link please!  I googled but I couldn't find it :(  I'd like to find out what
you and the authors have learned about the inappropriateness of monads for
large software systems.


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


Re[2]: [Haskell-cafe] Monad Input/Output and Monad Transformers

2009-07-02 Thread Bulat Ziganshin
Hello Luke,

Friday, July 3, 2009, 12:18:21 AM, you wrote:

 I used to approach problems by designing a monad for my whole
 program, using an appropriate stack of transformers.  I suspect such
 an approach led to the claim that monads are not appropriate for
 large software systems in a popular paper a few months ago.  As I
 have gained more experience, I found that this is the wrong way to
 go about using them. 

was it ghc authors paper? :)

-- 
Best regards,
 Bulatmailto:bulat.zigans...@gmail.com

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


Re: [Haskell-cafe] Monad Input/Output and Monad Transformers

2009-07-02 Thread Maciej Piechotka
On Thu, 2009-07-02 at 14:18 -0600, Luke Palmer wrote:
 On Thu, Jul 2, 2009 at 5:31 AM, Maciej Piechotka
 uzytkown...@gmail.com wrote:
 2. I find writing monad transformers annoying.
 Additionally if package defines transformer A and another
 transformer B
 they need to be connected 'by hand'.
 
 You have not given any concrete problems or examples, so it's hard for
 me to comment.  But at first glance, I would conjecture that you are
 relying too heavily on monads and sequential thinking.
 
 Consider what your code would look like without a single monad.
 Obviously you cannot talk to the network without IO, but your program
 can still be modeled purely, and then toss in IO at the last second to
 tie it to the network.  This model may be difficult for you because it
 requires your brain to be rewired; feel free to mail this list with
 concrete modeling problems and we will help you out.
 
 As for the pure model, throw away Reader, Writer, State -- everything,
 and just use pure functions.  Then add monads back in at small scopes
 when they clean things up. 
 

AFAIU you comment the 2de point only. I look at this moment from
library, not program point of view.

So consider the library IOMonad which defined some MonadInput v m monad.
Then you have NNTP library which has NntpT m monad.

Each of them defines appropriate stack such as that NntpT (State s) is
instance of MonadState. But if there is NntpT MyInput, where MyInput
isinstance of MonadInput, is not MonadInput. To do it with current
approach the libraries would have to be interlinked.

Also it is quite boring to include for all monad
instance ... = ... where
f1 = lift f1
f2 = lift f2
...

 I used to approach problems by designing a monad for my whole program,
 using an appropriate stack of transformers.

I thought about others which might have want to use my monads in their
functions...

 I suspect such an approach led to the claim that monads are not
 appropriate for large software systems in a popular paper a few
 months ago.

I'd appreciate the link - google find nothing. I fall in love in Haskell
about a week or two ago and I fall in love just after I started learning
it ;)

 As I have gained more experience, I found that this is the wrong way
 to go about using them.  Now my primary use of monads is within the
 scope of a single function, to tie together the helper functions in
 the where clause.
 
 Luke
 

Regards

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


Re: [Haskell-cafe] Monad Input/Output and Monad Transformers

2009-07-02 Thread Gwern Branwen
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA512

On Thu, Jul 2, 2009 at 5:05 PM, Maciej Piechotka wrote:
 I'd appreciate the link - google find nothing. I fall in love in Haskell
 about a week or two ago and I fall in love just after I started learning
 it ;)

Research programming languages like Haskell [22] and ML [20] didn't
seem to offer any near-term solution. Diatchki's work on fine-grain
representation in Haskell [25] is not yet main-stream, and had not yet
started when we began work on BitC. Support for state in Haskell
exists in the form of the I/O monad [23], but in our opinion the
monadic idiom does not scale well to large, complexly stateful
programs,1  and imposes constraints that are unnatural in the eyes of
systems programmers.

Oh, and not only do our monads not scale, they're slow to boot:

 Ultimately, the problem with Haskell and ML for our purposes is that
the brightest and most aggressive programmers in those languages,
using the most aggressive optimization techniques known to the
research community, remain unable to write systems codes that compete
reasonably with C or C++. The most successful attempt to date is
probably the FoxNet TCP/IP protocol stack, which incurred a 10x
increase in system load and a 40x penalty in accessing external memory
relative to a conventional (and less aggressively optimized) C
implemenation. [ 4 ,6  ]

http://www.bitc-lang.org/docs/bitc/bitc-origins.html

- --
gwern
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEAREKAAYFAkpNJWoACgkQvpDo5Pfl1oLpeQCcDXUnfBaitwii3rhortVqO8Fr
SXIAnAiKY5EGg/ssZHOaooP1ag1xGIE4
=iugB
-END PGP SIGNATURE-
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe