Variable Typing

Get help using and writing Nisus Writer Pro macros.
Post Reply
waltzmn
Posts: 44
Joined: 2013-05-05 12:52:00

Variable Typing

Post by waltzmn »

Nisusy folks:

I'm intermittently teaching someone about programming with NWP macros. I was recently trying to explain the concept of variable typing. I wrote a tiny piece of example code:

Code: Select all

$Name = 'George'
$Number = 3
$FullName = $Name + $Number
My goal, quite frankly, was to have this fail with a type mismatch.

It didn't happen. The macro ran, and when I added a prompt command to show me the value of $FullName, it was 3.

OK, I get it, sort of: the macro language determined that a sum must have a numeric value, and since 'George' is not a number, it treated it as 0, added 3, and gave 3 as a result. I don't like that :-), but I get it.

What I don't know, and the single paragraph on variables in the macro reference manual does not make clear, is what emerges when one does a type-crossing operation. If I had had to guess the outcomes of $FullName = $Name + $Number, my guesses would have been, in order:
1. Error (type mismatch)
2. 'George3' (treating the result as a string, since the first variable was a string, and concatenating -- or just defaulting to concatenating whenever there is a string)
3. 'George' (retaining the first value, since it was defined as a string)
4. Using whatever type $FullName had before, if it had a type (which it didn't in this case)

Obviously I got outcome 5. :-)

I try not to create type mismatches, because I consider them an error even if NWP doesn't :-), but for debugging purposes if no other, how does NWP decide what type to use when combining mismatched entities?

User avatar
phspaelti
Posts: 1095
Joined: 2007-02-07 00:58:12
Location: Japan

Re: Variable Typing

Post by phspaelti »

waltzmn wrote:
2020-02-23 08:14:01
I try not to create type mismatches, because I consider them an error even if NWP doesn't :-)
That is indeed the approach one should take, even if a language (like Nisus macro language) is "loosely" typed. In that sense you should ask yourself what happens when I add "George" and 3? As any first grader could tell you "Duh, that's a stupid thing to do!"

The problem is you should think not of adding "George" and 3, but what if instead I wanted to add "15" and 3? In that case you will find that Nisus gives you the answer 18, which is a sensible answer. In particular it does not give give you "153", or "15" or ERROR, which would be the answers you would seem to prefer ;-)

Nisus does not treat "George" + 3 as concatenation (which might be the case in Javascript, or some other loosely typed languages) because "+" is not the concatenation operator. Nisus has "&" for that purpose. "George" & 3 will give you "George3" even without needing to do a typecast first. Instead treating strings as numbers in arithmetic contexts is useful, because it comes up a lot in non-artificial examples. Usually in Nisus you will be processing text, searching for numbers in text and then extracting them. In contexts like that you will be really happy not to have to worry about "Is this number still a string?" before you try adding 1 or dividing by 2.

waltzmn wrote:
2020-02-23 08:14:01
…how does NWP decide what type to use when combining mismatched entities?
I think this stuff is explained reasonably well in the Macro Language reference in appropriate places. I'm not sure that there is a simple answer, probably because the underlying implementation is probably complex. But reviewing what I wrote above, I'd guess that the rule is interpret strings as numbers in arithmetic context, and interpret numbers as strings in 'text' contexts. I guess the most confusing thing about your original example is asking what kind of number is "George"?

The main place one needs to use typecasts is division, where you need to "Cast to Int" if you want whole number division.

Hope this helps
philip

waltzmn
Posts: 44
Joined: 2013-05-05 12:52:00

Re: Variable Typing

Post by waltzmn »

Thanks for your reply. Both your knowledge and your willingness to share are amazing.

phspaelti wrote:
I think this stuff is explained reasonably well in the Macro Language reference in appropriate places. I'm not sure that there is a simple answer, probably because the underlying implementation is probably complex. But reviewing what I wrote above, I'd guess that the rule is interpret strings as numbers in arithmetic context, and interpret numbers as strings in 'text' contexts. I guess the most confusing thing about your original example is asking what kind of number is "George"?
I could go into a lot of detail in my reply, but I'll spare the innocent bystanders. :-) Just remember that I was trying to deliberately generate a type mismatch to teach the <i>idea</i> of type mismatches, and it didn't work.

