Some good-hearted criticism

Alastair David Reid reid@cs.utah.edu
27 Jun 2001 15:26:37 -0600


Juan Carlos Arevalo Baeza <jcab@roningames.com> writes:

>     Hmmm... I guess I'll have to look more closely into the Hugs
> documentation. I wasn't aware that it had profiling in it
> too... O:-) And, looking closer, this option is not mentioned
> anywhere, and it rejects the option. Hmmm... I have the February
> 2001 version, for Windows. Maybe I need to check for a new one?

It's a configure time option (--enable-profiling).
You need (someone) to compile Hugs from source code with that
 option turned on.

Other useful options that Windows (and Unix?) people may not know about are:

  --enable-timer            enable evaluation timing
  --enable-stack-dumps      enable stack dump on stack overflow
  --enable-only98           make Hugs Haskell 98 only
  --with-readline           support fancy command line editing
  --with-preprocessor       allow use of a preprocessor

The rest of the options are either for use by developers or are likely
to have suffered severe bitrot but, for the record, they are:

  --disable-modules         disable module system
  --enable-path-canonicalization enable filepath canonicalization
  --enable-profiling        enable heap profiler
  --with-nmake              produce nmake compatible Makefile
  --disable-large-banner    disable multiline startup banner
  --with-gui                build Hugs for Windows GUI
  --enable-internal-prims   experimental primitives to access Hugs' innards
  --enable-debug            include C debugging information (for debugging use)
  --enable-lint             enable lint flags (for debugging use)
  --enable-tag-checks       runtime tag checking (for debugging use)

The useful ones are documented in the file hugs98/Install - but you
usually only read that if you install from source.  Now that most
people get their Hugs in binary form for Windows or Linux, it might be
worth mentioning these features more prominently on the web page or in
the Hugs documentation.

> manynot :: Parser p inp => p inp v -> p inp a -> p inp ([v],Maybe a)
> manynot s p = mn [] p where mn r p = force $ do a <- p
>                                                  return (r,Just a)
>                                               +++
>                                               do x <- s
>                                                  mn (r ++ [x]) p
>                                               +++
>                                               return (r,Nothing)

Many people would code that more trickily by consing x onto the front
of r and then returning the reverse of r:

> manynot :: Parser p inp => p inp v -> p inp a -> p inp ([v],Maybe a)
> manynot s p = mn [] p where mn r p = force $ do a <- p
>                                                  return (reverse r,Just a)
>                                               +++
>                                               do x <- s
>                                                  mn (x:r) p
>                                               +++
>                                               return (reverse r,Nothing)

This avoids quadratic cost from the repeated appends (N appends with
time of each one proportional to length of list).  Both approaches are
equally strict.  I think both require stack space proportional to the
list length though I could be wrong about the repeated appends (too
hot to figure it out).

Less trickily, you could use one of Chris Okasaki's data structures
that guarantees fast append to the tail of the list.

-- 
Alastair Reid        reid@cs.utah.edu        http://www.cs.utah.edu/~reid/