Re: [Haskell-cafe] How to translate Haskell to other languages?

2008-10-11 Thread Matthew Naylor
Hi Jason,

I don't know Python, but let me share some thoughts that you might
find useful.

First, a few questions about your manual translations.  Are your
functions curried?  For example, can I partially apply zipWith?  Also,
you put a thunk around things like cons(...) --- should it not be
the arguments to cons that are thunked?

Now, on to an automatic translation.  As you may know already, Haskell
programs can be transformed to combinator programs which are quite
simple and easy to work with.  Here is what I mean by a combinator
program:

  p ::= d*(a program is a list of combinator definitions)
  d ::= c v* = e  (combinator definition)
  e ::= e e   (application)
 |  v (variable/argument)
 |  c (constant: integer literal, combinator name, etc.)

As an example of a combinator program, here is one that reverses the
list [0,1,2].

  rev v acc = v acc (rev2 acc)
  rev2 acc x xs = rev xs (cons x acc)
  cons x xs n c = c x xs
  nil n c   = n

  main  = rev (cons 0 (cons 1 (cons 2 nil))) nil

This program does not type-check in Haskell!  But Python, being
dynamically typed, doesn't suffer from this problem. :-)

A translation scheme, D[], from a combinator definition to a Python
definition might look as follows.

  D[c v* = e]   =   def c() : return (lambda v1: ... lambda vn: E[e])
  E[e0 e1]  =   E[e0] (E[e1])
  E[v]  =   v
  E[c]  =   c()

