Jump to content

BSL:Manual: Difference between revisions

885 bytes added ,  6 December 2015
→‎Functions: moving Concurrency section down since it is more advanced, and adding Looping section (I hope the part about "sleep" is correct)
(→‎Loop: wording; mentioning "fork" (duh))
(→‎Functions: moving Concurrency section down since it is more advanced, and adding Looping section (I hope the part about "sleep" is correct))
Line 423: Line 423:
  some_function(num_heroes, enemy);
  some_function(num_heroes, enemy);


====Concurrency====
===Recursive calling===
A function can call itself, which is useful for various looping behavior, but a function can only call itself recursively up to about four times. Note that this limit is bypassed if you use "[[#Fork|fork]]" to call a function from within itself, but this no longer counts as recursing because the logic will not complete in a predictable inside-to-outside order. For a non-recursive way to loop a function, see [[#Looping|Looping]].
 
===Returning===
As mentioned under [[#Flow interrupt|Flow interrupt]], "return" exits the function at that point. Because of the bug documented in that section, you cannot exit early from a function under some condition. Since "return" can thus only be placed at the end of a function, there is no point in using it at all unless you are going to pass back a value by placing a variable name after "return":
 
func int add_ten(int input)
{
    var int the_result = input + 10;
    return the_result;
}
 
You would then use this function to set a variable, as follows:
 
some_number = add_ten(enemy_count);
 
Function return values can also be used in "if" statements to provide a true/false condition:
 
func bool is_it_safe(void)
{
    var bool result = false;
    # do some investigation here and set result to true if it is safe
    return result;
}
 
if (is_it_safe())
    dprint("It is safe.");
else
    dprint("It is not safe.");
 
===Looping===
The following function creates a loop using "[[#Fork|fork]]".
 
var int counter;
func void increment_counter_to(int limit)
{
    counter = 0;
    fork increment(limit);
}
func void increment(int limit)
{
    counter = counter + 1;
    if (counter < limit)
      fork increment(limit);
}
 
Note that calling the same function again before it finishes running the first time can have undesired effects. Using "sleep" before each call can prevent this overlapping execution. A short function like the example above should not need a "sleep" statement, as the remainder of the function after the "fork" call will complete in the same tick. But the more complex the function, the more ticks you will need to allow for it to complete, placing "sleep(1);", "sleep(3);", etc. before the "fork" call.
 
===Concurrency===
When you call a function, all the code inside that function will finish running before giving control back to the calling function; that is, unless you use one of the following keyword sets to run parallel "threads" of BSL at the same time. Unlike robust programming languages, there is very little control over BSL's version of "multi-threading", so see the caveats at the end of the "fork" section.
When you call a function, all the code inside that function will finish running before giving control back to the calling function; that is, unless you use one of the following keyword sets to run parallel "threads" of BSL at the same time. Unlike robust programming languages, there is very little control over BSL's version of "multi-threading", so see the caveats at the end of the "fork" section.


Line 469: Line 519:


  schedule dprint("Is this annoying yet?") repeat 50 every 20;
  schedule dprint("Is this annoying yet?") repeat 50 every 20;
===Recursive calling===
A function can call itself, which is useful for various looping behavior, but a function can only call itself recursively up to about four times. Note that this limit is bypassed if you use "[[#Fork|fork]]" to call a function from within itself, but this no longer counts as recursing because the logic will not complete in a predictable inside-to-outside order.
===Returning===
As mentioned under [[#Flow interrupt|Flow interrupt]], "return" exits the function at that point. Because of the bug documented in that section, you cannot exit early from a function under some condition. Since "return" can thus only be placed at the end of a function, there is no point in using it at all unless you are going to pass back a value by placing a variable name after "return":
func int add_ten(int input)
{
    var int the_result = input + 10;
    return the_result;
}
You would then use this function to set a variable, as follows:
some_number = add_ten(enemy_count);
Function return values can also be used in "if" statements to provide a true/false condition:
func bool is_it_safe(void)
{
    var bool result = false;
    # do some investigation here and set result to true if it is safe
    return result;
}
if (is_it_safe())
    dprint("It is safe.");
else
    dprint("It is not safe.");


==Variables==
==Variables==