foldM vs. foldL and foldR

1997-02-02 Thread Tommy Thorn

Please, could anybody explain me what the rationale behind the current
foldM in Monad?  At least of the IO monad, it seems important to have
a left associative fold instead of the right associative foldM.
Adding to my confusion, it seems that earlier in time, there was
indeed two monad fold's instead of just one.

Confused,
  Tommy






Haskell 1.3?

1996-03-05 Thread Tommy Thorn


Quoting from "Introducing Haskell 1.3" (http://www.cs.yale.edu/
HTML/YALE/CS/haskell/haskell13.html):

 "The final version of the Haskell 1.3 is expected to be complete in
  January, 1996."

Does anyone know what happens?

Regards, Tommy
-- 
 "When privacy is outlawed, only outlaws will have privacy."
  -- Phil Zimmerman






pattern guards and guarded patterns

1997-04-30 Thread Tommy Thorn

I can see the arguments for the pattern guard extension and the syntax
seem reasonable.  

I also agree with Chris on the shortcomings of if-then-else.  (I have
disliked it in any language where I've seen it, and it "feels"
un-Haskell-like to me.)  On the other hand, the suggested

  case
| ... -> ... 

syntax seems confusing (overloads `case') and redundant (we don't need
a SML-like `|', we have layout rules).  Although its origin is the
case expression, the special syntax is a witness to the fact that it
is different.  Something like

  cond
x == y -> same x
x == y*2 -> haly x
.
otherwise -> default x

would be much easier on my stomach.

My only worry is that Haskell (if not already) is turning into the C++
of functional languages, ie. feature upon feature.  Haskell is already
quite a mouthfull to learn.

/Tommy






Evaluating Haskell

1997-08-27 Thread Tommy Thorn

David Wilczynski raises some very important and interesting questions
about Haskell from a "Real World" point of view.  I would very much
like to see this kind of discussions, which I feel are essential if
Haskell is ever to move out of the laboratories.  Please do *not* move
this discussion into private email or phone.

I'll just comment on one small item:
> Is there a strategy in which an
> engineer can learn a useful subset of Haskell, and grow into it as need be?
> I am unconvinced by arguments such as "this perfectly ordinary Yale
> graduate student learned Haskell in just 8 days."

I think it was about correct for me, although understanding type
classes well enough to create my own (as opposed to just using them)
too a lot longer.  I generally "feel" Haskell as one of the simplest
languages I know(!), in the sense that things are natural, logical,
general, and without unpleasant surprises.  Of course, this is just
relatively to the many other languages I know (not least Java).

> 4) Concurrency -- I saw that one of the compilers supported Concurrent
> Haskell. I don't recall seeing any mention of it in any of the material I
> have. Have I missed it?

No, concurrency is not part of the standard language, but it would
sure be nice if it was (hint hint).

I look forward to follow the discussion,
  Tommy





Punning: Don't fix what ain't broken.

1998-02-11 Thread Tommy Thorn

John Hughes wrote on the Std Haskell board:
 
> `Punning' can be used in three places in Haskell. Suppose a record
> type is defined by
> 
> data R = R{x :: Int}
> 
> Then
> * R{x} constructs a record, and is equivalent to R{x=x}
> * r{x} updates the x field of record r, and is equivalent to r{x=x}
> * R{x} can be used as a pattern; its meaning is not defined by the
>   report, but is presumably supposed to be the same as R{x=x}
> 
> I've used this. It's convenient, but I had a bad taste in my mouth
> afterwards. I support removing all forms of punning from the
> language. But this would, of course, break existing programs. I want
> to do it anyway. Note that the puns become syntactically incorrect
> in every case, so broken programs can be mended just by correcting
> the syntax errors.

I'm surprised and disappointed with the Standard Haskell effort on
punning.  A grand total of two messages but absolutely no discussion
and *pop* there it went down the pipe.

Yes it convenient, and sometimes even very convenient.  I can't see
the value of arguments like "bad taste in the mouth".  Why was it
introduced in the first place?  Are there any *known* examples where
this feature has caused problems?  As John notices, the punning form
do not overlap syntactically with anything, so you can't used them by
accident.

Instead of junking it, I would rather have seen the pattern matching
punning syntax (R{x}) become official, as this is the most useful of
the three punning.

/Tommy





Re: Punning: Don't fix what ain't broken.

1998-02-12 Thread Tommy Thorn

Koen Claessen:
> This brings us to another issue. Doesn't the following definition look
> a bit awkward? 
> 
>   R{ x = x }

Definitely wierd.  The left and right-hand side denotes two different
things, which AFAIK is the only place where `=' behaves like this.
Wouldn't `<-' have been a better choice?  `<-' bindings are never
recursive, thus `R{ x <- x } is less surprising, as the two x's can't
be the same.

