How to make a variable length tuple with inferred type

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

How to make a variable length tuple with inferred type

Sheehan Olver
I'm doing the following:


immutable FooIterator{d} end

Base.start(::FooIterator{d}) = tuple(zeros(Int,d)...)::NTuple{d,Int}


But is there a more elegant way of getting the type inferred?  I suppose I can override low order d directly:

Base.start(::FooIterator{2}) = (0,0)
Base.start(::FooIterator{3}) = (0,0,0)
Reply | Threaded
Open this post in threaded view
|

Re: How to make a variable length tuple with inferred type

David P. Sanders


El domingo, 31 de julio de 2016, 20:16:04 (UTC-4), Sheehan Olver escribió:
I'm doing the following:


immutable FooIterator{d} end

Base.start(::FooIterator{d}) = tuple(zeros(Int,d)...)::NTuple{d,Int}


You can use the `ntuple` function, which constructs a tuple from a function:

julia> ntuple( x -> 0, 3)
(0,0,0)

julia> typeof(ans)
Tuple{Int64,Int64,Int64}
 


But is there a more elegant way of getting the type inferred?  I suppose I can override low order d directly:

Base.start(::FooIterator{2}) = (0,0)
Base.start(::FooIterator{3}) = (0,0,0)
Reply | Threaded
Open this post in threaded view
|

Re: How to make a variable length tuple with inferred type

Sheehan Olver
It still doesn't infer the type in 0.5:

julia> @code_warntype ntuple( x -> 0, 3)

Variables:

  #self#::Base.#ntuple

  f::##5#6

  n::Int64


