`*-----------------------------------*`

`*           >>>Pico 2.0<<<          *`

`*         Wolfgang De Meuter        *`

`*  VUB Programming Technology Lab   *`

`*               2004               *`

`*-----------------------------------*`

`*  Cons-cells & Lists Abstractions  *`

`*-----------------------------------*`

{ cons(x,y)::[x,y];

  is_list(x)::if(is_table(x),size(x)=2,is_void(x));

  car(l)::if(is_list(l),

            if(is_table(l),

              l[1],

              error("car expects a non-empty pair")),

          error("not a list"));

  cdr(l)::if(is_list(l),

            if(is_table(l),

              l[2],

              error("cdr expects a non-empty pair")),

          error("not a list"));

  is_atom(x)::!is_list(x);

  list@tab::{ walk(t):

                if(t=size(tab)+1,

                  void,

                  cons(tab[t],walk(t+1)));

              walk(1)};

  is_null(x)::is_void(x);

  length(l)::if(is_null(l),0,1+length(cdr(l)));

  append(l1,l2)::if(is_null(l1),l2,cons(car(l1),append(cdr(l1),l2)));

  reverse(l)::{ reverse_iter(l1,l2):

                  if(is_null(l1),

                     l2,

                     reverse_iter(cdr(l1),cons(car(l1),l2)));

                reverse_iter(l,void)};

  map(l,f)::

    if(is_null(l),l,cons(f(car(l)),map(cdr(l),f)));

  foldr(op,init,lst)::

    if(is_null(lst),init, op(car(lst),foldr(op,init,cdr(lst))));

  foldl(op,init,lst)::{

    foldit(lst,res):

      if(is_null(lst),

        res,

        foldit(cdr(lst),op(res,car(lst))));

    foldit(lst,init)};

  zip(l1,l2,null,op)::{

    elm(l):if(is_null(l),null,car(l));

    nxt(l):if(is_null(l),l,cdr(l));

    if(is_null(l1) & is_null(l2),

       void,

       cons(op(elm(l1),elm(l2)),zip(nxt(l1),nxt(l2),null,op))) };

  lisp_print(l)::{

    lst(l): { lisp_print(car(l));

                        if(is_null(cdr(l)),

                            void,

                            { display(" ");lst(cdr(l)) } )  };

    if(is_atom(l),display(l),{display("(");lst(l);display(")")})};

  `* SAMPLE CODE *`

  l1:list(1,2,3,4,5);

  l2:list(6,7,8);

  lisp_print(reverse(l1));display(eoln);

  lisp_print(append(l1,l2));display(eoln);

  display(foldr(-,0,l1),eoln);

  display(foldl(-,0,l1),eoln);

  lisp_print(zip(l1,l2,0,+))

}