Yes, if you need one parameter to toggle the existence of multiple arguments/fields (of arbitrary type), then the feature that I suggested probably wouldn’t be sufficient.
I can see the value of the feature you’re suggesting.
Here’s a different idea. Again, my goal is to allow Mojo users to express a comptime equivalent of Optional
and Variant
.
Python and Mojo already have if
-expressions. What if we allow such expressions to return a type?
fn foo[cond: Bool](optional_arg: Float64 if cond):
# Or equivalently:
fn foo(optional_arg: Float64 if _)
struct Thing[cond: Bool = False]:
var _a: List[Int] if cond
var _b: List[Float32] if cond
You’ll notice that I’ve omitted the else
branch in the above examples. This seems like a clean way to model optionality. This is also consistent with my proposed syntaxes for having comptime control over async
and raises
:
fn foo() raises if cond:
fn bar() yields if cond:
This syntax can express more than just optionality. To select between two types, one could write:
fn foo[is_integer: Bool](arg: Int64 if is_integer else Float64):
It would be possible to abstract these if
-expressions behind parametric aliases:
alias Foo[cond: Bool] = T1 if cond or something() else T2
alias Bar = Thing[X, Y, T1 if blah() else T2]
To be honest, I like this design better than my earlier ideas! It’s simultaneously more concise, more expressive, and easier to teach. Python and Mojo users are already comfortable with if
-expressions.
This feature seems like it would subsume @rd4com’s idea for parameterized var
declarations.
@clattner, perhaps this expanded set of use cases comes closer to justifying the feature? The current use cases are:
- optional arguments (whose existence is known at comptime)
- optional fields (whose existence is known at comptime)
- optional local
var
s (whose existence is known at comptime) - arguments/fields/locals whose type is selected from 1 of N possibilities, using a comptime
Bool
, or maybe anInt
(in other words, “comptime type selection”)