# First, we start with:
sub __{my
@perl=@_;sub{&{$_[perl]}(@perl);};sub
___{$"=l;&{$_[perl]}(sub{$_[perl
]});}}$__=
__#___
qw([ o l ' W l y);$_=sub{print
"@_\n";};$/ = join $\, &{$__}(sub{$, = __(q#:i|;!l1#);map {$_=chr(ord($_
)-7);} @_});&{$,}(sub{$_[0
]=~tr/|!1i;l:/ro nuJa/;}
)
;$,=reverse(___(
$,));&{__($/,$,,$\)}
($_);
#########################################################
# Sub 0 for bare words and "pretty print"
# Remove the one comment on the 5th line

sub __{
    my @perl=@_;
    return sub{&{$_[0]}(@perl);};

    sub ___{
	$"=l;
	return &{$_[0]}(sub{$_[0]});
    }
}

$__= __ qw([ o l ' W l y);
$_=sub{print "@_\n";};

$/ = join $\, &{$__}(sub{$, = __(q#:i|;!l1#);map {$_=chr(ord($_)-7);} @_});
&{$,}(sub{$_[0]=~tr/|!1i;l:/ro nuJa/;});
$,=reverse(___($,));
&{__($/,$,,$\)}($_);
#############################################################
# Re-order and pull stuff out of sub-routines
sub __{
    my @perl=@_;
    return sub{&{$_[0]}(@perl);};
}

sub ___{
    return &{$_[0]}(sub{$_[0]});
}

$__= __ qw([ o l ' W l y);
$/ = join $\, &{$__}(sub{map {$_=chr(ord($_)-7);} @_});

$, = __(q#:i|;!l1#);
&{$,}(sub{$_[0]=~tr/|!1i;l:/ro nuJa/;});
$,=reverse(___($,));

$"=l;
$_=sub{print "@_\n";};
&{__($/,$,,$\)}($_);

#########################################################
# Re do variable names
# Sub '' for $\

sub cons{
    my @saved_list=@_;
    return sub{&{$_[0]}(@saved_list);};
}

sub car{
    return &{$_[0]}(sub{$_[0]});
}

$first_cons_ls= cons(qw([ o l ' W l y));
$first = join '', &{$first_cons_ls}(sub{map {$_=chr(ord($_)-7);} @_});

$second_cons = cons(q#:i|;!l1#);
&{$second_cons}(sub{$_[0]=~tr/|!1i;l:/ro nuJa/;});
$second=reverse(car($second_cons));

$"=l;
$println=sub{print "@_\n";};
&{cons($first,$second,'')}($println);

############################################################
# The General idea here is that anonymous subs are used (thanks to static
# scoping) to store data.  cons (an expanded version of it's lisp cousin) 
# takes a list and returns a function that takes another function, which 
# is called on that list.  This allows for loads of fun things to be done with
# anonymous subs.
# Commented Version:

# Cons (Think Lisp)
# Input:  A list: ls
# Output: A function whose:
#  Input:  A function f who takes a list
#  Output: The output of f when it is called with ls
sub cons{  
    my @saved_list=@_;
    return sub{return &{$_[0]}(@saved_list);};
}

# Car (Think Lisp)
# Input: A 'cons-cell'
# Output: The first element in the list
sub car{
    return &{$_[0]}(sub{return $_[0]});
}

# Create a cons cell with a list of characters.  Subtract 7 from the 
# ASCII value of each and join with ''
$first_cons_ls= cons(qw([ o l ' W l y));
$first = join '', &{$first_cons_ls}(sub{map {$_=chr(ord($_)-7);} @_});

# Create a cons cell with one string, then to a tr to it, and reverse it.
$second_cons = cons(q#:i|;!l1#);
&{$second_cons}(sub{$_[0]=~tr/|!1i;l:/ro nuJa/;});
$second=reverse(car($second_cons));

# Set the string interpolation of list character to 'l' (used to be done
# in a subroutine).
$"=l;

# A reference to a function that takes a list and prints it (uses the 
# interpolation character above)
$println=sub{print "@_\n";};

# Put it all together for the print.
&{cons($first,$second,'')}($println);


