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