[I7] iterate over things in container in to decide phrase

Why can’t you iterate over things in a container using a parameter from a to decide phrase? Or am I making a stupid mistake?

demo code (not working):

the demo is a room.

every thing has a number called size. The size of a thing is usually 5.

the null thing is a thing.

to decide which thing is the smallest item in (box - a container):
	let find be a random thing in the box;
	if find is nothing, decide on the null thing;
	repeat with item running through the list of things in the box:
		if the size of the item is less than the size of find:
			now find is the item;
	decide on find;

the bag is a container in the demo. 

the pebble is a thing in the bag. The size of the pebble is 2.
the book is a thing in the bag.
the towel is a thing in the bag. The size of the towel is 7.

the description of the bag is "The smallest item is [the smallest item in the bag].";

When I try to compile this I get

This error message is repeated three times.

It’s weird that “let find be a random thing in the box” works as intended, but you can’t iterate over the list of things in the box. Why is that? If you change box to bag in the repeat line it works. Can somebody explain that error message to me?

Actually, what I want to know is how to do what I am trying to do: to select one item in a container based on a property value. Is there already some easier way of doing this? Can I for example sort the list of things in the bag based on size?

I can’t answer your overarching question, but I think this will answer what you really want:

every thing has a number called size. The size of a thing is usually 5. Definition: A thing is small if its size is 4 or less. [If you don't want to use the "small" property the number doesn't matter, all that matters is that it says "or less" rather than "or more."]

And now you can automagically say “the smallest thing in the box.” See sections 6.7 and 6.8 of the documentation.

EDIT: More here.

Matt is right, but your initial problem was syntax: the code works if you change “list of things in the bag” to “things in the bag”. The compiler assumes you want to create a temporary list of things in the first case, and gets confused.

ChrisC: you’re right, although it should be box, not bag - inside the “to decide” phrase I want to use the parameter.

repeat with item running through…

  • the things in the box: works, using the parameter “box”
  • the list of things in the box: does not compile
  • the things in the bag: works, with “hard-coded” reference to bag
  • the list of things in the bag: this also works.

How come I can use an extra “list of” in one case but not the other? It’s stuff like this that makes I7 so painful to learn.

But of course Matt’s solution wins. Thanks Matt, I had totally missed that defining adjectives lets you use superlatives like that. It’s stuff like this that makes I7 so cool!

As ChrisC said: the “list of” means you want to turn the description-of-objects into a temporary (dynamic) list, and then iterate over that. A description-of-objects is iterable as-is, so you don’t need to.

I can’t say precisely what is bad about constructing a temporary list around a temporary variable. I7’s treatment of references is somewhat non-traditional and I’ve never been able to construct a clear explanation of how. On the other hand, this may be a compiler bug, rather than the intended semantics.

The lack of closures, no? Until they’re implemented, there’s no way to bundle the temporary variable’s value up with the description before handing it off to the list-building code in LIST_OF_TY_Desc.

Yeah, but you might as well say “the semantics don’t make sense because of internal implementation details”. The difference between iterating in place and calling a function that does the same iteration is pretty unclear. I mean, unclear to me – I wouldn’t have gotten down to that explanation without compiling some test code and seeing what the I6 looked like. (Which I haven’t done.)