Closed ta0kira closed 11 months ago
<-|
should have both statement and inline assignment implementations so that something like return (foo <-| bar())
can be done.
What would the return type of inline <-|
be if the right side isn't optional
? It would be easy enough to make it non-optional
because that can automatically convert to optional
.
optional Int value <- empty
Int value2 <- (value <-| 123)
This isn't unique to <-|
, however; we could just as easily apply this to <-
.
For inline <-
(and not <-|
) there's a question of if we'd use the entire type from the right side, e.g.,
optional Formatted value <- empty
Int value2 <- (value <- 123)
Overall, this seems fine, although there could be issues when it comes to unboxed types.
For the return type of inline <-|
:
optional A
on the left and B
on the right: [A|B]
.optional A
on the left and optional B
on the right: optional [A|B]
.I think short-circuiting &.
will require a compound expression so that it can be executed inline and it doesn't evaluate the left expression more than once.
({
BoxedValue result = // execute left side
BoxedValue::Present(result)
? // execute call on result
: result;
})
Using a lambda would be infeasible due to the complexity of capturing all necessary variables.
Rather than putting that mess everywhere it's needed, it can probably go in a macro in category-source.hpp
. Then it would be just a matter of selecting TYPE_VALUE_CALL_UNLESS_EMPTY
vs. TypeValue::Call
.
#define TYPE_VALUE_CALL_UNLESS_EMPTY(expr, func, args) ({ \
BoxedValue result = (expr).At(0); \
BoxedValue::Present(result) \
? TypeValue::Call(result, func, args) \
: result; \
})
I'm going to skip ||
just because of the type ambiguity.
optional A
on the left and optional B
on the right, use optional [A|B]
?foo() || returnsNothing()
, or for that matter foo() && returnsNothing()
?optional Bool
and the right is Bool
? Do we convert the right to optional Bool
? For example, in optionalBool || false || something()
, if optionalBool
is empty
, does something()
get called`?The proposed functionality for ||
with optional
seems very useful still; it just needs a different operator to avoid ambiguity. I think <||
clearly indicates both "alternative" (||
) and preference for the left with <
.
optional X
on the left and Y
on the right, the result can be [X|Y]
.optional X
on the left and optional Y
on the right, the result can be optional [X|Y]
.
Some ideas:
Optionally call a function on
optional
. Something like what Ruby does?foo&.bar()
would callbar()
iffoo
isn'tempty
. This would require addingoptional
tobar
's return types.Other than possibly-confusing semantics of
optional optional
, it's unclear if this should short-circuit evaluating arguments. Infoo&.bar(baz())
, wouldbaz()
be called iffoo
isempty
? Skippingbaz()
might be easier to implement in C++, since we could just repeatedly reuse the sameReturnTuple
for calls in a single chain.Optionally overwrite value, with short-circuit evaluation.
foo <-| bar()
would evaluatebar()
and assign the result tofoo
ifffoo
isempty
. I think it would just expand to:Implement
||
foroptional
types, with the obvious semantics.&.
||
and use<-|
instead because the state variable determines the type.