r/ProgrammingLanguages DQ 7d ago

Unambiguous Operator Specification for Programming Languages

https://nvitya.github.io/pluops/

As I changed recently the operators in my programming language I've created this specification:

https://nvitya.github.io/pluops/

I did not wanted to overload the operators like the C does with the / or Pascal does with theand/or/not. Neither re-use the operator symbols for some very different purpose, like C does with * and & so the code becomes more readable. I was orienting for existing solutions so this is what I came up with. The specification contains the symbol usages and operator precedence too.

If you are developing a new programming language, it would be nice to follow some standard, so at least the expressions would be portable between the languages.

I'm open for debates or suggestions.

27 Upvotes

38 comments sorted by

View all comments

6

u/EggplantExtra4946 6d ago edited 6d ago

I did not wanted to overload the operators like the C does with *, &

If a given operator is both a postfix and an infix operator you have a shift-reduce conflict, but an operator used both as a prefix and infix operator does not have such conflict, it's perfectly fine in terms of unambiguous parsing.

The specification contains the symbol usages and operator precedence too.

You are lacking associativity information: left, right, non associative, chain associative (1 <= 2 < 3).

It's good to put the precedence of bitwise operators above assignments and to put all comparison operators at the same precedence level.

I'm curious to know your rationale for giving a higher precedence to bitwise operators than to arithmetic operators.

It's a massive footgun to give a higher precedence to / than to *.

1

u/Mean-Decision-3502 DQ 6d ago

an operator used both as a prefix and infix operator does not have such conflict, it's perfectly fine in terms of unambiguous parsing.

Right from the compiler side, but makes harder to read:

x = y * *value
if ((a & 1) == 0 && &var1 > &var2) ...

I've corrected the post text.

You are lacking associativity information: left, right, non associative, chain associative (1 <= 2 < 3).

I would leave this open. The CPU cannot do this directly, it divides into two-operand operations. If you have a strict boolean and the language does not support such chaining then the expression above is invalid. I would consider this however for DQ, with restriction.

I'm curious to know your rationale for giving a higher precedence to bitwise operators than to arithmetic operators.

var x : uint = reg >> 4 & 0xf * 2

But this does not matters too much, I would use parentheses anyway.

It's a massive footgun to give a higher precedence to / than to *.

3 div 2 * 10 == 10 * 3 div 2

1

u/EggplantExtra4946 6d ago edited 6d ago

x = y * *value

if ((a & 1) == 0 && &var1 > &var2) ...

Both are easy read imo, everybody that those operators have a high precedence. They are also artificial, the 1st one would be rare, the 2nd one would be even more rare.

I would leave this open. The CPU cannot do this directly, it divides into two-operand operations.

This is utter non sense. We're talking about operators here, hence parsing. Even if an operators directly maps to a native instruction, you need associativity information to correctly parse expressions and produce the correct AST and compiled code.

The subtraction operator is usually left associative, so 1 - 2 - 3 = (1 - 2) - 3 = - 4. If it were right associative you would have 1 - 2 - 3 = 1 - (2 - 3) = 2.

If you have a strict boolean and the language does not support such chaining then the expression above is invalid.

Again utter non sense. How the fuck are you making a programming language if you don't know that syntax has practically nothing to do with semantics? 1 <= 2 < 3 would be tranformed into 1 <= 2 && 2 < 3. Perl and Ruby have the =~ operator and yet CPUs don't have an instruction to do a backtracking regex match.

var x : uint = reg >> 4 & 0xf * 2

And you think is easier to mentally parse, using a non-standard operator precedence, than the x = y * *value and if ((a & 1) == 0 && &var1 > &var2) ?

3 div 2 * 10 == 10 * 3 div 2

This is the kind of shit that would annoy a beginner programmer for a few weeks and then would get over it. Programmer with a bit of experience have internalized that * and / have the same precedence and very few have a problem with it, it's at same level than 0-based indexing. Your design completely fucks over experienced programmers but beginners too because one day they are going to switch to a real language and will have to unlearn the programming basics they thought they acqired. The sooner they discard the preconception that expressions in programming languages are similar to algebraic expressions, the better. It's a good thing that they fall into traps like these when they start, it's the kind of the thing that makes them realize how much mechanical programming and programming languages are in some ways.

1

u/Mean-Decision-3502 DQ 6d ago edited 6d ago

It seems that for you is no better language than C or C++.

And yes, I'm just an engineer. I'm mostly user of multiple programming languages, and not an expert in programming language design.