[Haskell-cafe] Re: Functional programming for processing of
largeraster images
Brian Hulley
brianh at metamilk.com
Wed Jun 21 15:30:36 EDT 2006
Joel Reymont wrote:
> I think the issue wasn't using functional programming for large image
> processing, it was using Haskell. OCaml is notoriously fast and
> strict. Haskell/GHC is... lazy.
>
> Everyone knows that laziness is supposed to be a virtue. In practice,
> though, I'm one of the people who either can't wrap their heads
> around it or just find themselves having to fight it from the start.
Perhaps laziness is more "foundational", in that you can write
if2 c x y = if c then x else y
However:
1) What's the advantage of being able to define if2?
2) Many control constructs, like >>=, foldl', map etc don't require laziness
because they already take a function as argument rather than a plain
expression. In fact, I can't think of any useful user defined control
constructs that actually use laziness in the same way as if2, and the
presence of laziness in foldr, foldl etc just seems to be a real pain
leading to excessive heap consumption. (Counterexample? )
3) "Lazy lists as glue" can easily be replaced by force/delay lists + an
extension to pattern matching where pattern matching against [a] forces the
argument and the syntax [h|t] is used as in Prolog, instead of h:t (This
would also free : to be used for "with type" or "with partial type" instead
of ::)
4) Other examples of the utility of laziness can turn out to be impractical
chimera. For example, the famous repmin replaces the traversal of a tree
twice with the dubious "advantage" of traversing it "only once" and the
building up of a cluster of expensive thunks instead, and since the thunks
effectively encode the structure of the tree, evaluation of them effectively
constitutes the second traversal. So nothing's gained except difficulty of
understanding the all-too-clever code (very bad software engineering
practice imho), more heap consumption, and more time consumption.
>
> Should we all switch to OCaml? I wish I had a criteria to determine
> when to use Haskell and when to use OCaml.
Everything else about Haskell is so great and well thought out (eg type
classes, no side effects, higher rank polymorphism, existentials) it seems a
pity to throw all this away just because of one unfortunate feature. An
alternative would be to write a converter that reads a file of Haskell
source which is to be interpreted strictly and outputs a file of lazy
Haskell source with stictness annotations everywhere, with desugaring of [a]
into force/delay representation (*). (Also in general, !x could mean "force
x" ie x(), and ~x could mean \()->x (in value syntax) or ()->x (in type
syntax), and !x could be allowed in patterns also (when the type at that
position is ~x))
foo : ~Int -> Int -- also taking the opportunity to replace :: by :
foo !x = x
desugared to
foo :: (() -> Int) -> Int
foo cx = case cx () of
x -> x
The main challenge I think would be in converting bindings in let and where
to appropriate case bindings to ensure that as far as possible, redundant
bindings for a given path of control flow are not made, and analysis of
mutually recursive bindings to ensure that everything is bound before being
used.
Some issues would need to be resolved about what the user can expect. For
example whole program optimization could allow some expressions to be
optimized out (eg by splitting a function returning a pair into two
functions, one for each element) that would otherwise be non-terminating,
whereas with lazy Haskell, there is an easy rule that (effectively)
expressions are only evaluated when needed, regardless of optimization.
Then an interesting investigation would be to see how easy it is to port
lazy Haskell to the new, totally strict, language, and if there are any
situations where existing code has used laziness (for algorithmic reasons or
just for efficiency) without being aware of it.
(*) So that eventually a new compiler could be written to take full
advantage of the side-effect-free nature of the language + the strictness
which means that values can be accessed without having to go through the "if
unevaluated then evaluate, store, and return else return" for each
unoptimized access. Because OCaml and SML have side effects, which limit
optimizations due to possible aliasing etc, it might be possible to compile
such a language to code which is certainly no slower, and possibly *even
faster* than OCaml!!! :-)
Regards, Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.
http://www.metamilk.com
More information about the Haskell-Cafe
mailing list