# Function definition

## Basic definition

With functions is lot of fun. Their definition starts with keyword `fun` followed by its name and arguments list in parenthesis. Then follows function body enclosed in braces which contains function statements. There are two valid function statements. First is constant definition, second is return expression which should be last statement and it is `return` keyword followed by return expression.

#### Input

 123456789101112 // function definition example 01fun one() { return 1;}let x = one(); fun twoTimes(x) { return x * 2;}let y = twoTimes(4); process Constants with ConstantDumper;

#### Output

```x = 1;
y = 8;```

Local constant definition.

#### Input

 123456789 // function definition example 02fun pythagoras(a, b) { let a2 = a*a; let b2 = b*b; return sqrt(a2 + b2);}let x = pythagoras(3, 4); process Constants with ConstantDumper;

#### Output

`x = 5;`

Function's parameters can have their default values.

#### Input

 1234567891011121314 // function definition example 03fun add(a, b = 0) { return a + b;}let w = add(1, 2);let x = add(5); fun power(x = sqrt(2)) { return x * x;}let y = power(4);let z = power(); process Constants with ConstantDumper;

#### Output

```w = 3;
x = 5;
y = 16;
z = 2;```

## Global and local scope

Function can be defined on both local or global scopes and they behave in the same way like constants (local definitions overlays global).

#### Input

 1234567891011121314151617 // function definition example 04fun alpha() { return 1;}fun beta() { return -1;}lsystem Lsystem1 { fun beta() { return 7; } set symbols axiom = A(alpha()) B(beta());}lsystem Lsystem2 { set symbols axiom = C(alpha()) D(beta());}process all with SymbolPrinter;

#### Output

1. `A(1) B(7)`
2. `C(1) D(-1)`

## Parameters overlays constants

Parameters have greater precedence than any constants. Local constants overlays parameters.

#### Input

 1234567891011121314 // function definition example 05let x = 7;fun alpha(x) { return x;}let a = alpha(0); fun beta(x) { let x = 1; return x;}let b = beta(0); process Constants with ConstantDumper;

#### Output

```a = 0;
b = 1;
x = 7;```

## Inheritance of functions

Inheritance of functions works as expected. Functions from derived L-systems are defined and new functions can redefine them.

#### Input

 12345678910111213141516 // function definition example 06abstract lsystem Base { fun a() { return 1; } fun b() { return 2; }}lsystem Derived extends Base { fun a() { return 3; } set symbols axiom = A(a()) B(b());}process all with SymbolPrinter;

#### Output

`A(3) B(2)`

## Formal grammar

Defines function with name represented by `ID`, parameters `params_list`, local constants `constant_def` and return value `expression`.

 12 function_def = 'fun' ID '(' params_list? ')' '{' constant_def* 'return' expression ';' '}'params_list = ID ('=' expression)? (',' params_list)?