crab
crab copied to clipboard
Add the Ternary Operator
Summary
Now that there's a fork getting enough traction, I'd like to propose our best competitive advantage: The Ternary Operator. It'll make my code look nice and run faster I think
Motivation
Please. Listen to me, okay. It's all I've wanted since like 2015. It can't be that hard, I've made my own language before and it had a ternary operator. Just figure it out idk
Guide-level explanation
- Get in the code
- Make the ternary operator
- Ship it
Reference-level explanation
It would look like this
let b = true;
let i = b ? "Yes" : "No";
assert_eq!(i, "Yes");
Drawbacks
None
Rationale and Alternatives
Rationale:
- Because it would look cool
- Because I want it
- Do it now
Alternatives:
- Failure
Unresolved Questions
- Why hasn't this been in the language for the past 8 years
Future possibilities
- Rule the world
omg yes
The actual problem with ternary operator is that people can't agree on how to format it. Of course every serious person knows the one true way though:
c1 ? v1 :
c2 ? v2 :
c3 ? c31 ? v31 :
v3d :
vd;
There is already let i = if b {"Yes"} else {"No"};
This will be in our "easy to use new super awesome gateway language" to introduce users from C#, Java, JavaScript, Python, etc. to the way of the crab:
https://github.com/crablang/crab/issues/6
I don't have any responses on this one yet and it makes me sad :(. Lol. I actually believe in this one tho. I think it's the key ingredient to taking over the world.
Although we need a new name for it now. Crabby has been taken for clippy.
Can we elaborate more on its integrarion with ?
try operator
Let's we have
fn foo(x : Option<bool>) -> Option<S> {
// should we use
x?? Some(S) : None
// or propagate unwrapping to Some branch
x? (x? Some(S) : None) : None
// or shorten
x?? S
}
What if this was done with a macro?
let some_var = ?!(some_condition ? "true" : "false");
There is already
let i = if b {"Yes"} else {"No"};
And it would literally just expand to this
?!
Brilliant. Just brilliant. Yes.
I know this is a pipe-dream which is why I didn't take my little "RFC" message seriously. I do think that ~~rust~~ crab needs more syntax sugar! Chances that this actually happens are basically none, but if we want to try, I have a good starting-point on how to actually implement this!
I suggest we change it from ?
to ??
, and from :
to ?:
in order to keep parity with the try
operator and avoid breaking things in general. Here's how it would look:
let b = true;
let i = (b ?? "Yes") ?: "No";
In this snippet, ??
and ?:
are both nonterminal, infix expressions the same way that +
, -
, etc. are. We don't have a builtin function for ??
, so it should be implemented as a trait the same way that Add
or Sub
are:
// Impl for the `??` operator
impl<T> core::ops::IsTrue for bool {
type Output = T;
fn is_true(self, rhs: T) -> Option<Self::Output> {
if self {
Some(rhs)
} else {
None
}
}
}
For ?:
, it would be easiest if we could implement the functionality already present in Option::unwrap_or,
since IsTrue
requires that an Option should be returned.
With both operators implemented, the equivalent "desugared" code from the first snippet would look like this:
let b = true;
let i = (if b {
Some("Yes")
} else {
None
}).unwrap_or("No");
There definitely could be a better way at implementing this, but using Option
s seems the most natural to me. If someone's also interested in digging through the compiler to make this work with me, I'll spend a full day trying to get this implemented if I have to! Sounds like a good exercise.
If using the ?
is out of the question, I don't think python's alternative for this is bad.
value if True else value2
yeah it is kinda the opposite of true ? value : value2
but still better than if true { value } else { value2 }