It would be worth taking into account if completely revising the
record handling of Haskell, but in itself it's too small a gain to be
worthwhile.

My humble opinion,
  Tommy





the overloading of ==

1998-03-12 Thread Tommy Thorn

Victor M. Gulias wrote/a ecrit/skrev:
> As a naive implementation of "all" and "any", one of my students coped with 
> these definitions:
> 
> any' p xs = [x | x <- xs, p x] /= []
> all' p xs = [x | x <- xs, p x] == xs 

I used to be in favor of the monadic overloading of list operations,
but this example is really shocking.  I note as well that the errors
messages from both Hugs and GHC leaves a lot to be desired.

/Tommy





FP Naming/Directory Service

1998-03-24 Thread Tommy Thorn

S. Alexander Jacobson wrote/a ecrit/skrev:
> I just started playing with Haskell for CGI applications.
> I would like to try writing a more serious CGI app, but
> missing infrastructure makes it more difficult than conventional
> approaches.

On a general note, I too try employ Haskell for more and more common-
day tasks (eg replacing a great number of shell/Perl hacks) and almost
daily face the lack of support, mostly in the form of missing
libraries.

I think there are two major causes to this effect: one is the high
emphasize on theoretical aspects of the language and a disproportional
low effort on plain practial aspects.  Contrast this with the
development of languages like Erlang and Java.  In the latter case the
language was carved in stone long time ago (*) and the effort
concentrated on producing a mind-bogling large library, covering all
sorts of applications.

Another causes is the simple observation that Java users largely
outnumber Haskell users.

The only option we have (IMHO) is to ease and streamline the process
of introducing new libraries and write and make available good
libraries as the needs are encountered.  In this respect, GreenCard
constitutes a key element.


(*) I'm not claiming that this is a good idea, even less that they
where successful.

> In decreasing order of preference, is there an available
> implementation of:
> * an equivalent to Java's Naming and Directory Services interface
> * an LDAP client for some particular LDAP server
> * an XML editor
> * a generic ODBC/JDBC database client
> * an interface to berkeleyDB (or some persistent hashtable
>   implementation)
> 
> I suppose that I could have Haskell talk to Jacl to access the Java
> implementations of these capabilities, but this seems like a hack.
> 
> Any pointers?

I don't the first three at all, so I can't comment on them.  AFAIK,
writing a library with more or less the same functionality as
ODBC/JDBC should be perfectly doable.  As for the latter, I imagine
that something very useful could be built in combination with the
Binary library from York (a should-be standard library, IMHO).

/Tommy





Phil's Pretty Printing Library

1998-03-27 Thread Tommy Thorn

In an attempt to gather experience with Philip Wadlers pretty printing
combinators, I converted a semi big pretty printer to his pretty
printing.  My initial experiences are positive: while Phil's
combinators are clearly less expressive, they were expressive enough
(at least with the improvements below) and the results was subjectly
clearer.

For the utility of others which might wish to experiment I include my
library, apologizing up front from the lack of clean-up,
documentation, and optimization.

On an unrelated note, I like to add that I consider it a feature, not
a bug, that combinators build a Doc structure, as this enables a later
unforseen interpretation of the document.  Such an interpretation
could be for proportional fonts, colors, etc.

/Tommy
---

  Philip Wadlers Simplified Pretty Printing Library

Hacked somewhat to pieces by Tommy Thorn, 26/3-1998

Major changes:
  - <+> and $$ has nil (empty) as unit.
  - bline is a blind line that disappears when flattened

> module WadlersPretty where

> infixr 5 :<|>
> infixr 6 :<>
> infixr 6 <>, <+>
> infixr 5 , $$

> data Doc= Nil
> | Doc :<> Doc
> | Nest Int Doc
> | Text String
> | Line
> | BLine -- blind line
> | Doc :<|> Doc
> 
> data DOC= NIL
> | String `TEXT` DOC
> | Int `LINE` DOC
> 
> 
> nil = Nil

Maintain canonical form

> Nil <> y= y
> x   <> Nil  = x
> x <> y  = x :<> y
> nest k Nil  = Nil
> nest k x= Nest k x

