Is there a way to extract all elements of a list in place
Asked Answered
H

4

7

Im looking for a way to extract all the elements of a list in common lisp. Like this

[194]> (break-out-of-list '(a b c d))
A
B
C
D

Edit: The usage example I gave was not thought out very well, however I'm still curious if it is possible to break out of a list like in the example above.

Haver answered 23/11, 2011 at 14:27 Comment(4)
what does 'extract' or 'break out' mean? what does it do? if you want to print list elements to the terminal, map print over them.Rhombic
With extract I mean the inverse of list. A function where (break-list '((a b c)) ) would return `(a b c)Haver
The 'inverse'? What is that? In your example you just take the first element. Maybe you mean some kind of 'flatten', where all atoms in a list or its sublists are moved into a single flat list?Rhombic
Ok, what I want is some construct such that: (some-macro (break-list '(a b c d))) is equivalent to (some-macro 'a 'b 'c 'd). For functions I could use apply as Chris Jester-Young pointed out below.Haver
J
6

What you demonstrate seems to be the question how to get the elements of a list as multiple values:

CL-USER> (values 1 2 3)
1
2
3
CL-USER> (apply #'values '(1 2 3))
1
2
3

See also multiple-value-bind and nth-value in the hyperspec.

Jdavie answered 23/11, 2011 at 22:38 Comment(0)
D
4

While (apply #'values '(1 2 3)) works there is also a function to this called values-list which is used like this:

(values-list '(1 2 3))

And it has the same result.

Dicast answered 30/9, 2016 at 5:16 Comment(0)
T
2

Sure, just use apply:

(defun wraptest (&rest arguments)
  (apply #'test arguments))

This technically doesn't "break out of list"; it simply uses a list's elements as arguments to a function call.

(Disclaimer: I'm a Schemer, not a Common Lisper, and there may be a more-idiomatic way to achieve the same result in CL.)

Thoracotomy answered 23/11, 2011 at 15:23 Comment(1)
You're right, that works for the example I gave. However the example I gave was a bit flawed so I removed it. I'm mostly curious if a break out of list function or operator existsHaver
A
1

I think you might be looking for this:

http://cl-cookbook.sourceforge.net/macros.html#LtohTOCentry-2

That's mostly all there is to backquote. There are just two extra items to point out. First, if you write ",@e" instead of ",e" then the value of e is spliced into the result. So if v=(oh boy), then `(zap ,@v ,v) evaluates to (zap oh boy (oh boy)). The second occurrence of v is replaced by its value. The first is replaced by the elements of its value. If v had had value (), it would have disappeared entirely: the value of (zap ,@v ,v) would have been (zap ()), which is the same as (zap nil).

Reading your comments:

(some-macro (break-list '(a b c d))) is equivalent to (some-macro 'a 'b 'c 'd)

With this, you could do:

`(some-macro ,@'(a b c d))

and you'd get:

(some-macro a b c d)
Artois answered 23/11, 2011 at 14:39 Comment(3)
But since I have to use backquote in order to use ,@ I'm still left with the outer list. But yes I'm looking for a equivalent of the,@ operator that can be used without backquote.Haver
I think you can use it anyway, example underway ;-)Artois
Wouldn't I have to write a macro that returns `(some-macro ,@'(a b c d)) to use this?Haver

© 2022 - 2024 — McMap. All rights reserved.