Forgive me for jumping in here in all my newbie glory, but if you want to do something for each element in an array, can you not use mapcar? I thought that it worked for sequences in general - not just lists but also vectors and arrays.
GB
"Wade Humeniuk" <humen...@cadvision.com> wrote in message
> > (loop for i from 0 to (- (length array)) > > do > > (let ((x (aref i array))) > > ; For one thing I keep forgetting which goes first > > ; i or array. > > ...
Glenn Burnside <glenn.burns...@ni.com> wrote: >Forgive me for jumping in here in all my newbie glory, but if you want to do >something for each element in an array, can you not use mapcar? I thought >that it worked for sequences in general - not just lists but also vectors >and arrays.
No. The only mapping functions that work on sequences are MAP and MAP-INTO.
Also, since you say "vectors and arrays", I assume you're using "arrays" to refer to multi-dimensional arrays. They aren't sequences, only vectors and lists are.
-- Barry Margolin, bar...@genuity.net Genuity, Woburn, MA *** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups. Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
In article <u8fhtrks7tb...@corp.supernews.com>, Glenn Burnside wrote: > "Wade Humeniuk" <humen...@cadvision.com> wrote in message > news:a68bou$4e2$1@news3.cadvision.com...
>> > (loop for i from 0 to (- (length array)) >> > do >> > (let ((x (aref i array))) >> > ; For one thing I keep forgetting which goes first >> > ; i or array. >> > ...
>> > is there some wqay of doing something like:
>> > (loop for x element-of array >> > do ....
>> (loop for x across array do ......
>> Array is of type vector. > Forgive me for jumping in here in all my newbie glory, but if you want to do > something for each element in an array, can you not use mapcar? I thought > that it worked for sequences in general - not just lists but also vectors > and arrays.
No, mapcar works only for lists. There is map:
(map 'vector #'1+ #(1 2 3))
=> #(2 3 4)
But it might not be what the OP wants (of course, it might as well be).
Regards, -- Nils Goesche "The sooner all the animals are dead, the sooner we'll find their money." -- Ed Bluestone PGP key ID 0x42B32FC9
> Forgive me for jumping in here in all my newbie glory, but if you want to do > something for each element in an array, can you not use mapcar? I thought > that it worked for sequences in general - not just lists but also vectors > and arrays.
This is true. But usually I only use map when I am transforming a sequence into a sequence of equal size. I still use iteration for things like
CL-USER 5 > (loop for c across "Hello World!" when (char= #\l c) count 1) 3
olc...@interaccess.com (Thaddeus L Olczyk) writes:
> I'm getting tierd of doing
> (loop for i from 0 to (- (length array)) > do > (let ((x (aref i array))) > ; For one thing I keep forgetting which goes first > ; i or array. > ...
> is there some wqay of doing something like:
> (loop for x element-of array > do ....
(loop for x across array ....)
Note that you must ensure that `array' is actually a `vector'.
Also note that the LOOP macro allows you to do things in a nicer ways, when it comes to bound checking. Even if you wrote the above using the integer variable, the result could look like
(loop for i from 0 below (length array) do (let ((x (aref array i))) .....))
Cheers
-- Marco Antoniotti ======================================================== NYU Courant Bioinformatics Group tel. +1 - 212 - 998 3488 719 Broadway 12th Floor fax +1 - 212 - 995 4122 New York, NY 10003, USA http://bioinformatics.cat.nyu.edu "Hello New York! We'll do what we can!" Bill Murray in `Ghostbusters'.
for i across array for j from 0 by 1 do (format t "Element ~D is ~A~%" j i)) Element 0 is 1 Element 1 is 4 Element 2 is 9 Element 3 is 16 Element 4 is Foo Element 5 is Bar Element 6 is 'FROBOZZ Element 7 is Bogomatic NIL -- (reverse (concatenate 'string "ac.notelrac.teneerf@" "454aa")) http://www.ntlug.org/~cbbrowne/lisp.html Points are awarded for getting the last word in. Drawing the conversation out so long that the original message disappears due to being indented off the right hand edge of the screen is one way to do this. Another is to imply that anyone replying further is a hopeless cretin and is wasting everyone's valuable time. -- from the Symbolics Guidelines for Sending Mail
Marco Antoniotti <marc...@cs.nyu.edu> writes: > (loop for x across array ....)
> Note that you must ensure that `array' is actually a `vector'.
> Also note that the LOOP macro allows you to do things in a nicer ways, > when it comes to bound checking. Even if you wrote the above using > the integer variable, the result could look like
> (loop for i from 0 below (length array) > do (let ((x (aref array i))) .....))
Actually, it's even easier, you can do
(loop for i below (length array) do ...)
-- /|_ .-----------------------. ,' .\ / | No to Imperialist war | ,--' _,' | Wage class war! | / / `-----------------------' ( -. | | ) | (`-. '--.) `. )----'
In an attempt to throw the authorities off his trail, Marco Antoniotti <marc...@cs.nyu.edu> transmitted:
> Also note that the LOOP macro allows you to do things in a nicer ways, > when it comes to bound checking. Even if you wrote the above using > the integer variable, the result could look like
> (loop for i from 0 below (length array) > do (let ((x (aref array i))) .....))
Wouldn't it be nicer to do:
(loop with len = (length array) ;;; evaluate length just once... for i from 0 below len for x = (aref array i) do ....)
It seems really silly to open up a DO clause just to do an assignment when LOOP is perfectly able to hide that behind: for x = (aref array i) -- (concatenate 'string "cbbrowne" "@ntlug.org") http://www.ntlug.org/~cbbrowne/unix.html "Programming graphics in X is like finding sqrt(pi) using Roman numerals." -- Henry Spencer
Christopher Browne <cbbro...@acm.org> writes: > Wouldn't it be nicer to do:
> (loop with len = (length array) ;;; evaluate length just once... > for i from 0 below len > for x = (aref array i) > do ....)
I don't think anything in the standard requires or disallows evaluating the below argument only once. I'd imagine most LOOPs only evaluate it once, it seems the obvious implementation. I know CMUCL does:
* (defun foo () (print 'foo) 3) FOO * (loop for i below (foo) collecting i) FOO (0 1 2)
-- /|_ .-----------------------. ,' .\ / | No to Imperialist war | ,--' _,' | Wage class war! | / / `-----------------------' ( -. | | ) | (`-. '--.) `. )----'
> > (loop for i from 0 below (length array) > > do (let ((x (aref array i))) .....))
> Wouldn't it be nicer to do:
> (loop with len = (length array) ;;; evaluate length just once... > for i from 0 below len > for x = (aref array i) > do ....)
While I couldn't (quickly) find anything in the HyperSpec to say it must not do so, if I discovered an implementation that re-evaluated (length array) every iteration I would think the developers were being malicious! Not just for efficiency reasons, but also so that other forms in that position with side effects will cause them only once.
In article <_JXh8.95449$kb.5708...@news1.calgary.shaw.ca>, Coby Beck wrote:
> "Christopher Browne" <cbbro...@acm.org> wrote in message > news:m3k7soc5ir.fsf@chvatal.cbbrowne.com... >> In an attempt to throw the authorities off his trail, Marco Antoniotti ><marc...@cs.nyu.edu> transmitted: >> > (loop for i from 0 below (length array) >> > do (let ((x (aref array i))) .....))
>> Wouldn't it be nicer to do:
>> (loop with len = (length array) ;;; evaluate length just once... >> for i from 0 below len >> for x = (aref array i) >> do ....)
> While I couldn't (quickly) find anything in the HyperSpec to say it must not > do so, if I discovered an implementation that re-evaluated (length array) > every iteration I would think the developers were being malicious! Not just > for efficiency reasons, but also so that other forms in that position with > side effects will cause them only once.
It's in 6.1.2.1.1 The for-as-arithmetic subclause:
# In the for-as-arithmetic subclause, the for or as construct iterates # from the value supplied by form1 to the value supplied by form2 # in increments or decrements denoted by form3. Each expression is # evaluated only once and must evaluate to a number.
Regards, -- Nils Goesche "The sooner all the animals are dead, the sooner we'll find their money." -- Ed Bluestone PGP key ID 0x42B32FC9
In article <a68jdg$78...@news3.cadvision.com>, "Wade Humeniuk" <humen...@cadvision.com> wrote:
> "Glenn Burnside" <glenn.burns...@ni.com> wrote in message > news:u8fhtrks7tbd9f@corp.supernews.com... > > Forgive me for jumping in here in all my newbie glory, but if you want to > do > > something for each element in an array, can you not use mapcar? I thought > > that it worked for sequences in general - not just lists but also vectors > > and arrays.
> This is true. But usually I only use map when I am transforming a sequence > into a sequence of equal size. I still use iteration for things like
> CL-USER 5 > (loop for c across "Hello World!" > when (char= #\l c) count 1) > 3
? (loop for c across "Hello World!" count (char= #\l c)) 3
> behaves like DOLIST, but works on lists and vectors. That or you can use > the LOOP macro on the array, treating it like a vector.
I realize this was give more as an approach rather than complete code. As someone not yet comfortable with writing macroes, and working detached from any other lisp programmers, I ask the following, hoping not to seem too nieve.
As Marco Antoniotti pointed out the "loop" code for vectors is quite clean:
(loop for x across array do ...)
The lack of a "doseq" macro in the language seems to indicate that it was felt that it was not needed in the language.
Would a more "sufficiently" written general sequence macro be:(?)
On Mon, 11 Mar 2002 18:18:15 GMT, Barry Fishman <barry_fish...@att.net> wrote: >As Marco Antoniotti pointed out the "loop" code for vectors is quite >clean:
> (loop for x across array do > ...)
>The lack of a "doseq" macro in the language seems to indicate that it >was felt that it was not needed in the language.
>Would a more "sufficiently" written general sequence macro be:(?)
Barry Fishman <barry_fish...@att.net> writes: > The lack of a "doseq" macro in the language seems to indicate that it > was felt that it was not needed in the language.
Maybe. But it's hard to tell. Probably it's more indicative of the fact that what gets standardized is what's "in use". And usage patterns are not always what you'd expect. They can be influenced by a large number of accidental factors.
> Would a more "sufficiently" written general sequence macro be:(?)
(Aside: Boy, I hate that "&optional result" thing. What a terrible place to put it. I'd just leave it out... ;)
> (if (consp proseq)
This would mean that (do-each (foo (gethash 'foo *the-vectors*)) ...) would take this branch.
> `(dolist (,var ,proseq ,result) ,@body)
And would mean that (do-each (foo *the-list*) ...) would take this branch.
That is, you are doing your CONSP test at compile time [on the lisp code, not on the expression that will result from later execution of the lisp code. You're testing whether the _program_ is a cons, not whether the _data_ is a cons.
Yes. You would really want is to expand into a runtime test, which is a lot of code. I don't have time to test it, but the general shape of what you want will look like the following:
> (Of course it still isn't sufficent without a documentation string.)
Last I checked, doc strings aren't required. In delivered applications, doc strings just help an end-user violate his contract promising not to reverse engineer the product. Sometimes doc strings have a purpose, but it's a stretch to call code incomplete without them.
I mentioned before I don't like the RESULT-FORM and this gives me a new reason not to like it. DOTIMES and DOLIST, for better or worse, seem to put the result in the scope of the variable, I'm not sure to what end. Doing this correctly probably requires:
> I mentioned before I don't like the RESULT-FORM and this gives me a new > reason not to like it. DOTIMES and DOLIST, for better or worse, seem to > put the result in the scope of the variable, I'm not sure to what end.
Me neither, especially since the spec also says (for dolist):
At the time result-form is processed, var is bound to nil.
Thanks for all the help analysing the generalized doloop code I presented. I should have realized the problem with my array type check. I hadn't considered using map, which seems much simpler than trying to handle sequences by type, but it was worthwhile hearing the details of the type checking approach discussed.
I get the impression that macroes, by giving such a fine grain control over the code generated, requires a lot of the specifics to always be expressed as part of it. But many macros do simple things and seem to be simple to write.
I feel driven (although reluctant) to rexpress the macro in the way people have shown me.
The simpler map approach, first expressed by Tim Moore and refined by Kent Pitman and Thomas Burdick seems to be:
I was more formal about testing the above code, and it seems to work OK. Last time i just interactively typed in what I thought were the basic cases, but entered sequences directly into the form, so I missed the main problem.
I tried to compare respective performance of the two alternatives along just doing a:
(loop for val across proseq ...)
and found it hard see any consistant performance benefit in any of the approaches, once the code was compiled.
> Barry Fishman <barry_fish...@att.net> writes: >> (Of course it still isn't sufficent without a documentation string.)
> Last I checked, doc strings aren't required. In delivered > applications, doc strings just help an end-user violate his contract > promising not to reverse engineer the product. Sometimes doc strings > have a purpose, but it's a stretch to call code incomplete without > them.
My background is quite different. My end user was usually within my own company or the DOD, and they expected source. Within a company, if the software isn't easy to read and use, people tend to go off and write their own, which is a large waste of resources. While wasting too much of my life slogging through and fixing other peoples fragile code, I noticed that if someone could not describe a function they wrote in a short amount of text, that function would be visited again and again to fix bugs.
> Sorry Ken, but I put back in the '&optional result' to keep > consistancy with the dolist macro. Would you be a bit happyer with > doing something like:
No. My real objection to this has nothing to do with the implementation. I think that syntactically, this is just a bad place for a return value. It is too easy to overlook. The result form is rarely used, and people are used to DOLIST/DOTIMES returning NIL. Making it return T is a major change to its semantics and should not be lost in a binding list. I'd always rather people write
(defun foo () (dotimes (x list) ...) t)
than
(defun foo () (dotimes (x list t) ...))
I feel pretty much the same about this as I do about &aux variables. It may be handy to write
(defun foo (&aux (x 3)) ...)
but I'd rather people write
(defun foo () (let ((x 3)) ...))
And again, this has nothing to do with implementation (though the implementation of &aux is really gross).
> > Barry Fishman <barry_fish...@att.net> writes: > >> (Of course it still isn't sufficent without a documentation string.)
> > Last I checked, doc strings aren't required. In delivered > > applications, doc strings just help an end-user violate his contract > > promising not to reverse engineer the product. Sometimes doc strings > > have a purpose, but it's a stretch to call code incomplete without > > them.
> My background is quite different. My end user was usually within my > own company or the DOD, and they expected source. Within a company, > if the software isn't easy to read and use, people tend to go off and > write their own, which is a large waste of resources.
I use ;-comments sometimes. Just mostly not string comments unless there is a specific reason. The main reason being that using string comments gives the false suggestion that the comments will "survive". Implementations are allowed to discard comments, so their usefulness is questionable. The main use of comments is in the source, and there's no reason to waste address space making them be manifest as strings unless there's a mission-critical need.
> While wasting too much of my life slogging through and fixing other > peoples fragile code, I noticed that if someone could not describe a > function they wrote in a short amount of text, that function would > be visited again and again to fix bugs.
All of this is orthogonal to the intent of my remark, which was not intended at all to touch on the question of whether to comment code, only whether to use doc strings. I wouldn't have made a remark at all if you'd said something which seemed to accept