List!fill idx behavior


#1

I was revisiting List!fill for a real-world scenario and noticed the following.

// make a list of all page indexes
!pages : List{Integer}!fill @archive_files.length [idx]

Returns
{21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21}

While this
!pages : List{Integer}!fill @archive_files.length [idx + 0]

Returns my expected outcome
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}

Is this the expected behavior?

EDIT
Hmm, I also notice that it works fine if I pass in idx!, this somehow feels familiar… but I can’t quite remember.


#2

Yes, this is expected behavior.

idx is the same Integer object reused on each iteration and if it is used simply as idx then it will just use a reference to that same object for each list item.

If you make a copy of it (as you mentioned in your EDIT) then it will make a new Integer object for each list item.

So this is probably what you want:

// make a list of all page indexes
!pages : List{Integer}!fill @archive_files.length [idx!]

#3

:man_facepalming: So what I did in the first case was make an array like this:
{idx, idx, idx...}

This seems obvious in retrospect, I don’t know why I thought it would be passed in by value.


#4

It could be passed in by value, though that would make it a teensy bit slower.

We’ll make sure to clarify things in the comments in List@!fill() and other similar areas.

Thanks for continuing to report on any gotchas or stuff that does not seem obvious! It will help make things better over time for everyone using SkookumScript. :madsci:


#5

This just bit me – I didn’t find any relevant comments in the Fill method documentation describing this. It is quite unintuitive behavior. If I wanted the same value for each item of a list, I would not think to just use the idx object. It’d make it explicit, since that demonstrates intent.

I just changed my Fill to

count.do[append(item_gen(idx!))]

instead. Will I regret this later?


#6

You’re code looks okay. It all depends on how idx is used by item_gen().

You shouldn’t be regretting it later.

Updating the comments must have slipped through the cracks. Apologies for not being more clear - we will update the comments.


#7

When we do that (change our version of fill), won’t our code get over-written when the next SK update comes out?
Or perhaps there is a way to “overlay” this so, our edits don’t necessarily effect core SK edits that you guys do?

(because I do agree that the default fill behavior filling with the last iterator is very unusual, so we just decided to change it).