Search Unity

recursive calling

Discussion in 'Scripting' started by MrDude, Oct 26, 2007.

  1. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    hi again

    After the help I got yesterday I managed to get quite far with my coding and now I have finished my 475 lines of code and am ready to start testing it... except for this one single error message that pops up 4 times for two lines of code... help?

    I declared a method as so:
    Code (csharp):
    1.  
    2. function speak(id : int)
    3. {
    4. ...
    5. }
    6.  
    Inside this function I have a section that tests if this dialogue can be displayed or wether it should simply end or wether it should skip to another part of the dialogue.

    If I then determine that the dialogue should skip to a new part of the dialogue, I simply call the function again with a different line ID and end the function there. Because of the error I get here, I have done this in two ways and I still get the error. Here is what I do:

    Code (csharp):
    1.  
    2.                 tempKey = currentLine.requirements[x];
    3.                 switch(tempKey.kind)
    4.                 {
    5.                     case "+":
    6.                         if (gameKeysInUse.doesNotHave(tempKey.name, tempKey.value))
    7.                         {
    8.                             var nextLine : int = tempKey.redir;
    9.                             speak(nextLine);
    10.                             return false;
    11.                         }
    12.                    
    13.                     case "-":
    14.                         if (gameKeysInUse.doesHave(tempKey.name, tempKey.value))
    15.                         {
    16.                             speak(tempKey.redir);
    17.                             return false;
    18.                         }
    19.                 }
    20.  
    (I just noticed I am doing a switch on a char... Oops. Need to change that...!!!)

    Anyways, the tempKey.redir is explicitly defined as an int and as you can see, nextLine is also explicitly declared as an int. Yet, these two lines of code give me the following four errors: (Well, 1 error 4 times)

    I have only two questions:
    1. Why?
    2. What do I do?

    Any takers?
     
  2. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    Okay, this is wierd...

    For the sake of future proofing my code I exit my functions using return true or return false statements even if I don't require a value to be returned.

    As is the case with this function, I do not need the return value and as such never make use of it. However, looking at the error above, I managed to solve the problem by doing this:

    Code (csharp):
    1.     function speak(id : int) : int
    2.     {
    3. ...
    4. }
    5.  
    I then got an error that I cannot return boolean values since I now declared a return type for the function. Fine. I then changed the return true and return false to return 0 and return 1 and now I have no more errors... Funny that...

    I make no use of the returned value and yet, because I do not specify a return type I cannot do a recursive call...

    Weird!!!

    Any info on this?
     
  3. Bampf

    Bampf

    Joined:
    Oct 21, 2005
    Posts:
    369
    I'm guessing, but...

    In order to generate the code that calls Speak(), JS needs to know everything about the function, including how much space to reserve on the stack for the return value. It is willing to infer the return type based on how the function is used, but in this case it didn't know because you aren't using the return value.

    It could have been a little smarter if it had looked ahead to the next line in the file. It would have seen that since you were returning TRUE or FALSE, that it should infer a boolean return type. In a non-recursive example I'm sure it would have done that. But here I am guessing that Javascript saw that it had a recursive dependency and gave up immediately. It's not entirely unreasonable behavior- in the general case you might have a recursive chain involving 5 functions calling each other rather than just one calling itself. The simple solution is to give up as soon as a loop is detected, and ask the programmer to declare one of the functions, rather than look ahead on the off-chance that there is still a way to figure out what was meant.

    I don't think the details are very important. The gist of the error was, "I don't know the type", and all you had to do was declare it more specifically when it asked, which you soon figured out on your own.

    Professional programmers working on large scale projects usually learn to explicitly define types whenever they can. It allows the compiler to catch errors, which is much cheaper than trying to catch them in testing. Top of my head example: in Visual Basic you can mix booleans and ints together. But the boolean True is the integer value -1, so it is possible to make a mistake by accidentally performing a mathematical instead of a logical operation. Or, you might compare a "true" value that's simply non-zero (like 1) to the literal value True (-1), and they aren't equal. Hijinks ensue.

    In short, typechecking is your friend. Decide up front what type the function will return, if it's a boolean say so.

    Taken to its extreme one might end up declaring specific types for all functions and variables... And in fact, I do that. And since Javascript doesn't force me to do that, I do all my Unity programing in C#. After years of programming I find that my brain just wants to know the types of everything. It does take longer to get code to start running, but you get fewer errors at runtime, so you often save time in the end. Not saying that you should switch to C#, just pointing out some of the pros and cons of explicitly declaring things, even in Javascript.
     
  4. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    thanks for that bit of info.

    I have been using JavaScript for ages now but never knew it could even do typed returns. I just happened to see something that looked like a typecast in c# code for Unity and figured I'd try it and it worked. Bonus...

    Yeah, the thing about teaching yourself languages is that you pick up stuff now and then that make you go: "Ohh... ahh!"

    Am I right in understanding that JavaScript being typeless that JavaScript does not support typecasting functions, only Unity's JavaScript?

    If so: "Kudos to you OTEE!!!"