@nalimilan By telling Julia what method I’m referring to. It boils back to having missing typed arguments - or making arity and the corresponding types (let’s call this arity+type) an integral part of a method’s signature.
With typed missing arguments, bar()
would be bar(::Any)
. Which would be different from bar(::String)
and bar(::String, ::Symbol)
. It could be invoked as bar(::String)
or as bar("Hi!", ::Symbol)
.
With arity+type notation it could be bar<String,Symbol>()
corresponding to bar(a::String = "", s::Symbol = :s)
. With invocations looking like bar<String,Symbol>("Hi!")
.
I prefer the esthetics of the 2nd form, which would resemble the current bar{T,N}
as bar<T,N>
and would allow bar<T,N>{T,N}
.
@Tamas_Papp Sorry, my example was too convoluted. I’m basically suggesting what’s above: that the original method signature (arity+types) stays “sticky”. And can be invoked explicitly; versus the current behavior where Julia takes a higher-arity-more-specific method and generates lower-arity-less-specific methods, losing track of what was the original method and creating overwriting methods. Makes sense?
Indeed, I’ve read the issue referenced by @nalimilan - I assume you’re referring to the _hidden_f_
approach. Not sure how this would work with the examples we discussed, when higher-arity-more-specific methods generate less-specific-lower-arity methods?
It seems to me that
bar(s::String = "moo")
and
bar(i::Int = 2)
would generate
bar() = _hidden_bar_("moo")
and
bar() = _hidden_bar_(2)
which would still be overwriting implementations.
Unless we go back again to my suggestion:
bar(::String) = _hidden_bar_("moo")
or
bar<String>() = _hidden_bar_("moo")
But of course, if we have bar(::String)
or bar<String>()
we don’t need _hidden_bar_
anymore.
@yuyichao I understand. My point is no longer about the initial question (thank you all for clearing that out, btw), but rather about “can we think of a better way of doing this?”. In the end, the decision belongs to the core team - I just hope to offer a different (fresh?) perspective.
It took a bit of a detour but I’d say that the above defines my view of a possible implementation. Tagging method definitions with arity+type information which would allow the simultaneous definition of multiple methods without overwrites and would also allow disambiguation and explicit invocation. A possible syntax would be:
f<T,N>(x::T = T(), y::N = N()) = ...
So for
bar(s = "", i = 42) = # ...
Julia would generate the tagged methods
bar<String,Int64>(s::String, i::Int64)
bar<String,Int64>(s::String)
bar<String,Int64>()
And for
bar(s = "", sy = :s) = :x
Julia would generate
bar<String,Symbol>(s::String, sy::Symbol)
bar<String,Symbol>(s::String)
bar<String,Symbol>()
For disambiguation, where necessary, we could invoke the desired method as
bar<String,Int>()
The tagged invocation would be optional and only required for disambiguation, plain bar()
would still work if no ambiguities.
How other languages deal with this is indeed quite intriguing - I’ll do a bit of research into that, I’m curious too. If anything useful comes out, I’ll report back.