Updated Functions and methods (markdown)

Bartłomiej Przemysław Pluta
2020-04-01 21:12:22 +02:00
parent 71fbb3a5ac
commit fbc5cea463

@@ -14,7 +14,7 @@ As you can see on below examples implemented functions and methods mechanism
is really similar to other popular languages, like Java or Python.
Examples:
```
```php
# Invoking function 'println' without any arguments
println();
@@ -41,7 +41,7 @@ println(newNote1 == newNote2); # true
Note, that some functions or methods don't return anything.
In this case expecting any returned value can throw an exception.
```
```php
# 'println' is example function, that doesn't return anything
# in this case following instruction will raise an error
println(println()); # error
@@ -68,7 +68,7 @@ they cannot be nested in any blocks.
### Function definition
Functions can be defined with `function` keyword, like it is shown on following example:
```
```php
function multipleBy2(number) {
return 2*number;
}
@@ -90,7 +90,7 @@ Example above takes one arbitrary argument, multiplies it by 2 and then returns
Because arbitrary argument can be passed, the `multipleBy2` function can throw an error
in case of trying to multiple e.g. note or string, that don't support `*` operator.
In this case you can put a constraint to the argument which accepts only chosen types (using Pascal/Kotlin-like syntax):
```
```php
function multipleBy2(number: int) {
return 2*number;
}
@@ -108,7 +108,7 @@ Function `multipleBy2` will work only with int argument now. Any attempt to invo
with no-int values will cause Invocation Error related to mismatched signatures.
Of course, you are still able to create functions without any arguments or mix their types:
```
```php
function noArgs() {
println("Hello, I don't accept any arguments.");
println("Also see that I don't return anything!");
@@ -141,7 +141,7 @@ SMNP language allows you also to declare more than one argument that functions c
Accepted types can be declared using _union construction_ which consists of types separated with commas (`,`) and bounded on both sides with `<` and `>` characters.
Example:
```
```php
function foo(x: <string, bool, int, float>, y: note, z) {
# 'x' can be either string, bool, int or float
# whereas 'y' can be only a note
@@ -165,7 +165,7 @@ SMNP language allows you to specify what objects can be contained in lists.
It can be done with construction similar to _union construction_.
Accepted types are separated with commas (`,`), bounded on both sides with `<` and `>` characters and placed
next to `list` keyword:
```
```php
function foo(x: list<int>) {
# 'x' can be only list of ints
}
@@ -182,7 +182,7 @@ foo([ 1, 2, @c ]);
```
You are still able to use multiple type as constraints:
```
```php
function foo(x: list<int, note>) {
# 'x' can be only list of ints and notes, nothing else
}
@@ -201,7 +201,7 @@ foo({ @c -> 1 });
List specifier can be empty or even be absent. In this case list can contain
any available types:
```
```php
function foo(x: list<>) {
# 'x' can be only a list containing arbitrary objects
}
@@ -224,7 +224,7 @@ foo(true);
```
Specifiers can be nested - you are able to create e.g. list of lists of lists of ints etc.
```
```php
function foo(x: list<list<list<int>>>) {
}
@@ -236,7 +236,7 @@ foo([[[1, 2], [3, 4]], [[5, 6], [7, 8]], 9]);
```
Of course ambiguous arguments can include specified lists:
```
```php
function foo(x: <int, note, list<int, note>) {
# 'x' can be int, note or list containing only ints and notes
}
@@ -258,7 +258,7 @@ Maps can be also specified. All rules related to specified lists are also applic
The only difference is map supports **2** specifiers: first one for keys and second one for values.
Example:
```
```php
function foo(x: map<string><note>) {
# 'x' can be only a map with strings as keys and notes as values
}
@@ -295,7 +295,7 @@ totally optional to pass during invocation. Syntax of optional arguments is simi
to variable assignment syntax.
Example:
```
```php
function foo(x = 10) {
# 'x' can be of any available type.
# You can override default value but you don't have to.
@@ -311,7 +311,7 @@ y = foo(true); # y = true
```
All kinds of arguments mentioned so far can be optional:
```
```php
function foo(x = 1, y: int = 14, z: <note, list<list<int, note>> = [[1, @c], [@d]]) {
}
@@ -334,7 +334,7 @@ foo(0, 0, [], 3);
As you can see, you can have as many optional arguments as you want.
Just remember, that after first declared optional argument you can't use regular
arguments in the same signature anymore.
```
```php
# Correct signatures
function foo(a, b, c = 0) {}
function bar(a, b = "hello", c = true) {}
@@ -362,7 +362,7 @@ After invocation, all matched arguments are collected into one list which is pas
as vararg.
Example:
```
```php
function foo(a, b, ...c) {
# 'c' is a list of arguments passed after 'a' and 'b'
@@ -381,7 +381,7 @@ foo(true);
Same as optional arguments, vararg can work with any previously mentioned kinds
of arguments (except optional arguments of course).
```
```php
function foo(a, b: note, ...c: map<string><list<int, note>>) {
# after two arguments you can pass any number of
# maps with strings as keys and list of ints and notes as values
@@ -406,7 +406,7 @@ SMNP language introduces `extend` statement which allows you to add custom
methods to existing types. All you need is to precise desired type and define function
which will be working as new method. In the body of declared method, the extending object is available through `this` special identifier.
Following listing presents a syntax of `extend` statement:
```
```php
extend int with function multipleBy(x: int) {
return this*x;
}
@@ -422,7 +422,7 @@ is no need to cover `function multipleBy(...) {...}` statement again.
Note, that type being extended must be declared only as a simple data type or map/list with optional
Examples:
```
```php
# Correct
extend int with function a() {}
extend list with function b() {}
@@ -441,7 +441,7 @@ extend int with function k() {}
Because extending statement supports list/map specifiers, you can define
methods that are applicable only for list/map with specified content:
```
```php
# Extends all lists, no matter of content
extend list with function foo() {
println("foo()");
@@ -468,7 +468,7 @@ l3.bar(); # error!
Because SMNP doesn't allow you to extend multiple types in one instruction, if you want
extend for example `list<int>` and `list<note>` (but not `list<int, note>`) you have
to do it separately:
```
```php
# This won't work at all
extend <list<int>, list<note>> as l with function foo() {
# ...
@@ -488,7 +488,7 @@ extend list<note> as l with function foo() {
In case of extending type with more than one function you can use block of methods.
Example:
```
```php
extend int {
function multipleBy2() {
return 2*this;
@@ -519,7 +519,7 @@ to declare multiple functions and methods applicable to the same objects as long
Note, that potential signatures' collision is evaluated only at runtime, when method is being called.
Example:
```
```php
function display(x: int) {
println("int: ", x);
}
@@ -533,7 +533,7 @@ display(14.0); # float: 14.0
```
However:
```
```php
function display(x) {
println("any: ", x);
}
@@ -546,7 +546,7 @@ display(14); # any: 14
display(14.0); # error!
```
The code will end with following error:
```
```php
Function invocation error
Source: /.../.../scratchpad.mus
Position: line 16, column 1