Updated Functions and methods (markdown)
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user