`text ""'  is not the same as nil

> text= Text
> line= Line
> bline   = BLine

> group x = flatten x :<|> x
> 
> flatten Nil = Nil
> flatten (x :<> y)   = flatten x :<> flatten y
> flatten (Nest i x)  = Nest i (flatten x)
> flatten (Text s)= Text s
> flatten Line= Text " "
> flatten BLine   = Nil
> flatten (x :<|> y)  = flatten x
> 
> layout NIL  = ""
> layout (s `TEXT` x) = s ++ layout x
> layout (i `LINE` x) = '\n' : copy i ' ' ++ layout x
> 
> copy i x= [ x | _ <- [1..i] ]
> 
> best w k x  = be w k [(0,x)]
> 
> be w k []   = NIL
> be w k ((i,Nil):z)  = be w k z
> be w k ((i,x :<> y):z)  = be w k ((i,x):(i,y):z)
> be w k ((i,Nest j x):z) = be w k ((i+j,x):z)
> be w k ((i,Text s):z)   = s `TEXT` be w (k+length s) z
> be w k ((i,Line):z) = i `LINE` be w i z
> be w k ((i,BLine):z)= i `LINE` be w i z
> be w k ((i,x :<|> y):z) = better w k (be w k ((i,x):z)) (be w k ((i,y):z))
> 
> better w k x y  = if fits (w-k) x then x else y
> 
> fits w x | w < 0= False
> fits w NIL  = True
> fits w (s `TEXT` x) = fits (w - length s) x
> fits w (i `LINE` x) = True

A Pretty Class

> class Pretty a where pretty :: a -> Doc
> instance Pretty Char   where pretty c = text [c]
> instance Pretty Intwhere pretty n = text (show n)

Utilities

> Nil <+> y= y
> x   <+> Nil  = x
> x   <+> y= x <> space <> y

> Nil $$  x= x
> x   $$  Nil  = x
> x   $$  y= x <> line <> y

> xy= x <> line <> y  -- force a newline

> punctuate sep [] = nil
> punctuate sep [x]= x
> punctuate sep (x:xs) = x <> sep <> punctuate sep xs

> vcat = punctuate line
> sep x= group (vcat x)

> parens x = text "(" <> x <> text ")"
> brackets x   = text "[" <> x <> text "]"
> braces x = text "{" <> x <> text "}"

> empty= nil
> space= text " "
> period   = text "."
> comma= text ","
> semi = text ";"
> colon= text ":"

> int :: Int -> Doc
> int n = text (show n)

> char :: Char -> Doc
> char n = text [n]

> instance Show Doc where 
>   showsPrec _ x = showString (layout (best 79 0 x))

> putDoc :: Doc -> IO ()
> putDoc x = putStr (layout (best 79 0 x))





Re: Phil's Pretty Printing Library

1998-03-28 Thread Tommy Thorn

>   Incidentally, the above def of `sep' doesn't match Hughes' in an important
> way.  Consider:

