I actually dabbled in it a few years ago, but got sidetracked and
quit programming all together. But now I'm back for whatever
reason--curiosity, I guess.
Anyway, I hail mainly from the C/Fortran world, so I'm having a time
wrapping my brain around Lisp. But I wanted to start off kind of
simple, so:
(defun pairify (l)
(let ((r nil))
(do ()
((null l))
(push (cons (car l) (cadr l)) r)
(setq l (cddr l)))
r))
[68]> (pairify '(a b c d))
((C . D) (A . B))
[69]> (pairify '(a b c d e))
((E) (C . D) (A . B))
Questions:
Is there a standard equivalent in Common Lisp?
Style-wise (which I know is mostly subjective) is there a cleaner
way to go about this?
More questions later.
--
B.B. --I am not a goat! thegoat4 at airmail.net
Fire the stupid--Vote.
In article
<·······································@library.airnews.net>,
"B.B." <·················@airmail.net.com.org.gov.tw.ch.ru> wrote:
> I actually dabbled in it a few years ago, but got sidetracked and
>quit programming all together. But now I'm back for whatever
>reason--curiosity, I guess.
> Anyway, I hail mainly from the C/Fortran world, so I'm having a time
>wrapping my brain around Lisp. But I wanted to start off kind of
>simple, so:
>
>(defun pairify (l)
> (let ((r nil))
> (do ()
> ((null l))
> (push (cons (car l) (cadr l)) r)
> (setq l (cddr l)))
> r))
>
>[68]> (pairify '(a b c d))
>((C . D) (A . B))
>[69]> (pairify '(a b c d e))
>((E) (C . D) (A . B))
>
> Questions:
> Is there a standard equivalent in Common Lisp?
> Style-wise (which I know is mostly subjective) is there a cleaner
>way to go about this?
>
> More questions later.
Ah, silly me, I didn't try the recursive route. How's this:
(defun pairify (l)
(let ((r nil))
(if (and l (cdr l))
(cons (cons (car l)
(cadr l))
(pairify (cddr l))))))
--
B.B. --I am not a goat! thegoat4 at airmail.net
Fire the stupid--Vote.
B.B. wrote:
> In article
> <·······································@library.airnews.net>,
> "B.B." <·················@airmail.net.com.org.gov.tw.ch.ru> wrote:
>
>
>> I actually dabbled in it a few years ago, but got sidetracked and
>>quit programming all together. But now I'm back for whatever
>>reason--curiosity, I guess.
>> Anyway, I hail mainly from the C/Fortran world, so I'm having a time
>>wrapping my brain around Lisp. But I wanted to start off kind of
>>simple, so:
>>
>>(defun pairify (l)
>> (let ((r nil))
>> (do ()
>> ((null l))
>> (push (cons (car l) (cadr l)) r)
>> (setq l (cddr l)))
>> r))
>>
>>[68]> (pairify '(a b c d))
>>((C . D) (A . B))
>>[69]> (pairify '(a b c d e))
>>((E) (C . D) (A . B))
>>
>> Questions:
>> Is there a standard equivalent in Common Lisp?
>> Style-wise (which I know is mostly subjective) is there a cleaner
>>way to go about this?
>>
>> More questions later.
>
>
> Ah, silly me, I didn't try the recursive route. How's this:
>
> (defun pairify (l)
> (let ((r nil))
> (if (and l (cdr l))
> (cons (cons (car l)
> (cadr l))
> (pairify (cddr l))))))
>
There's nothing silly about iteration. Sometimes it's clearly the better
option compared to recursion. But it's good that you are able to
implement your function either way to compare.
Zach has already pointed out the features of DO which can simplify your
code. Here are some variations of your recursive implementation:
(defun pairify1 (l)
(cond ((null l) '())
((null (cdr l))
'error-odd-number-of-inputs) ;Various responses here
(t (cons (cons (first l) (second l)) (pairify1 (cddr l)))) ))
(defun pairify2 (l result)
(cond ((null l) result)
((null (cdr l)) 'error)
(t (pairify2 (cddr l)
(cons (cons (first l) (second l)) result)))) )
PAIRIFY2 is tail-recursive, which is better if your Lisp handles
last-call optimisation (but notice the difference in order of the
output). In order to present the same interface as PAIRIFY you can
either define a separate front-end or wrap PAIRIFY2 in another function:
(defun pairify3 (l) ;Takes only 1 arg
(pairify2 l '())
(defun pairify4 (l)
(labels ((pairify-aux (l result) ;Same as PAIRIFY2 here
(cond ((null l) result)
((null (cdr l)) 'error)
(t (pairify-aux (cddr l)
(cons (cons (first l) (second l)) result)))) ))
(pairify-aux l '())))
Note that your function is similar to the Lisp function PAIRLIS:
(pairlis '(a b c) '(1 2 3)) => ((C . 3) (B . 2) (A . 1))
This can be simulated as follows:
(defun my-pairlis (keys vals)
(mapcar #'cons keys vals))
MAPCAR constructs a list by applying the function (CONS here) to
successive pairs (in this example) of elements from the input list(s).
See the HyperSpec for more details:
http://www.lispworks.com/reference/HyperSpec/Body/f_mapc_.htm
http://www.lispworks.com/reference/HyperSpec/Body/f_pairli.htm
David Sletten
"B.B." <·················@airmail.net.com.org.gov.tw.ch.ru> wrote in message news:<·······································@library.airnews.net>...
> I actually dabbled in it a few years ago, but got sidetracked and
> quit programming all together. But now I'm back for whatever
> reason--curiosity, I guess.
> Anyway, I hail mainly from the C/Fortran world, so I'm having a time
> wrapping my brain around Lisp. But I wanted to start off kind of
> simple, so:
>
> (defun pairify (l)
> (let ((r nil))
> (do ()
> ((null l))
> (push (cons (car l) (cadr l)) r)
> (setq l (cddr l)))
> r))
>
> [68]> (pairify '(a b c d))
> ((C . D) (A . B))
> [69]> (pairify '(a b c d e))
> ((E) (C . D) (A . B))
>
> Questions:
> Is there a standard equivalent in Common Lisp?
> Style-wise (which I know is mostly subjective) is there a cleaner
> way to go about this?
I prefer recursion to iteration. (BTW, if you wanted to have the
option of specifying a starting list, you could simply remove the
labels and have an &optional acc argument - left as an easy exercise
to the reader ;)
(defun pairify (list)
"Creates an assoc list by matching even and odd elements of the list
together one to one, left to right."
(labels ((inner-pairify (list acc)
(cond ((null list) acc)
(t (inner-pairify (cddr list)
(acons (car list) (cadr list)
acc))))))
(inner-pairify list nil)))
[13]> (pairify '(1 2 3))
((3) (1 . 2))
The functionality looks a bit like pairlis
(http://www.lispworks.com/reference/HyperSpec/Body/f_pairli.htm#pairlis).
BTW, my description of the function sucks... sorry :)
"B.B." <·················@airmail.net.com.org.gov.tw.ch.ru> writes:
> Anyway, I hail mainly from the C/Fortran world, so I'm having a time
> wrapping my brain around Lisp. But I wanted to start off kind of
> simple, so:
>
> (defun pairify (l)
> (let ((r nil))
> (do ()
> ((null l))
> (push (cons (car l) (cadr l)) r)
> (setq l (cddr l)))
> r))
>
> [68]> (pairify '(a b c d))
> ((C . D) (A . B))
> [69]> (pairify '(a b c d e))
> ((E) (C . D) (A . B))
You don't actually mention what your function is supposed to do. While
it *seems* obvious, the recursive version you posted later produces
different output. If you're looking for various ways to do a
particular thing, it can be helpful to be explicit about what's
important and not important about the result.
> Questions:
> Is there a standard equivalent in Common Lisp?
I don't think so.
> Style-wise (which I know is mostly subjective) is there a cleaner
> way to go about this?
DO can
- initialize variables (no need for the LET binding)
- update the values on each iteration (no need for PUSH and SETQ)
- return a particular value when finished (no need for the trailing
R)
With that in mind, here's how I would write PAIRIFY with DO:
(defun pairify (head)
(do ((pairs nil (cons (cons (car list) (cadr list)) pairs))
(list head (cddr list)))
((null list) pairs)))
Zach
B.B. wrote:
> [68]> (pairify '(a b c d))
> ((C . D) (A . B))
> [69]> (pairify '(a b c d e))
> ((E) (C . D) (A . B))
>
> Questions:
> Is there a standard equivalent in Common Lisp?
> Style-wise (which I know is mostly subjective) is there a cleaner
> way to go about this?
For completeness, here's a LOOP version:
(defun pairify (list)
(loop for (a b) on list by #'cddr
collecting (cons a b)))
Jeremy.
Jeremy Yallop <······@jdyallop.freeserve.co.uk> writes:
> B.B. wrote:
>> [68]> (pairify '(a b c d))
>> ((C . D) (A . B))
>> [69]> (pairify '(a b c d e))
>> ((E) (C . D) (A . B))
>>
>> Questions:
>> Is there a standard equivalent in Common Lisp?
>> Style-wise (which I know is mostly subjective) is there a cleaner
>> way to go about this?
>
> For completeness, here's a LOOP version:
>
> (defun pairify (list)
> (loop for (a b) on list by #'cddr
> collecting (cons a b)))
BTW, is there any way of dealing with multiple values in a LOOP form?
Regards,
--
Julian Stecklina
Signed and encrypted mail welcome.
Key-Server: pgp.mit.edu Key-ID: 0xD65B2AB5
FA38 DCD3 00EC 97B8 6DD8 D7CC 35D8 8D0E D65B 2AB5
Any sufficiently complicated C or Fortran program
contains an ad hoc informally-specified bug-ridden
slow implementation of half of Common Lisp.
- Greenspun's Tenth Rule of Programming
Julian Stecklina wrote:
> BTW, is there any way of dealing with multiple values in a LOOP form?
(loop ... for (a b c) = (multiple-value-list (foo)) ...)
Paul
"Paul F. Dietz" <·····@dls.net> writes:
> Julian Stecklina wrote:
>
>> BTW, is there any way of dealing with multiple values in a LOOP form?
>
> (loop ... for (a b c) = (multiple-value-list (foo)) ...)
Ok, this is an alternative, but it seems as if this involves consing,
if the compiler does not recognises that the list is not neccessary.
Regards,
--
Julian Stecklina
Signed and encrypted mail welcome.
Key-Server: pgp.mit.edu Key-ID: 0xD65B2AB5
FA38 DCD3 00EC 97B8 6DD8 D7CC 35D8 8D0E D65B 2AB5
Any sufficiently complicated C or Fortran program
contains an ad hoc informally-specified bug-ridden
slow implementation of half of Common Lisp.
- Greenspun's Tenth Rule of Programming
Julian Stecklina wrote:
>>(loop ... for (a b c) = (multiple-value-list (foo)) ...)
>
>
> Ok, this is an alternative, but it seems as if this involves consing,
> if the compiler does not recognises that the list is not neccessary.
The compiler doesn't have to recognize it, but the LOOP macro should.
Paul
"Paul F. Dietz" <·····@dls.net> writes:
> Julian Stecklina wrote:
>
>>>(loop ... for (a b c) = (multiple-value-list (foo)) ...)
>> Ok, this is an alternative, but it seems as if this involves consing,
>> if the compiler does not recognises that the list is not neccessary.
>
> The compiler doesn't have to recognize it, but the LOOP macro should.
Ok, I'll try that. Thanks!
Regards,
--
Julian Stecklina
Signed and encrypted mail welcome.
Key-Server: pgp.mit.edu Key-ID: 0xD65B2AB5
FA38 DCD3 00EC 97B8 6DD8 D7CC 35D8 8D0E D65B 2AB5
Any sufficiently complicated C or Fortran program
contains an ad hoc informally-specified bug-ridden
slow implementation of half of Common Lisp.
- Greenspun's Tenth Rule of Programming
Julian Stecklina wrote:
>>The compiler doesn't have to recognize it, but the LOOP macro should.
>
> Ok, I'll try that. Thanks!
By 'should' I mean 'it would be nice if it did', not 'you can expect
that it will'.
Paul
Julian Stecklina <··········@web.de> writes:
> "Paul F. Dietz" <·····@dls.net> writes:
>
> > Julian Stecklina wrote:
> >
> >> BTW, is there any way of dealing with multiple values in a LOOP form?
> >
> > (loop ... for (a b c) = (multiple-value-list (foo)) ...)
>
> Ok, this is an alternative, but it seems as if this involves consing,
> if the compiler does not recognises that the list is not neccessary.
Consider using MULTIPLE-VALUE-SETQ if excessive storage allocation is
of concern to you.
(loop with v1 and v2 and v3
...
for nil = (multiple-value-setq (v1 v2 v3) form)
...
* Paul F Dietz wrote:
> Julian Stecklina wrote:
>> BTW, is there any way of dealing with multiple values in a LOOP form?
> (loop ... for (a b c) = (multiple-value-list (foo)) ...)
I do this as
(loop with a and b and c
do (setf (values a b c) ...)
Which is bad in all sorts of ways, but arguably might cons less.
--tim
B.B. wrote:
> I actually dabbled in it a few years ago, but got sidetracked and
> quit programming all together. But now I'm back for whatever
> reason--curiosity, I guess.
> Anyway, I hail mainly from the C/Fortran world, so I'm having a time
> wrapping my brain around Lisp. But I wanted to start off kind of
> simple, so:
>
> (defun pairify (l)
> (let ((r nil))
> (do ()
> ((null l))
> (push (cons (car l) (cadr l)) r)
> (setq l (cddr l)))
> r))
>
> [68]> (pairify '(a b c d))
> ((C . D) (A . B))
> [69]> (pairify '(a b c d e))
> ((E) (C . D) (A . B))
>
> Questions:
> Is there a standard equivalent in Common Lisp?
> Style-wise (which I know is mostly subjective) is there a cleaner
> way to go about this?
(loop for (a b) on '(a b c d e) by 'cddr
collecting (if b
(list a b)
(list a)))
...or if you don't mind padding the last pair:
(loop for (a b) on '(a b c d e) by 'cddr
collecting (list a b))
kt
--
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
In article <·······················@twister.nyc.rr.com>,
Kenny Tilton <·······@nyc.rr.com> wrote:
[...]
>(loop for (a b) on '(a b c d e) by 'cddr
> collecting (if b
> (list a b)
> (list a)))
>
>...or if you don't mind padding the last pair:
>
>(loop for (a b) on '(a b c d e) by 'cddr
> collecting (list a b))
So loop will set (a b) to corresponding elements in '(a b c d e)? Is
it possible to use more complex lists? <fires up clisp> Nope, guess
not.
While I'm thinking about it, anyone here familiar with the debugging
commands in clisp? I poked around on the internet myself, but with my
old modem it gets a little tedious and I haven't found much yet.
Mainly, I want to figure out how to use step. I tried
(step '(loop for (a (b c) d) on '(a b c d e f g h i j k) by 'cdddr
collecting (list a b c d)))
but I can't get it to actually step through. If I use the :s command it
seems to go ahead and run to completion.
Others who replied: thanks. Your explanations were very helpful.
--
B.B. --I am not a goat! thegoat4 at airmail.net
Fire the stupid--Vote.
B.B. wrote:
> In article <·······················@twister.nyc.rr.com>,
> Kenny Tilton <·······@nyc.rr.com> wrote:
>
> [...]
>
>
>>(loop for (a b) on '(a b c d e) by 'cddr
>> collecting (if b
>> (list a b)
>> (list a)))
>>
>>...or if you don't mind padding the last pair:
>>
>>(loop for (a b) on '(a b c d e) by 'cddr
>> collecting (list a b))
>
>
> So loop will set (a b) to corresponding elements in '(a b c d e)? Is
> it possible to use more complex lists? <fires up clisp> Nope, guess
> not.
Anyway, it took me almost a decade to get into loop, now it's the only
iterator I use.
> While I'm thinking about it, anyone here familiar with the debugging
> commands in clisp? I poked around on the internet myself, but with my
> old modem it gets a little tedious and I haven't found much yet.
> Mainly, I want to figure out how to use step.
No you don't, learn how to use format and debug the log of a run. In
Lisp one creates smart engines. When they get stupid, you'll be stepping
for days before you get to the bug, and then you will accidentally step
over it and have to start over.
Besides, Lisps have lousy source-level debugging. :)
kt
--
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
In article <·······················@twister.nyc.rr.com>,
Kenny Tilton <·······@nyc.rr.com> wrote:
[...]
>> While I'm thinking about it, anyone here familiar with the debugging
>> commands in clisp? I poked around on the internet myself, but with my
>> old modem it gets a little tedious and I haven't found much yet.
>> Mainly, I want to figure out how to use step.
>
>No you don't, learn how to use format and debug the log of a run. In
>Lisp one creates smart engines. When they get stupid, you'll be stepping
>for days before you get to the bug, and then you will accidentally step
>over it and have to start over.
I want to use it mainly to see how the expressions expand, not so
much to debug. I worked on c and other languages long enough without
debuggers that I became pretty proficient with strategic placement of
print statements and proving out an algorithm on paper before writing it.
I've never been too big a fan of real-time debuggers due to what you
mention, plus usually having data structures the debuggers can't display
worth a crap. But I suppose that wouldn't be too much of a problem in
LISP.
>Besides, Lisps have lousy source-level debugging. :)
Agreed. I dumped the stack and wound up with reams of expressions
that took a long while to sort through.
>kt
--
B.B. --I am not a goat! thegoat4 at airmail.net
Fire the stupid--Vote.
B.B. wrote:
> In article <·······················@twister.nyc.rr.com>,
> Kenny Tilton <·······@nyc.rr.com> wrote:
>
> [...]
>
>
>>> While I'm thinking about it, anyone here familiar with the debugging
>>>commands in clisp? I poked around on the internet myself, but with my
>>>old modem it gets a little tedious and I haven't found much yet.
>>> Mainly, I want to figure out how to use step.
>>
>>No you don't, learn how to use format and debug the log of a run. In
>>Lisp one creates smart engines. When they get stupid, you'll be stepping
>>for days before you get to the bug, and then you will accidentally step
>>over it and have to start over.
>
>
> I want to use it mainly to see how the expressions expand,
Expand? Not sure what you mean, but DISASSEMBLE and MACROEXPAND are
standard functions.
kt
--
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
In article <·······················@twister.nyc.rr.com>,
Kenny Tilton <·······@nyc.rr.com> wrote:
[...]
>> I want to use it mainly to see how the expressions expand,
>
>
>Expand? Not sure what you mean, but DISASSEMBLE and MACROEXPAND are
>standard functions.
>
>kt
Hmm. I think I can explain this, but I may not yet have the right
words. I'd like to see what gets bound to what when and how they change
throughout an expression. I think stepping through would be a little
more beginner-friendly than the big blocks of code sometimes pumped out
by macroexpand and disassemble. Granted, I'd have to step through those
big blocks (I think) but they'd be separated into locical units for me
without the risk of me mixing something up and confusing the hell out of
myself.
Did that make sense?
--
B.B. --I am not a goat! thegoat4 at airmail.net
Fire the stupid--Vote.
newsreader barfed--this might be posted twice. sorry.
In article <·······················@twister.nyc.rr.com>,
Kenny Tilton <·······@nyc.rr.com> wrote:
[...]
>> While I'm thinking about it, anyone here familiar with the debugging
>> commands in clisp? I poked around on the internet myself, but with my
>> old modem it gets a little tedious and I haven't found much yet.
>> Mainly, I want to figure out how to use step.
>
>No you don't, learn how to use format and debug the log of a run. In
>Lisp one creates smart engines. When they get stupid, you'll be stepping
>for days before you get to the bug, and then you will accidentally step
>over it and have to start over.
I want to use it mainly to see how the expressions expand, not so
much to debug. I worked on c and other languages long enough without
debuggers that I became pretty proficient with strategic placement of
print statements and proving out an algorithm on paper before writing it.
I've never been too big a fan of real-time debuggers due to what you
mention, plus usually having data structures the debuggers can't display
worth a crap. But I suppose that wouldn't be too much of a problem in
LISP.
>Besides, Lisps have lousy source-level debugging. :)
Agreed. I dumped the stack and wound up with reams of expressions
that took a long while to sort through.
>kt
--
B.B. --I am not a goat! thegoat4 at airmail.net
Fire the stupid--Vote.
B.B. <·················@airmail.net.com.org.gov.tw.ch.ru> wrote:
+---------------
| >(loop for (a b) on '(a b c d e) by 'cddr
| > collecting (list a b))
|
| So loop will set (a b) to corresponding elements in '(a b c d e)?
| Is it possible to use more complex lists?
+---------------
Of course it is:
> (loop for (a b . rest) in '((a b c d e) (f g h) (i j k l) (m n))
collect (list* a b :n-rest (length rest) :rest rest))
((A B :N-REST 3 :REST C D E)
(F G :N-REST 1 :REST H)
(I J :N-REST 2 :REST K L)
(M N :N-REST 0 :REST))
> (loop for ((a . b) (c . d)) on '((1 . 2) (3 . 4) (5 . 6) (7 . 8))
by #'cddr
collect (list d c b a))
((4 3 2 1) (8 7 6 5))
>
+---------------
| <fires up clisp> Nope, guess not.
+---------------
Show us what you tried. It may have been bad syntax, or a CLISP bug.
But without seeing it, we'll never know.
-Rob
-----
Rob Warnock <····@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607
In article <······················@speakeasy.net>,
····@rpw3.org (Rob Warnock) wrote:
>B.B. <·················@airmail.net.com.org.gov.tw.ch.ru> wrote:
>+---------------
>| >(loop for (a b) on '(a b c d e) by 'cddr
>| > collecting (list a b))
>|
>| So loop will set (a b) to corresponding elements in '(a b c d e)?
>| Is it possible to use more complex lists?
>+---------------
>
>Of course it is:
>
> > (loop for (a b . rest) in '((a b c d e) (f g h) (i j k l) (m n))
> collect (list* a b :n-rest (length rest) :rest rest))
Could you explain to me the difference between list and list*?
> ((A B :N-REST 3 :REST C D E)
> (F G :N-REST 1 :REST H)
> (I J :N-REST 2 :REST K L)
> (M N :N-REST 0 :REST))
> > (loop for ((a . b) (c . d)) on '((1 . 2) (3 . 4) (5 . 6) (7 . 8))
> by #'cddr
> collect (list d c b a))
>
> ((4 3 2 1) (8 7 6 5))
> >
>
>+---------------
>| <fires up clisp> Nope, guess not.
>+---------------
>
>Show us what you tried. It may have been bad syntax, or a CLISP bug.
>But without seeing it, we'll never know.
I no longer have exactly what I typed in, but I think I must have
screwed up the syntax because experimenting now it seems to work like
I'd expect. I think what was confusing me was that I was using the same
tokens in the data list and the list I was mapping onto it, so when it
said something to the effect of "b is not a list" I didn't fully
understand which was which.
In the future I'll make it a point to use different tokens in each to
avoid confusion.
--
B.B. --I am not a goat! thegoat4 at airmail.net
Fire the stupid--Vote.
B.B. wrote:
>
> Could you explain to me the difference between list and list*?
>
Here's a simple analogy:
(list 'a 'b 'c) <=> (cons 'a (cons 'b (cons 'c '())))
(list* 'a 'b 'c) <=> (cons 'a (cons 'b 'c))
Or:
(list 'a 'b 'c) <=> (list* 'a 'b 'c '())
http://www.lispworks.com/reference/HyperSpec/Body/f_list_.htm
B.B. wrote:
>> > (loop for (a b . rest) in '((a b c d e) (f g h) (i j k l) (m n))
>> collect (list* a b :n-rest (length rest) :rest rest))
>
> Could you explain to me the difference between list and list*?
You can get answers faster for this kind of question by looking into the
CL Hyperspec, which can be found here:
http://www.lispworks.com/reference/HyperSpec/Front/index.htm
Your question is answered here:
http://www.lispworks.com/reference/HyperSpec/Body/f_list_.htm#listST
Sometimes you can also simply try it out:
CL-USER 1 > (list 1 2 3 4 5)
(1 2 3 4 5)
CL-USER 2 > (list* 1 2 3 4 5)
(1 2 3 4 . 5)
Andr�
--
On Fri, 09 Apr 2004 21:21:36 -0500, "B.B." <·················@airmail.net.com.org.gov.tw.ch.ru> wrote:
> In article <·······················@twister.nyc.rr.com>,
> Kenny Tilton <·······@nyc.rr.com> wrote:
>
> [...]
>
>>(loop for (a b) on '(a b c d e) by 'cddr
>> collecting (if b
>> (list a b)
>> (list a)))
>>
>>...or if you don't mind padding the last pair:
>>
>>(loop for (a b) on '(a b c d e) by 'cddr
>> collecting (list a b))
>
> So loop will set (a b) to corresponding elements in '(a b c d e)?
> Is it possible to use more complex lists? <fires up clisp> Nope,
> guess not.
Sure you can. Don't "fire up" a Lisp and try something but read the
spec instead. In 6.1.2.1:
"The variable argument in iteration control clauses can be a
destructuring list. A destructuring list is a tree whose non-nil
atoms are variable names. See Section 6.1.1.7 (Destructuring)."
* (loop for (a b . c) in '((1 2 3) (4 5) (6 7 8 9))
do (print (list a b c)))
(1 2 (3))
(4 5 NIL)
(6 7 (8 9))
NIL
* (loop for (a . b) on '(1 2 3 4 5)
do (print (list a b)))
(1 (2 3 4 5))
(2 (3 4 5))
(3 (4 5))
(4 (5))
(5 NIL)
NIL
* (loop for (a . b) on '(1 2 3 4 5) by #'cddr
do (print (list a b)))
(1 (2 3 4 5))
(3 (4 5))
(5 NIL)
NIL
* (loop for (a . (b . c)) on '(1 2 3 4 5)
do (print (list a b c)))
(1 2 (3 4 5))
(2 3 (4 5))
(3 4 (5))
(4 5 NIL)
(5 NIL NIL)
NIL
Edi.
Kenny Tilton wrote:
>
>
> B.B. wrote:
>
>> I actually dabbled in it a few years ago, but got sidetracked and
>> quit programming all together. But now I'm back for whatever
>> reason--curiosity, I guess.
>> Anyway, I hail mainly from the C/Fortran world, so I'm having a
>> time wrapping my brain around Lisp. But I wanted to start off kind of
>> simple, so:
>>
>> (defun pairify (l)
>> (let ((r nil))
>> (do ()
>> ((null l))
>> (push (cons (car l) (cadr l)) r)
>> (setq l (cddr l)))
>> r))
>>
>> [68]> (pairify '(a b c d))
>> ((C . D) (A . B))
>> [69]> (pairify '(a b c d e))
>> ((E) (C . D) (A . B))
>>
>> Questions:
>> Is there a standard equivalent in Common Lisp?
>> Style-wise (which I know is mostly subjective) is there a
>> cleaner way to go about this?
>
>
> (loop for (a b) on '(a b c d e) by 'cddr
> collecting (if b
> (list a b)
> (list a)))
>
> ...or if you don't mind padding the last pair:
>
> (loop for (a b) on '(a b c d e) by 'cddr
> collecting (list a b))
Ooops, forgot you were consing each pair. The last one should do then if
you change that to cons.
kt
--
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
Kenny Tilton wrote:
> (loop for (a b) on '(a b c d e) by 'cddr
> collecting (if b
> (list a b)
> (list a)))
This indentation style looks like the one of LispWorks.
I don't see the benefit (in readability) of making it
(if (condition)
(then)
(else))
and switched to
(if (condition)
(then)
(else))
I have not seen enough Lisp code yet to know if there is a convention on
how to indent IF.
Andr�
--
Andr� Thieme wrote:
> Kenny Tilton wrote:
>
>> (loop for (a b) on '(a b c d e) by 'cddr
>> collecting (if b
>> (list a b)
>> (list a)))
>
>
> This indentation style looks like the one of LispWorks.
AllegroCL, in this case.
> I don't see the benefit (in readability) of making it
> (if (condition)
> (then)
> (else))
>
> and switched to
>
> (if (condition)
> (then)
> (else))
That would be my preference as well, since they are at the same level of
logical nesting (both branches under if), but I can imagine where the
convention came from (it looks like control would flow from the first to
the second. otoh, the if is right there... hey, maybe this is because
some people use if when there is no else. Maybe that is the second
difference KennyCL will have: no "else"? no "if". gotta use when.
kt
--
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
On Sat, 10 Apr 2004 01:53:23 GMT, Kenny Tilton <·······@nyc.rr.com> wrote:
> Andr� Thieme wrote:
>
>> Kenny Tilton wrote:
>>
>>> (loop for (a b) on '(a b c d e) by 'cddr
>>> collecting (if b
>>> (list a b)
>>> (list a)))
>> This indentation style looks like the one of LispWorks.
>
> AllegroCL, in this case.
>
>> I don't see the benefit (in readability) of making it
>> (if (condition)
>> (then)
>> (else))
>> and switched to
>> (if (condition)
>> (then)
>> (else))
>
> That would be my preference as well, since they are at the same
> level of logical nesting (both branches under if), but I can imagine
> where the convention came from (it looks like control would flow
> from the first to the second. otoh, the if is right there... hey,
> maybe this is because some people use if when there is no
> else. Maybe that is the second difference KennyCL will have: no
> "else"? no "if". gotta use when.
I think this comes from Emacs Lisp or other Lisp dialects where an IF
can have more than one 'else' form so
(if condition
then
else1
else2
else3)
is equivalent to
(cond (condition
then)
(t
else1
else2
else3))
Edi.
Kenny Tilton wrote:
> (loop for (a b) on '(a b c d e) by 'cddr
> collecting (if b
> (list a b)
> (list a)))
>
> ...or if you don't mind padding the last pair:
>
> (loop for (a b) on '(a b c d e) by 'cddr
> collecting (list a b))
Hmm, this looks like a good way to iterate over property lists. I have
implemented a relatively complex doplist some time ago, and I was
surprised that CL doesn't offer anything predefined for that purpose.
Now this is already considerably simpler.
However, you probably want to make sure that the length of a property
list is even, so that all properties get one value, and that the last
property doesn't accidentally get a nil value. So I came up with this:
(loop for (a b) on '(:a b :c d :e nil) by (lambda (list)
(assert (cdr list))
(cddr list))
collect (list a b))
Is there a simpler way to do this?
Pascal
--
1st European Lisp and Scheme Workshop
June 13 - Oslo, Norway - co-located with ECOOP 2004
http://www.cs.uni-bonn.de/~costanza/lisp-ecoop/
On Sat, 10 Apr 2004 23:18:32 +0200, Pascal Costanza <········@web.de>
wrote:
>(loop for (a b) on '(:a b :c d :e nil) by (lambda (list)
> (assert (cdr list))
> (cddr list))
> collect (list a b))
>
>Is there a simpler way to do this?
(loop for (a b) on '(:a b :c d :e nil) by 'cddr
do (assert b)
collect (list a b))
--
My email address is ··········@ISP.net where Name is
eric, Number is 9000, and ISP is earthlink.
On Sat, 10 Apr 2004 23:22:41 GMT, Eric Smith <·········@sig.txt>
wrote:
>(loop for (a b) on '(:a b :c d :e nil) by 'cddr
> do (assert b)
> collect (list a b))
Corrected version, because the above tests the last item instead of
the tail:
(loop for (a . b) on '(:a b :c d :e) by 'cddr
do (assert b)
collect (list a (car b)))
--
My email address is ··········@ISP.net where Name is
eric, Number is 9000, and ISP is earthlink.
Eric Smith wrote:
> On Sat, 10 Apr 2004 23:22:41 GMT, Eric Smith <·········@sig.txt>
> wrote:
>
>
>
>>(loop for (a b) on '(:a b :c d :e nil) by 'cddr
>> do (assert b)
>> collect (list a b))
>
>
> Corrected version, because the above tests the last item instead of
> the tail:
>
> (loop for (a . b) on '(:a b :c d :e) by 'cddr
> do (assert b)
> collect (list a (car b)))
Thanks a lot!
Pascal
--
1st European Lisp and Scheme Workshop
June 13 - Oslo, Norway - co-located with ECOOP 2004
http://www.cs.uni-bonn.de/~costanza/lisp-ecoop/
(message (Hello 'B.B.)
(you :wrote :on '(Fri, 09 Apr 2004 13:57:11 -0500))
(
B> Style-wise (which I know is mostly subjective) is there a
B> cleaner way to go about this?
i'd do it with LOOP:
(defun pairify (head)
(loop for list = head then (cddr list)
while list
collect (cons (car list) (cadr list))))
by the way, reverse function looks like:
(defun flatten (pairs)
(loop for (a . b) in pairs
collect a
collect b))
in kmrcl package you can find such implementations:
(defun alist-plist (alist)
(apply #'append (mapcar #'(lambda (x) (list (car x) (cdr x))) alist)))
(defun plist-alist (plist)
(do ((alist '())
(pl plist (cddr pl)))
((null pl) alist)
(setq alist (acons (car pl) (cadr pl) alist))))
note that alist-plist is limited (apply can handle not more than 256 items
in list in lispworks, for example)
and in cl-odcl:
(defun alist->plist (alist &aux plist)
(dolist (pair alist)
(destructuring-bind (key . val)
pair
(push key plist)
(push val plist)))
(nreverse plist))
(defun plist->alist (plist)
(and plist (cons (cons (car plist) (cadr plist)) (plist->alist (cddr
plist)))))
)
(With-best-regards '(Alex Mizrahi) :aka 'killer_storm)
(prin1 "Jane dates only Lisp programmers"))