Add infix operators

Bug #871246 reported by Matt Giuca
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Mars
Fix Committed
Wishlist
Matt Giuca

Bug Description

The time has come to make Mars code look a bit prettier. I have resisted adding infix operators, in order to preserve a very "no-sugar" approach to Mars, but really, this is a very small change and makes a big difference to the readability of the code.

Add new syntax for prefix and infix operators as follows:
-e is sugar for neg(e).
e1 op e2 is sugar for binary operators, where:
+ is add, - is sub, * is mul, / is fdiv (a new operation introduced when addressing bug #870515), // is div, % is mod, == is eq, != is ne, < is lt, <= is le, > is gt, >= is ge.

Note that unary -, !=, <, <=, > and >= sugar to functions which are in the prelude, not built-ins. This isn't really a problem. As a very high-level sugar, it just generates calls to those functions. If they don't exist, it would just print "Undefined variable: ge" -- this means we probably want to special-case those functions in the undefined error messages to avoid confusion.

We can also add array syntax:
e1[e2] is sugar for array_ref(e1, e2).
e1[e2] := e3 is sugar for array_replace(e1, e2, e3).
Though this might be going too far.

Related branches

Revision history for this message
Matt Giuca (mgiuca) wrote :

Note: Remove the '-' from the int literal syntax. It can just be a neg expression.

Revision history for this message
Matt Giuca (mgiuca) wrote :

Rather than depending on the prelude functions neg, ne, lt, le, gt and ge, we can have these operators sugar to the inlined versions of those functions:

-e is sub(0, e).
e1 != e2 is eq(eq(e1, e1), 0)
e1 < e2 is eq(cmp(e1, e2), -1)
e1 <= e2 is eq(eq(cmp(e1, e2), 1), 0)
e1 > e2 is eq(cmp(e1, e2), 1)
e1 >= e2 is eq(eq(cmp(e1, e2), -1), 0)

Matt Giuca (mgiuca)
Changed in mars:
status: Triaged → In Progress
Revision history for this message
Matt Giuca (mgiuca) wrote :

There is a subtle point here: when we say "x + y" is sugar for "add(x, y)", do we mean "whatever the name 'add' is bound to," or "the built-in function 'add'"? Consider the code:

def foo() :: Int:
    add = max
    return 8 + 3

Does this return 11 or 8? I think intuitively it should return 11, because it is not intuitive that + means "whatever add is bound to." Even less intuitive is the sugar of unary minus becoming sub(0, e):

def foo() :: Int:
    sub = min
    return -(4)

Does this return -4 or 0? Intuitively, it should be -4.

Therefore, these are not *quite* syntactic sugar because they do something which ordinary Mars code cannot: refer to the global function names even if there are local bindings to those names. So actually, x + y is sugar for @add(x, y), where @add is our internal syntax for referring to globals (and not legal Mars source code).

This will actually show up if you type:

?> :t x + y
@add(x, y) :: Int

That's potentially confusing, but we can use it to our advantage. Have the print code resugar global variable references with certain names. So @add(x, y) becomes x + y. This means we distinguish calls to the functions from operators:

?> :t add(x, y)
add(x, y) :: Int
?> :t x + y
x + y :: Int

This gets more complicated for the printer when it has to re-assemble eq(eq(cmp(e1, e2, -1), 0), but it can probably do it. Also note that there is an ambiguity between 0 - x and -x which should be resolved in favour of 0 - x to avoid confusion.

Revision history for this message
Matt Giuca (mgiuca) wrote :

Actually, it has to be resolved in favour of -x because otherwise expressions that were previously negative int literals (such as -4) will print out as (0 - 4). Perhaps later we can add a separate 'neg' built-in to disambiguate these.

Revision history for this message
Matt Giuca (mgiuca) wrote :

Fixed in trunk r1282.

Changed in mars:
status: In Progress → Fix Committed
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.