* Setting the nth element of a list @ 2009-06-04 21:08 Nordlöw 2009-06-04 22:06 ` Drew Adams ` (2 more replies) 0 siblings, 3 replies; 12+ messages in thread From: Nordlöw @ 2009-06-04 21:08 UTC (permalink / raw) To: help-gnu-emacs This simple example changes the second element in the list x: (setq x '(a nil c)) (setcar (cdr x 'b) How do I generalize this to a function that sets (changes) the nth element of a list (for side effects only)? Thanks in advance, Nordlöw ^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: Setting the nth element of a list 2009-06-04 21:08 Setting the nth element of a list Nordlöw @ 2009-06-04 22:06 ` Drew Adams 2009-06-04 22:35 ` Lennart Borgman 2009-06-05 2:25 ` Barry Margolin 2 siblings, 0 replies; 12+ messages in thread From: Drew Adams @ 2009-06-04 22:06 UTC (permalink / raw) To: 'Nordlöw', help-gnu-emacs > (setcar (cdr x 'b) > > How do I generalize this to a function that sets (changes) the nth > element of a list (for side effects only)? Use setcar with nthcdr. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Setting the nth element of a list 2009-06-04 21:08 Setting the nth element of a list Nordlöw 2009-06-04 22:06 ` Drew Adams @ 2009-06-04 22:35 ` Lennart Borgman 2009-06-05 2:25 ` Barry Margolin 2 siblings, 0 replies; 12+ messages in thread From: Lennart Borgman @ 2009-06-04 22:35 UTC (permalink / raw) To: Nordlöw; +Cc: help-gnu-emacs Use nthcdr On Thu, Jun 4, 2009 at 11:08 PM, Nordlöw <per.nordlow@gmail.com> wrote: > This simple example changes the second element in the list x: > > (setq x '(a nil c)) > (setcar (cdr x 'b) > > How do I generalize this to a function that sets (changes) the nth > element of a list (for side effects only)? > > Thanks in advance, > Nordlöw > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Setting the nth element of a list 2009-06-04 21:08 Setting the nth element of a list Nordlöw 2009-06-04 22:06 ` Drew Adams 2009-06-04 22:35 ` Lennart Borgman @ 2009-06-05 2:25 ` Barry Margolin 2009-06-05 13:06 ` Nordlöw 2 siblings, 1 reply; 12+ messages in thread From: Barry Margolin @ 2009-06-05 2:25 UTC (permalink / raw) To: help-gnu-emacs [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 612 bytes --] In article <8a7c4d36-195d-4517-827e-7fbeca7ae03f@r34g2000vba.googlegroups.com>, Nordlöw <per.nordlow@gmail.com> wrote: > This simple example changes the second element in the list x: > > (setq x '(a nil c)) > (setcar (cdr x 'b) > > How do I generalize this to a function that sets (changes) the nth > element of a list (for side effects only)? > > Thanks in advance, > Nordlöw (require 'cl-macs) (setf (nth n x) 'b) -- Barry Margolin, barmar@alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** *** PLEASE don't copy me on replies, I'll read them in the group *** ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Setting the nth element of a list 2009-06-05 2:25 ` Barry Margolin @ 2009-06-05 13:06 ` Nordlöw 2009-06-05 13:10 ` Nordlöw 2009-06-05 20:51 ` Barry Margolin 0 siblings, 2 replies; 12+ messages in thread From: Nordlöw @ 2009-06-05 13:06 UTC (permalink / raw) To: help-gnu-emacs On Jun 5, 4:25 am, Barry Margolin <bar...@alum.mit.edu> wrote: > In article > <8a7c4d36-195d-4517-827e-7fbeca7ae...@r34g2000vba.googlegroups.com>, > > Nordlöw <per.nord...@gmail.com> wrote: > > This simple example changes the second element in the list x: > > > (setq x '(a nil c)) > > (setcar (cdr x 'b) > > > How do I generalize this to a function that sets (changes) the nth > > element of a list (for side effects only)? > > > Thanks in advance, > > Nordlöw > > (require 'cl-macs) > (setf (nth n x) 'b) > > -- > Barry Margolin, bar...@alum.mit.edu > Arlington, MA > *** PLEASE post questions in newsgroups, not directly to me *** > *** PLEASE don't copy me on replies, I'll read them in the group *** Okey, here is my solution: (defun setnthcar (n list x) "Set N:th element of LIST to X for side effects only." (setcar (nthcdr n list) x)) Comments on that? How do I accomplish the same with arrays? Using aref I guess. Here is my mockup that doesn't yet do what I want: (defun setnthref (n array x) "Set N:th element of ARRAY to X for side effects only." (set (aref array n) x)) Thanks in advance, Nordlöw ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Setting the nth element of a list 2009-06-05 13:06 ` Nordlöw @ 2009-06-05 13:10 ` Nordlöw 2009-06-05 13:25 ` Pascal J. Bourguignon 2009-06-05 20:51 ` Barry Margolin 1 sibling, 1 reply; 12+ messages in thread From: Nordlöw @ 2009-06-05 13:10 UTC (permalink / raw) To: help-gnu-emacs On Jun 5, 3:06 pm, Nordlöw <per.nord...@gmail.com> wrote: > On Jun 5, 4:25 am, Barry Margolin <bar...@alum.mit.edu> wrote: > > > > > In article > > <8a7c4d36-195d-4517-827e-7fbeca7ae...@r34g2000vba.googlegroups.com>, > > > Nordlöw <per.nord...@gmail.com> wrote: > > > This simple example changes the second element in the list x: > > > > (setq x '(a nil c)) > > > (setcar (cdr x 'b) > > > > How do I generalize this to a function that sets (changes) the nth > > > element of a list (for side effects only)? > > > > Thanks in advance, > > > Nordlöw > > > (require 'cl-macs) > > (setf (nth n x) 'b) > > > -- > > Barry Margolin, bar...@alum.mit.edu > > Arlington, MA > > *** PLEASE post questions in newsgroups, not directly to me *** > > *** PLEASE don't copy me on replies, I'll read them in the group *** > > Okey, here is my solution: > > (defun setnthcar (n list x) > "Set N:th element of LIST to X for side effects only." > (setcar (nthcdr n list) x)) > > Comments on that? > > How do I accomplish the same with arrays? Using aref I guess. Here is > my mockup that doesn't yet do what I want: > > (defun setnthref (n array x) > "Set N:th element of ARRAY to X for side effects only." > (set (aref array n) x)) > > Thanks in advance, > Nordlöw Okey I found a solution: (defun setnthref (n array x) "Set N:th element of ARRAY to X for side effects only." (setf (aref array n) x)) ;; (equal (let ((l '[a b c])) (setnthref 1 l 'B) l) '[a B c]) Is this the most efficient way? I see that setf() is quite complicated. /Nordlöw ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Setting the nth element of a list 2009-06-05 13:10 ` Nordlöw @ 2009-06-05 13:25 ` Pascal J. Bourguignon 2009-06-05 13:57 ` Nordlöw 0 siblings, 1 reply; 12+ messages in thread From: Pascal J. Bourguignon @ 2009-06-05 13:25 UTC (permalink / raw) To: help-gnu-emacs Nordlöw <per.nordlow@gmail.com> writes: > On Jun 5, 3:06 pm, Nordlöw <per.nord...@gmail.com> wrote: >> On Jun 5, 4:25 am, Barry Margolin <bar...@alum.mit.edu> wrote: >> >> >> >> > In article >> > <8a7c4d36-195d-4517-827e-7fbeca7ae...@r34g2000vba.googlegroups.com>, >> >> > Nordlöw <per.nord...@gmail.com> wrote: >> > > This simple example changes the second element in the list x: >> >> > > (setq x '(a nil c)) >> > > (setcar (cdr x 'b) >> >> > > How do I generalize this to a function that sets (changes) the nth >> > > element of a list (for side effects only)? >> >> > > Thanks in advance, >> > > Nordlöw >> >> > (require 'cl-macs) >> > (setf (nth n x) 'b) >> >> >> Okey, here is my solution: >> >> (defun setnthcar (n list x) >> "Set N:th element of LIST to X for side effects only." >> (setcar (nthcdr n list) x)) >> >> Comments on that? It's awful, since there's is already a more standard and more general mechanism to do that: (setf (nth n x) 'b) >> How do I accomplish the same with arrays? Using aref I guess. Here is >> my mockup that doesn't yet do what I want: >> >> (defun setnthref (n array x) >> "Set N:th element of ARRAY to X for side effects only." >> (set (aref array n) x)) >> >> Thanks in advance, >> Nordlöw > > Okey I found a solution: > > (defun setnthref (n array x) > "Set N:th element of ARRAY to X for side effects only." > (setf (aref array n) x)) > ;; (equal (let ((l '[a b c])) (setnthref 1 l 'B) l) '[a B c]) > > Is this the most efficient way? I see that setf() is quite > complicated. Setf is a macro that is quite complicated, but it generates the best code to properly update a place. (require 'cl) (macroexpand '(setf (aref (aref (nth (incf a) list-of-arrays) (incf i)) n) 42)) --> (let* ((#1=--cl-var-- (aref (nth (incf a) list-of-arrays) (incf i))) (#2=--cl-var-- n)) (aset #1# #2# 42)) There's nothing more efficient to set an array than aset. Once you've found the array to set... So there's no need to define a setnthref for an array, since (setf (aref a n) v) does the job better. There's also no need to define a setnthcar for a list, since (setf (nth l n) v) does the job better. And if you don't know whether you have a list or a vector, there's no need to define anything, since (setf (elt sequence n) v) works better. (let (x) (setf (elt (setf x (funcall (if (oddp (random 2)) (function list) (function vector)) 1 2 3)) 1) 0) x) --> [1 0 3] or (1 0 3) -- __Pascal Bourguignon__ ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Setting the nth element of a list 2009-06-05 13:25 ` Pascal J. Bourguignon @ 2009-06-05 13:57 ` Nordlöw 2009-06-05 15:08 ` Pascal J. Bourguignon 2009-06-05 16:56 ` bigfaceworm 0 siblings, 2 replies; 12+ messages in thread From: Nordlöw @ 2009-06-05 13:57 UTC (permalink / raw) To: help-gnu-emacs On Jun 5, 3:25 pm, p...@informatimago.com (Pascal J. Bourguignon) wrote: > Nordlöw <per.nord...@gmail.com> writes: > > On Jun 5, 3:06 pm, Nordlöw <per.nord...@gmail.com> wrote: > >> On Jun 5, 4:25 am, Barry Margolin <bar...@alum.mit.edu> wrote: > > >> > In article > >> > <8a7c4d36-195d-4517-827e-7fbeca7ae...@r34g2000vba.googlegroups.com>, > > >> > Nordlöw <per.nord...@gmail.com> wrote: > >> > > This simple example changes the second element in the list x: > > >> > > (setq x '(a nil c)) > >> > > (setcar (cdr x 'b) > > >> > > How do I generalize this to a function that sets (changes) the nth > >> > > element of a list (for side effects only)? > > >> > > Thanks in advance, > >> > > Nordlöw > > >> > (require 'cl-macs) > >> > (setf (nth n x) 'b) > > >> Okey, here is my solution: > > >> (defun setnthcar (n list x) > >> "Set N:th element of LIST to X for side effects only." > >> (setcar (nthcdr n list) x)) > > >> Comments on that? > > It's awful, since there's is already a more standard and more general > mechanism to do that: (setf (nth n x) 'b) > > > > >> How do I accomplish the same with arrays? Using aref I guess. Here is > >> my mockup that doesn't yet do what I want: > > >> (defun setnthref (n array x) > >> "Set N:th element of ARRAY to X for side effects only." > >> (set (aref array n) x)) > > >> Thanks in advance, > >> Nordlöw > > > Okey I found a solution: > > > (defun setnthref (n array x) > > "Set N:th element of ARRAY to X for side effects only." > > (setf (aref array n) x)) > > ;; (equal (let ((l '[a b c])) (setnthref 1 l 'B) l) '[a B c]) > > > Is this the most efficient way? I see that setf() is quite > > complicated. > > Setf is a macro that is quite complicated, but it generates the best > code to properly update a place. > > (require 'cl) > (macroexpand '(setf (aref (aref (nth (incf a) list-of-arrays) (incf i)) n) 42)) > --> > (let* ((#1=--cl-var-- (aref (nth (incf a) list-of-arrays) (incf i))) > (#2=--cl-var-- n)) > (aset #1# #2# 42)) > > There's nothing more efficient to set an array than aset. > Once you've found the array to set... > > So there's no need to define a setnthref for an array, since (setf > (aref a n) v) does the job better. > > There's also no need to define a setnthcar for a list, since (setf > (nth l n) v) does the job better. > > And if you don't know whether you have a list or a vector, there's no > need to define anything, since (setf (elt sequence n) v) works better. > > (let (x) > (setf (elt (setf x (funcall (if (oddp (random 2)) > (function list) > (function vector)) > 1 2 3)) > 1) > 0) > x) > --> [1 0 3] or (1 0 3) > > -- > __Pascal Bourguignon__ I really believe such a function increases the readability of the code that uses it, don't you? What if I define it as a macro (defmacro) or inline (defsubst)? Doesn't that give the best of both worlds+ /Nordlöw ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Setting the nth element of a list 2009-06-05 13:57 ` Nordlöw @ 2009-06-05 15:08 ` Pascal J. Bourguignon 2009-06-05 16:56 ` bigfaceworm 1 sibling, 0 replies; 12+ messages in thread From: Pascal J. Bourguignon @ 2009-06-05 15:08 UTC (permalink / raw) To: help-gnu-emacs Nordlöw <per.nordlow@gmail.com> writes: > I really believe such a function increases the readability of the code > that uses it, don't you? > What if I define it as a macro (defmacro) or inline (defsubst)? > Doesn't that give the best of both worlds+ Readability is somewhat in the eyes of the reader. That said, I can just repeat wat I wrote: setf is a standard and well known operator designed to assign a value to any kind of place, so it will be understood readily by any lisp programmer. Defining redundant and specific operators just give you more work -- if you change the type of a sequence between list and vector, you'll have to edit all the place where you used setnthcar or setnthref instead of (setf (elt ...) ...) -- and it will give more work to the reader who will have to refer to your functions definitions to know what they mean. If you were talking about a new kind of data structure, I'd agree that it would be ok to define a setter, but then it would have to be defined with the arguments in the 'correct' order: (defun set-my-own-data-structure (new-value data-structure index1 ...) ...) so you could bind it to setf: (defsetf my-own-data-structure set-my-own-data-structure) and right away forget about set-my-own-data-structure, but write: (setf (my-own-data-structure my-ds i...) new-value) -- __Pascal Bourguignon__ ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Setting the nth element of a list 2009-06-05 13:57 ` Nordlöw 2009-06-05 15:08 ` Pascal J. Bourguignon @ 2009-06-05 16:56 ` bigfaceworm 2009-06-06 6:01 ` Miles Bader 1 sibling, 1 reply; 12+ messages in thread From: bigfaceworm @ 2009-06-05 16:56 UTC (permalink / raw) To: help-gnu-emacs On Jun 5, 6:57 am, Nordlöw <per.nord...@gmail.com> wrote: > I really believe such a function increases the readability of the code > that uses it, don't you? > What if I define it as a macro (defmacro) or inline (defsubst)? > Doesn't that give the best of both worlds+ > > /Nordlöw In general, no. Writing your own functions to increase "readability" decreases the portability of code using those functions, in increases the effort required to read such code (for a new person), and ultimately it leads to bunches of little, disparate, libraries all doing the same thing but with completely different nomenclature. Once you learn and understand 'setf, its meaning is incredibly clear, and adding layers over that just obfuscates the code. Using widely available, standard libraries (such as 'cl) is what leads to more readable code. Such libraries are the result of many years of experience by people who know the language intimately. TJ ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Setting the nth element of a list 2009-06-05 16:56 ` bigfaceworm @ 2009-06-06 6:01 ` Miles Bader 0 siblings, 0 replies; 12+ messages in thread From: Miles Bader @ 2009-06-06 6:01 UTC (permalink / raw) To: help-gnu-emacs bigfaceworm <bigfaceworm@gmail.com> writes: > Using widely available, standard libraries (such as 'cl) is what leads > to more readable code. Such libraries are the result of many years of > experience by people who know the language intimately. You have to be careful with cl.el. In general if there's an "elisp-native" way to do something (like `aset'), it's probably a better idea to use that instead. While I like common-lisp a lot, cl.el's attempt to fit it into elisp doesn't always succeed very well (though the authors went to huge lengths trying). You can't just assume it's all good -- parts of it are very useful, but parts are just horrid (e.g., anything related to multiple-values, or that results in runtime-evaluated keyword arguments). -Miles -- `To alcohol! The cause of, and solution to, all of life's problems' --Homer J. Simpson ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Setting the nth element of a list 2009-06-05 13:06 ` Nordlöw 2009-06-05 13:10 ` Nordlöw @ 2009-06-05 20:51 ` Barry Margolin 1 sibling, 0 replies; 12+ messages in thread From: Barry Margolin @ 2009-06-05 20:51 UTC (permalink / raw) To: help-gnu-emacs [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 705 bytes --] In article <b775c362-a37c-4d38-bce1-8de6922acbd3@b1g2000vbc.googlegroups.com>, Nordlöw <per.nordlow@gmail.com> wrote: > How do I accomplish the same with arrays? Using aref I guess. Here is > my mockup that doesn't yet do what I want: > > (defun setnthref (n array x) > "Set N:th element of ARRAY to X for side effects only." > (set (aref array n) x)) There's already a built-in function aset that does exactly that, except it takes its arguments in a different order. Why do you need your own function? -- Barry Margolin, barmar@alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** *** PLEASE don't copy me on replies, I'll read them in the group *** ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2009-06-06 6:01 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-06-04 21:08 Setting the nth element of a list Nordlöw 2009-06-04 22:06 ` Drew Adams 2009-06-04 22:35 ` Lennart Borgman 2009-06-05 2:25 ` Barry Margolin 2009-06-05 13:06 ` Nordlöw 2009-06-05 13:10 ` Nordlöw 2009-06-05 13:25 ` Pascal J. Bourguignon 2009-06-05 13:57 ` Nordlöw 2009-06-05 15:08 ` Pascal J. Bourguignon 2009-06-05 16:56 ` bigfaceworm 2009-06-06 6:01 ` Miles Bader 2009-06-05 20:51 ` Barry Margolin
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).