Re: [Audacity-nyquist] Lisp list making question
A free multi-track audio editor and recorder
Brought to you by:
aosiniao
From: <edg...@we...> - 2008-01-28 05:38:08
|
George Jenner wrote: Hello list, > > Well I've spent the first half of a public holiday not being able to write the simplest of lisp, so I'm giving up, asking you, and going to the beach :-) > > I want to use a while loop to create a list of numbers, then print the output. So in the code below I'm expecting to get (3 4 5) as the output. But I get nothing. In the code below I would expect the list e, created with "append", to give me this output, and the list d, created with "list", to give me (3 (3 4) (3 4 5)) - or something like that which I don't want. > > If anyone could point me to the right solution I'd be most grateful. > > George > > ---code--- > > > (setq d (list)) > (setq e (list)) > (setq b 0) > (setq a 1) > (while (<= a 3) > (setq b (+ a 2)) > (print b) > (list d b) > (append e b) > (setq a (+ a 1)) > ) > (print d) > (print e) > > ---output--- > ; loading "C:\Documents and Settings\George\My Documents\test.lsp" > 3 > 4 > 5 > NIL > NIL > T Hi George, (setq d (list)) (setq e (list)) I assume you try to initialize 'd' and 'e' as lists. This would usually be done with 'nil', because 'nil' represents the empty list. E.g.: (setq d nil) (setq e nil) The funny thing is that your code works too, because if you call the 'list' function [the first word inside the parens in Lisp is always understood as a function name] without arguments, it also returns nil. (while (<= a 3) (setq b (+ a 2)) (print b) (list d b) (append e b) (setq a (+ a 1)) ) Here you obviously try to find ways how to build lists within a loop. (list d b) (append e b) (list d b) will return a list (nil 0) because 'd' was initialized to nil [the empty list], and 'b' was initialized to 0. (append e b) will return 0, because 'b' [initialized to 0] was appended to the empty list nil. An important principle of Lisp is that it RETURNS values, it doesn't modify variables in-place, so you must 'catch' the return values of 'list' and 'append' and assign them with 'setq' to variables, to store and 'collect' the values. Because Lisp always evaluates the innermost parens first you can assign the return value to the same variable name: (setq d (list d b)) (setq e (append e b)) But this here only works in theory because 'append' in XLISP only works right if BOTH arguments are lists, and in your case one of the arguments, 'b', is a number. Unfortunately XLISP raises no error with this [what is IMHO a bug in XLISP], it just 'swallows' the argument from the second turn and all other turns of the loop. To collect a list with 'append' in XLISP you must either write: (setq e (append (if (atom e) (list e) e) (if (atom b) (list b) b)))) Plain english translation: if 'e' is an atom, make it a list, otherwise leave it as-is, the same with 'b', what is rather awkward code, or you can use 'cons' and reverse the list at the end, because 'cons' builds lists 'backwards' [beginning from the end]. (setq e (cons b e)) where 'e' must be a list [what it is, because it is initialized to nil]. If you then write a function like this: (defun collect-list () (setq d nil) (setq e nil) (setq b 0) (setq a 1) (while (<= a 3) (setq b (+ a 2)) (print b) (setq d (list d b)) (setq e (cons b e)) (setq a (+ a 1)) ) (setq e (reverse e)) (print d) (print e)) After you loaded (or copied) the function into the interpreter you can type: (collect-list) and you will get: 3 4 5 ((NIL 3) 4) 5) (3 4 5) (3 4 5) Now try it yourself and find out how it works. - edgar -- The author of this email does not necessarily endorse the following advertisements, which are the sole responsibility of the advertiser: _______________________________________ GRATIS: Movie-FLAT. Jetzt freischalten! http://freemail.web.de/club/maxdome.htm |