Page 1 of 1
enforce variable type checking?
Posted: Sun May 15, 2011 7:56 am
by sp27
Is there a way to enforce variable type checking in LC?
For example, this doesn't throw an error:
put (char 2 of field "ABC" of this card is 254)
I wish it did. Is there a switch maybe that can turn on stricter type checking?
Thanks,
Slava
Re: enforce variable type checking?
Posted: Sun May 15, 2011 9:03 am
by jmburnod
Hi Slava,
254 is a chartonum, not a char
Try this :
Code: Select all
put chartonum(char 2 of field "ABC" of this card) =254
Best regards
Jean-marc
Re: enforce variable type checking?
Posted: Sun May 15, 2011 5:14 pm
by sp27
That's exactly my point: LC should raise an error because char N of "someString" cannot be reasonably compared to the integer 254. But apparently LC doesn't do data type checking, evaluates [char 2 of field "ABC" is 254] as false, and lets you think that all is well in your code. This will let to many silent failures, e.g. the syntax error in this condition will go unnoticed:
Code: Select all
if charToNum(char 1 of field "ABC" is 255) then
--this will never be true, and no one will know, so the code will fail silently;
--instead, an error should be raised when you click Apply
end if
So my question from a perfect newbie was, Is there a switch sonmewhere that would enforce data type checking? I like the switch called explicitVariable, so maybe there something similar for data types?
Slava
Re: enforce variable type checking?
Posted: Sun May 15, 2011 5:47 pm
by jmburnod
Hi Slava
I'm sorry if i don't understand your post. I'm a bad student for english.
For me
Code: Select all
if charToNum(char 1 of field "ABC" is 65) then
return false always.
I agree we can expect an error message in this case
but
Code: Select all
put charToNum(char 1 of field "ABC")=65
return the correct result
Curiously
Code: Select all
put charToNum((char 1 of field "ABC")=65)
return 102
Someone can explane this ?
Jean-Marc
Re: enforce variable type checking?
Posted: Sun May 15, 2011 5:53 pm
by SparkOut
Because
Code: Select all
put charToNum((char 1 of field "ABC")=65)
the test for
(char 1 of field "ABC") = 65 is returning the string "false" and charToNum("false") will give 102 as the ascii code for "f", being the first letter of "false".
Code: Select all
if charToNum(char 1 of field "ABC" is 65) then
should not generate an error.
char 1 of field "ABC" is 65 is false (since it is comparing a single char with an integer). The boolean value
false is parsed by the charToNum statement as a literal string, working on the first letter "f" and discarding the rest, to give the result "102". 102 is not
true, so the outcome of the if condition is
false.
I think maybe a type enforcement flag that could be optionally set would be alright, but there are many situations where you would want to evaluate a boolean result by comparing text with numbers or other type variants, so I really wouldn't wish to have an error message returned by checking "A" = 1 instead of the result being "false". I
like the fact that Livecode isn't strongly typed. Strong typing is not a substitute for error trapping and data validation.
Re: enforce variable type checking?
Posted: Sun May 15, 2011 6:10 pm
by dunbarx
I am not sure what the actual issue is. The charToNum function compares a single char to its ASCII value. What has this to do with variable type checking?
The original post had both conceptual and a syntactical errors in it. Can the issue be restated? I'll bet there will be no problem at all once we get our semantics straight.
Craig Newman
Re: enforce variable type checking?
Posted: Sun May 15, 2011 6:41 pm
by sp27
Craig,
The issue is that the original poster (me) thought that this line should trigger an error message when the script is compiled:
Code: Select all
if char 2 of field "ABC" is 254 then
-- do something
end if
because comparing a character to an integer is comparing apples and oranges and can only indicate the programmer's error. Values of different types cannot be reasonably compared. A trap for that sort of error makes a language more robust and saves debugging time.
But other posters say that this is because LC is a losely typed language, and that this has its uses, because you can have statements like:
Code: Select all
if ("A" is 1) then
--do somethiong
end if
I think this closes the matter, although I can't think of a sitruation where the above would be useful.
Thanks, everybopdy,
Slava
Re: enforce variable type checking?
Posted: Sun May 15, 2011 7:39 pm
by jacque
Right, LiveCode is a typeless language. You can easily compare strings and integers, for example, because under the hood everything is converted to text. The engine decides what type is inferred by the usage, but as a developer you don't need to worry about it. There is a little trick you can use to force a numeric type if required (add 0 to any number and it becomes either an integer or a float internally, depending) but typing isn't necessary. It's one of the great freedoms of the language, and i's why you don't get any errors with your example.
The engine will see "char 2 of field 'abc'" as a string, as you'd expect. It will also see "254" as a string, and since the two strings are not identical, the comparison returns false.
If, for example, you were to compare words instead, and word 2 was "254", then the engine would return true. If you want to add 5 to word 2, that would work too; the engine would internally convert the string to a numeric type and happily add the values together.
Re: enforce variable type checking?
Posted: Sun May 15, 2011 11:08 pm
by dunbarx
Slava.
Now I see what you had in mind.
I guess, as Jacques said, sort of, it is really a matter of getting used to the language. If you think about it the LC way, it should not only make sense, and seem internally consistent, but also suggest tremendous freedom. You can always restrict yourself in the way you code; it is not so easy to do it the other way around.
Craig Newman
Re: enforce variable type checking?
Posted: Mon May 16, 2011 3:24 am
by mwieder
I'd love to have type-checking *when I want it* but not otherwise. And a compiler switch would do the trick. Meanwhile, as Craig mentioned, it's easy enough to roll your own, even if it's a pain to have to do your own type-checking.
on assert.isNumber pValue
if not pValue is a number then
throw "NaN"
end if
end assert.isNumber
assert.isNumber (char 2 of field "ABC" of this card)
if (char 2 of field "ABC" of this card is 254) then
endif
...however, note that in the aboveyou really should be using charToNum() or the assert will fail most of the time.
put charToNum(char 2 of field "ABC" of this card) into tChar
assert.isNumber tChar
if (tChar is 254) then
endif
Re: enforce variable type checking?
Posted: Fri May 20, 2011 5:21 am
by sp27
As a PS to this discussion, I just discovered that not everything is converted to a string. The error message "menuHistory is not an integer" alerted me to that: my script was trying to assign a value of empty to menuHistory of a button.
Apparently, type checking is not a frivolous pursuit

