# Implementing Enumerable#inject in Io

**URL:** <https://www.ruby-forum.com/t/implementing-enumerable-inject-in-io/61127>\
**Category:** Ruby\
**Created:** [May 20, 2006, 3:09pm UTC](https://www.ruby-forum.com/t/implementing-enumerable-inject-in-io/61127 "2006-05-20T15:09:29Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![dasch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dasch](https://www.ruby-forum.com/u/dasch)\
**Post date:** [May 20, 2006, 3:09pm UTC](https://www.ruby-forum.com/t/implementing-enumerable-inject-in-io/61127/1 "2006-05-20T15:09:29Z")

</div>

This has nothing to do with Ruby – I thought there might just be some  
Io users here, and I didn’t want to sign up for some Io mailing list  
just for this one question.

I’m trying to implement Enumerable#inject in Io, just because I’d like  
to get a sense of the language.

I’ve tried this:

List inject := method(n, blk, self foreach(v, n = blk call(n, v)))

but when running this:

list(1, 2, 3) inject(0, block(n, v, n + v))

I get this error:

Importer: Nil does not respond to ‘+’

What am I doing wrong?

Daniel

---

<div class="post-metadata">

**Author:** ![dasch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dasch](https://www.ruby-forum.com/u/dasch)\
**Post date:** [May 20, 2006, 3:48pm UTC](https://www.ruby-forum.com/t/implementing-enumerable-inject-in-io/61127/2 "2006-05-20T15:48:53Z")

</div>

Daniel S. wrote:

> List inject := method(n, blk, self foreach(v, n = blk call(n, v)))

Found out what the problem was – the ‘call’ message to ‘blk’ messed  
things up. This works:

List inject := method(n, blk, self foreach(v, n = blk(n, v)))  
list(1, 2, 3) =\> 6

Cheers,  
Daniel

---

<div class="post-metadata">

**Author:** ![dasch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dasch](https://www.ruby-forum.com/u/dasch)\
**Post date:** [May 20, 2006, 10:04pm UTC](https://www.ruby-forum.com/t/implementing-enumerable-inject-in-io/61127/3 "2006-05-20T22:04:15Z")

</div>

On 5/20/06, Daniel S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Daniel S. wrote:
> 
> > List inject := method(n, blk, self foreach(v, n = blk call(n, v)))
> 
> Found out what the problem was – the ‘call’ message to ‘blk’ messed  
> things up. This works:
> 
> List inject := method(n, blk, self foreach(v, n = blk(n, v)))  
> list(1, 2, 3) =\> 6

I’ve written this one quite a few times and ways in Io. The way you  
write it heavily depends on the features you want and which idioms you  
want to use. My first attempt at it was to mirror Ruby’s inject as  
close as possible (updated to work with the latest darcs at  
[iolanguage.com](http://iolanguage.com)):

List inject := method(  
lst := self clone  
index := 0  
if(call argCount == 3,  
memo := lst removeFirst  
index = index - 1  
,  
memo := call evalArgAt(0)  
)  
memoName := call argAt(index + 1) name  
varName := call argAt(index + 2) name  
body := call argAt(index + 3)  
yield := block setMessage(body)  
setArgumentNames(list(memoName,varName)) setScope(call sender)  
lst foreach(elem, memo = yield(memo, elem))  
memo  
)

# Usage

list(1,2,3) inject(0,m,v, m+v)  
list(3,2,1) inject(m,v, m+v)

Note that it is a bit complex looking because I allow it to work for  
calls with and calls without a seed value. This mirrors the ruby  
philosophy quite close as you might note that the inject code is  
called with a Block object that I construct (calling it yield even).  
It also creates the lexical closure and a block local scope like ruby  
would have. I prefer this in general but it is NOT considered  
idiomatic Io (at least at this point).

The main thing Io does away with is scoping the code in its own block.  
Instead, most code is directly evaluated in the scope of the sender.  
This is simpler to write but can cause problems if you are not aware  
of this difference. In the end it comes down to a stylistic issue (I  
tend to lean more towards FP so I don’t like such broad side effects).  
A sample implementation might look like this:

List inject := method(  
lst := self clone  
index := 0  
if(call argCount == 3,  
memo := lst removeFirst  
index = index - 1  
,  
memo := call evalArgAt(0)  
)  
memoName := call argAt(index + 1) name  
varName := call argAt(index + 2) name  
bodyIndex := index + 3  
lst foreach(elem,  
call sender setSlot(memoName, memo)  
call sender setSlot(varName, elem)  
memo = call evalArgAt(bodyIndex)  
)  
memo  
)

Of course, most of the code is the same (most of it is for dealing  
with optional seed values anyway). This time you can see that I am  
evaluating the messages in a very specific context rather than  
creating a high level calling mechanism. This mirrors a lot of Io (for  
many reasons outside the scope of this email).

In the end I usually end up writing with my own style because many  
idioms in Io are still immature. Things are slowly developing but  
there are still things to be worked out (IMO – some people refuse to  
admit fault on some things). I highly recommend you join the ML (no  
yahoo account needed – find the subscribe email addr. and just send a  
mail to it) if you want to listen in. In the archives you might find  
some interesting threads. Related to this one might be the IoProp1  
thread that deals with activation of objects which heavily determines  
how easy it is to build correct code that uses high order procedures  
(hint: both of the above have a bug in it related to activatable  
objects… I left it in for clarity as the solution muddles the  
solutions a bit more than I wanted).

Brian.

---

<div class="post-metadata">

**Author:** ![dasch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dasch](https://www.ruby-forum.com/u/dasch)\
**Post date:** [May 20, 2006, 11:11pm UTC](https://www.ruby-forum.com/t/implementing-enumerable-inject-in-io/61127/4 "2006-05-20T23:11:58Z")

</div>

Brian M. wrote:

> [long post]

Thanks for the post! Yeah, I still think Io’s a bit immature, but it’s  
very interesting. I’ll be signing up on the mailing list 🙂

Thanks  
Daniel
