# kewl lisp functions
sub car { $_[0] }
sub cdr { shift; @_ }
Where is your god now ?
You also posted this to /prog/.
Kill yourself.
This is /prog/, dumbass.
sub car { eval { $_[0]->[0] }; }
sub cdr { eval { $_[0]->[1] }; }
sub cons { [ $_[0], $_[1] ] }
sub list { my $x = []; map { $x = [ $_, $x ]; } reverse @_; $x; }
sub liststar { my $x = pop; map { $x = [ $_, $x ]; } reverse @_; $x; }
sub list { eval '['.(join ',[', @_).']'x@_ }
sub liststar { my $x=pop; (map { $x = [ pop, $x ] } @_)[-1] }
This thread is prog quality.
Your sub list
doesn't work for list(qw('foo bar'))
, or any list()
using references and your sub liststar
is wrong for liststar(qw(a))
In lisp, you'd usually use a tail-cdr algorithm- except on implementations which cdr-code (in which case list
maps neatly to a primitive). In practice, reverse
is so absurdly fast in perl that it usually isn't worth optimizing away.
> In practice, reverse is so absurdly fast in perl that it usually isn't worth optimizing away.
No it's not.
>>8
ok then...
sub list { my $x = []; (map { $x = [ pop, $x ] } @_)[-1] }
sub liststar { my $x = pop; map { $x = [ pop, $x ] } @_; $x }
>>9 Of course it is. You can see easily within a few minutes:
time perl -e 'print join(",", (1...16553600));' >/dev/null
and
time perl -e 'print join(",", reverse(1...16553600));' >/dev/null
complete in the same amount of time here. Of course, for sets this large using @lists
is usually a mistake anyway.
>>10 Looks better, although it has the same deficiency mine had which requires other code to treat []
and undef
as the same specially which I don't like. Oh well.
You may enjoy knowing that I did some tests with large sets, and it looks like the slice operation with all the pop
s on your sub list
uses a lot more memory and is noticeably slower than mine. This makes sense: pp_reverse
keeps the list operations entirely in cache whereas the path to av_pop
is long enough that it requires extra memory accesses, which is in-turn combined with the (relatively) slow pp_aslice
.
>>11
No, it is not.
when the parser sees reverse(1...N) he replaces it with N...1
Try to read the array from a file, then reverse it and join.
time perl -e 'open(FI,"/usr/share/dict/words"); @g=<FI>; reverse @g; print join(",",@g) . "\n";' >/dev/null
seems to be yielding the same results for me: reverse
is negligable.
What exactly are you suggesting? That reverse
of an n-element list isn't faster than (n-1) pop
s from the same list? Or are you arguing that you have a different definition of "absurdly fast" than I do?
You can implement reverse such that the speed is linear in many languages, so if it's slower than not doing it then Perl simply sucks.
"Linear"? What about constant? That's pretty much trivial to do.
True enough, I meant constant and typed the wrong thing.