Functions are declared with a variable name followed by the takes keyword (alias wants) and a list of arguments separated by one of the following: and , & , and 'n'

Sum takes x and y
Give back x with y

Print sum taking 3, 4 (prints: 7)
Print sum taking "hello", "world" (prints: helloworld)

Success takes blood, sweat & rhythm'n'blues
Say blood with sweat, rhythm & blues, baby

Success taking 1, 2, 3 & 4 (prints: 10)
Success taking "r", "o", "c", "k" (prints: rock)

Functions can be one-liners, usually written with the giving keyword:

Sum takes x, y giving x with y
Reverse takes a string giving a string times -1

Print sum taking 18, 24 (prints: 42)
Print reverse taking "rockstar" (prints: ratskcor)

Function bodies can also be a block. Functions in Rockstar specified by the return keyword and its aliases giving, give, give back and send. A return statement can be followed by the keyword back (which has no effect but can make code more lyrical).

Polly wants a cracker
Cheese is so delicious
Put a cracker with cheese into your mouth
Give it back

Say Polly taking 5 (prints: 14)

Functions are called using the ‘taking’ keyword and must have at least one argument. Multiple arguments are separated with one of the following: , & , and 'n'.

Function arguments must be primary expressions:

Sum takes X and Y giving X with Y
Product takes X and Y giving X times Y

Shout sum taking product taking 2, 15, product taking 3, 4 (prints: 42)
Shout sum taking 600 & product taking sum taking 2, 4, sum taking 5, 6 (prints: 666)

Swap takes X and Y giving Y with X
Bolt takes X and Y giving X with "⚡" & Y

Shout bolt taking swap taking "C", "A", swap taking "C", "D" (prints: AC⚡DC)

The reason you can’t use operators inside function arguments is that it makes it awkward to write recursive function calls. Consider this expression

```rockstar Fibonacci takes a number If it’s less than 2 give it back Let the first be a number without 2 Let the second be a number without 1 Give back Fibonacci taking the first plus Fibonacci taking the second End

Print Fibonacci taking 0 (prints: 0) Print Fibonacci taking 1 (prints: 1) Print Fibonacci taking 5 (prints: 5) Print Fibonacci taking 8 (prints: 21) Print Fibonacci taking 20 (prints: 6765)

Fibonacci takes a number If a number is result = foo taking 1 + foo taking 2

...is that `foo(1 + foo(2)`, or `foo(1 + foo(2))`? Without using parentheses to surround function arguments, the parser 

```

This is one of the few features where the language grammar is ambiguous, and what’s produced by the parser doesn’t necessarily match what’s executed by the interpreter. The parser is greedy and it doesn’t know anything about how many arguments a function takes (its arity), so this expression:

 FuncA taking FuncB taking 1, 2, FuncB taking 3, 4

will produce this parse tree:

call: FuncA
  args:
  1: call: FuncB:
     args:
     1: number: 1
     2: number: 2
     3: call: FuncB
        args:
        1: number: 3
        2: number: 4

That’s actually wrong, because it’ll try to invoke FuncB with three arguments - so rather than failing, the Rockstar interpreter only evaluates as many function arguments as the function is expecting, and any “leftover” expressions will be passed back to the outer function call, so what actually gets executed is:

call: FuncA
  args:
  1: call: FuncB:
     args:
     1: number: 1
     2: number: 2
  2: call: FuncB    }
     args:          } FuncB only expects two arguments, so 
     1: number: 3   } the interpreter passes this one to the 
     2: number: 4   } outermost function instead.

Functions can contain other functions, and because every function defines its own variable scope, nested functions can have the same names as the functions which enclose them. (I have no idea why you would ever want to do this, but making it impossible would have been really difficult.)

 Johnny takes a ride
Johnny takes a ride
Johnny takes a ride
Give back "Glauten " with a ride, yeah!
Give back "Glieben " with Johnny taking a ride, yeah!	
Give back "Gunter " with Johnny taking a ride, yeah!

Say Johnny taking "Globen"

To declare a function with no arguments, specify it takes null (or aliases nothing, nowhere, nobody). To call a function with no arguments, use the call keyword, or suffix the function name with an exclamation mark:

 Tommy takes nothing
Gina says we got to hold on 
Write it, baby

Call Tommy!
Call Tommy!
Call Tommy

(writes: we got to hold on we got to hold on we got to hold on )

Variables, Closures and Function Scope

Rockstar uses the same scoping mechanism as JavaScript:

  • Variables are global unless you declare them with let
  • Global variables aren’t really global unless they’re declared at the top level of your program.

In this example, calling My function initialises two variables:

 The function takes x, y
Put x into the global (create a new global variable)
Let my local be y (create a new local variable)
Print x with " " with y
End

Call the function with "a", "b" (prints: a b)
Shout the global (prints: a)
Shout my local (prints: mysterious)


You can declare variables inside functions, functions can contain other functions, and declaring a function inside another function creates a closure, which captures the state of any variables that existed when the function was declared.