Hi Jimmie, thanks for your long feedback and sharing your experiences!
> I have spent a fair amount of the last 4 days playing with PicoLisp. I Yess. From your code I see that you master PicoLisp already quite well! I suspect that you gave up just a little bit too early. > : (scl 12) > -> 12 > : (*Scl) > Segmentation fault (core dumped) Haha, right. Calling (*Scl) is a prefect way to segfault. Think about what it means: It calls a *function* starting in memory at address 12! HOWEVER! The segfaults you observed in your program are NOT your fault! You indeed found a bug in the bignum functions of PicoLisp, causing a crash upon a certain combination of numeric arguments. Strange that this was not detected earlier, I used a lot of test routines with random numbers. I cound not locate the exact location of the bug yet. It is a Heisenbug, because it only occurs if the garbage collector runs in the right moment. I know this because it all runs well if you call 'gc' *before* the test, e.g. (gc 700) (doit) I will dig into it now, to find and fix it, and release a new PicoLisp version. Thanks for finding it! As you spent already so much time on it, I feel that I should try it myself. I rewrote parts of it to be more PicoLisp-like, as you violate some of the PicoLisp programming rules and styles. I won't comment on the details, but paste my own version below. The new version is about 150 times faster. The main reason is that you used 'nth' to index into long lists again and again. Here on my notebook it finishes the 100 reps in one and a half minutes: $ time ./pil x.l + *Scl: 12 createlist "loop1" 87.144 sec loop2 nsum: 11257.349310772499 navg: 0.390880184402 4.093 sec 91.250 sec nsum: 11228.585386471924 navg: 0.389881437030 real 1m31.628s user 1m31.308s sys 0m0.400s > A successful 100 rep run should give an > nsum: 11322.307098752284 and > navg: 0.393135663151121 within acceptable floating point differences. Note that I get slightly different results, because I use '*/' instead of '/' in the 'average' function. I believe that this is more correct, as '*/' rounds the result. Now let me start the bug hunt. ♪♫ Alex PS: Here is my code: (scl 12) (de average (L) (*/ (sum prog L) (length L)) ) (de normalize (N) (let NN (if (=0 N) 0.000123456789 N) (while (<= NN 0.0001) (setq NN (* 10 NN)) ) (while (>= NN 1.0) (setq NN (*/ NN 10)) ) NN ) ) (de createlist (Lsize) (make (let I 0 (do Lsize (link (normalize (inc 'I 1.0))) ) ) ) ) (de loop1calc (I J N) (let V (*/ N (+ I N) (- J N) 0.1234567 `(* 1.0 1.0 1.0)) (normalize (*/ V V V `(* 1.0 1.0)) ) ) ) (de loop2calc (I J N) (normalize (*/ N (+ J 1.0) (+ N N N) 0.1234567 `(* 1.0 1.0 1.0) ) ) ) (de loopN (Fun Lst Reps) (let I 1.0 (do Reps (let J 0 (map '((L) (set L (Fun I (inc 'J 1.0) (car L)) ) ) Lst ) ) (inc 'I 1.0) ) ) (setq *Nsum (sum prog Lst) *Navg (average Lst) ) ) (de loop1 (Lst Reps) (loopN loop1calc Lst Reps) ) (de loop2 (Lst Reps) (loopN loop2calc Lst Reps) ) (de doit () (prinl "*Scl: " *Scl) (bench (let Reps 100 (prinl "createlist") (let L (createlist (* 60 24 5 4)) (println "loop1") (bench (loop1 L Reps)) (prinl "loop2") (prinl "nsum: " (format *Nsum *Scl)) (prinl "navg: " (format *Navg *Scl)) (bench (loop2 L Reps)) ) ) ) (prinl "nsum: " (format *Nsum *Scl)) (prinl "navg: " (format *Navg *Scl)) ) (gc 700) (doit) (bye) -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe