Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

how to map a variable to a list?

28 views
Skip to first unread message

Jinsong Zhao

unread,
Apr 10, 2023, 9:05:45 AM4/10/23
to
Hi there,

In the following code example,

(defun a-test (lst)
(let ((a (elt lst 0))
(b (elt lst 1))
(c (elt lst 2)))
(+ a (- c b))))

How to map local variable a, b, and c to the elements of lst? In my
actual code, the lst have 12 elements, and I have 12 named local
variables that appeared in the body with high frequency.

Best,
Jinsong

Spiros Bousbouras

unread,
Apr 10, 2023, 9:49:46 AM4/10/23
to
Why is the above code not satisfactory ?
Message has been deleted

Tom Russ

unread,
Apr 10, 2023, 12:46:23 PM4/10/23
to
It isn't clear to us what behavior you want to have from your mapping.
In the code you show, each of the variables is bound to a particular element
of your input list. So you can use them to reference the values of the list.
But each of the variables is a local variable inside the LET form, so any change
to the variable is just a local effect. It will not change the value in the input
list unless the change you make on the local variable is a mutation of the object
that the variable is bound to.

The code you provided should return the value of (+ A (- C B)). What do you
expect it to do?

Some other comments.
In general ELT is not a great function to use on lists, because it has to walk the
list until it gets to the Nth element. If you want to bind a number of variables to
elements of a list, then DESTRUCTURING-BIND will be more convenient and also
more efficient.

But if you have a fixed size list where the individual elements have some meaningful
names, then perhaps an even better approach would be to use a struct (via DEFSTRUCT)
to provide named accessors to the elements. It would also have the side benefit
of being both more space and time efficient.

Kaz Kylheku

unread,
Apr 10, 2023, 2:38:37 PM4/10/23
to
(destructuring-bind (a b c) lst
...)

--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @Kazi...@mstdn.ca

Kaz Kylheku

unread,
Apr 10, 2023, 2:41:16 PM4/10/23
to
Other than that nobody who knows Common Lisp inside out would
write it that way, rather than doing a destructuring-bind?

This could be an X-Y problem; perhaps the function just wants
to take separate arguments, and the caller should apply the list.

(defun a-test (a b c) ...)

(apply #'a-test '(1 2 3))

Ben Bacarisse

unread,
Apr 10, 2023, 4:16:47 PM4/10/23
to
As others have said, it's not clear what the problem is. It would help
if you posted the actual code, because giving a simplified example may be
hiding what you see as the problem.

In the meantime, since 'lst' suggests a list, have you considered using
destructuring-bind?

(defun a-test (lst)
(destructuring-bind (a b c &rest _) lst
(+ a (- c b))))

(Note: elt works on any sequence so this may not suit your use.)

--
Ben.

Yong

unread,
Apr 11, 2023, 9:13:05 AM4/11/23
to
Emacs macro seq-let can do the similar thing:

(seq-let (v1 v2) '(val1 val2 val3)
(message "%s %s" v1 v2))


I believe that common lisp must have a similar function, currently a
known way to do this is:

;; assign 5, 6 to v1, v2
(let (v1 v2)
(mapcar (lambda (sym val) (set sym val)) '(v1 v2) '(5 6)))

Madhu

unread,
Apr 11, 2023, 12:26:48 PM4/11/23
to
* Yong <u13mcm$2l1uj$1...@dont-email.me> :
Wrote on Tue, 11 Apr 2023 21:12:53 +0800:

> Emacs macro seq-let can do the similar thing:
>
> (seq-let (v1 v2) '(val1 val2 val3)
> (message "%s %s" v1 v2))
>
>
> I believe that common lisp must have a similar function, currently a
> known way to do this is:
>
> ;; assign 5, 6 to v1, v2
> (let (v1 v2)
> (mapcar (lambda (sym val) (set sym val)) '(v1 v2) '(5 6)))

In general this is wrong, unless v1 and v2 are "declared" "special". SET
modifies the global binding of the variable. You should have done a
(defvar v1) (defvar v2) first before using LET.

presumably the op was asking only about lexical bindings.

For dynamic bindings there is progv, which is a strange beast

http://www.lispworks.com/documentation/lw80/CLHS/Body/s_progv.htm
"progv allows binding one or more dynamic variables whose names may be
determined at run time"

assuming v1 and v2 do not have top-level bindings and are not declared
globally special,

```
(let ((v1 1) (v2 2)) (progv '(v1 v2) '(5 6) (list v1 v2))) ;=> (1 2)

(let ((v1 1) (v2 2))
(declare (special v1 v2))
(progv '(v1 v2) '(5 6)
(list v1 v2))) ;=> (5 6)
```

Kaz Kylheku

unread,
Apr 11, 2023, 5:45:56 PM4/11/23
to
On 2023-04-11, Yong <luo.yo...@gmail.com> wrote:
>
> Emacs macro seq-let can do the similar thing:
>
> (seq-let (v1 v2) '(val1 val2 val3)
> (message "%s %s" v1 v2))
>
>
> I believe that common lisp must have a similar function, currently a
> known way to do this is:
>
> ;; assign 5, 6 to v1, v2
> (let (v1 v2)
> (mapcar (lambda (sym val) (set sym val)) '(v1 v2) '(5 6)))

Please refrain from posting "AI"-generated drivel.

Jinsong Zhao

unread,
Apr 12, 2023, 9:02:29 AM4/12/23
to
Thanks a lot for all your replies. DESTRUCTURING-BIND is what I want.

Before asking this question, I actually read its CLHS pages, however, I
did not understand it well.

Best,
Jinsong

Tom Russ

unread,
Apr 12, 2023, 9:06:04 PM4/12/23
to
On Wednesday, April 12, 2023 at 6:02:29 AM UTC-7, Jinsong Zhao wrote:
> Thanks a lot for all your replies. DESTRUCTURING-BIND is what I want.

Out of curiosity, what is an example of the code that you want to write?

I ask because I wonder if a struct would be a better data structure than a list.

jimtaylor

unread,
Apr 12, 2023, 10:42:37 PM4/12/23
to
Jinsong Zhao <jsz...@yeah.net> writes:

> Before asking this question, I actually read its CLHS pages, however,
> I did not understand it well.

It just takes time to familiarize yourself with it.

Be sure to check out the Common Lisp Cookbook as well, it's often a bit
easier to follow at least initially.

Jinsong Zhao

unread,
Apr 13, 2023, 6:15:16 AM4/13/23
to
The list in my sample code is the size of the different sections decoded
from the binary header. Mapping them to locally named variables makes it
easy to check the validity of the file. Because it is only used once,
structure is perhaps too heavy. Also, there are rumors that structure is
obsolete and class should be used, which I am even less familiar with.

Thanks again for the reply and helps.

Best,
Jinsong

Spiros Bousbouras

unread,
Apr 13, 2023, 6:55:11 AM4/13/23
to
On Thu, 13 Apr 2023 18:14:39 +0800
Jinsong Zhao <jsz...@yeah.net> wrote:
> The list in my sample code is the size of the different sections decoded
> from the binary header. Mapping them to locally named variables makes it
> easy to check the validity of the file. Because it is only used once,
> structure is perhaps too heavy.

Perhaps. Without knowing how the list gets created to begin with , it is
impossible to tell.

> Also, there are rumors that structure is
> obsolete and class should be used, which I am even less familiar with.

I don't know where you heard the "rumours" but they are wrong. Main
differences between classes and structures :

Classes Structures

Support multiple
inheritance YES NO


Can be redefined YES NO ; undefined
behaviour if you attempt
to do so.


So classes offer greater flexibility at the cost of execution speed
although I don't think it would cost too much in execution speed
if structures also offered multiple inheritance.

With structures you also get automatically defined accessors , print methods
and copier functions ; you can optionally define the layout to be a vector or
a list but then the structure does not become a new type in the CL type
system but counts as a vector or list respectively.

--
If it was a Bill Clinton day, the dry cleaners could have a special on removing
stains.
Mark O'Brien
http://www.stonekettle.com/2016/02/presidents-daze.html

Spiros Bousbouras

unread,
Apr 13, 2023, 10:34:25 PM4/13/23
to
On Thu, 13 Apr 2023 10:55:06 -0000 (UTC)
Spiros Bousbouras <spi...@gmail.com> wrote:
> On Thu, 13 Apr 2023 18:14:39 +0800
> Jinsong Zhao <jsz...@yeah.net> wrote:
> > Also, there are rumors that structure is
> > obsolete and class should be used, which I am even less familiar with.
>
> I don't know where you heard the "rumours" but they are wrong. Main
> differences between classes and structures :
>
> Classes Structures
>
> Support multiple
> inheritance YES NO
>
>
> Can be redefined YES NO ; undefined
> behaviour if you attempt
> to do so.
>
>
> So classes offer greater flexibility at the cost of execution speed
> although I don't think it would cost too much in execution speed
> if structures also offered multiple inheritance.
>
> With structures you also get automatically defined accessors , print methods
> and copier functions ; you can optionally define the layout to be a vector or
> a list but then the structure does not become a new type in the CL type
> system but counts as a vector or list respectively.

Also the accessors in structures are regular functions whereas in classes they
are generic functions. So again , you get greater flexibility with classes at
the cost of execution speed. So structures and classes offer different
tradeoffs and neither one is going away , even without taking into account
backwards compatibility.
0 new messages