Aiee, I knew this was gonna backfire.  No, my `sep' does not (and
wasn't intended to) have exactly the same semantics as Hughes' `sep'.
Also, please understand that Phil never proposed such a `sep'. 

Likewise with the other combinators with the same name as Hughes'.
The purpose of using the same names was just to ease the transition,
not to eliminate it.  Apologies to everyone for not making this
clear. 

/Tommy





Keep it up! [Re: Where is Haskore discussed?]

1998-05-06 Thread Tommy Thorn

Hi there,

Just a my "deux centimes" to say that I'm happy with "application"
oriented discussion on the Haskell list.  In fact, I'd be happy to see
more "applications" discussed, like CGI, Fran, Happy, ...

/Tommy





Re: FW: Exceptions are too return values!

1998-06-10 Thread Tommy Thorn

Thats a wonderful idea.  With that it will be so much easier to write
robust code without bloating the code with error checks.

I've always been annoyed that I couldn't trap arbitrary errors, say to
close down the application cleanly.

Now, we only need extendible data types, and then we have an (almost)
ML-like exception system :)

/Tommy

Simon L Peyton Jones wrote/a ecrit/skrev:
> 
> Alastair Reid has been very quiet, so I'll pipe up for him.
> 
> Here's a reasonable design for exceptions in Haskell:
> 
> * A value of Haskell type T can be
>   EITHER one of the values we know and love 
>  (bottom, or constructor, or function,
>   depending on T),
> 
>   OR it can be a set of exceptional values.
> 
> * raise :: String -> a
>   (raise s) returns a single exceptional value, named by string s
> 
> * All strict operations (case, +, etc) return the union of
>   the exceptional values returned by their strict arguments
>   For example, if both arguments to "+" return an exceptional value
>   then "+" returns both. Similarly, any strict context.  
> 
> * handle :: (String -> IO a) -> IO a -> IO a
>   (handle h a) tries to perform the action a.
>   If doing so delivers a set of exceptional values then
>   apply the exception handler h to the string that names
>   one of them.  It is not defined which of the exceptional 
>   values is picked.
> 
> 
> The neat thing about this is that the exceptions can
> be *raised* in arbitrary purely functional code, without
> violating referential transparency.  The question of
> which exception is chosen is done in the IO monad, where
> of course it is allowed to be non-deterministic.
> The implementation does not keep sets of exceptional values,
> of course.  It simply propagates the first one it trips
> over to the nearest enclosing handler.
> 
> (It is likely that successive runs will actually give
> the same behaviour, but recompiling the program with
> (say) different optimisation levels might change the order
> of evaluation, and hence change which exception is tripped
> over first.)
> 
> We're implementing an experimental version of this
> in GHC, integrated with the IO monad exceptions, so that
> 
>   handle :: (IOError -> IO a) -> IO a -> IO a
> 
> and we add an extra constructor (UserError String) to the
> IOError type for exceptions raised by raise.
> 
> Calls to "error" also show up as an exceptional value, of
> course.
> 
> One merit of the system is that it chops out a tremendous
> number of run-time error checks in the IO monad, since
> we are now free to implement the mechanism with standard
> stack-unwinding techniques.  Result: much better I/O performance.
> 
> 
> I'd be interested to know what people think of this.
> 
> Simon





GHC import chasing [Was: GHC/Hugs Status]

1998-07-20 Thread Tommy Thorn

Alastair Reid wrote/a ecrit/skrev:
> > * import-chasing as part of the spec
> 
> This is an environment feature not a language feature.
> 
> What does it mean for GHC?
> Are you wanting to do away with Makefiles?
> Makefiles can do an awful lot more than import chasing can
>  and GNU makefiles are very, very short in the normal case.

I use a lot of Makefiles, but why must we use ugly tools with beatiful
languages?  They are especially bad for a novice, just trying to gain
a little more speed on his Hugs program.

What I'd really like to do is just: ``ghc Main.hs'', and obtain a Main
executable.  For the more advance user (using Green-Card, Happy, and
whatnot) there should always be the brainless "C-style" way.  I fail
to see why GHC must be so difficult to use for multi file programs(*).

/Tommy
(*): I'm perfectly willing to accept that I'm a clueless newbie, but
even after having read the manual and studied the code, I wasn't able
to get a working Makefile.  Is it doable in a few easy steps?  Mind
you, that ``ghc -M'' did not cut it: the default rules weren't
specified.





Plea for Change #1: Why, O why, `Main'?

1999-03-29 Thread Tommy Thorn

Jens' question gave my a perfect opportunity to open my a pet peeve of 
mine: the ditatorship of `Main'.

In Haskell, the `main' function must reside in the `Main' module.
Add to this that the `Main' module must reside in a `Main' file and
you have an unfortunate consequence that you can only have one `Main'
function in each directory.  This in turn means that to have, for
example several variants of a program, you *must* defer to either
messing with a preprocessor or dealing with multi-directory
compilation, not a pretty sight in either case and especially daunting 
to a beginner.

In this Haskell is in contrast to most other popular programming
language.  The alternative seems quite straightforward and there are
no technical difficulties:

  1) Accept the `main' function can be put in any module, and/or
  2) Introduce a nothing of "anonymous" modules, of which the file
 name can be anything.

I'd prefer 1) alone.  

/Tommy





Plea for Change #2: Tools

1999-03-29 Thread Tommy Thorn

I have another pet peeve: ease of use of tools.

The Haskell standard (intentionally?) leaves the interface to tools an 
implementors question.  Unfortunate, IMHO, every Haskell compiler I've 
tried (GHC, NHC, HBC) have just had plain horrible interfaces.
Interpreters are inherently a different story, but Hugs at least is a
lot more friendly.

Even when taking the simple example from my previous^2 post

  ghc -c Add.hs
  ghc -c Main.hs
  ghc -o Main Main.o Add.o

