arturo
arturo copied to clipboard
[Parser] Unary operator returns an error
Describe the bug Parser can't handle unary operators
To Reproduce
$> b: +5
>> Runtime | cannot perform add
error | not enough parameters: 2 required
=> 5
$> print -1 * 3
>> Runtime | cannot perform sub
error | not enough parameters: 2 required
=> 3
Expected behavior
$> print -1 * 3
-3
Desktop (please complete the following information):
- Linux Mint 20.3 x64
- Nim 1.6.6
- Arturo 0.9.80 b/267
As incredible as it may sound, Arturo does not support unary operators at all.
And as weird as it may seem, there is a solid reason for that (I have thoroughly explained it at some point, but I honestly cannot find where exactly... lol)
Symbols in Arturo are nothing but aliases to a word/function (either prefix, or infix) - and you can assign them, or re-assign them yourself as well (using alias
- the examples don't look that awesome, but it's mainly because of the font ligatures not being properly used).
So, whenever you see a symbol (apart from the very few cases where it forms part of a specific value's syntax e.g. a:
is a label, etc) it's actually a function.
In the case of the two symbols that are commonly used as unary operators, +
and -
, in Arturo, they are functions as well. Or, properly put, they "point" to 2 built-in functions: add
and sub
respectively. So, be it with infix precedence (as in the case of +
,-
) or with prefix precedence (as in the case of e.g. ~
-> render
, this is always the case.
And here comes the catch: if there is ONE thing that is an absolute must, given how Arturo's syntax works in general (and of all its siblings as a matter of fact: Rebol, Red, etc) is respecting Arity.
In a few words: when you declare a function, the flexibility of what types it may take is endless. Practically you can do whatever you want, only you have to be relatively careful not to mess up (lol). But it can only take a specific number of arguments. And this cannot change, no matter what.
So... let's take again -
, for example. This points to sub
which is a function that subtracts two numbers. And it, quite obviously, takes 2 arguments. Which means that it cannot take only 1 parameter, which would be the case when potentially used as a unary operator.
In terms of the parser (and the evaluator), when Arturo sees a -
, it's a symbol, so it moves on to find out what's next.
For example
Let's take a short expression with -
in it: 3-1
...

if we allowed for unary--
s, what would that be?
- [
3
:integer-1
:integer]? - or... [
3
:integer-
:symbol1
:integer]?
(I can think of even more cases where it would cause complete... havoc lol)
Rebol/Red "solves" this by making spaces significant 100% of the time, in a way that 3-1
(i think it could be an id?!?!) is one thing and 3 - 1
is another. But come on, I don't know of anyone that finds this practical or a natural way to write code (at least, I for one cannot help it not eat up all the spaces from time to time, plus it makes a mess out of something seemingly ultra-flexible).
So, long story short: this is not supported by Arturo. Given that the unary version of -
is - most likely - much less common than its use as an operator (honestly, after thousands of lines of code written in Arturo, this hasn't been an issue to me so far), I went for using -
as an alias to sub
(subtraction) and add another function (unaliased for now), neg
that actually negates its (one) argument, and acts pretty much like a unary--
would work.
Now, what could actually be a solution would be to introduce a "viable" alias to neg
, that is a new symbol that would act like a unary--
but which (and that's the trickiest part) a) has not been in use anywhere else, b) is short and meaningful enough (the candidate has been _
since the very beginning, but I still keep thinking that there may be better use cases for this...) I don't know... (Writing too much, I know! lol)
Ideas? 😄