-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Closed
Labels
missing dataBase.missing and related functionalityBase.missing and related functionalityspeculativeWhether the change will be implemented is speculativeWhether the change will be implemented is speculative
Description
I'd like to discuss the opportunity and possible implementations of a syntax similar to Swift's if let. The idea is to offer a compact syntax to check whether a Nullable is null, performing an action on its value if it isn't (with an optional fallback if it is).
This was mentioned recently on julia-users: https://groups.google.com/d/msg/julia-users/pgaw6VnBJ34/bBe2lJ1mAQAJ
I gave a try at writing a macro offering a similar feature in Julia, and as expected it can be made to work quite easily. There are a few issues to discuss, though:
- First, do people think it would be worth having in Base? I think making it easy to work with
Nullablein a rigorous way is a major feature, and this seems to be a quite common opinion nowadays. @if letcannot be used because of parsing issues. That's not a big deal IMO, as I'm not a fan of that naming choice. I've retained@unwrap if, but we could find a better name (ifis required to allowelse).- I've chosen to override the same variable binding using
let x=get(x)(i.e. you access the value with the same name as theNullable). I think this is clearer as there's no reason to need both variables in the same context, and it avoids prompting people to use artificially different names for the "same" thing. - I think an alternative solution to this ad-hoc macro would be extend the
dosyntax to allow for anelsepart, which would be implemented by passing two functions toget(one for when a value is present, one for when it isn't). The advantage is that it could be useful in other places: for example to allow working efficiently with dicts, with code to update a value if found, and code returning a default value (?= "get or set" operator #2108).
So, here's the macro, and examples of how it can be used:
macro unwrap(ex)
if !isa(ex, Expr) || ex.head != :if
throw(ArgumentError("@unwrap expects an if or if...else block"))
end
x = esc(ex.args[1])
if length(ex.args) == 3
quote
if !isnull($x)
let $x = get($x)
$(esc(ex.args[2]))
end
else
$(esc(ex.args[3]))
end
end
else
quote
if !isnull($x)
let $x = get($x)
$(esc(ex.args[2]))
end
end
end
end
end
v = Nullable(1)
@unwrap if v
res = v + 1
end
@unwrap if v
res = v + 1
else
res = 0
endCc: @johnmyleswhite
helgee and fhucho
Metadata
Metadata
Assignees
Labels
missing dataBase.missing and related functionalityBase.missing and related functionalityspeculativeWhether the change will be implemented is speculativeWhether the change will be implemented is speculative