Re: SBCL is now faster than Java, as fast as Ocaml, and getting better
- From: Jon Harrop <jon@xxxxxxxxxxxxxxxxx>
- Date: Sat, 12 Jul 2008 02:22:20 +0100
Kaz Kylheku wrote:
On 2008-07-11, Jon Harrop <jon@xxxxxxxxxxxxxxxxx> wrote:
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.
Yes.
(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.
Note that the Lisp was written by Juho Snellman, one of the authors of SBCL,
and not by me. Those types are implicit in the OCaml but they are both
inferred and anonymous so they add no syntactic overhead at all.
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.
Your Lisp code would be littered with CAR and CDR instead.
(values lam normal))
(sphere
(values lamt (unitise
(-v (+v orig (*v lamt dir))
center)))))))))
(aux infinity zero scene)))
62 tokens.
Only if you ignore the superfluous parentheses that make up most of the Lisp
code, which is absurd because they are essential in Lisp.
In reality, the Lisp has 125 tokens.
The considerable difference in verbosity is primarily due to pattern
The Lisp is actually only 15% larger in abstract syntax tree size.
The Lisp is 2.3x longer by tokens if you count the (essential) parentheses.
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.
You may have noticed that almost all programmers disagree with you: huge
numbers of superfluous parentheses being one of the most complained about
disadvantages of Lisp.
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.
No, more parentheses are not needed.
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?
Yes. That is the inferred type.
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)?
My "polar" function was curried.
What is the associativity and precedence of -> ?
Right associative and low precedence.
# 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.
You say that as if we were not all capable of deciphering the precedence of
addition and multiplication by the age of 5.
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.
Every argument to every function is a pattern in all MLs. When you write:
let polar(x, y) = ...
the "(x, y)", the "x" and the "y" are all patterns and the pattern matcher
automates the dissection of the pair.
So you can write:
let f((x, y), z) = ...
or:
let f(x, y as pair) = ...
or:
let f(`A x | `B x) = ...
The terseness of
the definition depends on a bizarre syntax notation full of associativity
and precedence rules, and on slicker handling of multiple values.
What you call "slicker handling of multiple values" is largely thanks to
pattern matching.
--
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com/products/?u
.
- Follow-Ups:
- Re: SBCL is now faster than Java, as fast as Ocaml, and getting better
- From: Kaz Kylheku
- Re: SBCL is now faster than Java, as fast as Ocaml, and getting better
- From: Don Geddis
- Re: SBCL is now faster than Java, as fast as Ocaml, and getting better
- 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
- From: Kaz Kylheku
- Re: SBCL is now faster than Java, as fast as Ocaml, and getting better
- Prev by Date: Re: future in software industry as a lisp programmer
- Next by Date: Re: Hybrid RC/GC system to support real-time applications that can't afford pauses?
- 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):