Pico: Scheme for mere mortals
Pico: Scheme for mere mortals
Pico: Scheme for mere mortals
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
<strong>Pico</strong>: <strong>Scheme</strong> <strong>for</strong> <strong>mere</strong><br />
<strong>mortals</strong><br />
Wolfgang De Meuter<br />
Theo D’Hondt<br />
Programming Technology Lab<br />
Vrije Universiteit Brussel<br />
= 10 -12<br />
http://pico.vub.ac.be
A Linked List in C++<br />
template class List<br />
{<br />
public:<br />
! struct Node<br />
! {<br />
! ! Node(const T& data, Node* next=0):data(data),next(next) {}<br />
! ! Node* next;<br />
! ! T data; ! void swap(List& x)<br />
! };<br />
! {<br />
!<br />
! ! Node* tmp = head; head = x.head; x.head = tmp;<br />
List() : head(0) ! {}}<br />
! List(const List& ! L) List& : head(0) operator=(const List& x)<br />
! {<br />
! {<br />
! ! <strong>for</strong> ( const ! Node* ! List i = L.begin(); tmp(x); i!= L.end(); i=i->next )<br />
! ! ! push_front(i->data);<br />
! ! swap(tmp);<br />
! ! reverse(); ! ! return *this;<br />
! }<br />
! }<br />
C++ = 10 12<br />
! void reverse() ! ~List() { clear(); }<br />
! {<br />
! void clear() { while (!empty()) ! T& front() pop_front(); { return } head->data; }<br />
! ! Node* p = 0; Node* i = begin(); Node* n;<br />
! const T& front() const { return head->data; }<br />
! ! while (i)! bool empty() { return !head; }<br />
! ! {<br />
! Node* begin() { return head; }<br />
! ! ! n = i->next;<br />
! void push_front(const ! T& x) Node* { end() { return 0; }<br />
! ! ! i->next ! = ! p; Node* tmp = new Node(x,head); head = tmp;<br />
! ! ! p = i; ! i } = n;<br />
! const Node* begin() const { return head; }<br />
! ! }<br />
! const Node* end() const { return 0; }<br />
! ! head = p; ! void pop_front() {<br />
! }<br />
! ! if (head) { Node* private: tmp = head; head=head->next; delete tmp; }<br />
! }<br />
! Node* head;<br />
};
A Linked List in <strong>Scheme</strong><br />
(define l (list 1 2 3 4 5))<br />
(car l)<br />
(cdr l)<br />
(cons 0 l)<br />
(eq? l1 l2)<br />
(define head car)<br />
(define tail cdr)<br />
(define (reverse l)<br />
(define (reverse-iter l a)<br />
(if (null? l)<br />
a<br />
(reverse-iter (cdr l) (cons (car l) a))))<br />
(reverse-iter l ()))
Good Reasons <strong>for</strong> <strong>Scheme</strong><br />
• LISP Derivative<br />
• It’s small & full of fundamental concepts<br />
• It’s extremely powerful<br />
• Automatic GC & Dynamically Typed<br />
• Interactive Programming<br />
• Portable (R6RS)<br />
• Higher Order Programming Made Easy<br />
• Meta-Programming <strong>for</strong> Real : Extensible<br />
• Validated by Industrial Applications
Argument against <strong>Scheme</strong><br />
(define (QuickSort V Low High)<br />
(define Left Low)<br />
(define Right High)<br />
(define Pivot (vector-ref V (quotient (+ Left Right) 2 )))<br />
(define Save 0)<br />
(do ((stop #f (> Left Right))) (stop)<br />
(do () ((>= (vector-ref V Left) Pivot))<br />
(set! Left (+ Left 1)))<br />
(do () ((
<strong>Pico</strong>: <strong>Scheme</strong> <strong>for</strong> <strong>mere</strong> <strong>mortals</strong><br />
QuickSort(V, Low, High):<br />
{ Left: Low;<br />
Right: High;<br />
Pivot: V[(Left + Right) // 2];<br />
Save: 0;<br />
until(Left > Right,<br />
{ while(V[Left] < Pivot, Left:= Left+1);<br />
while(V[Right] > Pivot, Right:= Right-1);<br />
if(Left Left, QuickSort(V, Left, High)) }
Another Teaser: Linked Lists<br />
{ pair(x,y):[x,y];<br />
is_pair(x):if(is_table(x),size(x)=2,false);<br />
head(l):if(is_pair(l),<br />
l[1],<br />
error(“not a pair”));<br />
tail(l):if(is_pair(l),<br />
l[2],<br />
error(“not a pair”));<br />
list@tab:{ walk(t):if(t=size(tab)+1,<br />
void,<br />
pair(tab[t],walk(t+1)));<br />
walk(1)};<br />
is_null(x):is_void(x);<br />
reverse(l):{ reverse_iter(l1,l2):<br />
if(is_null(l1),<br />
l2,<br />
reverse_iter(cdr(l1),pair(car(l1),l2)));<br />
reverse_iter(l,void)}<br />
}
The Dictionary*<br />
program<br />
dictionary = { (name, value) }<br />
eval<br />
value<br />
reference<br />
dictionary = { (name, value) }<br />
addition<br />
*aka The Evaluation Environment<br />
{ i:0;<br />
from1To10[10]:(i:=i+1);<br />
succ(x):x+1;<br />
i:=0;<br />
from2To11[10]:succ(from1To10[i:=i+1]);<br />
display(from1To10);<br />
display(eoln);<br />
display(from2To11)<br />
}<br />
overwriting
Fundamental Concepts<br />
dictionary<br />
operations<br />
reference addition overwriting<br />
invocations<br />
name<br />
pi<br />
variable<br />
reference<br />
pi:3.14<br />
variable<br />
definition<br />
pi:=3.1459<br />
variable<br />
assignment<br />
name[exp]<br />
A[i]<br />
table<br />
reference<br />
A[10]:5<br />
table<br />
definition<br />
A[i+3]:=7<br />
table<br />
assignment<br />
name(exp, ..., exp)<br />
id(5)<br />
function<br />
application<br />
id(x):x<br />
function<br />
definition<br />
id(x):=x+4<br />
function<br />
assignment
+ Syntactic Sugar:<br />
+ Bells and Whistles<br />
{ x:1; y:2; z:x+y }<br />
... sequencing ...<br />
begin(x:1,y:2,z:x+y)<br />
[ 1, “hi!”, 3.14 ]<br />
3+4<br />
x
Foundation: Functions<br />
{ t:4;<br />
f(x): { g(y): x+y+t;<br />
g }<br />
myG:f(4);<br />
myG(6)<br />
}<br />
f<br />
t 4<br />
“f”<br />
[“x”]<br />
{ g(y) ... }<br />
x 4<br />
myG<br />
g<br />
“g”<br />
[“y”]<br />
x+y+t<br />
y 6
Table Arguments<br />
main@args:{<br />
display(args[1],args[2])<br />
}<br />
main(1,2,3)<br />
accumulate@t:<br />
<strong>for</strong>(i:(res:0)+1,i
Functional Arguments (1)<br />
zero(a, b, f(x), epsilon):<br />
{ c: (a+b)/2;<br />
if(abs(f(c)) < epsilon,<br />
c,<br />
if(f(a)*f(c) < 0,<br />
zero(a, c, f(x), epsilon),<br />
zero(c, b, f(x), epsilon))) }<br />
zero(-2,2, x, 0.01)<br />
zero(-1,1, x*x-5, 0.001)
Functional Arguments (2)<br />
selection(t,l
Functional Arguments (3)<br />
The Essence<br />
{ delay(exp()):exp;<br />
<strong>for</strong>ce(exp):exp()<br />
}<br />
{ e:delay(display(x));<br />
x:3;<br />
<strong>for</strong>ce(e)<br />
}
Functional Arguments (4)<br />
true(t, f()): t<br />
false(t(), f): f<br />
if(cond, t(), f()): cond(t(),f())<br />
while(cond(), exp()):<br />
{ loop(value, pred): pred(loop(exp(), cond()), value);<br />
loop(void, cond()) }<br />
<strong>for</strong>(i,p(), c(), e()):<br />
while(c(),{v:e();p();v})
Functional Arguments (5)<br />
{ tag => fun:<br />
[tag, fun];<br />
else: 0;<br />
}<br />
case@clauses:<br />
{ default: void;<br />
siz: size(clauses);<br />
max: 0;<br />
<strong>for</strong>(k: 1, k:= k+1, not(k > siz),<br />
{ clause: clauses[k];<br />
if(clause[1] = else,<br />
default:= clause[2],<br />
if(clause[1] > max,<br />
max:= clause[1],<br />
void)) { raise(exc,val):error(“UNCAUGHT });<br />
EXCEPTION”);<br />
tbl[max]: default;<br />
<strong>for</strong>(k: 1, k:= k+1, trycatch(try(), not(k > siz), filter(exception),catch(exception,value)):<br />
{ clause: clauses[k]; call({ keep:raise;<br />
if(clause[1] = else, raise(id,retval):={<br />
void,<br />
raise:=keep;<br />
tbl[clause[1]]:= clause[2]) if(filter(id), });<br />
continue(cont,catch(id,retval)),<br />
select(tag):<br />
raise(id,retval))};<br />
if(tag > max, default, res:try();<br />
tbl[tag]) }<br />
raise:=keep;<br />
res}) }
Implementation<br />
• 8000 lines of C<br />
• Mark&Sweep GC<br />
• Multi-threaded<br />
• Continuation Passing Style (100% Tail Recursive)<br />
• Windows, MacOS, Linux<br />
http://prog.vub.ac.be/~tjdhondt/ICP2/HTM.dir/introduction.htm
<strong>Pico</strong> as a Teaching Tool<br />
• pre-2002: 1st year of Sciences<br />
• Biology: <strong>Pico</strong> as a Fractal-Lab<br />
• Math: <strong>Pico</strong> as a Numerical Experimentarium<br />
• Physics: <strong>Pico</strong> as a Simulation Engine<br />
• Chemistry: <strong>Pico</strong> as a Mini DBMS + Query System<br />
• 1st year Mathematics (“Programming in 10Hrs”)<br />
• 2nd year Computer Science (“Interpretation of Computer<br />
Programs II”)<br />
http://prog.vub.ac.be/
<strong>Pico</strong> as a Research Tool<br />
• Borg: Agent-version of <strong>Pico</strong><br />
• Pic%: Object-Oriented Extension of <strong>Pico</strong><br />
• Sic%: Implementation in Smalltalk<br />
• Java<strong>Pico</strong>: Implementation in Java<br />
• ChitChat: Pic% with Distribution and Mobility<br />
• AmbientTalk: <strong>Pico</strong> <strong>for</strong> PDA’s<br />
http://prog.vub.ac.be/
<strong>Pico</strong>: Summary<br />
Fundamental Concepts<br />
dictionary<br />
operations<br />
invocations<br />
reference addition overwriting<br />
+ Bells and Whistles<br />
+ Syntactic Sugar:<br />
{ x:1; y:2; z:x+y }<br />
... sequencing ...<br />
begin(x:1,y:2,z:x+y)<br />
name<br />
name[exp]<br />
name(exp, ..., exp)<br />
pi<br />
variable<br />
reference<br />
A[i]<br />
table<br />
reference<br />
id(5)<br />
function<br />
application<br />
pi:3.14<br />
variable<br />
definitio<br />
A[10]:5<br />
table<br />
definitio<br />
id(x):x<br />
function<br />
definitio<br />
pi:=3.1459<br />
variable<br />
assignment<br />
A[i+3]:=7<br />
table<br />
assignment<br />
id(x):=x+4<br />
function<br />
assignment<br />
[ 1, “hi!”, 3.14 ]<br />
3+4<br />
x