|
Prev: CMUCL 18b coredumped unexpectedly
Next: (CN-CIRCLE )cheap wholesale Air rift,Airmax 89,Airmax 360,Airmax 180, Airmax TN,Airmax 97,Airmax 87,air max LTD,Airmax 95,Airmax 2006,Airmax 2007,Airmax 2003,Airmax 90 outlet shoes.
From: andrewbutchart on 14 Apr 2008 09:00 hi, i am new to lisp and i thought i would write a function to convert a string to a list of characters. but instead i get a list of (singleton) lists of characters. here's the code: defun str2list (str) (let ((lis)) (map 'list #' (lambda (c) (append (list c) lis)) str))) if i execute (str2list "ab") i get ((#\a) (#\b)) and NOT (#\a #\b) as expected. any ideas? thanks, andrew
From: John Thingstad on 14 Apr 2008 09:28 P� Mon, 14 Apr 2008 15:00:31 +0200, skrev <andrewbutchart(a)gmail.com>: > hi, > > i am new to lisp and i thought i would write a function to convert a > string to a list of characters. but instead i get a list of > (singleton) lists of characters. here's the code: > > defun str2list (str) > (let ((lis)) > (map 'list #' (lambda (c) (append (list c) lis)) str))) > > if i execute (str2list "ab") i get ((#\a) (#\b)) and NOT (#\a #\b) as > expected. > > any ideas? > > thanks, > andrew CL-USER 1 > (defparameter *s* "hello") *S* CL-USER 2 > (coerce *s* 'list) (#\h #\e #\l #\l #\o) CL-USER 3 > (map 'list #'char-code *s*) (104 101 108 108 111) CL-USER 7 > -------------- John Thingstad
From: Peter Hildebrandt on 14 Apr 2008 09:41 On Mon, 14 Apr 2008 15:00:31 +0200, <andrewbutchart(a)gmail.com> wrote: > defun str2list (str) > (let ((lis)) > (map 'list #' (lambda (c) (append (list c) lis)) str))) I think it's high time to read up on *non-destructive* functions (map and append in particular) and think about what's actually going on. What is lis for (why is it not "list", btw? Lisp can handle variables called like operators)? And what is the append supposed to do? The short answer is: - lis is always nil and never gets changed - (append (list c) lis) thus returns (list c), i.e. (#\a), (#\b), ... - map conses up a list of all the items the lambda form returns, i.e. it is like (list (#\a) (#\b) ...) Now you let the lambda return a single character, not a list (map 'list (lambda (c) c) "hello") This does something like (list #\a #\b ...) HTH, Peter > > if i execute (str2list "ab") i get ((#\a) (#\b)) and NOT (#\a #\b) as > expected. > > any ideas? > > thanks, > andrew -- Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
From: Zach Beane on 14 Apr 2008 09:42 andrewbutchart(a)gmail.com writes: > hi, > > i am new to lisp and i thought i would write a function to convert a > string to a list of characters. but instead i get a list of > (singleton) lists of characters. here's the code: > > defun str2list (str) > (let ((lis)) > (map 'list #' (lambda (c) (append (list c) lis)) str))) > > if i execute (str2list "ab") i get ((#\a) (#\b)) and NOT (#\a #\b) as > expected. > > any ideas? I recommend using non-abbreviated names for functions and variables. For this particular task... MAP returns an accumulation of the result of the function it calls, so there's no need to try to affect LIS in MAP's function. You could do this: (map 'list (lambda (c) c) str) In CL, there's already a function that does (lambda (c) c): (map 'list #'identity str) This also works: (coerce str 'list) Zach
From: Pascal J. Bourguignon on 14 Apr 2008 09:51
andrewbutchart(a)gmail.com writes: > hi, > > i am new to lisp and i thought i would write a function to convert a > string to a list of characters. but instead i get a list of > (singleton) lists of characters. here's the code: > > defun str2list (str) > (let ((lis)) > (map 'list #' (lambda (c) (append (list c) lis)) str))) > > if i execute (str2list "ab") i get ((#\a) (#\b)) and NOT (#\a #\b) as > expected. > > any ideas? John showed you how to do it. Here is what is wrong with your code: > defun str2list (str) Missing an opening parenthesis. Without parentheses, the processor sees a symbol and tries to find its value, but DEFUN has no value... > (let ((lis)) You're binding NIL to the variable LIS. NIL represents false, the empty list, and the symbol NIL itself. And you do that without saying so. So we are very puzzled. Do you care what value LIS is? If you care, do you consider it's a boolean, a list, or a symbol? (let ((lis)) ...) or better: (let (lis) ...) I don't care what lis is, I'll assign a value later. (let ((lis '())) ...) lis is the empty list. (let ((lis 'NIL)) ...) lis is the symbol NIL. (let ((lis NIL)) ...) lis is false. Note, the last combination, () is used only for code, like in: (let () ...) I write a let, but I define no variable. > (map 'list #' (lambda (c) #' is not necessary in front of lambda, I prefer to skip it. Anyways, if you want to write it, don't insert a space: #'(lambda ...) > (append (list c) lis)) str))) APPEND is a pure function, it doesn't modify anything. It will copy all the arguments but the last, and paste the copies and the last argument together to make a big list. Since LIS is NIL, (append (list c) lis) is equivalent to (copy-list (list c)): you are making a list containing the value of C, copying it and immediately forgetting the first list you just created. Andways, what this does is to explicitely putting every C into a list, hence the result you get. (defun str2list (str) (map 'list (function identity) str)) is what (COERCE str 'LIST) does. (defun str2list (str) (let ((result '())) (map 'list (lambda (c) (setf result (append result (list c)))) str) result)) would be AWFUL! It would copy over and over partial results, accumulating them in a list returned by MAP, to be forgotten when you only return the last result. Try: (defun str2list (str) (let ((result '())) (map 'list (lambda (c) (setf result (append result (list c)))) str))) to see what MAP returns. (defun str2list (str) (let ((result '())) (map nil (lambda (c) (setf result (append result (list c)))) str) result)) would reduce the constant on O(N), but this would still be O(N�) because of the repeatitive calls to APPEND. -- __Pascal Bourguignon__ |