Richard Waters' Series and lispmoo2
This is a quite technical fizzbuzz article about totally avoiding writing iteration with your own hands.
Based on these Mastodon toots by KMP, mdh, jackdaniel and all: https://mastodon.sdf.org/@screwtape/113490818622436062 I read AIM-1082; Optimization of Series Expressions: Part I: User's Manual for the Series Macro Package by Richard C. Waters
which is a bit of a read!
1. Long story short
Instead of the vast majority of iteration, you make these weird statements of intent. Waters' package infers the best way it knows how to do what you asked of it. Er…
2. Fizzbuzz With Series
(defun series-fizzbuzz-of (x) (let* ((nos (scan-range)) (fizz-src (series 'fizz)) (buzz-src (series 'buzz)) (by3s (scan-range :from 0 :by 3)) (by5s (Scan-range :from 0 :by 5)) (fizzes (mask by3s)) (buzzes (mask by5s))) (list (collect-nth x (#Mand fizzes fizz-src)) (collect-nth x (#Mand buzzes buzz-src)) (collect-nth x nos))))
I don't know about you, but this looks crazy to me. I never tried writing this jazz before just now. Basically I just calculate the fizzbuzz information for one number, which can be interpreted. The idea being I can pick a large-enough number, and compare its speed.
3. Me trying to use the loop facility
(defun loopfizz-of (no) (let ((res (loop :repeat (1+ no) :for x :from 0 :by 1 :for y := '0 :then y :for z := '0 :then z :when (eql x y) :do (incf y 3) :When (eql x z) :do (incf z 5) :finally (return (list x (decf y 3) (decf z 5)))))) (list (car res) (when (= (car res) (cadr res)) 'fizz) (when (= (car res) (cadr res)) 'buzz))))
4. Results
Series appears to be about 10% better.
4.1. Series
LISPMOO2/USER> (time (eg 1555432)) Evaluation took: 0.065 seconds of real time 0.063839 seconds of total run time (0.063798 user, 0.000041 system) 98.46% CPU 71,738,506 processor cycles 0 bytes consed (NIL NIL 1555432)
4.2. Loop
LISPMOO2/USER> (time (loopfizz-of 1555432)) Evaluation took: 0.080 seconds of real time 0.079086 seconds of total run time (0.078894 user, 0.000192 system) 98.75% CPU 87,505,433 processor cycles 0 bytes consed (1555432 NIL NIL)
5. What's the difference, is Series not a loop?
A bunch of dolists are made out of Series' macros, so it does a loop.
The difference is that you don't write the loop. You make one Series, then another, then another one out of the first two, and so on until the values you want can be addressed in one of your series.
This is a different approach to loop; in the loop facility, you describe how to do the iteration. In Waters' Series macros, you describe Series (in terms of other Series) until you can point a finger at where what you want is. You don't know anything about how your values are actually resolved, though sometimes the result of the macro is a warning that it doesn't think you did a good job in one way or another.
6. Series are appropriate for lispmoo2
because they track how yduJ tells us to program in-MOO in her famous wind-up-duck tutorial. Basically she says to prefer the Series approach and calculating what hypothetically happened lazily when asked, rather than painstakingly simulating the wind-up duck moment to moment to moment. Save those cycles for the players who need them.
Aesthetically, a Series solution is a static graph inferred from your statements about it. This tracks lispmoo2, where I want a lispMOO2 $thing to really be a $thing, not a description of ongoing iteration.
On the other hand, when I want the world's clock to tick along moving us through real time; that still is and is written as iteration.
Get lispmoo2
lispmoo2
Status | Prototype |
Author | screwtape |
Tags | common-lisp, emacs, lisp, mcclim, moo, new-kind-of-society, swank, Text based |
More posts
- LISPMOO2 INSTRUCTIONS (IMPORTANT)31 days ago
- repeatedly-eval-qt - good old-fashioned AI, in my lispmoo2?34 days ago
- Itches Of Mine Lispmoo2 Scratches36 days ago
- Princess revisited36 days ago
- My very own computing revolution47 days ago
- A moonew language for itneraction.50 days ago
- Defining north between two rooms with the low engine50 days ago
- Figuring out how my moonclimb worked50 days ago
- LISP kind of society urgently needed58 days ago
Comments
Log in with itch.io to leave a comment.
* Not that you were about to say so, but I used counting up instead of just
(time (list (mod 1555432 3) (mod 1555432 5) 1555432))
in the spirit of fizzbuzz.