Re: SBCL is now faster than Java, as fast as Ocaml, and getting better
- From: Kaz Kylheku <kkylheku@xxxxxxxxx>
- Date: Fri, 11 Jul 2008 20:10:34 +0000 (UTC)
On 2008-07-11, Jon Harrop <jon@xxxxxxxxxxxxxxxxx> wrote:
Try any of the above languages and the enormous advancement made by built-in
pattern matching will be blindingly obvious.
Compare this OCaml code:
Can't be parsed without a detailed knowledge of OCaml syntax.
let rec intersect orig dir (l, _ as hit) (center, radius, scene) =
match ray_sphere orig dir center radius, scene with
| lam', _ when lam' >= lam -> hit
| lam', [] -> lam', unitise (orig +| lam' *| dir -| center)
| _, scenes -> List.fold_left (intersect orig dir) hit scenes
54 tokens. Maybe more; it's not clear what is and is not a token in this
syntax.
With the equivalent Common Lisp:
Can be reduced to an abstract syntax tree by someone who doesn't know Common
Lisp.
(defun intersect (orig dir scene)
(labels ((aux (lam normal scene)
(let* ((center (sphere-center scene))
(lamt (ray-sphere orig
dir
center
(sphere-radius scene))))
(if (>= lamt lam)
(values lam normal)
(etypecase scene
(group
(dolist (kid (group-children scene))
(setf (values lam normal)
(aux lam normal kid)))
Your ``fold_left'' function improves code density, and has nothing to do with
pattern matching. Here the analogous logic is performed by an open-coded loop.
Some kind of LOOP would probably be more dense. Or you could actually
use some Common Lisp version FOLD-LEFT.
You've increased verbosity by using types like GROUP and SPHERE, which don't
appear in the OCaml.
If the type here was simply CONS, then you wouldn't have to call the accessor
(GROUP-CHILDREN SCENE) to pull out the scene elements. So that's one less
abstract syntax tree node right away.
(values lam normal))
(sphere
(values lamt (unitise
(-v (+v orig (*v lamt dir)) center)))))))))
(aux infinity zero scene)))
62 tokens.
The considerable difference in verbosity is primarily due to pattern
The Lisp is actually only 15% larger in abstract syntax tree size.
matching, which is used both for destructuring (replacing
MULTIPLE-VALUE-BIND, DESTRUCTURING-BIND, CAR, CDR etc.) and for dispatch
(replacing COND etc.).
With pattern matching, the syntactic overhead is as low as possible, e.g.
Syntactic size is not the entire overhead of syntax.
There is also the mental overhead of sorting through incomprehensible line
noise.
Terseness isn't everything, and let's not forget that it is one dominant
attribute of obfuscated programming contest entries.
destructuring a pair return value:
# let polar x y = sqrt(x *. x +. y *. y), atan2 y x;;
This looks like incomrehensible drivel. More parentheses are needed to show
what goes with what.
I have to resort to the semantics of Cartesian to polar to work out the idiotic
syntax!!!
In any reasonable programming language, the comma would have a the lowest
precedence.
Here is a better syntax:
let polar (x, y) = (sqrt(x *. x +. y *. y), atan2(y, x));
val polar : float -> float -> float * float = <fun>
I'm guessing this is the output seen in REPL? But I can't make head or tail out
of it. This polar is supposed to take two numbers, and yield two numbers. So
isn't it a mapping from (float, float) -> (float, float)?
What is the associativity and precedence of -> ?
# let r, theta = polar 3. 4.;;
val r : float = 5.
val theta : float = 0.927295218001612187
Compared to:
* (defun polar (x y)
(values (sqrt (+ (* x x) (* y y))) (atan y x)))
Ahh, clear structure. No associativity and precedence bull*** to deal with.
Even someone who doesn't know Common Lisp can at least work out the
abstract syntax tree.
It's obvious that the major syntax here is
(defun polar (x y) (values ...))
That is, a DEFUN node with three children.
Pattern matching improves most function definitions.
Huh? The polar function doesn't use pattern matching. The terseness of the
definition depends on a bizarre syntax notation full of associativity and
precedence rules, and on slicker handling of multiple values.
.
- Follow-Ups:
- References:
- Re: SBCL is now faster than Java, as fast as Ocaml, and getting better
- From: Jon Harrop
- Re: SBCL is now faster than Java, as fast as Ocaml, and getting better
- From: jon . harrop . ms . sharp
- Re: SBCL is now faster than Java, as fast as Ocaml, and getting better
- From: Marco Antoniotti
- Re: SBCL is now faster than Java, as fast as Ocaml, and getting better
- From: Jon Harrop
- Re: SBCL is now faster than Java, as fast as Ocaml, and getting better
- From: Marco Antoniotti
- Re: SBCL is now faster than Java, as fast as Ocaml, and getting better
- From: Jon Harrop
- Re: SBCL is now faster than Java, as fast as Ocaml, and getting better
- From: jon . harrop . ms . sharp
- Re: SBCL is now faster than Java, as fast as Ocaml, and getting better
- From: John Thingstad
- Re: SBCL is now faster than Java, as fast as Ocaml, and getting better
- From: Vassil Nikolov
- Re: SBCL is now faster than Java, as fast as Ocaml, and getting better
- From: John Thingstad
- Re: SBCL is now faster than Java, as fast as Ocaml, and getting better
- From: Jon Harrop
- Re: SBCL is now faster than Java, as fast as Ocaml, and getting better
- Prev by Date: Re: McCarthy's original proposal for Lisp
- Next by Date: Re: SBCL is now faster than Java, as fast as Ocaml, and getting better
- Previous by thread: Re: SBCL is now faster than Java, as fast as Ocaml, and getting better
- Next by thread: Re: SBCL is now faster than Java, as fast as Ocaml, and getting better
- Index(es):