-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use ? to lift missing values #36628
Comments
I (or even we as people working with data 😄) might be opinionated, but after a longer time of working with both Also an especially annoying thing with In summary - I support the proposal by @juliohm - if this is possible to extend a parser in this way of course (I have not analyzed the consequences in detail, but it seems safe as in |
Also then I would rise again the idea of:
|
What "lift missing values" is needs to be specified.
It's interesting because I use |
We could have syntax for both Maybe And |
There are several RFCs for adding API based on
|
We could come up with another syntax. Maybe |
Should we make them the same, and simply change the definition to I think it could be worthwhile to have a JuliaCon BoF topic to hammer this discussion out, since we can't rely on hallway conversations this year! And syntax would be really nice for this. |
Isn't the math different? julia> 1 + missing
missing
julia> 1 + nothing
ERROR: MethodError: no method matching +(::Int64, ::Nothing)
Closest candidates are:
+(::Any, ::Any, ::Any, ::Any...) at operators.jl:538
+(::T, ::T) where T<:Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8} at int.jl:86
+(::Union{Int16, Int32, Int64, Int8}, ::BigInt) at gmp.jl:531
...
Stacktrace:
[1] top-level scope at REPL[2]:1 |
Actually, I just made an exactly the same comment in Zulip:
I guess you could write |
Quoting yet another comment of mine:
|
Isn't I've never used |
I think there is no obvious choice because people come from different backgrounds. I personally feel that For a vector of objects |
I'm processing https://www.hl7.org/ data represented as JSON. In the JSON binding of FHIR, when data is not provided for a field, it is simply omitted empty key; Hence, the datatypes and functions we've defined for working with FHIR data use quite a bit of At a more abstract level, I picture |
Yeah, I think these parts of @StefanKarpinski's comment are key: (emphasis mine)
|
Reposing my comments from https://julialang.zulipchat.com/#narrow/stream/137791-general/topic/Crazy.20thought.3A.20is.20it.20possible.20to.20merge.20nothing.20and.20missing.3F/near/203667599
|
A I guess this really comes down to making it nice for systems people ( |
Wouldn't this be |
There is no ambiguity because you'd get |
@KristofferC - I agree and I also use it often in package code. My comment was about user code (especially in data science related domains). Of course this is opinionated, as I have commented. Though, I think that in package code writing Now regarding |
Sure, but if the value of a dictionary key is Anyway, I can see how one might want |
Because that is how you distinguish a value of |
I just want to complain about the low quality of this issue (not the discussion, the issue itself). There is no actual proposal, and this seems to be doing no more than forking the discourse thread onto github. A link to discourse is not an acceptable issue description. If I want to read discourse, I'll read discourse. |
This seems like a very niche thing to have it's own special case in the parser. Wouldn't it make way more sense to just add a method to You could have Base.:(|)(::Type{T}, ::Type{U}) where {T, U} = Union{T, U}
Vector{Int | Nothing} # Array{Union{Int, Nothing}, 1}
struct Foo
x::(Int | Missing) # field x must be either Int or Missing
end or if you prefer Base.union(::Type{T}, ::Type{U}) where {T, U} = Union{T, U} # alias ∪
Vector{Int ∪ Missing} # Array{Union{Int, Missing}, 1}
struct Foo
x::(Int ∪ Nothing) # field x must be either Int or Nothing
end Even better is that you can have this today without type piracy or needing anyone else on the planet to agree with you: # new sesssion
julia> |(a, b) = Base.:(|)(a, b)
| (generic function with 1 method)
julia> |(::Type{T}, ::Type{U}) where {T, U} = Union{T, U}
| (generic function with 2 methods)
julia> Int | Nothing
Union{Nothing, Int64}
julia> @eval Base Int | Nothing
ERROR: MethodError: no method matching |(::Type{Int64}, ::Type{Nothing})
Closest candidates are:
|(::Any, ::Any, ::Any, ::Any...) at operators.jl:538 |
@JeffBezanson, I hope this isn't taken the wrong way, and I acknowledge that there may be some context I'm missing, but I feel your response here was not constructive and rather brusque. I was going to say that I feel a better response would be to request that @juliohm consult the CONTRIBUTING.md on how to phrase a feature request that is up to the standards of this repository, but it appears that there isn't really any mention there about language level feature requests, only bug reporting and notes not to make library level feature feature requests, so I opened an issue on that here: #36667. In the meantime, I'm feel that requesting that the issue be edited to contain an actual description of what Julio is proposing would be more constructive than simply complaining that the issue is not up to your standards. |
I see that the OP text (rather than the issue title) emphasizes the union type shorthand. But I fear this is a rather too trivial usage for very valuable ASCII-based syntax. Rather, I think a better focus here should be the lifting of the function calls like |
I think that even if this weren't a very niche thing (unlike broadcast), I'd still be against it just because of the huge amount of ambiguity it'd add to the already confusing ternary operator syntax. If anything, we should be thinking of how we can have less special syntactic forms in the parser, not more. I also think the use-case you show above is just better handled by a macro anyways: julia> using MacroTools, Missings
julia> @eval macro $(Symbol("?"))(expr)
(esc ∘ MacroTools.postwalk)(expr) do ex
if isexpr(ex, :call)
ex.args[1] = :($(passmissing)($(ex.args[1])))
end
ex
end
end
@? (macro with 1 method)
julia> f(x::Int) = x + 1
f (generic function with 1 method)
julia> @? sin(f(missing) * 2)
missing |
It seems (from this issue discussion, as well as discussions on Discourse and Zulip) that this is a sufficiently complicated topic to justify a BoF at JuliaCon as @vtjnash suggested |
There are reasons why it's nice to have native dot calls and not just |
I also feel that this is the key point. In my view, the decision is whether we want In particular, I'm not sure I agree with this comment:
Because to me the point of My two questions are:
|
We should review if this special On the other hand, Regardless, Jeff has a great point about venue; I suppose we should be using Discourse? (since Slack history disappears) Could there be a "Feature Request" section in Discourse, perhaps under "Usage" (most feature requests are answered with how to use Julia more effectively...) and shuffle discussion there till enough consensus emerges that we have a feature set suitable for review? |
@piever I think the answer is "no." For concrete definition of "lifting", this function may be a nice toy example: return1(_) = 1 This function picks the right argument. The question is what In the return1?(Some(x)) === Some(1)
return1?(nothing) === nothing Note: equivalent code in Haskell's maybe monadPrelude> Just 1 >>= return . const 1
Just 1
Prelude> Nothing >>= return . const 1
Nothing It is also straightforward to define An implementation of
|
FYI here is my POC for |
@piever One difficulty is that the three-valued logic implemented by logical operators differs from standard lifting semantics. So lifting cannot replace all operations defined on
@tkf I don't get why you would want |
It seems that this is a popular topic. There is a blog post on |
@nalimilan I know what |
"Maybe T? for missing and T?? for nothing. " If you want shortcuts for both then I'd switch it around because T? means T | Null or Nullable in languages that support that notation (Kotlin, C#,...) and that maps to Union{T,Nothing}. |
The issue is that AFAICT do not have |
Did we reach a conclusion regarding this FR? |
No, AFAICT the discussion is stalled. Still - I personally would support parsing |
I've come to regret including Missing in Base Julia and am therefore reluctant to give it dedicated syntax. If the syntax could be used for different things and loading |
I think using T? for Union{T, Nothing} seems like a better use of the syntax.
That was my proposal. This is also inline with what other languages do (C#, Kotlin,…)
… On 9 Apr 2024, at 15:49, Stefan Karpinski ***@***.***> wrote:
I've come to regret including Missing in Base Julia and am therefore reluctant to give it dedicated syntax. If the syntax could be used for different things and loading Missings defined it, that would be ok. However, from my admittedly biased experience I think using T? for Union{T, Nothing} seems like a better use of the syntax.
—
Reply to this email directly, view it on GitHub <#36628 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/ACASZIJ233PBBINMNTVSL6LY4PWXZAVCNFSM4OX52RMKU5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TEMBUGUZDENJTGA3A>.
You are receiving this because you commented.
|
Imho Eg if julia> findfirst(Returns(true), Dict(nothing=>10, 2=>20))
# incorrectly assume it wasn't found Using This issue is discussed more in #29565 and by Takafumi in this very thread above. #36628 (comment) |
Must it be one meaning or the other? Why can't |
We've been working with SQL databases often. It's great to have Conversely, having better conventions and tools for working with |
Kotlin's "elvis operator" is kind of snazzy, where e.g. although I guess it's trivially replaced by |
The elvis operator is too late: once (If we're gonna keep going on this point let's do it in #29565) |
As discussed in https://discourse.julialang.org/t/status-of-question-mark-syntax-for-missing-values/27189 it would be really nice to have this syntax at some future release where one could type
T?
to indicateUnion{T,Missing}
. Possibly, also writemean?(xs)
to automatically handle inputs with missing values.The text was updated successfully, but these errors were encountered: