Assuming we have:
It turns out
something(Some(2), do_work(3)) still invoke do_work, which returns 2 seconds later.
It would be better to define it as a macro, which retains the arguments as AST and only evaluate them when necessary.
This is simply eager evaluation. If you really need
something to behave like this, you need to use a macro. Alternatively,
|| already short-circuits, so if it does no side effects, you can consider using those too.
This is harder than I thought.
return :(throw(ArgumentError("No value arguments present")))
macro something(head, rest...)
expr = quote
if $head isa Nothing
return # somehow insert expansion of @something($(rest...)) at this position
I wonder if it is even possible to make such a macro.
It’s possible: macros are arbitrary functions which transform syntax into syntax. One fairly direct way to write it could be as follows (there’s shorter ways but this should be relatively easy to understand):
function something_expr(ex, exs...)
s = $(esc(ex))
something_expr(ex) = :(something(ex))
Thank you very much! There is a error in the base case. Here is the complete code:
# All credits to Chris Foster
function something_expr(head, rest...)
head_val = $(esc(head))
if head_val isa Some
@something 1 2 # 1
@something 1 f(2) # 1, without delay
@something Some(1) 2 # 1
@something nothing 2 # 2
@something sleep(1) 2 # 2, 1s delay