merits of Lisp vs Python
André Thieme
address.good.until.2006.dec.22 at justmail.de
Fri Dec 15 10:22:34 EST 2006
Paul Rubin schrieb:
> André Thieme <address.good.until.2006.dec.22 at justmail.de> writes:
>> def nif(num, pos, zero, neg):
>> if num > 0:
>> return pos
>> else:
>> if num == 0:
>> return zero
>> else:
>> return neg
>
> def nif(num, pos, zero, neg):
> return (neg, zero, pos)[cmp(num, 0)+1]
That is a nice idea. I can do the same in Lisp, but have to do it
without syntactic sugar which makes it longer, characterwise:
(defun nif2 (num pos zero neg)
(nth (1+ (truncate (signum num)))
(list pos zero neg)))
What Python has is cmp. That is doing what truncate+signum do in
Lisp. So that makes the biggest difference. Another one is that Lisps
signum keeps the datatype:
cmp(5.3, 0) => 1
(signum 5.3) => 1.0
Or also with complex numbers [syntax #C(real, img)]:
(signum #C(10 4)) => #C(0.9284767 0.37139067)
Anyway, from the complexity the Lisp version is a bit better.
The Python version has 11 tokens:
return, tuple-reference, comma, neg, zero, pos, +, 1, cmp, num, 0
and the Lisp version has only 9:
nth, 1+, truncate, signum, num, list, pos, zero, neg
(I didn't count the function head, because both have the same
token count).
>> The messages were printed in each case.
>> To stop that I need lazy evaluation:
>> CL-USER> (mapcar #'(lambda (x)
>> (funcall
>> (nif x
>> #'(lambda () (p))
>> #'(lambda () (z))
>> #'(lambda () (n)))))
>> '(0 2.5 -8))
>
> in Python:
>
> def lazy_nif(num, pos, zero, neg):
> return (neg, zero, pos)[cmp(num, 0)+1]() # the () at the end means funcall
>
> map(lambda x: lazy_nif(x, p, z, n), (0, 2.5, -8))
We could do the same in Lisp:
(defun lazy-nif (num pos zero neg)
(funcall (nth (1+ (truncate (signum num)))
(list pos zero neg))))
Here the token count is 12py vs 10cl.
CL-USER> (mapcar #'(lambda (x) (lazy-nif2 x #'p #'z #'n))
'(0 2.5 -8))
"no no"
"very negative"
"very positive"
("zero" "negative" "positive")
But there is a disadvantage:
>>> lazy_nif(0, "p", "z", "n")
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 2, in lazy_nif
TypeError: 'str' object is not callable
I don't know how I can fix that. Maybe you could tell me.
In Lisp I would just go with the macro. That works for all cases.
> "nif" is even cleaner in Haskell, if I have this right:
>
> nif x p z n | (x < 0) = n
> | (x == 0) = z
> | (x > 0) = p
>
> All Haskell evaluation is automatically lazy, so no lambdas etc. needed.
Yes, that was what I already supposed.
Do you also know how I can "deactivate" lazyness?
André
--
More information about the Python-list
mailing list