MantisBT - opensim
View Issue Details
0008933opensim[REGION] Scripting Enginepublic2021-10-05 17:072021-10-10 04:42
mewtwo0641 
 
normalminoralways
confirmedopen 
 
 
Grid (Multiple Regions per Sim)
ubODE
YEngine
.NET / Windows64
None
0008933: YEngine allows other data types to be used where string is expected
YEngine allows other data types to be used where strings are expected without casting them to string first.

XEngine and SL properly throw a "Type mismatch" error when attempted there

============================================================================

As a side note... Strangely, it also allows this situation:

integer someNumber = 15.3;

Where assigning a float to an integer is allowed but it gets truncated to 15, which is expected, but I was just surprised that it compiled at all.
Supply a data type other than a string to something that expects a string without casting it
// Test Script

SomeFunction(string input)
{
    llSay(0, "This is the result from SomeFunction(): " + input);
}

default
{
    state_entry()
    {
        integer someInteger = 10;
        llSay(0, "This is some integer: " + someInteger);
        
        float someFloat = 15.3;
        llSay(0, "This is some float: " + someFloat);
        
        vector someVector = <1,1,1>;
        llSay(0, "This is some vector: " + someVector);
        
        rotation someRotation = <1,1,1,1>;
        llSay(0, "This is some rotation: " + someRotation);
        
        key someKey = llGenerateKey();
        llSay(0, "This is some key: " + someKey);
        
        //Using expected string input
        SomeFunction("Hello");
        
        //Using unexpected data types
        SomeFunction(someInteger);
                
        SomeFunction(someFloat);
        
        SomeFunction(someVector);
        
        SomeFunction(someRotation);
        
        SomeFunction(someKey);
    }
}
No tags attached.
Issue History
2021-10-05 17:07mewtwo0641New Issue
2021-10-05 17:08mewtwo0641Additional Information Updatedbug_revision_view_page.php?rev_id=9928#r9928
2021-10-05 17:09mewtwo0641Additional Information Updatedbug_revision_view_page.php?rev_id=9929#r9929
2021-10-05 22:53tampaNote Added: 0037989
2021-10-05 23:44mewtwo0641Note Added: 0037990
2021-10-06 01:23tampaStatusnew => confirmed
2021-10-06 01:47tampaNote Added: 0037991
2021-10-07 08:22UbitUmarovNote Added: 0037993
2021-10-08 18:02mewtwo0641Note Added: 0037996
2021-10-08 23:59djphilNote Added: 0037997
2021-10-09 00:08tampaNote Added: 0037998
2021-10-09 02:08mewtwo0641Note Added: 0037999
2021-10-09 02:11mewtwo0641Note Edited: 0037999bug_revision_view_page.php?bugnote_id=37999#r9931
2021-10-09 04:56UbitUmarovNote Added: 0038000
2021-10-10 04:42mewtwo0641Note Added: 0038001

Notes
(0037989)
tampa   
2021-10-05 22:53   
I seem to remembered this wrong that LSL would allow integers, but it does seem like any data type is allowed in YEngine. Could have sworn it threw an error before. One could argue for it being a feature as it does mean less code to write, but of course is not to spec. perhaps this could be a yoption hint hint ;)
(0037990)
mewtwo0641   
2021-10-05 23:44   
@tampa - I did test on SL, it throws "Type mismatch" and refuses to compile... I could see how it may be useful to allow the loose "implicit" casting, but it does have the potential to create headaches if you're porting code to SL or XEngine and may have forgotten to cast your types to string in a few dozen places lol.

An option to toggle the strictness of this might be nice
(0037991)
tampa   
2021-10-06 01:47   
Thought this might be just specifically the talking functions, but anything that is string can be anything and is treated as such. Typecasting exists in YEngine so I assume it just treats everything as the type that it is meant to be regardless of input. From what I can tell the scripts are parsed as strings as well, which would explain why it can just treat parameters this without additional code. Gotta say that's as far as I can read into this given abstract code it is.

Funny, you can even specifically typecast it to something other than string and it still treats it as string. Gotta respect that determination or stubbornness :)
(0037993)
UbitUmarov   
2021-10-07 08:22   
i removed a few excessive implicit or automatic cast Y was doing.
The example script will still work, because i kept the useful casts to string.

but if you change to SomeFunction(integer input)
you will now get errors

- integer i = 1.5 will error now.

but
- i *= 0.5; will still work as does at sl (does not on X)

-All types cast to Boolean (internal) to it so if(val) can work for example.
-All types cast on object (in fact all are objects) - internal use
-All types cast to string. Not as SL but useful.
-All types cast to list. (needed for list ops).

removed casts:
 string no longer auto cast to other types (except above)
 floats no longer auto cast to integer ( except on *= )


note that this will never be exactly as SL
One should never trust on a language implicit cast (or evaluation order)
 where it does matter we should add explicit casting (and well defined order).
(0037996)
mewtwo0641   
2021-10-08 18:02   
@Ubit - Gave master a try with those changes and discovered that a lot of the scripts on my grid are broken due to forgotten casts, which is admittedly easy to forget when the compiler doesn't tell you about them ;)

I was able to fix some of the scripts, but I am wondering if the potential for broken scripts for many other people is worth any benefit these changes introduce since not every one is a scripter/programmer, and would know how to fix their broken scripts, or worse, might not have access to the scripts because of permissions.

With that in mind, perhaps it might be better to revert the changes and go back to the old behavior to avoid a potential broken content catastrophe.

Worse comes to worse, one could always "check their work" on SL to catch anything they might have missed, which is what I sometimes do when I want to make sure my scripts are as compatible across platforms as possible.
(0037997)
djphil   
2021-10-08 23:59   
@mewtwo0641 : What is catastrophic is the way people write the scripts ...
Please don't revert 8933, a script engine more strict is better.
(0037998)
tampa   
2021-10-09 00:08   
The aim is always to get as close to LSL spec as possible in order to make it easier to write scripts in accordance with the guidelines outlined for it. XEngine is strict with strings in its functions, which ultimately forces consideration of types when writing code, which is always a good thing as type mismatch can lead to unwanted results down to even runaway scripts.

It's mesh all over again. In a sense YEngine all over again as well, writing proper scripts nothing broke switching to that, yet I heard a lot of complaints from others that ended up writing up all sorts of mess that XEngine allowed. When it comes down to it, it outweighs what effort one might have to do to add a few casts. :)
(0037999)
mewtwo0641   
2021-10-09 02:08   
(edited on: 2021-10-09 02:11)
@djphil - I can agree to that... I've seen people make so much of a mess out of the scripts they wrote that I kind of just want to hide in a dark corner and forget it exists. But as I mentioned in my previous note, it's very easy for one to forget to cast when the compiler doesn't tell them about it; especially when typing out a lot of tedious code (such as logging) and perhaps they are tired, distracted, or some other reason. It's happened to me plenty of times lol.

@tampa - If we are aiming to be close to LSL spec to the possible detriment of existing content... Then I think that we should go further with the strictness of YEngine. The changes made recently on master only apply when passing values to a custom function, such as MyFunction(integer num), but not when working inline i.e.

default
{
    state_entry()
    {
        //This still compiles and works even though there is no cast to string
        integer num = 5;
        llSay(0, "This is my number: " + num);
    }
}

Ubit mentioned that he wanted to preserve the implicit casting to string outside of passing to a function for the convenience. I have no issue with this personally, but I do think that we should either go one direction or the other; either always allow the implicit cast, or never allow the implicit cast. I just think that it serves to cause confusion and headache to scripters if there's a mix of where it's allowed and where it isn't allowed, which is why I suggested reverting the changes, along with the reasonings that not every one would know how to fix their broken scripts, or not having access to fix the scripts due to no mod permissions.

(0038000)
UbitUmarov   
2021-10-09 04:56   
any thing has auto cast to string not just llSay.. (would be harder and pointless to filter just those). This can hide errors/typos, but imo less severe than other cases.

basically i only did remove the reverse, ie string to other types and float to integer with the exception of the *= case that for some reason is also done at sl.
this are two cases than can easy lead to hard to spot bugs, and that is the reason why not go all the way into auto casts. C# as similar rules to the ones we are having now.
from c# doc:
"
For built-in numeric types, an implicit conversion can be made when the value to be stored can fit into the variable without being truncated or rounded off...
"

SomeFunction("Hello"); above was doing things no matter the argument type of SomeFunction.
auto cast from float to integer can mean loss of data with the loss of the fractional parts.
(0038001)
mewtwo0641   
2021-10-10 04:42   
@Ubit - Ah okay that makes sense, hard to spot bugs and unintentional truncation of data is never a good thing.

Should we pause here and monitor for any possible issues related to the recent changes that may pop up, or close this mantis?