c3d / db48x

RPL runtime for the DM42 calculator, in the spirit of HP48/49/50
http://48calc.org
GNU Lesser General Public License v3.0
63 stars 9 forks source link

Variable names conflict with units conversion, e.g. 'M' with m/s #649

Open jthole opened 6 months ago

jthole commented 6 months ago

Version: 0.6.0 on DM42

Steps to reproduce: (there are several ways; issue is that 'M' variable gets used in the units conversion, when unit contains meters)

Store 200 in variable named 'M'

Put 100 on first level of the stack

Press Units menu, select Speed, and choose 'm/s'

On the stack, '100 200/s' appears (remember, variable M contained value 200)

Expected: 100 m/s (variable names should not conflict with units)

c3d commented 6 months ago

This was originally intentional, to make it possible to define custom units using variables. And 200 is a valid unit expression, so it does something sensible with it.

That being said, I do not like nor really fully understannd the way classic RPL extends the unit system. Apparently, you can define $=1_? and then you can define other currencies based on this definition of $. This is according to the HP50G advanced reference, page 3-288, in case you care to check. What is unclear/unlikable is

1) Unit lookup rules and precedence. Experimentally, it seems that you cannot override standard units that way. This is unfortunate, because some units have changed over time, e.g. the ftUS defintion would need adjusting since January 1st, 2023.

2) Whether $ as define above would be a base unit, and whether a O=1_? would be seen as an independent unit from $. I would have thought that the system would allow you to create multiple independent base units, but apparently there is only one spare unit.

DB48X shifted to having custom units defined by a CSV file. You can have as many base units as you want. A base unit is a unit that refers to itself, e.g. USD=1_USD. That mechanisms makes it less essential to also be able to define units using variables. However, I'd like to preserve it for compatibility reasons.

jthole commented 6 months ago

@c3d thanks to the explanation! That makes sense, even if I might want to propose another approach (after coffee ;-) ).

I feel like using single letter variables to substitute in unit conversions, can lead to "semantic overloading".

For instance, is the 'N' variable a counter, number of periods, or a force? Besides, when defining N and M as numerical variables, a unit conversion to Nm becomes very hard to read.

Moreover, when I store a text object in M, the unit conversion to m/s fails with an "internal:object[0x2000e95d]" error. For me, that is unexpected behavior of variables.

Edit (after coffee):

A possible way to solve this, would be to prefix "unit variables", for instance with 'z' or '_'. In this way, M would be a regular variable, but zM or _M would define a custom unit value. That would essentially be the way the HP50G treats them, though I am not familiar with that (will have to read the section in the manual). Another option, which I like less, is to treat uppercase and lowercase variable names differently (that will lead to it's own inconsistencies).

I understand wanting to keep the variable substitution mechanism as it is now. But from my current point of view, it has more drawbacks than advantages.