we notice that it takes three commands, in the right order, each with
a non optional flag.  There is nothing present here that couldn't be
deducted directly from the contents of `Main.hs', thus a simple `ghc'
(or `ghc Main' assuming my first plea) command should have sufficed.

Now granted the three commands above isn't exactly rocket science and
anyone with a little exposure to `C' (God forbid) would immediately
feel at home.  Only, this naive interface only brings the deficiencies
of C to the complexity of a type checked module based language.
Maintaining dependencies with makefiles is both hairy and error prone.
There exists scripts like `ghcmake', but that's only patching a rotten
foundation and cracks are quick to surface (try anything non trivial,
like using multiple directories).

I'm not targeting `ghc' in particular, but I do feel that for a
programming language that stresses cleaness, the tools should reflect
the same: simple things should be simple to do.

The report should state the least common denominator interface to
command line tools, at least up to relatively simple tasks like
compiling a multi-module program (spanning several directories).

How about `haskell2 [-I ] '?

/Tommy






Main.main [Was: question to GHC 4.02]

1999-03-29 Thread Tommy Thorn

Dear Jens,

the problem is quite simple, but alas, the error message leaves much
to be disired: standalone Haskell program must contain a `main'
function in the `Main' module (thus the missing Main_main_closure
reference).  Furthermore, this `main' function must have the type
signature `IO ()' (or was that finally changed to `IO a'?).

In essence, you have just given a function (`add'), but not specified
how your program should interact with the world.  To do this you could 
add a module like:

  module Main where
  import Add
  main = print (add 42 1729)

and compile with

  ghc -c Add.hs (file and module name must be identical)
  ghc -c Main.hs
  ghc -o Main Main.o Add.o

Best regards,
  Tommy


[EMAIL PROTECTED] wrote/a ecrit/skrev:
> Dear Sir or Madam
> 
> I have written this small simple program
> 
> module Add where
> add :: Int -> Int -> Int
> addx1 x2 x1 + x2
> 
> I have create an object file with the command % ghc -c additon.hs
> Now I will create an executable file.
> What I have to do?
> 
> The command % ghc -o addition addition.o give me following failure message:
> 
> /usr/lib/ghc-4.02/libHS.a(PrelMain__8.0)(.text+0x2a)
> undefined reference to 'Main_main_closure'
> /usr/lib/ghc-4.02/libHS.a(PrelMain__8.0)(.data+0xc)
> undefined reference to 'Main_main_closure'
> 
> If you can help me, please contact me under:
> 
> [EMAIL PROTECTED]
> 
> I use a Red Hat 5.1 system and GHC 4.02 .
> 
> Yours sincerely
> 
> Jens Fiedler





A datatype for the text editor buffer?

1999-07-06 Thread Tommy Thorn

Peter Hancock wrote/a ecrit/skrev:
> I don't think its crazy.  I thought that one could start with
> something simple, like a "before" list and an "after list".

Indeed.  When I was getting into Haskell, I hacked the ansi.hs example
from the Hugs distribution to add editing.  Parts of the function
actually became simpler this way.

Regards,

  Tommy


readAt:: Pos  ->  -- Start coordinates
 Int  ->  -- Maximum input length
 (String -> Interact) ->  -- How to use entered string
 Interact

readAt (x,y) l use = writeAt (x,y) (copy l '_') (moveTo  (x,y) (loop "" ""))
 where loop rh t   -- Inv: s == (reverse rh)++t
   = readChar (return rh t) (\c ->
 case c of '\BS' -> delete1 rh t
   '\DEL'-> delete1 rh t
   '\n'  -> return rh t
   '\002'-> backwards rh t
   '\006'-> forwards rh t
   c | (length (rh++t)) < l && ' ' <= c
 -> writeChar c (writeLoop (c:rh) t)
 | otherwise -> ringBell (loop rh t))
   backwards [] t = loop [] t
   backwards (c:rh) t = writeChar '\b' (loop rh (c:t))
   forwards rh[]  = loop rh []
   forwards rh (c:t)  = writeChar c (loop (c:rh) t)
   delete1 [] t   = ringBell (loop [] t)
   delete1 (c:rh) t   = writeChar '\b' (writeLoop rh t)
   writeLoop rh t = writeString (t++"_"++(copy ((length t)+1) '\b'))
(loop rh t)
   return rh t   = use ((reverse rh)++t)






Stylistic question about Haskell optional arguments

1999-08-16 Thread Tommy Thorn

Andy Gill wrote/a ecrit/skrev:
> I've got a stylistic question about Haskell.
> What's the best way to add optional arguments to a
> embedded DSL?
> 
> For example, say I've got an library of HTML combinators.
> To represent
> 
> This is a Header
> 
> you might write
> 
> h1 (stringToHtml "This is a Header")
> 
> The types of the functions are
> 
> h1 :: Html -> Html
> stringToHtml :: String -> Html

Please make that an instance operator, such that you don't have to
litter the name space, eg.

h1 :: HTML -> HTML
class HTMLable a where
  html :: a -> HTML

> Looks OK, but what about if you want this header
> right aligned? I can see three ways.


> (2) Combinators that take arguments have different names.
> So you might have
> 
> h1 :: Html -> Html
> h1' :: [HtmlAttr] -> Html -> Html

IIRC this is what TkGofer used.  Works nice in practice and is
_simple_!

Say, are you making a better version of LibCGI?  We could use a
maintained, unified, and more complete library.

Regards,

  Tommy





Re: Haskell HTTP lib?

1999-08-27 Thread Tommy Thorn

Sven Panne wrote/a ecrit/skrev:
> William Lee Irwin III wrote:
> > Personally, I'd like to see some equivalent of the C system call
> > select(2) in GHC's socket library; [...]
> 
> About a year ago this has been discussed, but the implementation has
> somehow vanished from GHC's sources. Strange...
> 
>http://www.dcs.gla.ac.uk/mail-www/glasgow-haskell-bugs/msg01147.html

I'm happy to see my old plea reanimated.

It interesting to note that now, a year later, the situation hasn't
improved much.  It seems most everybody agrees that lack of access to
system libraries makes it impossible to employ Haskell for certain
tasks.  The various FFIs promises to help out here, but correct me if
I'm wrong, but it seems that _none_ of the existing FFIs would help
here, as support for select depends on the implemention of Haskell
primitives, such as Handle.

Regads,

  Tommy





Mixing fruits [Was: Clean and Haskell]

2000-01-13 Thread Tommy Thorn

I makes very little sense to compare GCC (C++) with GHC (Haskell) inspite of the
sneaky names.

1) While no C++ expert, I'd conjecture that compiling C++ is roughly five times
harder than C, due to C++ being a much larger language with _many many_ ugly
corners.  The difficulty in compiling Haskell is not exactly comparable, as the
language it much more advanced, but also far more streamlined.  Haskell however, has
also grown to be a fairly large language.

2) Whereas for the speed of compilers there's little in C++ that should slow down a
_non_ optimizing compiler (well...).  C++ evolved from C and C++ compilers evolved
from C compilers.  C was designed such that you could compilable it on the machines
available at the time (that is, less than 64k).  Haskell, however, was designed in
modern time and require much more work of the compiler (even a _non_ optimizing
compiler) in order to save the work of the programmer.

As a consequence of the language there is less room and need for optimization when
compiling C++, and the optimization rarely improves the result in a spectacular way.
With Haskell, the situation is quite different.  There can be a world of difference
between the performance of a naive Haskell compiler and a sophisticated one and there
is likely to be a correlation with the compile time.

3) Compiling C and C++ is relatively well understood and GCC is a production level
compiler.  Compiling Haskell is still the basis of active (? :-) research and GHC is
a research project.

Frank A. Christoph wrote:
>  The number of times GHC has been too slow and
> memory-hungry for me indicates that Haskell is not suitable for writing
> anything as general-purpose as a compiler.

That's a fairly naive remark.  I could write you a really slow and fat C++ compiler i
C if you like. There are a number of reasons why it's too early judge.  For a
stunning example, you should look at Niklas Rojemo's thesis about NHC.  Now there's a
space-tight compiler (although slow).

Having said all that, yes, predictable memory behavior is IMHO the biggest problem of
lazy language implementation these days.

Juergen Pfitzenmaier wrote:

> Maybe it is because GHC is doing some things that are difficult ;) Oh I know
> a C++ compiler is handling complicated things (but only because the design of
> C++ is brain damaged). Haskell is well designed (not neccessarily in every
> detail but more as a whole) and has some features that need memory to compile.
> I know of C++ programms with ca. 10.000 lines that take about 20 (twenty !!)
> minutes to compile with egcs 1.1 on a 300Mhz pentium II. So there does GHC stand ?

To make even the slightest useful statements based on these opservations we would
have to know much more, at the very least, the level of optimization used.



/Tommy





drop & take [was: fixing typos in Haskell-98]

2000-01-24 Thread Tommy Thorn

S. Alexander Jacobson writes:
 > The correct definitions would be:
 > 
 > take -2 -- drops the last 2 elements from the list
 >  (takes everything except the last 2 elements)
 > drop -2 -- grabs the last 2 elements from the list
 >  (drops everything except the last 2 elements)

 > These are also sane definitions..  

IMHO, that would be the _insane_ definitions :-)  Firstly, nothing
suggests to me that rationale of such behaviour.  Secondly, it would
mean loosing an important set of laws:

  drop n . drop m === drop (n + m)
  take n . take m === take (n + m)

(which, I note in passing, is broken also by suggestion A)

Regards,

   Tommy



Re: drop & take [was: fixing typos in Haskell-98]

2000-01-25 Thread Tommy Thorn

Chris Okasaki wrote:

> For the people that share this sentiment, can you please
> explain why ints that are too big should not similarly
> give an error?  I can see both being ok, or both being
> errors.  I just don't see why one should be ok and the
> other an error.

IMHO, both should be errors.  If we really need, we can provide
takeSloppy, takeBackwards, etc, but the default should be a tight as
possible to catch errors.

I still believe that take and drop should satisfy the compositional laws
on legal arguments.

Regards,

  Tommy





Re: A hard core game programmers view

2000-01-27 Thread Tommy Thorn

"D. Tweed" wrote:

> Another reason for the popularity of Perl is that it's _popular_ &
> _ubiquitous_. Although I like Haskell and some other languages (e.g.,
> Mathematica, python, even C++) more than Perl, when I want to produce
> something that I hope other people in my lab will use/contribute fixes to,
> Perl's what I use (with much swearing & looking up in the manual). There's
> only a few machines with a Haskell system available on them, whereas
> everything has a Perl interpreter installed, and few people who are
> comfortable with the language.

That true, there are other contributing factors.  Look and the following
list, and notice how ever point is in striking contrast to Haskell:

  - Perl has one implementation
  - The implementation is rather lightweight *and* reasonable efficient
  - A large class of problems can be solved %90 very quickly with Perl
  - Perl has a _very_ complete library, including _all_ of unix api
  - The language has remained fairly stable
  - In the begining Perl advotates would tirelessly answer every question in
comp.unix with some Perl code that answered the question
  - Perl is easy to install and is omnipresent

Notice that the language itself is far from the whole story.  In fact, while
the language "features" will get you 90% of the solution fairly quickly, I
know from professional experience that maintaining Perl scripts written by
others can be a living nightmare and that the Quick'N'Dirty style promoted by
Perl _will_ bite you in the end.

> Of course, what can be done to help the start an epidemic `infecting'
> people & machines with Haskell I don't know...

Apart from the obvious of engineering better implementations and more
complete libraries, we could publish code that solves common problems.
Unfortunately it takes time to do properly, and in contrast to Perl, Haskell
really shines on larger problems...

/Tommy



Constrained instances?

2000-04-29 Thread Tommy Thorn

Isn't it possible to constrain instances? 

I tried the following where the idea is to implement a simple monad,
but one which can only pass and return values that are showable.

  newtype Show a => TracingEv a = TE (Int -> IO (Int,a))
  unTE :: Show a => TracingEv a -> Int -> IO (Int,a)
  unTE (TE x) = x

  instance Monad TracingEv where

return i = TE (\c -> do print c; putChar ':'; print i; putChar '\n'
return (c+1,i))

m >>= f  = TE (\c -> do (c',v) <- (unTE m) c
(unTE (f v)) c')

Neither GHC, nor hugs likes this.  Hugs report:

  ERROR "MonadProblem.hs" (line 9): Cannot justify constraints in
  instance member binding
  *** Expression: return
  *** Type  : Monad TracingEv => a -> TracingEv a
  *** Given context : Monad TracingEv
  *** Constraints   : Show a

?? "Cannot justify constraints??"  Isn't the case here rather that some
constraints are lacking?

GHC offers a little more explanation, but it remains cryptic:

  MonadProblem.hs:9:
  Could not deduce `Show a' from the context: ()
  Probable cause: missing `Show a' in type signature for `return'
  arising from use of `TE' at MonadProblem.hs:9
  In the right-hand side of an equation for `return':
  TE (\ c -> do
   print c
   putChar ':'
   print i
   putChar '\n'
   return (c + 1, i))

Sure there's a missing Show a, but I can't change the signature of
return and it seems to me that Show a should follow from the
constraint on TracingEv

Is this a fundamental limitation?  If so, why?

Regards,

  Tommy




Desugarer for the happy Haskell parser?

2000-05-03 Thread Tommy Thorn

First let me thank the authors of the prototype Haskell parser (Simon
Marlow, Sven.Panne, and Noel Winstanley).  It's a beautiful piece of
work.

While writing a desugarer for this, it occurred to me that somebody
might already have done the work and be willing to share it, if not
I'll make it available once it's finished.

I looked at the desugarer from GHC, but it seems to different enough
that it would be simpler to write a new, rather than adapt it to the
Happy Haskell Parser.

Best regards,

  Tommy





What happened to the GRIN project?

2000-06-19 Thread Tommy Thorn

Long time ago I read 

  The GRIN Project:
A Highly Optimising Back End for Lazy
 Functional Languages

Urban Boquist
Thomas Johnson

I thought it sounded very promising, but never heard anything since.
Why?  Didn't it work?

Best regards,

  Tommy




Re: What happened to the GRIN project?

2000-06-19 Thread Tommy Thorn

Thanks John,

that's what I want to hear.  Now the obvious follow up questions:

  1) are anyone pursuing this line of work, and
  2) is the software available?

Best wishes,

  Tommy


John Hughes writes:
 > The results of the GRIN experiment are written up in Urban Boquist's
 > PhD thesis from last year, which you can fetch from his home page:
 > 
 >  http://www.cs.chalmers.se/~boquist/
 > 
 > I found the results very exciting. It's true that GRIN uses a whole-program
 > analysis, but in practice that turned out not to be particularly expensive
 > (usually no more than 2% of compile time). If I remember rightly, Urban
 > compiled programs up to around 10,000 lines without a problem, although the
 > benchmarks in the thesis are much smaller. The code generated was on average
 > three-and-a-half times faster than code from GHC, and in the best case 40
 > times faster! That extra order of magnitude seems to come from conservative
 > unfolding transformations which are effectively disabled in larger programs,
 > which raises the possibility that, with more aggressive unfolding, a further
 > substantial improvement in the running times of large programs might be
 > achievable.
 > 
 > I recommend the thesis heartily. I enjoyed reading it very much.
 > 
 > John Hughes




Pattern matching

2000-06-20 Thread Tommy Thorn

I've looked at the pattern matching semantics as defined in the
Haskell 98 report and there is few things I don't understand.

1) In Figure 3 (Semantics of Case Expressions, Part 1) clause c reads:

case v of { p | g1 -> e1 ; ...
  | gn -> en where { decls }
_ -> e' }

= case e' of
  { y ->  -- (where y is a completely new variable)
case v of {
 p -> let { decls } in 
if g1 then e1 ... else if gn then en else y
 _ -> y }}

  My question is this: doesn't this mean that e' all of a sudden
  becomes strict, ie. that 

case v of { p | g1 -> e1 ; ...
  | gn -> en where { decls }
_ -> _|_ }
= _|_

  ???  Why is it defined like this.

2) In the following clause (d) it is required that x1',...,xn' be
   completely new variables.  Why?  It seems to me that reusing
   x1,..,xn works just fine.  Is there an alpha conversion requirement
   that I missed?

Thanks,

  Tommy




Desugaring of top-level pattern bindings?

2000-06-29 Thread Tommy Thorn

I'm puzzled by the Haskell 98 report, as it doesn't seem to explain
how to desugar top-level pattern declarations, such as

  (x,y) = e

In Section 4.4.3 (Function and Pattern Bindings) under Pattern
Bindings it essentially says 

  ``A simple pattern binding has form p = e.  The pattern p is matched
"lazily" as an irrefutable pattern, as if there were an implicit ~
in front of it.  See the translation in Section 3.12.''

and then goes on the show how to eliminate guards.

In Section 3.12 (Let Expressions) the translation given for 

  let p = e1 in e0

are

  case e1 of ~p -> e0

if no variable in p appears free in e0, and

  let p = fix ( \ ~p -> e1) in e0

otherwise.

Both of these translations only work in a expression context and thus
does not work for top level bindings.

It look like the required translation would look a lot like clause (d)
from Figure 3, ie.:

  v = e
  x1 = case v of p -> x1
  ...
  xn = case v of p -> xn

where v is a new variable and x1,...,xn are the variables bound by p.

Regards,

  Tommy