Question for the group: does this mail help you see what kind of
things might need watering? 'cos if not I can just keep quiet for a
bit. 8-)
On Mon, Jan 09, 2006 at 08:35:10PM +0900, JC Helary wrote:
> It may be pointless, but I'd like to do my 100 lines perl stuff in
> Lisp. I have OSX so I can try a few implementations and put all that
> on a comprehensive page.
(I shuffled the order to put the good news first)
Following the advice of the SBCL manual, I made a package that allows
me to write "Lisp scripts" like this,
[EMAIL PROTECTED]:/tmp$ cat > test
#! /usr/bin/env shell-sbcl
(format t "Hello, World!~%Called with ~s~%"
shebang:+script-argv+)
ctrl-D
[EMAIL PROTECTED]:/tmp$ chmod a+x test
[EMAIL PROTECTED]:/tmp$ ./test
Linux with NPTL support (e.g. kernel 2.6 or newer) required for
thread-enabled SBCL. Disabling thread support.
Hello, World!
Called with NIL
[EMAIL PROTECTED]:/tmp$
[EMAIL PROTECTED]:/tmp$ ./test wibbly\ wobbly woo
Linux with NPTL support (e.g. kernel 2.6 or newer) required for
thread-enabled SBCL. Disabling thread support.
Hello, World!
Called with ("wibbly wobbly" "woo")
[EMAIL PROTECTED]:/tmp$
So I can write my next 100-liner in Lisp and just run it, same as I do
for Perl. Oh and "my other kernel is a 2.6".
PDF is at
http://www.t8o.org/~mca1001/cgi/viewcvs/*checkout*/lisp/shell-sbcl.pdf?rev=HEAD
and contains links to the source. I've only made it work for SBCL so
far. I listed some things I know are wrong with it, presumably there
are other problems too.
> [...] I am not sure it is necessary (tell me if I'm wrong) but I'd
> like to write stuff for total beginners that include how to do i/o
> with the file system, and other simple stuff that are not always in
> the books (implementation dependant, platform dependant) etc.
Even string manipulation. It wasn't until someone on #lisp gave me
the incantation for an adjustable character array with fill-pointer,
when I asked for an extensible string, that I realised it was even
possible to do the equivalent of
my $foo = "bill"; # new lexically scoped variable, initialised
$foo .= " bloggs"; # .= is like += but for strings
I read the book, I knew it can be done for arrays of objects, but I
hadn't joined the dots to realise the result is also a string.
So the next task I've set me is to implement Perl's substr() in Lisp.
substr() does substring extraction "gimme chars 3 -> 7" in the usual
way.
It also does replacement: overwrite, insert or delete. subtr() can be
used as an lvalue. In Lisp terms it's setf'able, I guess.
substr($foo, 0, 4) = "alexander";
# "alexander bloggs"
There's an extend, some copy and then some overwrite. All done so's
you don't have to worry about how it works. Even if $foo is forty
megs of junk.
The arrays are the same. You can insert or delete anywhere with
splice(), but doing it at either end is cheap and convenient
(push/pop/shift/unshift).
All manner of stacks, fifos and list processing are easy. You can
take an arbitrary subset of elements from an array, using another
array as indices, and this is also an lvalue.
[EMAIL PROTECTED]:/tmp$ perl -e '@foo=(1..7); print "@foo\n"'
1 2 3 4 5 6 7
[EMAIL PROTECTED]:/tmp$ perl -e '@foo=(1..7); @foo[1,3,5] = qw(bish bosh
bash); print "@foo\n"'
1 bish 3 bosh 5 bash 7
It's concise and fast, although accessing nested arrays is untidy.
Sure it's an abuse off innocent punctuation characters, but that's
exactly as important as Lisp's excessive use of ()s.
I think there's a clever data structure behind Perl's arrays, but
frankly it never seemed terribly important to find out about it.
They're fast enough that if there's a problem with speed, it was
probably caused by something else.
I've no doubt that these things can be done. I'll probably build
myself a cribsheet until I have it all memorised or some handy code
written. Until then
;; this works
(let ((str (make-array 0
:element-type 'character
:fill-pointer t
:adjustable t)))
(loop for ch across "boggle" do
(vector-push-extend ch str))
str)
;; might be more efficient?
(let ((str (make-array 0
:element-type 'character
:fill-pointer t
:adjustable t))
(inp "boggle"))
;; stuff inp into str
(let ((len (length inp)))
(adjust-array str (list len) :fill-pointer len)
(loop for i from 0 to (1- len) do
(setf (elt str i)
(elt inp i))))
str)
...I'll carry on tripping over my shoelaces and wondering if there's a
better way. I don't mind, I figure it's part of the fun of learning a
new language.
Thanks for reading,
Matthew #8-)
_______________________________________________
Gardeners mailing list
[email protected]
http://www.lispniks.com/mailman/listinfo/gardeners