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.
|
is really similar to other popular languages, like Java or Python.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
```
|
```php
|
||||||
# Invoking function 'println' without any arguments
|
# Invoking function 'println' without any arguments
|
||||||
println();
|
println();
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ println(newNote1 == newNote2); # true
|
|||||||
|
|
||||||
Note, that some functions or methods don't return anything.
|
Note, that some functions or methods don't return anything.
|
||||||
In this case expecting any returned value can throw an exception.
|
In this case expecting any returned value can throw an exception.
|
||||||
```
|
```php
|
||||||
# 'println' is example function, that doesn't return anything
|
# 'println' is example function, that doesn't return anything
|
||||||
# in this case following instruction will raise an error
|
# in this case following instruction will raise an error
|
||||||
println(println()); # error
|
println(println()); # error
|
||||||
@@ -68,7 +68,7 @@ they cannot be nested in any blocks.
|
|||||||
|
|
||||||
### Function definition
|
### Function definition
|
||||||
Functions can be defined with `function` keyword, like it is shown on following example:
|
Functions can be defined with `function` keyword, like it is shown on following example:
|
||||||
```
|
```php
|
||||||
function multipleBy2(number) {
|
function multipleBy2(number) {
|
||||||
return 2*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
|
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 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):
|
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) {
|
function multipleBy2(number: int) {
|
||||||
return 2*number;
|
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.
|
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:
|
Of course, you are still able to create functions without any arguments or mix their types:
|
||||||
```
|
```php
|
||||||
function noArgs() {
|
function noArgs() {
|
||||||
println("Hello, I don't accept any arguments.");
|
println("Hello, I don't accept any arguments.");
|
||||||
println("Also see that I don't return anything!");
|
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.
|
Accepted types can be declared using _union construction_ which consists of types separated with commas (`,`) and bounded on both sides with `<` and `>` characters.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
```
|
```php
|
||||||
function foo(x: <string, bool, int, float>, y: note, z) {
|
function foo(x: <string, bool, int, float>, y: note, z) {
|
||||||
# 'x' can be either string, bool, int or float
|
# 'x' can be either string, bool, int or float
|
||||||
# whereas 'y' can be only a note
|
# 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_.
|
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
|
Accepted types are separated with commas (`,`), bounded on both sides with `<` and `>` characters and placed
|
||||||
next to `list` keyword:
|
next to `list` keyword:
|
||||||
```
|
```php
|
||||||
function foo(x: list<int>) {
|
function foo(x: list<int>) {
|
||||||
# 'x' can be only list of ints
|
# '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:
|
You are still able to use multiple type as constraints:
|
||||||
```
|
```php
|
||||||
function foo(x: list<int, note>) {
|
function foo(x: list<int, note>) {
|
||||||
# 'x' can be only list of ints and notes, nothing else
|
# '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
|
List specifier can be empty or even be absent. In this case list can contain
|
||||||
any available types:
|
any available types:
|
||||||
```
|
```php
|
||||||
function foo(x: list<>) {
|
function foo(x: list<>) {
|
||||||
# 'x' can be only a list containing arbitrary objects
|
# '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.
|
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>>>) {
|
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:
|
Of course ambiguous arguments can include specified lists:
|
||||||
```
|
```php
|
||||||
function foo(x: <int, note, list<int, note>) {
|
function foo(x: <int, note, list<int, note>) {
|
||||||
# 'x' can be int, note or list containing only ints and notes
|
# '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.
|
The only difference is map supports **2** specifiers: first one for keys and second one for values.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
```
|
```php
|
||||||
function foo(x: map<string><note>) {
|
function foo(x: map<string><note>) {
|
||||||
# 'x' can be only a map with strings as keys and notes as values
|
# '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.
|
to variable assignment syntax.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
```
|
```php
|
||||||
function foo(x = 10) {
|
function foo(x = 10) {
|
||||||
# 'x' can be of any available type.
|
# 'x' can be of any available type.
|
||||||
# You can override default value but you don't have to.
|
# 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:
|
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]]) {
|
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.
|
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
|
Just remember, that after first declared optional argument you can't use regular
|
||||||
arguments in the same signature anymore.
|
arguments in the same signature anymore.
|
||||||
```
|
```php
|
||||||
# Correct signatures
|
# Correct signatures
|
||||||
function foo(a, b, c = 0) {}
|
function foo(a, b, c = 0) {}
|
||||||
function bar(a, b = "hello", c = true) {}
|
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.
|
as vararg.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
```
|
```php
|
||||||
function foo(a, b, ...c) {
|
function foo(a, b, ...c) {
|
||||||
# 'c' is a list of arguments passed after 'a' and 'b'
|
# '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
|
Same as optional arguments, vararg can work with any previously mentioned kinds
|
||||||
of arguments (except optional arguments of course).
|
of arguments (except optional arguments of course).
|
||||||
```
|
```php
|
||||||
function foo(a, b: note, ...c: map<string><list<int, note>>) {
|
function foo(a, b: note, ...c: map<string><list<int, note>>) {
|
||||||
# after two arguments you can pass any number of
|
# after two arguments you can pass any number of
|
||||||
# maps with strings as keys and list of ints and notes as values
|
# 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
|
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.
|
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:
|
Following listing presents a syntax of `extend` statement:
|
||||||
```
|
```php
|
||||||
extend int with function multipleBy(x: int) {
|
extend int with function multipleBy(x: int) {
|
||||||
return this*x;
|
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
|
Note, that type being extended must be declared only as a simple data type or map/list with optional
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
```
|
```php
|
||||||
# Correct
|
# Correct
|
||||||
extend int with function a() {}
|
extend int with function a() {}
|
||||||
extend list with function b() {}
|
extend list with function b() {}
|
||||||
@@ -441,7 +441,7 @@ extend int with function k() {}
|
|||||||
|
|
||||||
Because extending statement supports list/map specifiers, you can define
|
Because extending statement supports list/map specifiers, you can define
|
||||||
methods that are applicable only for list/map with specified content:
|
methods that are applicable only for list/map with specified content:
|
||||||
```
|
```php
|
||||||
# Extends all lists, no matter of content
|
# Extends all lists, no matter of content
|
||||||
extend list with function foo() {
|
extend list with function foo() {
|
||||||
println("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
|
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
|
extend for example `list<int>` and `list<note>` (but not `list<int, note>`) you have
|
||||||
to do it separately:
|
to do it separately:
|
||||||
```
|
```php
|
||||||
# This won't work at all
|
# This won't work at all
|
||||||
extend <list<int>, list<note>> as l with function foo() {
|
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.
|
In case of extending type with more than one function you can use block of methods.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
```
|
```php
|
||||||
extend int {
|
extend int {
|
||||||
function multipleBy2() {
|
function multipleBy2() {
|
||||||
return 2*this;
|
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.
|
Note, that potential signatures' collision is evaluated only at runtime, when method is being called.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
```
|
```php
|
||||||
function display(x: int) {
|
function display(x: int) {
|
||||||
println("int: ", x);
|
println("int: ", x);
|
||||||
}
|
}
|
||||||
@@ -533,7 +533,7 @@ display(14.0); # float: 14.0
|
|||||||
```
|
```
|
||||||
|
|
||||||
However:
|
However:
|
||||||
```
|
```php
|
||||||
function display(x) {
|
function display(x) {
|
||||||
println("any: ", x);
|
println("any: ", x);
|
||||||
}
|
}
|
||||||
@@ -546,7 +546,7 @@ display(14); # any: 14
|
|||||||
display(14.0); # error!
|
display(14.0); # error!
|
||||||
```
|
```
|
||||||
The code will end with following error:
|
The code will end with following error:
|
||||||
```
|
```php
|
||||||
Function invocation error
|
Function invocation error
|
||||||
Source: /.../.../scratchpad.mus
|
Source: /.../.../scratchpad.mus
|
||||||
Position: line 16, column 1
|
Position: line 16, column 1
|
||||||
|
|||||||
Reference in New Issue
Block a user