start_at = place
locations {
place: location "You're in a place.";
}
objects {
koala: object "a koala" at="place";
}
booleans {
noun_is_manipulable: boolean "false";
}
collections {
objects_to_check: list {
items = ["koala"];
}
}
on_command {
: match "hug _" {
/* This block causes the bug to appear: */
: set_false "noun_is_manipulable";
: collection_iterate "objects_to_check" {
: if (noun1_is {(item())}) {
: set_true "noun_is_manipulable";
}
}
/* This block does not: */
// : execute_one_at_random {
// : set_false "noun_is_manipulable";
// : set_true "noun_is_manipulable";
// }
/* When this code runs after the first block, "True branch taken." is printed regardless of whether noun_is_manipulable is false or true. */
: print {("noun_is_manipulable = " + noun_is_manipulable)};
: if (noun_is_manipulable) {
: print "True branch taken.";
}
: else {
: print "False branch taken.";
}
}
}
Run it, and type the following commands (the output shown is what I get in the Adventuron Classroom web IDE):
You're in a place.
You see a koala.
>HUG KOALA
noun_is_manipulable = true
True branch taken.
> HUG ELEPHANT
noun_is_manipulable = false
True branch taken.
I do not understand how it’s possible for (something equivalent to) : if (false) to execute the code inside of it. I don’t think it’s related to the idiosyncratic control flow in on_command; the same thing happens in a subroutine. As the comments in the source explain, switching out the collection_iterate block for an execute_one_at_random block no longer causes the issue to manifest.
Even weirder is the fact that replacing : if (noun_is_manipulable) with : if (!noun_is_manipulable) still causes the true branch to run both times.
Is this a bug, or is Adventuron fundamentally different from other programming languages in some regard?
I don’t know Adventuron but I’ve long been kind of intrigued by it, so I poked at this for a while and tried some things. For what it’s worth, IMO it certainly does seem to be a bug rather than any kind of intentional behavior.
I’ve been playing around with this for the last hour or two and I’ll be stuffed if I can work out why it’s not working. I can’t see anything wrong with your code. It’s as though the value of the boolean is somehow magically being changed in between printing it and testing it or the test is being ignored. This has got to be a bug, but I’ve been using if…then…else for yonks and never struck anything like this.
I’ve seen weird stuff with more complex collection_iterate code. Sometimes having null code in it helps it work, like so. It’s maybe a long shot, but it’s maybe worth a look.
(question removed – Garry noticed the OP did indeed say the code was written in Adventuron Classroom)
details of my code
: collection_iterate "ask_list" {
: if (int(item()) < 3) {
: return ;
} : else {
} # the "else" is necessary. Note to self: DO NOT DELETE
}
Amusingly I had put in a lot of debug code, including an “else” at first, because it was my first time working with collection_iterate. So it worked okay, then I said “ha! Don’t want that debug text in release!” and once I zapped it the odd bug popped up.
The code is Adventuron Classroom. Coincidentally, I just tried it in Adventuron betabeta and it works fine. The only difference is that collection_iterate has to be changed to iterate. This convinces me that it must have been a bug that has been fixed in a later version.
Incidentally, I should point out that collections aren’t really appropriate for this sort of thing. When you’re interested in the properties of an individual object, you should be using traits. Here’s how:
start_at = place
locations {
place: location "You're in a place.";
}
objects {
koala: object "a koala" at = "place" {traits = [huggable_t]};
}
traits {
huggable_t : trait;
}
on_command {
: match "hug _" {
: disambiguate_s1 "universal" with_trait = "huggable_t";
: if (s1_has_trait "huggable_t") {
: print "True branch taken.";
}
: else {
: print "False branch taken.";
}
}
}
EDIT: If you’re not familiar with traits, see Traits.
(I should note that this is a stripped-down example to illustrate the bug, and traits wouldn’t work in my actual use case, which involves generating the collection with some look_inside and collection_union calls. Thank you for the suggestion, though.)
Anyway, since everyone agrees that it’s a bug, I’ll download the betabeta version and see if that works instead. If not, I’ll try @aschultz’s workaround.
After migrating my code to betabeta, I have now solved my original problem. I think using a newer version where the bug is fixed is the best solution here. Thank you for investigating.