Switch or case like structure failing when comparing current action

This is question might be related to Switch-style condition list causes error - bug or not? although that problem appears to be related more to using properties.

But my intentions are the same here: ascertaining if this is a bug or not.

The following code compiles and works as expected:

Lab is a room.

To display it:
	if current action is fooing:
		say "You tried the fooing action.";
	else if current action is barring:
		say "You tried the barring action.";
	else:
		say "You did not try fooing or barring.".

Instead of display-action:
	display it.

Fooing is an action applying to nothing.
Fooing is a display-action.
Understand "foo" as fooing.

Barring is an action applying to nothing.
Barring is a display-action.
Understand "bar" as barring.

Bazzing is an action applying to nothing.
Bazzing is a display-action.
Understand "baz" as bazzing.

But this code:

Lab is a room.

To display it:
	if current action is:
		-- fooing:
			say "You tried the fooing action.";
		-- barring:
			say "You tried the barring action.";
		-- otherwise:
			say "You did not try fooing or barring.".

Instead of display-action:
	display it.

Fooing is an action applying to nothing.
Fooing is a display-action.
Understand "foo" as fooing.

Barring is an action applying to nothing.
Barring is a display-action.
Understand "bar" as barring.

Bazzing is an action applying to nothing.
Bazzing is a display-action.
Understand "baz" as bazzing.

Results in the following compile error:

It seems odd that one works and one doesn’t. Especially when the error has the text “specifically, it has to be an action”, since both fooing and barring are actions.

Am I missing something?

Yeah, this is a bit subtle.

Inform has actions (“inserting the coin into the chest”) and action names (“inserting it into action”). Action names are simple constants. Actions are complex structures with parts.

(Roughly, an action is a struct containing an action name, one or more nouns, and an actor.)

When you write “if the current action is fooing”, this is not a simple equality test. It’s matching the current action structure against a constraint. You could also write “if the current action is taking the rock”, which is a more complex constraint.

The switch-case structure only works with simple equality tests.

This works:

	if the action name part of current action is:
		-- fooing action:
			say "You tried the fooing action.";
		-- barring action:
			say "You tried the barring action.";
		-- otherwise:
			say "You did not try fooing or barring.".
2 Likes

The old “action vs. action name” problem again. Not the first time it has tripped me up. Anyway, thanks for the solution. Hopefully, this will help others in the future as well.

1 Like

I would not describe it as “action vs action name” – fooing is an action pattern, albeit a very simple one. Of course, inserting the coin into the chest and taking the rock are also action patterns.

This workaround shows that, in principle, the compiler should be able to handle the construction being attempted:

SA1 is always the action of fooing.
SA2 is always the action of barring.
SA3 is always the action of bazzing.

To display it:
	if the current action is:
		-- SA1:
			say "You tried the fooing action.";
		-- SA2:
			say "You tried the barring action.";
		-- otherwise:
			say "You did not try fooing or barring.".

This works as intended in 10.1.2, but swapping SA1 with fooing or the action of fooing results in the Problem message shown above.

It seems that the compiler is not treating constant stored actions as constant when evaluating the switch-like construction. (Or am I misinterpreting something?)

@lkcampbell: Note that there is a significant difference between this and zarf’s example code in that this (same as the original version) assumes that the player is the one performing the action. Because zarf’s code is extracting the action name part of the current action, it would evaluate true even for NPCs.

[EDIT: Note that for the workaround to work it may be necessary to move the paragraphs defining the new actions to above this in your code. There are a few places where the compiler still needs to see declarations in a certain order.]

1 Like

True. There’s no internal reason that a switch statement has to be simple equality tests; it can be a sequence of arbitrary conditions, tested in order. (It’s compiling to I6, whose switch statement is implemented as a sequence of arbitrary conditions anyhow!)

I think maybe some subtlety is escaping me here.

The current action is a stored action, and the action of fooing evaluates as a stored action. Shouldn’t the compiler count a comparison of these within a switch-like construction as a “simple equality test” at the I7 level?

If you replace the always keyword for the definition of SA1 in the example workaround with initially (i.e. make it no longer a constant value), then you get the same Problem message that lkcampbell reported. I think maybe the compiler is for some reason just not treating the action of fooing as a constant value, at least not in the context of the switch-like construction. (… which seems like a possible bug to me.)

EDIT: I think I’m being really unclear, so I’ll try again.

lkcampell’s original code is (with comments added):

To display it:
	if current action is: [the current action is a stored action variable]
		-- fooing: ["fooing" should mean the same as "the action of fooing" in this context, and is a constant value]
			say "You tried the fooing action.";
		-- barring: ["barring" should mean the same as "the action of barring" in this context, and is a constant value]
			say "You tried the barring action.";
		-- otherwise:
			say "You did not try fooing or barring.".

My example workaround shows that if -- fooing: is replaced with -- SA1: (where SA1 is defined as a constant stored action) and -- barring: is similarly replaced with -- SA2: (another constant stored action), then the code compiles without issue.

The Problem message that lkcampbell isn’t super clear, but it’s main complaint seems to be that it’s expecting a constant stored action, which implies that it’s not interpreting a stored action literal such as fooing as a constant value for the purposes of the check that generates this Problem message.

zarf’s example redefines the problem as being one of comparing something that evaluates as an action name (the action name part of the current action) to various action name literals. Presumably, the compiler is correctly interpreting an action name literal as a constant value.

If zarf’s code is modified to:

foo-act-const is initially the fooing action.

To display it:
	if the action name part of current action is:
		-- foo-act-const: [not a constant!]
			say "You tried the fooing action.";
		-- barring action:
			say "You tried the barring action.";
		-- otherwise:
			say "You did not try fooing or barring.".

then the same Problem message (with slightly different details) is produced.