Functions in Plain are similar to functions in any language with a few important differences. A function in Plain will return an event with parameters, meaning we return a different set of parameters depending on what even we raise.
The second difference is that we let a function call be an implicit state-engine where we override optional or mandatory event with an “On” statement.
The third difference is that we allow a function call to act like a control statement by merging the body between the call and the first On into the function. This allows us to create new control statements.
The fourth difference is that I want to introduce named parameters.
And we need a way to make a function accessible from expressions.
use System Func Parallel(uint32 Timeout) Timer(Timeout) ExecuteBody While ThreadsRunning() Sleep(10) End Raise Synchronize() On Timeout() Raise Parallel.Timeout() End On Timeout() On Synchronize() Mandatory End Parallel ( Timeout=10000 ) for x=1 to 20 spawn Math[x] transaction arr[x] arr[x] = Compute(x) state (Compute) on Error(..) // todo end update end On Timeout() // On Synchronize() // End
This example create a function Parallel that use experimental Syntax “ExecuteBody” to “call” the embedded, main body. After that we loop checking if threads are running – again using experimental RTOS functions. The example use a different function Timer that also act as a control statement itself. I could have used “Parallel(10000)”, but chose to write “Parallel(Timeout=10000)” since the parameter name add readability.
I mentioned “named parameters” – we sometime have functions with many parameters that can be given a default value in declaration. The classic solution is that if you want to override default parameters you start from left to right leaving out those on the far right side – I want to introduce is an option to do this by using an embedded assign to the parameters name.
func foo(uint32 something=10, uint32 somethingelse=20, uint32 mypar=30) ... end foo(mypar=40)
In this example the assembler will create a call to foo with 10,20,40 as parameters as we use the name of the 3rd parameter to specify only this. We can leave parameter 1 & 2 out because they have a default value – if they did not the assembler must give an error – missing parameter.
As to making a function accessible from inside an expression I suggest using either “Raise Continue” or “Return” – with one parameter. I am considering syntax like “x,y = foo()” where we Return multiple parameters – but, let us wait a bit with that one.
func foo(uint32 x) raise continue(x) Event continue(uint32 x) end uint32 xx = foo(2)
We still have loose ends here, but I finally start to see syntax that I feel solve the Parallelism riddle and add something to Plain. The actual functions Parallel and Timer will be C functions – we will need to include a library of System functions anyway. At the end I also need to review if this actually serve the main objectives of Plain – ideas are ideas – they do not always stand their ground.