# this time, we will use a closure-based implementation of lists directly
# based on pure lambda calculus.

undef $NIL;  # use an undefined variable for empty list

sub lambdacons {   
    my ($car,$cdr) = @_;
    sub {
        if ($_[0]) {$car} else {$cdr}
    }
};  # lambda a.lambda b.lambda c.if c a b
sub lambdacar { $_[0]->(1) }  # lambda p.(p True)
sub labmdacdr { $_[0]->(0) }  # lambda p.(p False)

# can use built-in nested tuples for lists
sub cons{ \@_ } # just return pointer to tuple
sub car { $_[0]->[0] }
sub cdr { $_[0]->[1] }

$M = cons(2,cons(3,cons(5,cons(7,cons(11,$NIL)))));

sub forevery {
    my ($list,$action) = @_;  
    while ($list) {
        $action->(car($list));  # 0 used for false
        $list = cdr($list);
    }
}

forevery($M, sub{ print @_," " });


### last value in list
sub lastval {
    my $m = $_[0];
    while (cdr($m)) { $m = cdr($m); }
    $m  # error: should be car($m)
}

print "\n", lastval($M), "\n";
    
print lastval($M) + 1, "\n";   # should get 12?  error?