Here is the result of (manually) applying D to the list-reversing program.

  def nil()  : return (lambda n: lambda c: n)
  def cons() : return (lambda x: lambda xs: lambda n: lambda c: c(x)(xs))
  def rev2() : return (lambda acc: lambda x: lambda xs:
 rev()(xs)(cons()(x)(acc)))
  def rev()  : return (lambda v: lambda acc: v(acc)(rev2()(acc)))

  def main() : return (rev() (cons()(0)(
cons()(1)(
  cons()(2)(
nil()(nil()))

The result of main() is a partially-applied function, which python
won't display.  But using the helper

  def list(f) : return (f([])(lambda x: lambda xs: [x] + list(xs)))

we can see the result of main():

   list(main())
  [2, 1, 0]

Of course, Python is a strict language, so we have lost Haskell's
non-strictness during the translation.  However, there exists a
transformation which, no matter how a combinator program is evaluated
(strictly, non-strictly, or lazily), the result will be just as if it
had been evaluated non-strictly.  Let's call it N, for Non-strict or
call-by-Name.

  N[e0 e1]   =   N[e0] (\x. N[e1])
  N[v]   =   v (\x. x)
  N[f]   =   f

I've cheekily introduced lambdas on the RHS here --- they are not
valid combinator expressions!  But since Python supports lambdas, this
is not a big worry.

NOTE 1: We can't remove the lambdas above by introducing combinators
because the arguments to the combinator would be evaluated and that
would defeat the purpose of the transformation!

NOTE 2: i could be replaced with anything above --- it is never
actually inspected.

For the sake of interest, there is also a dual transformation which
gives a program that enforces strict evaluation, no matter how it is
evaluated.  Let's call it S for Strict.

  S[e0 e1]=   \k. S[e0] (\f. S[e1] (\x. k (f x)))
  S[v]=   \k. k v
  S[f]=   \k. k f

I believe this is commonly referred to as the CPS
(continuation-passing style) transformation.

Now, non-strict evaluation is all very well, but what we really want
is lazy evaluation.  Let's take the N transformation, rename it to L
for Lazy, and indulge in a side-effecting reference, ML style.

  L[e0 e1]   =   L[e0] (let r = ref None in
  \x. match !r with
 None - let b = L[e1] in r := Some b ; b
   | Some b - b)
  L[v]   =   v (\x. x)
  L[f]   =   f

I don't know enough to define L w.r.t Python.

I haven't tried too hard to fully understand your translation, and
likewise, you may not try to fully understand mine!  But I thought I'd
share my view, and hope that it might be useful (and correct!) in some
way.

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


Re: [Haskell-cafe] FPGA / Lava and haskell

2008-07-10 Thread Matthew Naylor
Hi Marc,

 The Chalmers Lava homepage tells abouta Xilinx version which should
 be merged in soon. But on the xilinx homepage there was no reference
 to neither Lava nor haskell..
 I'm thinking about designing a similar tool to www.combimouse.com.

you also might consider using a PIC or some such microcontroller for
this kind of project.  I don't think there is a Haskell library for
PIC programming, but it would be fun to make one!  For somewhat
related work, see issues 6 and 7 of The Monad.Reader
(http://www.haskell.org/haskellwiki/The_Monad.Reader), especially
Russell O'Conner's article.  As mentioned in issue 7, I did use Lava
to program an RCX microcontroller, but in general the techniques I
used are much better suited to hardware.  Also, there is PICBIT: A
Scheme System for the PIC Microcontroller by Marc Feeley
(http://www.iro.umontreal.ca/~feeley/papers/sw03.pdf) which might be
of interest.

Regarding Lava, there is a version on Satnam Singh's website
(http://raintown.org/lava/).  I use Emil Axelsson's version of
Chalmers Lava (http://www.cs.chalmers.se/~emax/darcs/Lava2000/) that
works with the latest GHC.  I made some mods to target the Xilinx
toolset and to provide very basic support for block RAMs
(http://www.cs.york.ac.uk/fp/darcs/reduceron2/Lava2000/).  I wish I
had time to work more on this, and make it more accessible to others!
Nevertheless, Chalmers Lava as it stands is already very usable.  It
is also very hacker-friendly, so I can recommend diving in!

As an aside: I'm currently finishing off a document about my uses of
Lava and its capabilities/weaknesses.  Hopefully this will be
publicly available soon.

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


Re: [Haskell-cafe] Copy on read

2008-05-13 Thread Matthew Naylor
Hi Andrew,

my probably dodgy reason for mentioning deforestation is that sharing
of intermediate values is a major stumbling block; code that uses data
linearly is possibly well suited for deforesting.  See Frankau's SASL
for a language that deforests all lists simply by not letting you copy
them!  (IIRC there is another constraint that forbids accumulating
parameters too.)

 Similarly, there are recursion patterns for which fusion isn't very 
 easy.

Yep, I suspect you're right.

 That's why most array-based code is explicitly in-place.  wouldn't
 it be nice if it didn't have to be?

I agree.  As an aside, DiffArray looks quite nice:

  http://www.haskell.org/haskellwiki/Modern_array_libraries

``if a diff array is used in a single-threaded style, ..., a!i takes
O(1) time and a//d takes O(length d).''

Notice the use of seq in 2nd example to enforce a kind of
single-threaded behaviour.  Seems nasty!  I wonder if this could be
avoided by providing a (*!*) such that

  arr *!* i = seq x (arr, x)
where x = arr ! i

It returns a new array which the programmer should use if they want
single-threaded behaviour.

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


Re: [Haskell-cafe] Copy on read

2008-05-11 Thread Matthew Naylor
 Uniqueness typing does not lead to in-place update.  If a value is  
 only used once, then there is no need to update it at all!

my understanding is that if a value is uniquely-typed then it is
statically known never to have more than one reference, thus it can be
modified in-place.  Some potential advantages seem to be:

  * Less heap is used, reducing the strain on the garbage collector.

  * Memory writes can sometimes be avoided. Imagine changing the value of
a leaf in a large unique tree.  Only one memory write is required
rather than N, where N is the length of the path to that leaf
from the root.  Such paths can obviously be quite long when working
with lists.  Also, the cost of rebuilding constructors with many
fields -- only to change a single field -- could be expensive.

I wonder to what extent deforestation supersedes such optimisations.
This would be a good topic to raise with a Cleaner.  The paper Neil
mentions looks like a nice alternative to uniqueness typing -- and it
appears that there will be a FitA talk about it, this Thursday.

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


Re: [Haskell-cafe] Functional board games

2008-04-21 Thread Matthew Naylor
Hi Dougal,

 Does anyone know of functional-style implementations of
 chess/draughts/go/anything else that might give me ideas?

there's the Mate-in-N solver in the nofib suite:

  ftp://www.cs.york.ac.uk/pub/haskell/nofib.tar.gz

It takes quite a simple approach, representing the board as two lists
(white and black) of piece/square pairs, where a square is just a pair
of ints.

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


Re: [Haskell-cafe] Designing DSL with explicit sharing [was: I love purity, but it's killing me]

2008-02-16 Thread Matthew Naylor
Hi Oleg,

at the possible risk of straying from Tom's original problem, consider
the following generator that could conceivably occur in practice:

 sklansky f [] = []
 sklansky f [x] = [x]
 sklansky f xs = left' ++ [ f (last left') r | r - right' ]
   where
 (left, right) = splitAt (length xs `div` 2) xs
 left' = sklansky f left
 right' = sklansky f right

 test_sklansky n = runState sk exmap0
   where
 sk = sequence (Prelude.map unA (sklansky add xs))
 xs = Prelude.map (variable . show) [1..n]

(Example due to Chalmers folk, Mary Sheeran and Emil Axelsson;
sklanksy is similar to scanl1, but contains more parallelism.)

If a 128-bit processor were being developed, sklansky could reasonably
be passed 128 elements,

  *Main test_sklansky 128-- on an AMD64 2200
  (3.71 secs, 296129440 bytes)

and could form part of a larger expression, and be called several
times.  So I think this is close to a real situation where CSE is not
practical.  But like you say, a human would not write such a humungous
expression by hand; hand-written expressions may therefore be ideal
for crunching by your CSE method.

Still, we might like to write generators like sklansky.  Hope is
offered by the new let_ construct, but it's not clear how to use it
in this case. The problem is that sklansky is a function over lists of
expressions rather than single expressions, and the let_ construct
can only bind single expressions and return single expressions.  To
write sklansky using your approach, it seems (to me) that the DSL's
expression type needs to be extended to support lists.  Will this not
be complicated and introduce notational inconvenience?  (In an earlier
post, I outlined a method for embedding algebraic data types in
Haskell, and it does have some notational burden.)

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


Re: [Haskell-cafe] Designing DSL with explicit sharing [was: I love purity, but it's killing me]

2008-02-13 Thread Matthew Naylor
Hi Oleg,

it's not immediately clear (to me at least) how efficient your method
will be in practice.  Any method based on common sub-expression
elimination surely must inspect every node in the flattened graph.  In
the worst case, an acyclic graph containing n nodes could have 2^n
nodes when flattened to a tree:

  tricky 0 = constant 0
  tricky d = add g g
where
  g = tricky (d-1)

Of course, in practice the worst case may not occur.  Also, my
mental model is big circuits, which may be different to yours and
Tom's.

(Sorry if I'm just pointing out the obvious.)

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


Re: [Haskell-cafe] Designing DSL with explicit sharing [was: I love purity, but it's killing me]

2008-02-13 Thread Matthew Naylor
Hello again,

since Oleg presented an approach to the sharing problem that works on
acyclic graphs, I may as well mention an alternative, pure, standard
Haskell solution which is to express the fork points in the circuit
(or expression), i.e. the points at which an expression is duplicated.
You need to introduce a fork primitive:

  fork :: Bit - (Bit, Bit)

or

  fork :: Exp - (Exp, Exp)

This fits quite naturally in the context of circuit description, and I
called it expressible sharing.  Under some mild restrictions, it
even works on cyclic graphs.  In particular, it works nicely for
regular circuits.  The tricky example I mentioned earlier would be
written:

  tricky 0 = constant 0
  tricky d = add e0 e1
where
  (e0, e1) = fork (tricky (d-1))

However, in the end I admitted defeat and decided I preferred
observable sharing!

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


Re: [Haskell-cafe] Designing DSL with explicit sharing [was: I love purity, but it's killing me]

2008-02-13 Thread Matthew Naylor
   tricky 0 = constant 0
   tricky d = add e0 e1
 where
   (e0, e1) = fork (tricky (d-1))

Oops, I just realised that this isn't a very good example of
expressible sharing!  The problem is that it doesn't take any inputs,
and expressible sharing just collapses (partially evaluates) operators
when they are applied to constants.  A better example would be
something that takes an input, such as

  distrib a [] = []
  distrib a (x:xs) = (a0, x) : distrib a1 xs
where
  (a0, a1) = fork a

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


Re: [Haskell-cafe] I love purity, but it's killing me.

2008-02-10 Thread Matthew Naylor
Hi Tom,

 So is the general strategy with observable sharing to use
 unsafePerformIO with Data.Unique to label expressions at
 construction?

something like that, yes.  Basically, you just need:

  {-# NOINLINE ref #-}
  ref x = unsafePerformIO (newIORef x)

and you can write expressions like

  ref False == ref False

and

  let x = ref False in x == x

However, while referential equality is enough for sharing detection, I
*suspect* it's simpler to use the fact that refs are IORefs and you
can read and write them (in the IO monad).  So a very simple Lava
might look like

  module Lava (Bit,Netlist,low,high,nand2,netlist) where

  import Data.IORef
  import System.IO.Unsafe

  {-# NOINLINE ref #-}
  ref x = unsafePerformIO (newIORef x)

  type Ref = IORef (Maybe Int)

  data Bit = Gate String Ref [Bit]

  type Netlist = [(String,   Int, [Int])]
  --   gate, output,  inputs

  low = Gate low (ref Nothing) []
  high = Gate high (ref Nothing) []
  nand2 (a, b) = Gate nand2 (ref Nothing) [a, b]

  netlist :: Bit - IO Netlist
  netlist x = do i - newIORef (0 :: Int) ; f i x
where
  f i (Gate str r xs) =
do val - readIORef r
   num - readIORef i
   case val of
 Nothing - do writeIORef r (Just num)
   writeIORef i (num+1)
   rest - mapM (f i) xs
   let is = map ((\(g,o,is) - o) . head) rest
   return ((str,num,is):concat rest)
 Just j - return [(indirection,j,[])]  -- explicit sharing!

Indirections can be filtered out at the end, they don't actually give
the netlist any information.

 Of course, now that you have me reading up on Yhc.Core, option #5 is
 looking considerably more fun.

Yeah, I think Yhc.Core is pretty nifty too.  Thank Neil!

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


Re: [Haskell-cafe] I love purity, but it's killing me.

2008-02-09 Thread Matthew Naylor
Hi Tom,

 In addition to the sharing problem, another shortcoming of Haskell
 DSLs is they can not fully exploit the benefits of algebraic
 datatypes.  Specifically, pattern matching ADTs can only be used to
 control the compile-time configuration of the target, it can't be used
 to describe the target's behavior -- at least for DSLs that generate
 code that executes outside of Haskell's runtime.

you can embed algebraic data types and pattern matching in Haskell
with your own semantics, and retain type inference.  It goes something
like this:

  (nil, (|)) = datatype (cons0 [] \/ cons2 (:))

  map f xs = match xs rules
where
  rules (x, xs) =
[ nil  --  nil
, x | xs  --  f x | map f xs
]

here, map :: (Term a - Term b) - Term [a] - Term [b].

The main issue is that you have to quantify the free variables in
patterns, hence the rules function.  I don't know if this helps you.

 Writing a real compiler would solve both of these problems.  Is there
 any Haskell implementation that has a clean cut-point, from which I
 can start from a fully type-checked, type-annotated intermediate
 representation?

The Yhc.Core library is very simple to use and fairly mature (Neil's
been tweeking it for about 3 years now), but it doesn't meet your
type-annotated requirement. (Untyped core is still pretty useful,
though.)

If you go the real compiler route, would it not make sense to take the
DSL as the source language rather than Haskell?  Or are the DSL and
Haskell quite similar?  Or perhaps you are thinking of a two language
system, where some code is evaluated at compile time by Haskell, and
some is compiled to the target language?  If so, maybe you just want
domain specific syntax inside a Haskell program, in which case the
paper Why it's nice to be quoted: quasiquoting for haskell might be
relevant (it's actually supported in GHC I think).

Anyway, all very thought provoking!

Matt.

P.S.

Tom Hawkins wrote:
 Emil Axelsson wrote:
  I know of a few of ways to express sharing in a pure language:
 
  1) Observable sharing, which, in general, is unsafe.
  2) Using Template Haskell
  3) Matthew Naylor has done some work on expressible sharing, which has
  4) Use a monad (but I'm sure this is what you're trying to avoid).
 
 Or...
 
 5) Forget embedding the DSL, and write a direct compiler.

Taking options 2 or 5 just to solve the sharing problem sounds to me
like a lot of hard work for little reward.  But don't worry, I won't
repeat my observable sharing speech. :-)
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] I love purity, but it's killing me.

2008-02-08 Thread Matthew Naylor
Hi,

(Warning: longish message!)

There is some concern, and rightly so, that observable sharing is
dangerous, and that your Haskell program will explode if you use it,
and perhaps even that anyone who uses it is dirty and should be sent
to matron's for a good scrubbing!  However, when used safely, it is
not a hack, nor even dirty, but a nice, simple solution to an
otherwise nasty problem.  Below I define what I mean by safely.

First consider the circumstances under which obserevable sharing is
useful.  Typically we have some Haskell function f that produces a
symbolic representation of an expression.  For whatever reason, we'd
like to *generate a program* that computes the value of this
expression, rather that computing it in Haskell.  For example, in
Lava, we want to generate a VHDL program so that the expression can be
computed on, say, an FPGA.  In Tom's case, he wants to generate a C
program to compute the expression.  All perfectly reasonable, and in
my opinion, a very powerfull way to use Haskell.

Now recall that referential transparency lets you replace equals with
equals without changing the *value produced* by a program.  Note that
it says nothing about preserving *runtime behaviour*.  Sharing, for
example, may be lost.  So if you do equational reasoning on function
f (above), and loose some sharing, then you can only expect that the
same sharing will also be also lost in the generated program.  As long
as the generated program computes the same result as it did before,
referential transparency will be, overall, preserved; it would only be
lost intermediately.  This is what I mean by safe.

Now, there remains the concern that Haskell's semantics does not
enforce sharing.  A Haskell compiler is free to change the sharing a
program at a whim, unknowingly to the programmer who may be relying on
it in for an efficient program.  However, to my knowledge, it is an
unwritten rule of Haskell compilers that sharing *is* preserved, and
that they do perform *graph* reduction.  Clean, a similar language to
Haskell, indeed has a semantics based on graphs.  So I don't believe
Haskell being non-strict (not necessarily lazy) is a good reason for
not using observable sharing.  Though I do feel better when I compile
without -O. :-)

Finally, when I say observable sharing, I don't necessarily mean it
as defined by Koen Claessen and David Sands.  I simply mean the use of
unsafePerformIO to detect sharing, whether or not this is done by an
eq predicate on Refs. (I say this because I think there are simpler
ways to detect sharing, though these will probably not have the nice
semantic properties of observable sharing.)

Sorry for the somewhat long exposition. :-)

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


ghc -O

2008-01-23 Thread Matthew Naylor
Hello GHC gurus,

specifying -O or -O2 to GHC enables various optimisations to the
frontend of the compiler, but I wonder does it turn on any
optimistions to the backend/code-generator that are independent of the
frontend?

I can imagine that knowledge such as strictness which is computed by
frontend would enable optimisations in the backend, but I'm more
interested in whether the backend would do anything independent (e.g.
peephole optimistion, C compiler options) with -O but not without.

Thanks,

Matt.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


[Haskell] ANNOUNCE: Lazy SmallCheck 0.1

2007-10-18 Thread Matthew Naylor
Announcing Lazy SmallCheck 0.1, a library for exhaustive,
demand-driven testing of Haskell programs.

Lazy SmallCheck is based on the idea that if a property holds for a
partially-defined input then it must also hold for all fully-defined
instantiations of that input. Compared to `eager' input generation 
in SmallCheck, Lazy SmallCheck may require significantly fewer
test-cases to verify a property for all inputs up to a given depth.

There is a webpage for Lazy SmallCheck:

  http://www-users.cs.york.ac.uk/~mfn/lazysmallcheck/

There you'll find a more detailed description, a worked example, a
comparison with SmallCheck on a number of benchmarks, and link to
download the library.

The library was developed together with Fredrik Lindblad during his
recent visits to York.

Suggestions, experiences and bug reports are welcome!

Matthew.
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


[Haskell] ANNOUNCE: SparseCheck

2007-09-18 Thread Matthew Naylor
Dear Haskellers,

You might be interested in SparseCheck, a library for typed,
depth-bounded logic programming in Haskell allowing convenient
expression of test-data generators for properties with sparse domains.

  http://www.cs.york.ac.uk/~mfn/sparsecheck/

SparseCheck is a based on a library called LP (to be presented at the
Haskell Workshop) that was developed jointly with Emil Axelsson.

Matthew.
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


[Haskell] ANNOUNCE: The Reduceron

2007-05-30 Thread Matthew Naylor
Dear Haskellers,

You may be interested in the Reduceron:

  http://www-users.cs.york.ac.uk/~mfn/reduceron/index.html

Here is a flavour:

The Reduceron is a processor for executing Haskell programs on FPGA
with the aim of exploring how custom architectural features can
improve the speed in which Haskell functions are evaluated. Being
described entirely in Haskell (using Lava), the Reduceron also serves
as an interesting application of functional languages to the design of
complex control circuits such as processors.

To program the Reduceron we provide a basic Haskell compiler, called
Tred, that translates Yhc.Core programs into codes of the Reduceron's
instruction set.

The Tred compiler and Reduceron processor are in the early stages of
development: they are both fairly naive, inefficient, and lacking in
many important features. But they represent a good start, already
capable of correctly compiling and executing (on FPGA) a reasonable
range of Haskell programs.

See webpage for more details.

Matthew.
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell-cafe] ANNOUNCE: nobench: Haskell implementaion benchmarks. GHC v Hugs v Yhc v NHC v ...

2007-02-19 Thread Matthew Naylor
Hi all,

 GHC v Hugs v Yhc v NHC v ...

 ...Hacle  Clean!

I shoved 5 of the benchmarks that Donald used through Hacle, and
compiled the outputs using version 2.1 of the Clean compiler.  Results
are below.

As for the other examples, Hacle doesn't like non-Haskell98 and
translates arbitrary-precision integers to fixed-precision ones (!)

I'm not sure how well Hacle would work with nobench because input
files must be unambiguously-typed assuming a default () at the top.
So some programs may require a little tweaking to go through.  Mind,
this was only a problem on 1 of the 5 programs I just tried...

Matt.

(Note: ignore the 65536 at the end of each Clean result -- my fault
for not compiling with the right options)

===
binarytrees (GHC)
===
stretch tree of depth 17 check: -1
131072   trees of depth 4check: -131072
32768trees of depth 6check: -32768
8192 trees of depth 8check: -8192
2048 trees of depth 10   check: -2048
512  trees of depth 12   check: -512
128  trees of depth 14   check: -128
32   trees of depth 16   check: -32
long lived tree of depth 16  check: -1

real0m3.301s
user0m3.280s
sys 0m0.016s
===
binarytrees (Clean)
===
Execution: 2.34  Garbage collection: 0.25  Total: 2.59
stretch tree of depth 17 check: -1
131072   trees of depth 4check: -131072
32768trees of depth 6check: -32768
8192 trees of depth 8check: -8192
2048 trees of depth 10   check: -2048
512  trees of depth 12   check: -512
128  trees of depth 14   check: -128
32   trees of depth 16   check: -32
long lived tree of depth 16  check: -1
65536

real0m2.691s
user0m2.592s
sys 0m0.100s
===
partial sums (GHC)
===
2.9987  (2/3)^k
3160.817621887086   k^-0.5
0.99602026  1/k(k+1)
30.31454150956248   Flint Hills
42.99523399808393   Cookson Hills
15.30901715473893   Harmonic
1.644933666848388   Riemann Zeta
0.6931469805600944  Alternating Harmonic
0.7853980633974358  Gregory

real0m4.887s
user0m4.888s
sys 0m0.000s
===
partial sums (Clean)
===
Execution: 4.41  Garbage collection: 0.05  Total: 4.46
3   (2/3)^k
3160.81762188709k^-0.5
0.9960203   1/k(k+1)
30.3145415095625Flint Hills
42.9952339980839Cookson Hills
15.3090171547389Harmonic
1.64493366684839Riemann Zeta
0.693146980560094   Alternating Harmonic
0.785398063397435   Gregory
65536

real0m4.545s
user0m4.468s
sys 0m0.076s
===
queens (GHC)
===
14200

real0m1.990s
user0m1.980s
sys 0m0.012s
===
queens (Clean)
===
Execution: 6.58  Garbage collection: 1.07  Total: 7.65
14200
65536

real0m7.921s
user0m7.656s
sys 0m0.264s
===
recursive (GHC)
===
Ack(3,9): 4093
Fib(36.0): 2.4157817e7
Tak(24,16,8): 9
Fib(3): 3
Tak(3.0,2.0,1.0): 2.0

real0m5.232s
user0m5.224s
sys 0m0.008s
===
recursive (Clean)
===
Execution: 2.40  Garbage collection: 0.00  Total: 2.40
Ack(3,9): 4093
Fib(36): 24157817
Tak(24,16,8): 9
Fib(3): 3
Tak(3,2,1): 2
65536

real0m2.403s
user0m2.400s
sys 0m0.000s
===
loop (GHC)
===
3.3335

real0m1.039s
user0m1.036s
sys 0m0.004s
===
loop (Clean)
===
Execution: 1.26  Garbage collection: 0.00  Total: 1.26
3.33
65536

real0m1.325s
user0m1.260s
sys 0m0.068s
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell] [ANNOUNCE] Hacle

2004-10-13 Thread Matthew Naylor
Dear Haskellers and Cleaners,

You may be interested in the results of my final-year student project
at the University of York.  It involved the development of a
translator from Haskell to Clean; an idea that probably won't be too
unfamiliar to most of you.

The project's homepage is:

  http://www.cs.york.ac.uk/~mfn/hacle/

I hope that you enjoy the read, and find the results of interest.

Kind regards.

-- 
Matthew
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell