I’ve been reworking how I handle basic type conversion in Leaf. This is a mechanism which allows implicit conversion of simple types. As part of this effort I had to refactor how lvalues work. In brief, an lvalue is simply a value which can be modified by assignment.
I realized that I could now solve an annoying issue of imperative programming. How often do you encounter code that looks like the following?
if( cond ) a = some_expr; else b = some_expr;
I’ve always hated that repetition of not just ‘some_expr’ but the assignment as well. In leaf I allow lvalues to survive conditionals. A working example:
var a : integer; var b : integer; (true then b else a) = 17; trace(b);
Note: you probably won’t need the parens since ‘=’ has a low enough precedence. I’ve just put them there for clarity. Of course you’d have an actual condition rather than just ‘true’.
This works for any conditional statement, though the only other one I have implemented so far is a switch (switches can return values). Its syntax isn’t so pretty yet (I haven’t settled on a good one), but here’s an example.
var a : integer; var b : integer; var c : integer; switch { cond_a then a, cond_b then b, else c } = 17;
C++
In C++ the same thing works using a ternary operator. If both operand types are lvalues then the resulting type is also an lvalue. It doesn’t work in C as-is, but with pointers and some syntax changes you can achieve something similar.
//C++ only int a, b; (1 ? a : b) = 17; //C as well *(1 ? &a : &b) = 17;
Categories: Leaf
I find I prefer the way the ternary operator usage looks in C++. Maybe such syntactic sugar can be added later?
I want to unify the ternary and if-else constructs, so it makes the syntax more difficult. That is, an if-else is merely a ternary which selects between code blocks. This is the part where I’m struggling to find a good unifying syntax.
Your switch statement that returns an lvalue looks like a lambda that returns a reference to variables:
I don’t know if you know what a switch-case structure really is. It’s essentially a jump table. In your case it seems to be a subroutine that returns an lvalue. You seem to implement the switch as an if-else-if… lambda:
I think the (boolean_condition ? a : b) = c;
structure is good enough, hey you can even nest them:
But you want to avoid function overhead as it seems, since you avoid calling a function like I do (with the lambda):
Then again, you don’t really need the int &ref reference but it’s just to demonstrate the principle.
My switches allow full expression conditions on each case, rather than a single value match (those will also come, I just haven’t done them yet). I agree the ?: is okay for a ternary case, but I don’t find it expands well to the general case. It may not be possible, but I’m hoping I can have a single conditional syntax which is essentially the same for if-else, and switch, whether used as flow control or value selection. Obviously my current syntax is not the desired goal. :(