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

RFC: Allow tuples as type parameters. #5164

Merged
merged 2 commits into from
Dec 17, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions doc/manual/types.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.. _man-types:

*********
Types
Types
*********

Type systems have traditionally fallen into two quite different camps:
Expand Down Expand Up @@ -61,7 +61,7 @@ Julia's type system that should be mentioned up front are:
- Only values, not variables, have types — variables are simply names
bound to values.
- Both abstract and concrete types can be paramaterized by other types
and by certain other values (currently integers and symbols).
and by certain other values (currently integers, symbols, bools, and tuples thereof).
Type parameters may be completely omitted when they
do not need to be referenced or restricted.

Expand Down Expand Up @@ -1153,4 +1153,3 @@ If you apply ``super`` to other type objects (or non-type objects), a

julia> super((Float64,Int64))
ERROR: no method super(Type{(Float64,Int64)})

14 changes: 12 additions & 2 deletions src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1447,8 +1447,18 @@ int jl_types_equal_generic(jl_value_t *a, jl_value_t *b, int useenv)

static int valid_type_param(jl_value_t *v)
{
// TODO: maybe more things
return jl_is_type(v) || jl_is_long(v) || jl_is_symbol(v) || jl_is_typevar(v) || jl_is_bool(v);
if (jl_is_tuple(v)) {
size_t i;
size_t l = jl_tuple_len(v);
for(i=0; i < l; i++) {
if (!valid_type_param(jl_tupleref(v,i)))
return 0;
}
return 1;
} else {
// TODO: maybe more things
return jl_is_type(v) || jl_is_long(v) || jl_is_symbol(v) || jl_is_typevar(v) || jl_is_bool(v);
}
}

jl_value_t *jl_apply_type_(jl_value_t *tc, jl_value_t **params, size_t n)
Expand Down
24 changes: 24 additions & 0 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1181,6 +1181,7 @@ end
f5150(T) = Array(Rational{T},1)
@test typeof(f5150(Int)) === Array{Rational{Int},1}


# issue #5165
bitstype 64 T5165{S}
make_t(x::Int64) = Base.box(T5165{Nothing}, Base.unbox(Int64, x))
Expand All @@ -1189,3 +1190,26 @@ b5165 = IOBuffer()
for x in xs5165
println(b5165, x) # segfaulted
end

# support tuples as type parameters

type TupleParam{P}
x::Bool
end

function tupledispatch(a::TupleParam{(1,:a)})
a.x
end

let
# tuples can be used as type params
t1 = TupleParam{(1,:a)}(true)
t2 = TupleParam{(1,:b)}(true)

# tuple type params can't contain invalid type params
@test_throws t3 = TupleParam{(1,"nope")}(true)

# dispatch works properly
@test tupledispatch(t1) == true
@test_throws tupledispatch(t2)
end