RSS Feed

Lisp Project of the Day

doplus

You can support this project by donating at:

Donate using PatreonDonate using Liberapay

Or see the list of project sponsors.

dopluslanguage

Do+ is a macro, similar to 'loop' or 'iterate', but built with simplicity in mind.

Documentation is good and contains some examples showing how does iteration works and how to extend the behaviour and add new iteration methods.

Here is a simple iteration on the list:

POFTHEDAY> (use-package :doplus)
T
POFTHEDAY> (do+
             (for i (in "Hello world!"))
             (collect i))
(#\H #\e #\l #\l #\o #\  #\w #\o #\r #\l #\d #\!)

Now let's try to extend do+ to iterate on week days:

POFTHEDAY> (defclause in-days ()
             `(for ,*iteration-variable*
                   (in '(:monday :tuesday :wednesday
                         :thursday :friday :saturday :sunday))))

POFTHEDAY> (do+
             (for day (in-days))
             (format t "Hello ~A~%" day))
Hello MONDAY
Hello TUESDAY
Hello WEDNESDAY
Hello THURSDAY
Hello FRIDAY
Hello SATURDAY
Hello SUNDAY

Another cool feature is support for generators. BTW, :iterate supports them too.

Let's try to build a generator which emits an infinite sequence of Fibonacci numbers.

The first step is to implement the iteration in do+ terms:

POFTHEDAY> (do+
             (with (prev 0))
             (for x (being 1 :then (prog1 (+ prev x)
                                     (setf prev x))))
             (format t "prev: ~A x: ~A~%" prev x)
             (stop-when (> x 100)))
prev: 0 x: 1
prev: 1 x: 1
prev: 1 x: 2
prev: 2 x: 3
prev: 3 x: 5
prev: 5 x: 8
prev: 8 x: 13
prev: 13 x: 21
prev: 21 x: 34
prev: 34 x: 55
prev: 55 x: 89

Next, we need to wrap it into the defclause.

This clause can be used in any do+ loops and will be lazily evaluated:

POFTHEDAY> (defclause in-fib ()
             `((with (prev 0))
               (for ,*iteration-variable*
                    (being 1 :then (prog1 (+ prev ,*iteration-variable*)
                                     (setf prev ,*iteration-variable*))))))

;; Now we can use it as a clause inside another do+ form:
POFTHEDAY> (do+
             (for x (in-fib))
             (format t "x: ~A~%" x)
             (stop-when (> x 100)))
x: 1
x: 1
x: 2
x: 3
x: 5
x: 8
x: 13
x: 21
x: 34
x: 55
x: 89
NIL

Manual lives on the wiki: https://bitbucket.org/alessiostalla/doplus/wiki/Home

See also :iterate, :for and :series.


Brought to you by 40Ants under Creative Commons License