Message Send
Unary
Let's look at nested function call from C like lang:
It reads from the inside out or from right to left.
Let's remove parenthesis
And now invert, to make it readable:
Now we got niva syntax!
Some ML languages use pipe operators to achieve the same readability42 |> foobar |> bar |> foo
So every call has a receiver that receive "message" 1 inc factorial
can be read as: receiver <- message1 <- message2
There are three kinds of messages.
You are already familiar with unary, it has one arg(it's receiver).
But what if we need more args?
Keyword
What about sending messages with arguments? 1 add 2
Okay, but what if we have more args1 addFirst 2 addSecond 3
This is pretty unreadable, so we need to distinguish each arg
So function calls in niva are always named: receiver keyword1: arg1 keyword2: arg2
equivalent to C/Java positional based syntax: receiver.keyword1keyword2(arg1, arg2)
If you need to compose keyword msgs inside each other use (), also you can put args on new lines:
In C like languages there is a concept of calling functions with named arguments...
So in niva name of the function and name of the arguments are the same
Binary
Binary messages is a pretty common syntax:
But its not operators, its still a messages for receiver: receiver + arg
unary always evaluate first, 1 inc inc + 4 dec
-> (1 inc inc) + (4 dec)
-> 3 + 3
-> 6
Here are some examples that became looks like DSL because of that rule:
So, the general rule is simple, every expression in niva is a message, and all the messages works the same way: receiver <- message1 <- message2
Send keyword to result of another keyword
There is easy to do it with unary and binary: 1 + 2 + 3
, 1 inc inc
But with keyword what if you want to send to:
kw msg to the result offrom:
1 from: 2 to: 3
This is just a single msg from: to:
to solve this you need to put the first part into parenthesis: (1 from: 2) to: 3
With more calls it starts to get messy: ((1 from: 2) to: 3) and: 4
kinda like in C, but the amount of parenthesis grow on the left side: and(4, to(3, from(1, 2)))
So I added pipe operator, which wraps everything to the left in brackets1 from: 2 |> to: 3 |> and: 4
More on that here: pipes
Named args vs positional args
Here you can see why I think named arguments are better than positional ones:
replaceAll " " "-" test
, it's nearly impossible to guess what's going on hereAll the functions in niva have receivers, because they are actually messages(Smalltalk term). So it's just much easier to get a list of all possible messages with auto-completion on any value and understand what they mean too: