Tuesday 2 February 2010

continuation passing style

quick experiment continuation passing style (cps).
clearly nothing miraculous happening here.
procedures bit limited though on accepting variable number of
arguments , think relaxing this make exploratory
programming easier


;; continuation passing style
(defun integer-divide(a b success failure)
(if (= b 0)
(funcall failure "division by zero")
(multiple-value-bind (c d) (floor a b)
(funcall success c d))))

CL-USER> (integer-divide 10 3 #'list (lambda (x) x))
(3 1)
CL-USER> (integer-divide 10 2 #'list (lambda (x) x))
(5 0)
CL-USER> (integer-divide 10 1 #'list (lambda (x) x))
(10 0)
CL-USER> (integer-divide 10 4 #'list (lambda (x) x))
(2 2)
CL-USER> (integer-divide 10 0 #'list (lambda (x) x))
"division by zero"
CL-USER>

foreach construct

foreach construct .
improvements - maybe get iteration over arrays , as well as a lists .?
small tweaks to common lisp language.


;; foreach
(defpackage :test
(:use #:cl))

(in-package :test)

(defmacro foreach(symbol sequence &rest body)
`(progn
(dolist (,symbol ,sequence)
,@body)))

;; tests
(foreach p '(1 2 3 4 5 )
(format t "p= ~a ~%" p))
p= 1
p= 2
p= 3
p= 4
p= 5
NIL

(foreach p '(1 2 3 4 5 )
(foreach q '(1 2 3 4 5 )
(format t "p= ~a q = ~a ~%" p q)))
p= 1 q = 1
p= 1 q = 2
p= 1 q = 3
p= 1 q = 4
p= 1 q = 5
p= 2 q = 1
p= 2 q = 2
p= 2 q = 3
p= 2 q = 4
p= 2 q = 5
p= 3 q = 1
p= 3 q = 2
p= 3 q = 3
p= 3 q = 4
p= 3 q = 5
p= 4 q = 1
p= 4 q = 2
p= 4 q = 3
p= 4 q = 4
p= 4 q = 5
p= 5 q = 1
p= 5 q = 2
p= 5 q = 3
p= 5 q = 4
p= 5 q = 5
NIL

common lisp - generators

exploring the very basics of generators in common lisp.
here is a simple counter . procedure make-counter when given number , produces next number above by one as result. each call to f , or g , produces the next value. values of n for f are seperate to those of g .
so can make as many counters as want.


;;attempt at generators in lisp
(defpackage :test
(:use #:cl))

(in-package :test)

(defun make-counter(n)
(lambda ()
(setq n (+ n 1))))

;; tests
(setq f (make-counter 0))

;; this generates next value
(funcall f)

(setq g (make-counter 321))

(funcall g)

macro hacking - while loop

common lisp code while construct from c language.
in small scale program , this seems to work ok .
reliant on behaviour return to escape inner loops , it seems to be working fine in sbcl so far.


(defpackage :test
(:use #:cl)
(:shadow #:while))

(in-package :test)

(defmacro while(condition &rest body)
`(progn
;; loop
(loop
;; check condition - if not met then exit loop
(if (not ,condition) (return))
;; insert body here...
,@body)))

;; tests

(let ((i 0))
(while (< i 10)
(format t "i= ~a~%" i)
(setq i (+ i 1))))
i= 0
i= 1
i= 2
i= 3
i= 4
i= 5
i= 6
i= 7
i= 8
i= 9
NIL


(let ((i 0) (j 0))
(while (< i 5)
(setq j 0)
(while (< j 5)
(format t "i= ~a j=~a~%" i j)
(setq j (+ j 1)))
(setq i (+ i 1))))

i= 0 j=0
i= 0 j=1
i= 0 j=2
i= 0 j=3
i= 0 j=4
i= 1 j=0
i= 1 j=1
i= 1 j=2
i= 1 j=3
i= 1 j=4
i= 2 j=0
i= 2 j=1
i= 2 j=2
i= 2 j=3
i= 2 j=4
i= 3 j=0
i= 3 j=1
i= 3 j=2
i= 3 j=3
i= 3 j=4
i= 4 j=0
i= 4 j=1
i= 4 j=2
i= 4 j=3
i= 4 j=4
NIL

macro hacking - repeat construct from logo

here we try to reproduce the repeat construct found in logo programming language.
logo would have repeat N [ ... ] , we would write maybe (repeat i N ...
where i holds number of iterations body has executed so far.
macro does pollute namespace though , test i after repeat statement run, find i variable has a value. not sure if this is a good thing or not.
maybe could of used a let construct.??


;;
(defpackage :test
(:use #:cl)
(:shadow #:repeat))

(in-package :test)

(defmacro repeat(symbol iterations &rest body)
`(progn
;;initialize
(setq ,symbol 0)
;; loop
(loop
;; check condition - if not met then exit loop
(if (>= ,symbol ,iterations) (return))
;; insert body here...
,@body
;; increment
(setq ,symbol (+ ,symbol 1)))))

;; tests

;; escape repeat loop use return
(repeat i 10 (if (= i 3) (return 'done)) (format t "i = ~a ~%" i))
i = 0
i = 1
i = 2
DONE

;; seems to work ok
(repeat i 5 (repeat j 5 (format t "i = ~a , j = ~a ~%" i j)))
i = 0 , j = 0
i = 0 , j = 1
i = 0 , j = 2
i = 0 , j = 3
i = 0 , j = 4
i = 1 , j = 0
i = 1 , j = 1
i = 1 , j = 2
i = 1 , j = 3
i = 1 , j = 4
i = 2 , j = 0
i = 2 , j = 1
i = 2 , j = 2
i = 2 , j = 3
i = 2 , j = 4
i = 3 , j = 0
i = 3 , j = 1
i = 3 , j = 2
i = 3 , j = 3
i = 3 , j = 4
i = 4 , j = 0
i = 4 , j = 1
i = 4 , j = 2
i = 4 , j = 3
i = 4 , j = 4
NIL

macro hacking - a simple for loop

first attempt at writing c like for loop construct in common lisp. macros are supposed to be very powerful , so thought try to write my own and see if can tame this beast.

;;
(defpackage :test
(:use #:cl)
(:shadow #:for))
(in-package :test)

(defmacro for( symbol init cond inc &rest body)
`(progn
;;initialize
(setq ,symbol ,init)
;; loop
(loop
;; check condition - if not met then exit loop
(if (not ,cond) (return))
;; insert body here...
,@body
;; increment
(setq ,symbol ,inc))))


and some quick tests

;; quick test
(for i 0 (< i 5) (+ i 1) (format t "i = ~a ~%" i))
i = 0
i = 1
i = 2
i = 3
i = 4
NIL

(for i 0 (< i 5) (+ i 1)
(for j 0 (< j 5) (+ j 1)
(format t "i = ~a j =~a ~%" i j)))
i = 0 j =0
i = 0 j =1
i = 0 j =2
i = 0 j =3
i = 0 j =4
i = 1 j =0
i = 1 j =1
i = 1 j =2
i = 1 j =3
i = 1 j =4
i = 2 j =0
i = 2 j =1
i = 2 j =2
i = 2 j =3
i = 2 j =4
i = 3 j =0
i = 3 j =1
i = 3 j =2
i = 3 j =3
i = 3 j =4
i = 4 j =0
i = 4 j =1
i = 4 j =2
i = 4 j =3
i = 4 j =4
NIL


seems okay .
think try some more things like repeat construct in logo.

Sunday 31 January 2010

emacs org-mode

org-mode video

* headers
some text
** sub headers
some text for sub headers
*** sub sub headers

just tried org-mode for emacs. its brilliant , so simple. type your notes in like this , any headers want just put * at beginning of new line and carry on typing. then want to rearrange things it really simple , use ALT + cursor keys on * header lines and it takes text associated and any sub-headers with it to new location.

Recap
put cursor on star then press
ALT+LEFT = promote
ALT+RIGHT = demote
ALT+UP = move up in list
ALT+DOWN = move down in list

try it , such a time saver.

typical install on linux goes something like this .

#get it from git repository
git clone git://repo.or.cz/org-mode.git
#
cp -r org-mode [your-target-destination]
cd [your-target-destination]
make
make doc
make install

if you dont use emacs , i would just for org-mode.