The following should work in principle but somehow the type inference
does not agree with codegen...

```julia

julia> @inline bar{N}(::NTuple{N}) = N
bar (generic function with 1 method)

julia> foo(args...) = bar(args)
foo (generic function with 1 method)

julia> @code_warntype foo(1, 2, 3)
Variables:
  args::Tuple{Int64,Int64,Int64}

Body:
  begin  # none, line 1:
      return 3
  end::Int64

julia> foo(1, 2, 3)
3

julia> @code_llvm foo(1, 2, 3)

define %jl_value_t* @julia_foo_21108(%jl_value_t*, %jl_value_t**, i32) {
top:
  %3 = alloca [4 x %jl_value_t*], align 8
  %.sub = getelementptr inbounds [4 x %jl_value_t*]* %3, i64 0, i64 0
  %4 = getelementptr [4 x %jl_value_t*]* %3, i64 0, i64 2
  %5 = getelementptr [4 x %jl_value_t*]* %3, i64 0, i64 3
  %6 = bitcast [4 x %jl_value_t*]* %3 to i64*
  store i64 4, i64* %6, align 8
  %7 = getelementptr [4 x %jl_value_t*]* %3, i64 0, i64 1
  %8 = bitcast %jl_value_t** %7 to %jl_value_t***
  %9 = load %jl_value_t*** @jl_pgcstack, align 8
  store %jl_value_t** %9, %jl_value_t*** %8, align 8
  store %jl_value_t** %.sub, %jl_value_t*** @jl_pgcstack, align 8
  store %jl_value_t* null, %jl_value_t** %4, align 8
  store %jl_value_t* null, %jl_value_t** %5, align 8
  %10 = call %jl_value_t* @jl_f_tuple(%jl_value_t* null, %jl_value_t**
%1, i32 %2)
  store %jl_value_t* %10, %jl_value_t** %4, align 8
  store %jl_value_t* %10, %jl_value_t** %5, align 8
  %11 = call %jl_value_t* @jl_apply_generic(%jl_value_t* inttoptr (i64
140728696104080 to %jl_value_t*), %jl_value_t** %5, i32 1)
  %12 = load %jl_value_t*** %8, align 8
  store %jl_value_t** %12, %jl_value_t*** @jl_pgcstack, align 8
  ret %jl_value_t* %11
}
```

On Sun, Jul 19, 2015 at 6:03 PM, David Gold <[email protected]> wrote:
> Also, what's wrong with
>
> `foo(args...) = length(args)`
>
> ? Seems like that ought to achieve your desired result.
>
> On Sunday, July 19, 2015 at 5:43:30 PM UTC-4, Tomas Lycken wrote:
>>
>> Hi everybody,
>>
>> I created the function
>>
>>     foo{N}(bar::NTuple{N}...) = N
>>
>> under the impression that I'd be able to do
>>
>>     julia> foo(2, 3)
>>     2
>>     julia> foo(1, 2, 3, 4, 5, 6, 7)
>>     7
>>     julia foo("bar", "qux", 3, rand(10))
>>     4
>>
>> but all the above yield no-method errors, since the `NTuple` isn't
>> splatted in the signature. The following works, though:
>>
>>     julia> foo((2,3))
>>     2
>>
>> so if I actually pass a tuple, it works. However,
>>
>>     julia> methods(foo)
>>     # 1 method for generic function "foo":
>>     foo{N}(bar::NTuple...) at none:1
>>
>> does show the splatting `...`. so I assume there's some difference between
>> the definition of `foo` and a similar function
>>
>>     bar{N}(foo::NTuple{N}) = N
>>
>> which doesn't splat. The behavior of `foo` above is what I would expect
>> (and what I get) from `bar`.
>>
>> I realize I'm probably trying to do something semi-pathological here, but
>> it'd be really nice if it was possible to make `foo` work the way I want it
>> too (and without `@ngenerate`, if I get to choose...). I seem to recall some
>> discussion that mentioned a way to do this, but I can't remember where (or
>> even if it was mentioned as a solution or as a suggestion for future
>> language features...).
>>
>> What is the actual difference between `foo` and `bar` above? How can I get
>> the behavior I want from `foo`?
>>
>> Regards,
>>
>> // T

Reply via email to