Body:

  begin 

      unless (Base.sle_int)(n::Int64,0)::Bool goto 3

      return (Core.tuple)()::Tuple{}

      3: 

      unless (n::Int64 === 1)::Bool goto 6

      return (Core.tuple)($(QuoteNode(0)))::Tuple{Int64}

      6: 

      unless (n::Int64 === 2)::Bool goto 9

      return (Core.tuple)($(QuoteNode(0)),$(QuoteNode(0)))::Tuple{Int64,Int64}

      9: 

      unless (n::Int64 === 3)::Bool goto 12

      return (Core.tuple)($(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)))::Tuple{Int64,Int64,Int64}

      12: 

      unless (n::Int64 === 4)::Bool goto 15

      return (Core.tuple)($(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)))::Tuple{Int64,Int64,Int64,Int64}

      15: 

      unless (n::Int64 === 5)::Bool goto 18

      return (Core.tuple)($(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)))::Tuple{Int64,Int64,Int64,Int64,Int64}

      18: 

      unless (Base.slt_int)(n::Int64,16)::Bool goto 21

      return (Core._apply)(Core.tuple,$(Expr(:invoke, LambdaInfo for ntuple(::##5#6, ::Int64), :(Base.ntuple), :(f), :((Base.box)(Int64,(Base.sub_int)(n,5))))),(Core.tuple)($(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)))::Tuple{Int64,Int64,Int64,Int64,Int64})::Tuple{Vararg{Any,N}}

      21: 

      return $(Expr(:invoke, LambdaInfo for _ntuple(::Function, ::Int64), :(Base._ntuple), :(f), :(n)))

  end::Tuple


On Monday, August 1, 2016 at 10:34:30 AM UTC+10, David P. Sanders wrote:


El domingo, 31 de julio de 2016, 20:16:04 (UTC-4), Sheehan Olver escribió:
I'm doing the following:


immutable FooIterator{d} end

Base.start(::FooIterator{d}) = tuple(zeros(Int,d)...)::NTuple{d,Int}


You can use the `ntuple` function, which constructs a tuple from a function:

julia> ntuple( x -> 0, 3)
(0,0,0)

julia> typeof(ans)
Tuple{Int64,Int64,Int64}
 


But is there a more elegant way of getting the type inferred?  I suppose I can override low order d directly:

Base.start(::FooIterator{2}) = (0,0)
Base.start(::FooIterator{3}) = (0,0,0)
Reply | Threaded
Open this post in threaded view
|

Re: How to make a variable length tuple with inferred type

Simon Danisch
In reply to this post by Sheehan Olver
How about:
julia> @code_warntype ntuple( x -> 0, Val{3})
Variables:
  #self#::Base.#ntuple
  f::##1#2
  #unused#::Type{Val{3}}

Body:
  begin
      $(Expr(:static_parameter, 2)) # line 73:
      # meta: location tuple.jl _ntuple 80
      # meta: location tuple.jl _ntuple 80
      SSAValue(1) = $(QuoteNode(0))
      # meta: pop location
      # meta: pop location
      return (Core.tuple)(SSAValue(1),$(QuoteNode(0)),$(QuoteNode(0)))::Tuple{Int64,Int64,Int64}
  end::Tuple{Int64,Int64,Int64}

Am Montag, 1. August 2016 02:16:04 UTC+2 schrieb Sheehan Olver:
I'm doing the following:


immutable FooIterator{d} end

Base.start(::FooIterator{d}) = tuple(zeros(Int,d)...)::NTuple{d,Int}


But is there a more elegant way of getting the type inferred?  I suppose I can override low order d directly:

Base.start(::FooIterator{2}) = (0,0)
Base.start(::FooIterator{3}) = (0,0,0)
Reply | Threaded
Open this post in threaded view
|

Re: How to make a variable length tuple with inferred type

Sheehan Olver
Cool!

Sent from my iPhone

On 1 Aug 2016, at 17:23, Simon Danisch <[hidden email]> wrote:

How about:
julia> @code_warntype ntuple( x -> 0, Val{3})
Variables:
  #self#::Base.#ntuple
  f::##1#2
  #unused#::Type{Val{3}}

Body:
  begin
      $(Expr(:static_parameter, 2)) # line 73:
      # meta: location tuple.jl _ntuple 80
      # meta: location tuple.jl _ntuple 80
      SSAValue(1) = $(QuoteNode(0))
      # meta: pop location
      # meta: pop location
      return (Core.tuple)(SSAValue(1),$(QuoteNode(0)),$(QuoteNode(0)))::Tuple{Int64,Int64,Int64}
  end::Tuple{Int64,Int64,Int64}

Am Montag, 1. August 2016 02:16:04 UTC+2 schrieb Sheehan Olver:
I'm doing the following:


immutable FooIterator{d} end

Base.start(::FooIterator{d}) = tuple(zeros(Int,d)...)::NTuple{d,Int}


But is there a more elegant way of getting the type inferred?  I suppose I can override low order d directly:

Base.start(::FooIterator{2}) = (0,0)
Base.start(::FooIterator{3}) = (0,0,0)
mmh
Reply | Threaded
Open this post in threaded view
|

Re: How to make a variable length tuple with inferred type

mmh
In reply to this post by Sheehan Olver
Is this a known bug/regression?

On Sunday, July 31, 2016 at 10:53:11 PM UTC-4, Sheehan Olver wrote:
It still doesn't infer the type in 0.5:

julia> @code_warntype ntuple( x -> 0, 3)

Variables:

  #self#::Base.#ntuple

  f::##5#6

  n::Int64


Body:

  begin 

      unless (Base.sle_int)(n::Int64,0)::Bool goto 3

      return (Core.tuple)()::Tuple{}

      3: 

      unless (n::Int64 === 1)::Bool goto 6

      return (Core.tuple)($(QuoteNode(0)))::Tuple{Int64}

      6: 

      unless (n::Int64 === 2)::Bool goto 9

      return (Core.tuple)($(QuoteNode(0)),$(QuoteNode(0)))::Tuple{Int64,Int64}

      9: 

      unless (n::Int64 === 3)::Bool goto 12

      return (Core.tuple)($(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)))::Tuple{Int64,Int64,Int64}

      12: 

      unless (n::Int64 === 4)::Bool goto 15

      return (Core.tuple)($(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)))::Tuple{Int64,Int64,Int64,Int64}

      15: 

      unless (n::Int64 === 5)::Bool goto 18

      return (Core.tuple)($(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)))::Tuple{Int64,Int64,Int64,Int64,Int64}

      18: 

      unless (Base.slt_int)(n::Int64,16)::Bool goto 21

      return (Core._apply)(Core.tuple,$(Expr(:invoke, LambdaInfo for ntuple(::##5#6, ::Int64), :(Base.ntuple), :(f), :((Base.box)(Int64,(Base.sub_int)(n,5))))),(Core.tuple)($(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)))::Tuple{Int64,Int64,Int64,Int64,Int64})::Tuple{Vararg{Any,N}}

      21: 

      return $(Expr(:invoke, LambdaInfo for _ntuple(::Function, ::Int64), :(Base._ntuple), :(f), :(n)))

  end::Tuple


On Monday, August 1, 2016 at 10:34:30 AM UTC+10, David P. Sanders wrote:


El domingo, 31 de julio de 2016, 20:16:04 (UTC-4), Sheehan Olver escribió:
I'm doing the following:


immutable FooIterator{d} end

Base.start(::FooIterator{d}) = tuple(zeros(Int,d)...)::NTuple{d,Int}


You can use the `ntuple` function, which constructs a tuple from a function:

julia> ntuple( x -> 0, 3)
(0,0,0)

julia> typeof(ans)
Tuple{Int64,Int64,Int64}
 


But is there a more elegant way of getting the type inferred?  I suppose I can override low order d directly:

Base.start(::FooIterator{2}) = (0,0)
Base.start(::FooIterator{3}) = (0,0,0)
Reply | Threaded
Open this post in threaded view
|

Re: How to make a variable length tuple with inferred type

Kristoffer Carlsson
Nope. nuple(::Function, ::Int) is not type stable because the return type depends on the value of the integer.

On Monday, August 1, 2016 at 5:17:10 PM UTC+2, mmh wrote:
Is this a known bug/regression?

On Sunday, July 31, 2016 at 10:53:11 PM UTC-4, Sheehan Olver wrote:
It still doesn't infer the type in 0.5:

julia> @code_warntype ntuple( x -> 0, 3)

Variables:

  #self#::Base.#ntuple

  f::##5#6

  n::Int64


Body:

  begin 

      unless (Base.sle_int)(n::Int64,0)::Bool goto 3

      return (Core.tuple)()::Tuple{}

      3: 

      unless (n::Int64 === 1)::Bool goto 6

      return (Core.tuple)($(QuoteNode(0)))::Tuple{Int64}

      6: 

      unless (n::Int64 === 2)::Bool goto 9

      return (Core.tuple)($(QuoteNode(0)),$(QuoteNode(0)))::Tuple{Int64,Int64}

      9: 

      unless (n::Int64 === 3)::Bool goto 12

      return (Core.tuple)($(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)))::Tuple{Int64,Int64,Int64}

      12: 

      unless (n::Int64 === 4)::Bool goto 15

      return (Core.tuple)($(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)))::Tuple{Int64,Int64,Int64,Int64}

      15: 

      unless (n::Int64 === 5)::Bool goto 18

      return (Core.tuple)($(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)))::Tuple{Int64,Int64,Int64,Int64,Int64}

      18: 

      unless (Base.slt_int)(n::Int64,16)::Bool goto 21

      return (Core._apply)(Core.tuple,$(Expr(:invoke, LambdaInfo for ntuple(::##5#6, ::Int64), :(Base.ntuple), :(f), :((Base.box)(Int64,(Base.sub_int)(n,5))))),(Core.tuple)($(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)))::Tuple{Int64,Int64,Int64,Int64,Int64})::Tuple{Vararg{Any,N}}

      21: 

      return $(Expr(:invoke, LambdaInfo for _ntuple(::Function, ::Int64), :(Base._ntuple), :(f), :(n)))

  end::Tuple


On Monday, August 1, 2016 at 10:34:30 AM UTC+10, David P. Sanders wrote:


El domingo, 31 de julio de 2016, 20:16:04 (UTC-4), Sheehan Olver escribió:
I'm doing the following:


immutable FooIterator{d} end

Base.start(::FooIterator{d}) = tuple(zeros(Int,d)...)::NTuple{d,Int}


You can use the `ntuple` function, which constructs a tuple from a function:

julia> ntuple( x -> 0, 3)
(0,0,0)

julia> typeof(ans)
Tuple{Int64,Int64,Int64}
 


But is there a more elegant way of getting the type inferred?  I suppose I can override low order d directly:

Base.start(::FooIterator{2}) = (0,0)
Base.start(::FooIterator{3}) = (0,0,0)
mmh
Reply | Threaded
Open this post in threaded view
|

Re: How to make a variable length tuple with inferred type

mmh
Care to explain in more depth? If the function is type stable i.e. it returns an Int for an Int input then why would ntuple(::Function,::Int) not be type stable?  What do you mean by the return type depends on the "value" of the integer (it's an integer!). Am I misunderstanding?



On Monday, August 1, 2016 at 11:40:25 AM UTC-4, Kristoffer Carlsson wrote:
Nope. nuple(::Function, ::Int) is not type stable because the return type depends on the value of the integer.

On Monday, August 1, 2016 at 5:17:10 PM UTC+2, mmh wrote:
Is this a known bug/regression?

On Sunday, July 31, 2016 at 10:53:11 PM UTC-4, Sheehan Olver wrote:
It still doesn't infer the type in 0.5:

julia> @code_warntype ntuple( x -> 0, 3)

Variables:

  #self#::Base.#ntuple

  f::##5#6

  n::Int64


Body:

  begin 

      unless (Base.sle_int)(n::Int64,0)::Bool goto 3

      return (Core.tuple)()::Tuple{}

      3: 

      unless (n::Int64 === 1)::Bool goto 6

      return (Core.tuple)($(QuoteNode(0)))::Tuple{Int64}

      6: 

      unless (n::Int64 === 2)::Bool goto 9

      return (Core.tuple)($(QuoteNode(0)),$(QuoteNode(0)))::Tuple{Int64,Int64}

      9: 

      unless (n::Int64 === 3)::Bool goto 12

      return (Core.tuple)($(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)))::Tuple{Int64,Int64,Int64}

      12: 

      unless (n::Int64 === 4)::Bool goto 15

      return (Core.tuple)($(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)))::Tuple{Int64,Int64,Int64,Int64}

      15: 

      unless (n::Int64 === 5)::Bool goto 18

      return (Core.tuple)($(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)))::Tuple{Int64,Int64,Int64,Int64,Int64}

      18: 

      unless (Base.slt_int)(n::Int64,16)::Bool goto 21

      return (Core._apply)(Core.tuple,$(Expr(:invoke, LambdaInfo for ntuple(::##5#6, ::Int64), :(Base.ntuple), :(f), :((Base.box)(Int64,(Base.sub_int)(n,5))))),(Core.tuple)($(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)))::Tuple{Int64,Int64,Int64,Int64,Int64})::Tuple{Vararg{Any,N}}

      21: 

      return $(Expr(:invoke, LambdaInfo for _ntuple(::Function, ::Int64), :(Base._ntuple), :(f), :(n)))

  end::Tuple


On Monday, August 1, 2016 at 10:34:30 AM UTC+10, David P. Sanders wrote:


El domingo, 31 de julio de 2016, 20:16:04 (UTC-4), Sheehan Olver escribió:
I'm doing the following:


immutable FooIterator{d} end

Base.start(::FooIterator{d}) = tuple(zeros(Int,d)...)::NTuple{d,Int}


You can use the `ntuple` function, which constructs a tuple from a function:

julia> ntuple( x -> 0, 3)
(0,0,0)

julia> typeof(ans)
Tuple{Int64,Int64,Int64}
 


But is there a more elegant way of getting the type inferred?  I suppose I can override low order d directly:

Base.start(::FooIterator{2}) = (0,0)
Base.start(::FooIterator{3}) = (0,0,0)
Reply | Threaded
Open this post in threaded view
|

Re: How to make a variable length tuple with inferred type

John Myles White

This example should clarify where you're confused:


julia> typeof(ntuple(x -> 1, 1))

Tuple{Int64}


julia> typeof(ntuple(x -> 1, 2))

Tuple{Int64,Int64}


On Tuesday, August 2, 2016 at 2:34:27 PM UTC-5, mmh wrote:
Care to explain in more depth? If the function is type stable i.e. it returns an Int for an Int input then why would ntuple(::Function,::Int) not be type stable?  What do you mean by the return type depends on the "value" of the integer (it's an integer!). Am I misunderstanding?



On Monday, August 1, 2016 at 11:40:25 AM UTC-4, Kristoffer Carlsson wrote:
Nope. nuple(::Function, ::Int) is not type stable because the return type depends on the value of the integer.

On Monday, August 1, 2016 at 5:17:10 PM UTC+2, mmh wrote:
Is this a known bug/regression?

On Sunday, July 31, 2016 at 10:53:11 PM UTC-4, Sheehan Olver wrote:
It still doesn't infer the type in 0.5:

julia> @code_warntype ntuple( x -> 0, 3)

Variables:

  #self#::Base.#ntuple

  f::##5#6

  n::Int64


Body:

  begin 

      unless (Base.sle_int)(n::Int64,0)::Bool goto 3

      return (Core.tuple)()::Tuple{}

      3: 

      unless (n::Int64 === 1)::Bool goto 6

      return (Core.tuple)($(QuoteNode(0)))::Tuple{Int64}

      6: 

      unless (n::Int64 === 2)::Bool goto 9

      return (Core.tuple)($(QuoteNode(0)),$(QuoteNode(0)))::Tuple{Int64,Int64}

      9: 

      unless (n::Int64 === 3)::Bool goto 12

      return (Core.tuple)($(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)))::Tuple{Int64,Int64,Int64}

      12: 

      unless (n::Int64 === 4)::Bool goto 15

      return (Core.tuple)($(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)))::Tuple{Int64,Int64,Int64,Int64}

      15: 

      unless (n::Int64 === 5)::Bool goto 18

      return (Core.tuple)($(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)))::Tuple{Int64,Int64,Int64,Int64,Int64}

      18: 

      unless (Base.slt_int)(n::Int64,16)::Bool goto 21

      return (Core._apply)(Core.tuple,$(Expr(:invoke, LambdaInfo for ntuple(::##5#6, ::Int64), :(Base.ntuple), :(f), :((Base.box)(Int64,(Base.sub_int)(n,5))))),(Core.tuple)($(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)),$(QuoteNode(0)))::Tuple{Int64,Int64,Int64,Int64,Int64})::Tuple{Vararg{Any,N}}

      21: 

      return $(Expr(:invoke, LambdaInfo for _ntuple(::Function, ::Int64), :(Base._ntuple), :(f), :(n)))

  end::Tuple


On Monday, August 1, 2016 at 10:34:30 AM UTC+10, David P. Sanders wrote:


El domingo, 31 de julio de 2016, 20:16:04 (UTC-4), Sheehan Olver escribió:
I'm doing the following:


immutable FooIterator{d} end

Base.start(::FooIterator{d}) = tuple(zeros(Int,d)...)::NTuple{d,Int}


You can use the `ntuple` function, which constructs a tuple from a function:

julia> ntuple( x -> 0, 3)
(0,0,0)

julia> typeof(ans)
Tuple{Int64,Int64,Int64}
 


But is there a more elegant way of getting the type inferred?  I suppose I can override low order d directly:

Base.start(::FooIterator{2}) = (0,0)
Base.start(::FooIterator{3}) = (0,0,0)