As for why "George" and "3" -- the United States rebelled from Britain under George III -- George 3. :-)

But I DID look in the macro language reference for help. The sum total information on variables, as located by the table of contents, is this:
Variables allow you to store any value in a named container. The value of a variable can change as your macro runs and you assign different values to the variable. Variables are always prefixed with a dollar sign and are declared simply by assigning them a value. For instance:
$age = 24
$name = "Pharika"
Variables can also be assigned by using a command, eg:
$name = Prompt Input ‘What is your name?’
Note that it doesn't even explain the idea of variable types. Maybe the information is in the reference manual, but with no index and no idea what to look for, I didn't know where to look. Reading the whole reference manual is not helpful -- I can't remember that much stuff. :-)

I don't really need $FinalName = 'George' + 3 to produce an error :-), but I think I do need some sort of reference as to how types are assigned. This was a demonstration, but someday I hope to have reason to know how such things work out. :-)

(I do see, now, that there is a section on type casting, which at least leads to a list of the types the macro language supports. That's something, though I could use more. But here's a suggestion for the manual: Put a link in the Variables section to the stuff on types.)

martin
Official Nisus Person
Posts: 4739
Joined: 2002-07-11 17:14:10
Location: San Diego, CA
Contact:

Re: Variable Typing

Post by martin »

waltzmn wrote:
2020-02-23 17:10:28
Maybe the information is in the reference manual, but with no index and no idea what to look for, I didn't know where to look.
The relevant statement is made just before the table of numeric operators:
The following mathematical operators always convert the values they operate on (operands) to a numeric form
But you're right that the section on variables doesn't discuss this.
Just remember that I was trying to deliberately generate a type mismatch to teach the <i>idea</i> of type mismatches, and it didn't work.
You're going to have a hard time getting the macro language to oblige. As Philip said, Nisus macros generally automatically coerce all values as necessary, which is mostly very convenient. It's generally a big nuisance having to cast scalar values all the time. This is pretty normal for scripting languages.

If you still want to pursue triggering a type mismatch error, you should use Object types instead of primitive values. Objects generally won't be coerced. Here's an example of such an error:

Code: Select all

$range = Range.new(0,3)
$range.containsRange("Cat")
That macro will fail and alert that a Range object was expected.
But here's a suggestion for the manual: Put a link in the Variables section to the stuff on types.)
That's always a good idea! I'll see about adding some cross-references between the topics you've discussed. Thanks :)

waltzmn
Posts: 44
Joined: 2013-05-05 12:52:00

Re: Variable Typing

Post by waltzmn »

martin wrote:
That's always a good idea! I'll see about adding some cross-references between the topics you've discussed. Thanks :)
Thank you. I can think of some cases where not casting types is useful, but they're mostly for debugging. (Real debugging, not joke code such as I used in this thread.) You'd probably think them pathological. :-) My big problem here was that I expected one thing and got something else.

But more cross-references in the macro manual would really help. I know most of the information I need is in there, but finding it often proves difficult. :-)

Here's another suggestion: Set up a place where we can make suggestions for the manual. I say that seriously; I know the manual is big, and I know it was a lot of work for someone, but when I am looking up stuff in it, I'm forever saying to myself, "But I just read about that somewhere...."

Anyway, thanks for the example of how to break things. :-)

martin
Official Nisus Person
Posts: 4739
Joined: 2002-07-11 17:14:10
Location: San Diego, CA
Contact:

Re: Variable Typing

Post by martin »

waltzmn wrote:
2020-02-24 15:47:37
Here's another suggestion: Set up a place where we can make suggestions for the manual
If you have any suggestions regarding the user guide or macro guide please feel free to post more topics on these forums, if you feel they're in the public interest or would benefit from discussion. Or you could just contact us directly, ideally via the menu Help > Send Feedback, if you don't think a public discussion is useful for a particular idea.

Thank you for your suggestions and positivity! :)

Post Reply