Given two arrays of the same size filled with numbers, can someone give me a code snippet that will show me how to add the numbers at the same index to produce a third array?
So that firstArray:= #(1 2 3 4) secondArray:= #(5 6 1 2)
will result in a thirdArray (6 8 4 6)
Cheers
John
(hangs head in shame....)
On Fri, 31 Aug 2001 03:36:19 +0100, John Hinsley jhinsley@telinco.co.uk wrote:
Given two arrays of the same size filled with numbers, can someone give me a code snippet that will show me how to add the numbers at the same index to produce a third array?
So that firstArray:= #(1 2 3 4) secondArray:= #(5 6 1 2)
will result in a thirdArray (6 8 4 6)
Try:
thirdArray := (1 to: firstArray size) collect: [:index | (firstArray at: index) + (secondArray at: index)]
Later, Jon
-------------------------------------------------------------- Jon Hylands Jon@huv.com http://www.huv.com/jon
Project: Micro Seeker (Micro Autonomous Underwater Vehicle) http://www.huv.com
On Thursday, August 30, 2001, at 10:49 PM, Jon Hylands wrote:
On Fri, 31 Aug 2001 03:36:19 +0100, John Hinsley jhinsley@telinco.co.uk wrote:
Given two arrays of the same size filled with numbers, can someone give me a code snippet that will show me how to add the numbers at the same index to produce a third array?
So that firstArray:= #(1 2 3 4) secondArray:= #(5 6 1 2)
will result in a thirdArray (6 8 4 6)
Try:
thirdArray := (1 to: firstArray size) collect: [:index | (firstArray at: index) + (secondArray at: index)]
This might be a touch clunkier than Jon's, but it's always good to see more than one example:
coll := OrderedCollection new. firstArray with: secondArray do: [:el1 :el2 | coll add: el1 + el2]. thirdArray := coll asArray.
- Doug Way dway@riskmetrics.com
Jon Hylands wrote:
Try:
thirdArray := (1 to: firstArray size) collect: [:index | (firstArray at: index) + (secondArray at: index)]
Thanks Jon
I'm coming rapidly to the realisation that I find it very difficult to internalise iterations (and not only in Smalltalk!).
I wonder how common this is?
I guess one way round it would be to find a good source of short examples. Anyone know of one?
Cheers
John
John Hinsley jhinsley@telinco.co.uk wrote:
thirdArray := (1 to: firstArray size) collect: [:index | (firstArray at: index) + (secondArray at: index)]
Thanks Jon
I'm coming rapidly to the realisation that I find it very difficult to internalise iterations (and not only in Smalltalk!).
I wonder how common this is?
I've heard that in intro programming classes, loops are the place where most students fall out. if-then is fine, variables are okay, operations are okay, and even (I think) subroutines are okay, but loops really kill students off. This matches my scant experience, as well, teaching an occasional person how to program.
Loops are actually quite similar to recursive functions. This sounds strange, but consider. The theoretical description of the meaning of a loop is recursive -- do one loop, then do the test, then possibly recur. People who study small programs a lot recommend studying loops in terms of invariants plus movement towards a terminating condition -- pretty much the same as for recursive functions! In fact, not only are loops pretty similar to recursive functions, I think they may even be harder: at least with the recursive function, the function name can help you figure out the equivalent to an invariant ("gee, it says sorted(x,1,n) -- guess the result will be x with elements 1..n sorted"). With loops, you must reverse engineer the invariant.
Finally, I'll add my personal experience: I still find it tricky to add a *new* kind of loop to my code. Now, I can whip out a "iterate over the elements and accumulate into a subsidiary array" very quickly, but that's because I've seen this kind of loop a zillion times! If the loop has a structure that's new, I really have to think about it for a minute or two, even after 15-20 years of programming (depending on how you count). It just so turns out that almost all loops are familiar ones, so this isn't an issue for me in practice. Perhaps other programmers will introspect the same thing?
Anyway, now for the good news: Smalltalk allows you to get away from low-level loop algorithms in almost all cases that occur in practice. The reason Smalltlak can do this, and many languages can't, is because of the powerful combination of collections and blocks. Consider this wonderful response to the original question:
firstArray with: secondArray collect: [ :a :b | a + b ]
Is this really a loop? Technically, with:collect: is using a loop internally, but cognitively, it just doesn't seem the same to me as a hand-coded loop. All the details of incrementing an index and moving toward completion are left out, and it just looks like combining two collections with an operation. Smushing two collections together really seems simpler to me than "start with element 1; do stuff with element i; move to element i+1;" etc.
By the way, there is a nice generalization of the above with:foo: pattern. It looks like this:
(firstArray with: secondArray) collect: [ :combo | combo first + combo second ]
This use of #with: (which doesn't currently exist), is identical to ML and Haskel's "zip" function, and it allows you to use all of collect:, select:, reject:, do:, detect:, etc. without writing with:collect:, with:select:, with:reject:, etc. In brief, the presence of a "with" clause can be orthogonal to which collection operation is being used.
Overall, I'm really starting to think loops should be treated like assembly language or two's complement: interesting for the terminally curious, probably useful to know a *little* about, but not incredibly useful in most programs. (Of course, this is only true in a nice language that actually has collections and blocks!)
John, you're not at all alone. :)
-Lex
"Lex" == Lex Spoon lex@cc.gatech.edu writes:
Lex> Overall, I'm really starting to think loops should be treated like Lex> assembly language or two's complement: interesting for the Lex> terminally curious, probably useful to know a *little* about, but not Lex> incredibly useful in most programs. (Of course, this is only true in a Lex> nice language that actually has collections and blocks!)
We find this true in Perl. Perl has some nice "iterate over this list" constructs, like foreach, map, and grep, which act like do:, collect:, and select:. (Yes, we're still missing inject:into:, but that's coming in the next release of Perl as reduce.) And Perl also has a very C-like "for" construct, permitting the user to select a starting condition, termination condition, and stepping condition.
Almost invariably, the loops I construct with "for" require about five times as much thinking to avoid fencepost problems or confusing setup or termination conditions. When I cast the problem in terms of foreach/map/grep/reduce, I never worry about that. I just say "do this for that", and it just works.
And I've noticed the same things in the students I teach... if they start out with a C or Java background, they start with the familiar "for" loop (which we deliberately teach later rather than earlier), but then *progress* to "speaking native Perl", and find the same thing I've found: using higher-level constructs removes debugging time, and reduces time-to-market delays and maintenance costs.
Oddly, I often get a student, upon seeing the foreach contruct, ask "but how do I know which element of the list it's accessing at the moment?". I always grin and say, "you don't, and that's the beauty". I feel like a Zen master at that point. :-)
On Sunday, September 2, 2001, at 10:19 PM, Lex Spoon wrote:
[snip]
Finally, I'll add my personal experience: I still find it tricky to add a *new* kind of loop to my code. Now, I can whip out a "iterate over the elements and accumulate into a subsidiary array" very quickly, but that's because I've seen this kind of loop a zillion times! If the loop has a structure that's new, I really have to think about it for a minute or two, even after 15-20 years of programming (depending on how you count). It just so turns out that almost all loops are familiar ones, so this isn't an issue for me in practice. Perhaps other programmers will introspect the same thing?
Yes, very much so. However, since almost all loops are familiar/similar, it seems one shouldn't have to write them...
Anyway, now for the good news: Smalltalk allows you to get away from low-level loop algorithms in almost all cases that occur in practice.
...which is why it is good when one doesn't have to.
The reason Smalltlak can do this, and many languages can't, is because of the powerful combination of collections and blocks.
You can actually do it just as well using just messaging, with Higher Order Messaging (HOM). I personally find blocks also to be somewhat obscure.
Consider this wonderful response to the original question:
firstArray with: secondArray collect: [ :a :b | a + b ]
Is this really a loop? Technically, with:collect: is using a loop internally, but cognitively, it just doesn't seem the same to me as a hand-coded loop.
I like
firstArray collect + secondArray each
better, because it is even further away from the single elements and has even less goobledygook.
All the details of incrementing an index and moving toward completion are left out, and it just looks like combining two collections with an operation. Smushing two collections together really seems simpler to me than "start with element 1; do stuff with element i; move to element i+1;" etc.
Exactly! I find it even easier when it is all just done with messaging. I've been into this far too long to be unbiased, but it seems to me that "this message gets sent to lots of objects instead of just one object" is easer than that of a block being invoked, especially since the single elements don't even show up any longer.
By the way, there is a nice generalization of the above with:foo: pattern. It looks like this:
(firstArray with: secondArray) collect: [ :combo | combo first + combo second ]
I have to admit I like
firstArray collect + secondArray each
better, though it is far from perfect, because the structure of the intended is still visible in the lexical structure of the code (LHS + RHS), even if both the LHS and the RHS are a little mucked up.
[snip description of with: -> it does seem useful]
Overall, I'm really starting to think loops should be treated like assembly language or two's complement: interesting for the terminally curious, probably useful to know a *little* about, but not incredibly useful in most programs.
That's been my thinking exactly for a couple of years. As a matter of fact, the same goes for many of the other "patterns" of code we keep producing. As soon as we have another of these patterns, we should be able to put it away and just use it, instead of re-creating it. However, in order for this to happen, or means of expressing and reusing such patterns must improve, the cost of putting them away and accessing them must decrease.
(Of course, this is only true in a nice language that actually has collections and blocks!)
Or even ones without blocks, as long as they have true messaging!
John, you're not at all alone. :)
Yup!
Marcel
Marcel Weiher wrote:
On Sunday, September 2, 2001, at 10:19 PM, Lex Spoon wrote:
By the way, there is a nice generalization of the above with:foo: pattern. It looks like this:
(firstArray with: secondArray) collect: [ :combo | combo first + combo
second ]
I have to admit I like
firstArray collect + secondArray each
better, though it is far from perfect, because the structure of the intended is still visible in the lexical structure of the code (LHS + RHS), even if both the LHS and the RHS are a little mucked up.
The best one so far ( I think) is firstArray + secondArray which works like a charm :-) But you still have to know that the arrays have equal size.
Karl
On Mon, 03 Sep 2001 20:39:25 +0200, you wrote:
The best one so far ( I think) is firstArray + secondArray which works like a charm :-) But you still have to know that the arrays have equal size.
One of the problems with using methods like this is that they are not typically in the "standard" Smalltalk class library (whatever that means...)
From my perspective, its much better to learn the general iterators and how you can use them to accomplish diverse tasks. For instance, most people with limited experience just don't understand that methods like #collect: and #select: work on Strings and Intervals as well as more "normal" collections like Arrays and Sets. Its always a pleasure to see the lights come on in their eyes when they get it :-)
Later, Jon
Given two arrays of the same size filled with numbers, can someone give me a code snippet that will show me how to add the numbers at the same index to produce a third array?
So that firstArray:= #(1 2 3 4) secondArray:= #(5 6 1 2)
will result in a thirdArray (6 8 4 6)
How about:
thirdArray := firstArray with: secondArray collect: [:a :b | a+b]
-- Duane
At 03:36 31.08.2001 +0100, you wrote:
Given two arrays of the same size filled with numbers, can someone give me a code snippet that will show me how to add the numbers at the same index to produce a third array?
So that firstArray:= #(1 2 3 4) secondArray:= #(5 6 1 2)
will result in a thirdArray (6 8 4 6)
MethodFinder, MethodFinder, MethodFinder! ;-)
Entering #(1 2 3 4). #(5 6 1 2). #(6 8 4 6) finds #+ and indeed
#(1 2 3 4) + #(5 6 1 2) => #(6 8 4 6)
Entering #((1 2 3 4) (5 6 1 2)). #(6 8 4 6) finds #sum and indeed
#((1 2 3 4) (5 6 1 2)) sum => #(6 8 4 6)
Voila. Ted, this tool is priceless! Thanks!
Cheers, Helge
How about #+?
On Thursday, August 30, 2001, at 10:36 PM, John Hinsley wrote:
Given two arrays of the same size filled with numbers, can someone give me a code snippet that will show me how to add the numbers at the same index to produce a third array?
So that firstArray:= #(1 2 3 4) secondArray:= #(5 6 1 2)
will result in a thirdArray (6 8 4 6)
Cheers
John
(hangs head in shame....)
Can't cope anymore? Desperate for help? Join the 12 step program for those who yearn to give up Microsoft: http://home.earthlink.net/~penguinrox/index.html
squeak-dev@lists.squeakfoundation.org