Skip to content
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

Unions with static type parameters are problematic #3738

Closed
GunnarFarneback opened this issue Jul 17, 2013 · 8 comments
Closed

Unions with static type parameters are problematic #3738

GunnarFarneback opened this issue Jul 17, 2013 · 8 comments
Labels
types and dispatch Types, subtyping and method dispatch

Comments

@GunnarFarneback
Copy link
Contributor

This works:

julia> f(x::Int; y::Union(Symbol, Int)=:foo) = println(y)
# methods for generic function f
f(x::Int64) at none:1

julia> f(1)
foo

julia> f(1, y=:bar)
bar

julia> f(1, y=3)
3

A parametric version instead fails with a cryptic message:

julia> g{T}(x::T; y::Union(Symbol, T)=:foo) = println(y)
# methods for generic function g
g{T}(x::T) at none:1

julia> g(1)
ERROR: no method g#g2(Symbol,Int64)

julia> g(1, y=:bar)
ERROR: no method g#g2(Symbol,Int64)

julia> g(1, y=3)
3

Possibly related, this should be an error but less cryptic and preferrably when the function is defined rather than used.

julia> h(x::Int; y::Int=0.0) = println(y)
# methods for generic function h
h(x::Int64) at none:1

julia> h(1)
ERROR: no method h#g3(Float64,Int64)
@JeffBezanson
Copy link
Member

Union with static parameters is generally problematic. Given a tuple of unions, determining valid assignments of the static parameters requires a probably-NP-complete matching algorithm that the type system so far declines to implement. A few easy cases are handled by the greedy approximation I use, but it's easiest just to keep static parameters out of unions for now. I should probably implement the full thing eventually...I hope N is small :)

@ihnorton
Copy link
Member

Should this be documented somewhere as a gotcha, for 0.2? (I ran in to it trying to use None as a default argument)

@nalimilan
Copy link
Member

I've just ran into this. This would be very useful since in many cases keyword arguments need to have a "no-op" default, specified by nothing, and a "real" vector value. In my use case, the user can specify weights, and nothing means no weighting; weights can be a vector of any Number, thus I need to use a parametric union.

@mbauman mbauman changed the title Parametric union for keyword argument Unions with static type parameters are problematic Feb 11, 2015
@mbauman
Copy link
Member

mbauman commented Feb 11, 2015

As Jeff alludes to, this isn't unique to keyword arguments. I've updated the title to make it a bit more obvious for future searchers.

The following modification to the above keyword case is a nice reduced example:

julia> type Foo{T} x::T end

julia> g{T}(x::Foo{T}, y::Union(Symbol, T)) = println(y)
g (generic function with 1 method)

julia> g(Foo(1), :bar)
ERROR: MethodError: `g` has no method matching g(::Foo{Int64}, ::Symbol)
Closest candidates are:
  g{T}(::Foo{T}, ::Union(Symbol,T))

julia> g(Foo(1), 1)
1

julia> g(Foo(:baz), :qux)
qux

It didn't occur to me that the parameter within the union would also try to match, as opposed to simply binding to the result of the match in the other (non-Union) arguments. It seems like that'd be a decent simplification to the NP-complete problem and yet work in almost all of the useful cases, no?

@nalimilan
Copy link
Member

@JeffBezanson Does the partial solution suggested by @mbauman sound reasonable to you?

@mbauman
Copy link
Member

mbauman commented Nov 13, 2015

That doesn't quite work since a common use for type-parameter matching within unions is *{T<:BlasFloat}(A::StridedArray{T,2}, x::StridedArray{T,1}), where StridedArray is actually a typealias for a Union with type parameters.

An alternate idea I played with a few weeks ago is disallowing Unions whose components are non-orthoganol in method signatures… but I didn't manage to see it the whole way through.

@timholy
Copy link
Member

timholy commented Apr 22, 2016

All of these examples are fixed on master.

@tkelman
Copy link
Contributor

tkelman commented Aug 19, 2016

All of these examples are fixed on master.

Do we know what fixed them? Are there corresponding tests?

Keno pushed a commit that referenced this issue Dec 21, 2023
Stdlib: Pkg
URL: https://github.com/JuliaLang/Pkg.jl.git
Stdlib branch: master
Julia branch: master
Old commit: 85f1e5564
New commit: 3c86ba27e
Julia version: 1.11.0-DEV
Pkg version: 1.11.0
Bump invoked by: @IanButterworth
Powered by:
[BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl)

Diff:
JuliaLang/Pkg.jl@85f1e55...3c86ba2

```
$ git log --oneline 85f1e5564..3c86ba27e
3c86ba27e add `add --weak/extra Foo` to add to [weakdeps] or [extras] (#3708)
2e640f92f respect --color=no in Pkg.precompile (#3740)
cbd5d08ad Automatically add compat entries when adding deps to a package (#3732)
03de920b3 rm old manual handling of `--compiled-modules` (#3738)
314d5497b Use realpaths for temp dirs during tests. Fix SparseArrays `why` breakage (#3734)
a6531d4be environments.md: update Julia version (#3715)
a509bc062 Revise the API of is_manifest_current. (#3701)
60b7b7995 rm incorrect kwargs in add docstring (#3733)
```

Co-authored-by: Dilum Aluthge <dilum@aluthge.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
types and dispatch Types, subtyping and method dispatch
Projects
None yet
Development

No branches or pull requests

7 participants