Difference between revisions of "Talk:State"

From Second Life Wiki
Jump to navigation Jump to search
Line 85: Line 85:


The reason they wanted to kill this "feature" was because in LSO it has the potential to leak memory. The stack in LSO is untyped, so even though it might be able to pop the items off the stack safely it can't know if they are primitives or pointers into the heap. To make matters worse, globals live at the front of the stack and are allocated normally in the heap. I don't know how they solved the problem in LSO. Since the stack in Mono is typed, Mono does not have this problem. -- '''[[User:Strife_Onizuka|Strife]]''' <sup><small>([[User talk:Strife_Onizuka|talk]]|[[Special:Contributions/Strife_Onizuka|contribs]])</small></sup> 23:41, 23 February 2013 (PST)
The reason they wanted to kill this "feature" was because in LSO it has the potential to leak memory. The stack in LSO is untyped, so even though it might be able to pop the items off the stack safely it can't know if they are primitives or pointers into the heap. To make matters worse, globals live at the front of the stack and are allocated normally in the heap. I don't know how they solved the problem in LSO. Since the stack in Mono is typed, Mono does not have this problem. -- '''[[User:Strife_Onizuka|Strife]]''' <sup><small>([[User talk:Strife_Onizuka|talk]]|[[Special:Contributions/Strife_Onizuka|contribs]])</small></sup> 23:41, 23 February 2013 (PST)
::Strife, if you're saying that Mono doesn't have a potential problem with this, can't the Wiki at least say it's fine to do this trick under Mono? (The 'trick' purely being a way of bypassing the compiler's attempt to protect LSO.) [[User:Omei Qunhua|Omei Qunhua]] 00:38, 25 February 2013 (PST)

Revision as of 01:38, 25 February 2013

Constant vs Explicit values?

I've noticed an ongoing style difference in recent edits, namely in the preference between named constants versus explicit values... as can be seen from difference in edits for this entry (namely 0 or PUBLIC_CHANNEL). I have no preference either way, and can see merits for both (the named constant is more informative to new users [tells what it does], the explicit value more informative to experienced users [tells what it is])... AFAIK neither compiler actually cares one way or the other so there appears not to be any side effects. should we settle on a preference?
-- Void (talk|contribs) 08:35, 27 December 2012 (PST)

My feeling was that new users are initially introduced to llSay(0, ... as that is what they are presented with from the very start with 2 occurrences in the default "new script". Using PUBLIC_CHANNEL in Wiki examples immediately adds a layer of confusion. Adding an explanatory comment each time seems like an admission that we've confused them, especially a comment that says "PUBLIC_CHANNEL has the integer value 0" ... as that is demonstrating the need to explain PUBLIC_CHANNEL rather than explaining '0' --- it's akin to a child being told "I think you'll find it easier to call me FEMALE PARENTAL HUMAN rather than Mum as that explains my role better" ... whereas Mum is what the child grew up with. SL scripters all 'grow up' with '0' as the open chat channel. I am strongly in favour of 99.9% of mnemonic constants, but 0 for channel 0 seems like a special case. For example CHANGED_OWNER is eminently more sensible than trying to remember the value 128. While we're at it, I do detest (float)FALSE and (float)TRUE ... if you really want to use TRUE and FALSE for the extremes of Alpha, then let the compiler auto-cast it for you e.g. llSetAlpha(FALSE, ALL_SIDES) but llSetAlpha(0.0, ALL_SIDES) says it much better for me and has the right flavour, as it's one value on a sliding scale. Omei Qunhua 14:31, 27 December 2012 (PST)

I'm not sure that adherence to the format of the default 'new script' does inexperienced users any favors... The default script simply a holdover from the early days of LSL, during which the only thing less friendly to inexperienced users than the language was the documentation for it =D Corey was, to put it mildly, a minimalist. There've actually been a few campaigns to get LL to replace the default (to no avail, may be buried in some fixed length record no one wants to dig up/mess with). There is no implicit understanding of what '0' means or does, or even why it's there, and the inexperienced simply repeat it cargo-cult style because it doesn't work if they omit it. it's more akin to a child calling every woman, or every parent "Mum" not knowing the relationship is specific. As for using TRUE|FALSE with things like alpha, I agree, it's generally horrible practice. As you pointed out, it's a percentage of opacity. I can't agree on relying on the compiler to autocast variables (actually it inserts a cast instruction, unless it's done in globals. even on key declarations) since there isn't a lot of consistency in what the compiler will and won't cast. it might be prettier to look at but that cast is still there whether it's documented or not, so if one must use that (admittedly horrible) structure, being explicit eliminates future subtle errors. Having that explicit cast there should serve as a warning sign

ETA: I don't usually write for inexperienced users, instead using comments for their benefit (I don't think I've ever used PUBLIC_CHANNEL myself). but that's just my natural mode, and I'm willing to work under consensus
-- Void (talk|contribs) 16:05, 27 January 2013 (PST)

I do not like PUBLIC_CHANNEL for the reason that it creates this exact problem. We aren't sure if we should use it or not. We aren't sure which is better. It's existence instead of fixing a problem created one. This is like an argument over which is better: Celsius or Fahrenheit. I don't know if we should use it in the documentation. I don't really care either way. -- Strife (talk|contribs) 21:45, 27 January 2013 (PST)

One advantage of allowing the compiler to cast an integer to a float in things like llSetTimerEvent(0), llSetAlpha(1), is that it saves bytecode space, bizarrely. Omei Qunhua 03:39, 15 February 2013 (PST)

Huh? unless something has changed drastically the compiler doesn't convert those numbers, it just inserts the cast instruction, just as if it'd been explicitly declared. It does something similar with negative numbers inserting a negation instruction instead of an actual negative number. Presumably this is for safety. Mind you that's LSO behavior, It's rather hard to pin down MONO behavior, since it's memory is assinged in blocks for functions, and can report different memory values for successive saves of event code (there seems to be some JIT insertions on run)
-- Void (talk|contribs) 08:12, 15 February 2013 (PST)
Void, I think you're not considering the full scenario. Tests just done under Mono suggest that llSetTimerEvent(0) is 3 bytes shorter than llSetTimerEvent(0.0). I suspect the reason is the excess bytecode space involved in declaring a float value of 0.0 rather than an integer of 0, which presumably is more than the inserted cast instruction. And yes, I am allowing for the 512 byte blocks of Mono allocation, by simply comparing the code size of two scripts, one containing 1024 copies of llSetTimerEvent(0) and the other containing 1024 copies of llSetTimerEvent(0.0); Omei Qunhua 13:47, 15 February 2013 (PST)
If memory serves me there is a special CIL instruction for 8bit integer constants (which get expanded to 32 by the vm). If they used that it might account for the savings. -- Strife (talk|contribs) 22:26, 16 February 2013 (PST)
That doesn't seem to be it, Strife. llSetText(message, <123456, 123456, 123456>, 123456) comes out the same size as llSetText(message, <1, 1, 1>, 1) Omei Qunhua 04:39, 17 February 2013 (PST)
Indeed. Integer constants take 6 bytes; float constants take 10 bytes; a cast from integer to float takes 1 byte. --Pedro Oval 20:38, 18 February 2013 (PST)

Change States with an if in a user function

Despite the comment in the main article that this trick no longer works, this script is working for me perfectly well, on Second Life Server 13.02.08.270166

<lsl>

ChangeStates() {

   if(1==1) {
        state other;
       }

}

ChangeBack() {

   if (1==1){
       llOwnerSay("Changing back");
       state default;
   }

} default {

   state_entry()
   {
      llOwnerSay("state default");
   }
   touch_end(integer total_number)
   {
     ChangeStates();
   }
   

}

state other{

    state_entry()
   {
      llOwnerSay("now in state other");
      ChangeBack();
   } 
   
   
   

} </lsl>

Innula Zenovka 09:25, 23 February 2013 (PST)

Yes, working for me too on same server Omei Qunhua 14:51, 23 February 2013 (PST)
Since a Linden made that edit, this would be a good question to bring to the server user group. If there's an error message in the compiler for this, then it's not really supposed to work. Docs should at least have a use at your own risk warning, unless a Linden can bless it as a supported construct. --ObviousAltIsObvious Resident 18:06, 23 February 2013 (PST)
It compiles without error, at least for me, just as it always used to. The server user group isn't at a very good time for me in the UK, but if anyone else would like to raise the matter, I would be most grateful.
I agree any reference to it should probably come with some sort of warning, but -- at least at present -- the caveat User-defined (global) functions cannot change a script's state. The compiler will throw the error 'ERROR: Global functions can't change state'. Note: Previously, global functions could change state in the body of a simple 'if' statement; this "workaround" no longer works. is demonstrably incorrect, in that the "workaround" does work and doesn't throw any sort of error message either when the script is compiled or when it runs. Innula Zenovka 19:48, 23 February 2013 (PST)
If you remove the if(){} parts, then the compiler does still stop with ÉRROR : Global functions can't change state, so a case that doesn't throw this error is still demonstrably a bug, and not behavior to rely on. Treat it like invisiprims or PosJump. --ObviousAltIsObvious Resident 20:05, 23 February 2013 (PST)
I agree it's not behaviour to rely on. I am simply suggesting that it would better to have a caveat that says, correctly, "this works, but don't rely on it," rather than one that incorrectly says, "this doesn't work at all" when clearly it does. This came up in a group yesterday, when someone asked about this. I said that I thought I'd seen in the wiki that this trick with "if" didn't work any more, and someone correctly said, "but it does still work, if you test it, so the wiki is wrong" Innula Zenovka 06:49, 24 February 2013 (PST)

The reason they wanted to kill this "feature" was because in LSO it has the potential to leak memory. The stack in LSO is untyped, so even though it might be able to pop the items off the stack safely it can't know if they are primitives or pointers into the heap. To make matters worse, globals live at the front of the stack and are allocated normally in the heap. I don't know how they solved the problem in LSO. Since the stack in Mono is typed, Mono does not have this problem. -- Strife (talk|contribs) 23:41, 23 February 2013 (PST)

Strife, if you're saying that Mono doesn't have a potential problem with this, can't the Wiki at least say it's fine to do this trick under Mono? (The 'trick' purely being a way of bypassing the compiler's attempt to protect LSO.) Omei Qunhua 00:38, 25 February 2013 (PST)