[MLton-user] Sockets+Monads in SML?
Wesley W. Terpstra
wesley at terpstra.ca
Thu Feb 14 21:02:43 PST 2008
On Feb 15, 2008, at 1:33 AM, Vesa Karvonen wrote:
> fun f x =
> myprint "hello\n" >>
> read >>= (fn x =>
> read >>= (fn y =>
> myprint (x ^ y ^ "\n")))
Well, I was hoping it might somehow be possible to come closer to
Haskell's:
do myprint "hello"
x <- read
y <- read
myprint (x ^ y ^ "\n")
I thought someone might know a more elegant style. When you have 4+
steps and a couple branching cases, the brackets become a problem. --
I am not an emacs user.
>> The problem I'm running up against is that only 'let' clauses and
>> function declarations can introduce variable scope. AFAICT, the let
>> clause prevents me from popping out of the method after installing a
>> signal handler.
>
> Do you have a specific reason to avoid threads? With threads you
> could avoid using monads and just write the program in direct style.
> Your example would become:
>
> fun f x s = let
> val () = print "hello\n"
> val x = read s
> val y = read s
> in
> print (x ^ y ^ "\n")
> end
Threads are very nice and tempting. However, if you have parallel
things to execute, threads are actually restrictive. Using the
functional callback style means you can write things like:
onceAnyFinishIn [ send "x", send "y", send "z" ] doThis
onceAllFinishIn ...
Also, most of these event chains are relatively short lived. Maybe I'm
wrong, but I think threads would be quite wasteful in this case.
>> The function approach suffers due to the syntax of SML.
>
> Yes, I agree that the required parenthesis are a bit of a nuisance. I
> would personally consider changing the syntax of SML to allow fn
> -expressions without parentheses in these contexts like in Haskell.
I assumed there is some reason the ()s are required..? Maybe to avoid
the problems nested 'case' statements have?
> I find the let -syntax fine for functional programming, but somewhat
> verbose for imperative programming (note the "val () =" in the earlier
> example). I would personally ditch the let -syntax and change the
> syntax of SML's sequence expressions to allow bindings like at the top
> level. This would make imperative programming more convenient. The
> thread based version would become:
>
> fun f x s =
> (print "hello\n"
> ; val x = read s
> ; val y = read s
> ; print (x ^ y ^ "\n"))
This is one of two things I like about OCaml as compared to SML. The
other is that constructors must be capitalized (so no brackets are
needed in patterns).
>> Does someone have a tidy way of writing code like this?
> If you can't stand the parentheses, I would recommend considering
> threads.
I suppose I'll have to live with them then.
>> Also, I am concerned by MLton's closure conversion. With this
>> style of
>> programming, there are a *lot* of bound variables which pile up
>> towards
>> the end of the event chain. As I understand it, the closure of MLton
>> is converted into a datatype which represents the function to call +
>> it's free variables. The longer these chains of event handlers get,
>> the more free variables in the later functions. My concern is that
>> it
>> will cost me a lot to convert these datatypes. I am under the
>> impression MLton will flatten them out into one record at each step
>> rather -> O(n^2) cost for n steps of function nesting (if nearly
>> all n
>> variables are used in the last step, which is quite typical).
>> Should I
>> be worried?
>
> I don't know enough about the specifics of MLton's closure conversion,
> but I would personally be more worried if MLton wouldn't be doing
> something like that to avoid space leaks.
Yes. I share your concern. In the end it probably won't matter if
MLton copies repeatedly. I just find waste that's out of my control
irksome.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mlton.org/pipermail/mlton-user/attachments/20080215/5cd8988d/attachment.html
More information about the MLton-user
mailing list