Using Imperial units with the Metric Units extension

I have a use for the Metric Units extension, but I am not really all that conversant in metric units and I don’t care too much about rounding errors, so I’d like to be able to say things in the source like “the height of a person is usually about 5 foot 6” and have Inform convert this into 167.64 centimeters (give or take) for me, but I can’t seem to figure out how to make this happen. I tried:

To decide which length is about (X - a number) foot (Y - a number): decide on ((X * 12 + Y) * 2.54) centimeters. To decide which length is about (X - a number) feet: decide on X foot 0. To decide which length is about (X - a number) inch: decide on 0 foot X. To decide which length is about (X - a number) inches: decide on 0 foot X. [...] A thing has a length called the height. The height of a person is usually 5 foot 6.

But Inform says:

What is the magic syntax that makes this work?

ETA: After experimenting, it seems that to really get the calculations right, the functions have to be like this:

To decide what length is about (X - a number) foot (Y - a number) (this is imperial-conversion): decide on (((X * 12) + Y) * 127cm) / 50. To decide what length is about (X - a number) feet: decide on imperial-conversion applied to X and 0. To decide what length is about (X - a number) inches: decide on imperial-conversion applied to 0 and X.
It will let me assign the result using “let” and can print them out using “say”, but I can’t use it as a default value or in any phrase using “is”. This is very tiresome.

How do you use the units in the game? If you’re not using metric units it seems to me you should just use imperial units as the basis instead of trying to convert them under the hood to metric. I’m not very familiar with the Metric Units extension but I have the impression that it just defines the units, but doesn’t offer any additional features you couldn’t do without it.

Fortunately, I7 makes provision for expressing the same kov using what it calls “equivalent notations” (see ch 14.5, very bottom of page). Unfortunately, it doesn’t seem to support multi-part notations for these equivalents, so “6 ft 5” is out. (This looks like a bug – I’m going to mess around with it some more and start another thread to see if anyone has any insights before reporting it.) Note that you can use both feet and inches as equivalents for already declared metric units, just not together:[code]Include Metric Units by Graham Nelson.

1in (in imperial units, in in) specifies a length equivalent to 25mm. [rounded from 25.4]
1ft (in imperial units, in ft) specifies a length equivalent to 12in.

[You can also substitute the previous two lines with the following two. Notice that the rounding errors will be different:]
[1ft (in imperial units, in ft) specifies a length equivalent to 305mm. [rounded from 304.8]
1in (in imperial units, in in) specifies a length equivalent to 25mm. [rounded from 25.4]]

A thing has a length called the height. The height of a thing is usually 1ft.
The height of a person is usually 66in.

Lab is a room. A stick is in the Lab.
Sam and Dwight are men in the Lab.
The height of Dwight is 83in.

Instead of examining a thing:
say “[height of the noun in metric units] or [height of the noun in ft] or [height of the noun in in].”

test me with “x me / x stick / x sam / x dwight”.[/code]

HTH,

To get rid of the rounding error, you could first define a new metric unit that’s 0.1mm, and base the imperial units off that. This will reduce the upper end of the range for metric units (from about 2100km to about 210km), so it depends on what sort of thing you want to measure.

1dmm specifies a length scaled down by 10000.
1in (in imperial units, in in) specifies a length equivalent to 254dmm.
1ft (in imperial units, in ft) specifies a length equivalent to 12in.

Ahh, thanks, I might try that.

Looking back at it (and being slightly less irked by it now), I note that I can use the “about X foot Y” notation in the other decides (I must have forgotten the “about” one of the times I rewrote it, like I did in the original code, but I7 error messages are not real helpful for figuring out syntax errors), and it can also be used with “now”. If you try to use a variable with an initialization or a default value, you get a message about how it’s not good to start things off with a variable value that can change, and if you try to initialize one variable to another, you get “At the start of play, variable values have to be set equal to definite constants, so this is not allowed.”

Maybe it treats the results of functions as variables, even if they use constant arguments, because they could, in theory, try to access or modify global state variables that might not have been initialized yet? I guess there isn’t any kind of way to declare a const function which explicitly doesn’t modify anything?

That’s right. I7 doesn’t have a notion of functions that are stateless or safe at compile time.