I was supposed to insert a check, something like "if locChoice is a number then..." Now if LC is such a beautifully typeless language, why didn't it convert empty to 0?
Re: enforce variable type checking?
Posted: Fri May 20, 2011 7:07 am
by jacque
It isn't that everything is converted to a string; it's that everything is a string. The engine then converts to whatever type it needs internally. It's pretty smart about that usually, but menuhistory must have been an oversight. The hilightedlines property does accept either empty or zero, and if you're using math, empty also converts to zero. It's legal to add 3 to empty.
You could bug report it I suppose. I never noticed the anomaly until you mentioned it.
Re: enforce variable type checking?
Posted: Fri May 20, 2011 5:32 pm
by mwieder
Well, I think "menuHistory is not an integer" is a reasonable response to trying to stuff a non-integer value into something that *requires* an integer value. Empty is an interesting special case, and you could well make a case for treating empty the same as zero here. But I like the fact that the engine tries to pinpoint exactly what the problem is - I wish we had a way to hook into this to use it ourselves instead of having to write lots of validation routines. Wouldn't it be simpler to say something like
function cube integer pValue
return pValue * pValue * pValue
end cube
instead of
function cube pValue
if pValue is not a number then
throw "not a number"
end if
if trunc(pValue) is not pValue then
throw "not an integer"
end if
return pValue * pValue * pValue
end cube
Re: enforce variable type checking?
Posted: Fri May 20, 2011 6:23 pm
by dunbarx
Hi.
Though I get your point, LC has always, in its verbose tradition, offered at least a direct path:
function cube integer pValue
if pValue is an integer then return pValue * pValue * pValue
end cube
So high level data typing is sort of part and parcel of the HC/LC paradigm. At both shallow and deep levels, I wouldn't trade that for anything.
Craig
Re: enforce variable type checking?
Posted: Fri May 20, 2011 8:02 pm
by mwieder
I wouldn't either. I wouldn't even *think* that. It would just be more efficient to be able to offload some of the error-checking onto the engine. That's why variable type-checking exists in other languages, not to make you do extra typing. You'll spend less time chasing after runtime bugs if the compiler won't let you insert them in the first place.
But you're right in that you can put your own type-checking in place at a higher level.