# Base.call() in Julia 0.6

#1

Hi All,

I can’t find information about the usage of base.call in Julia 0.6, but it breaks some code I have and that works well in Julia 0.5…

The function I am trying to run is

``````immutable SavitzkyGolayFilter{M,N} end

@generated function Base.call{M,N,T}(::Type{SavitzkyGolayFilter{M,N}},
data::AbstractVector{T})

#Create Jacobian matrix
J = zeros(2M+1, N+1)
for i=1:2M+1, j=1:N+1
J[i, j] = (i-M-1)^(j-1)
end
e₁ = zeros(N+1)
e₁[1] = 1.0

#Compute filter coefficients
C = J' \ e₁

#Evaluate filter on data matrix

To = typeof(C[1] * one(T)) #Calculate type of output
expr = quote
n = size(data, 1)
smoothed = zeros(\$To, n)
@inbounds for i in eachindex(smoothed)
smoothed[i] += \$(C[M+1])*data[i]
end
smoothed
end

for j=1:M
insert!(expr.args[6].args[2].args[2].args, 1,
:(if i - \$j ≥ 1
smoothed[i] += \$(C[M+1-j])*data[i-\$j]
end)
)
push!(expr.args[6].args[2].args[2].args,
:(if i + \$j ≤ n
smoothed[i] += \$(C[M+1+j])*data[i+\$j]
end)
)
end

return expr
end
``````

And it returns a

`LoadError: UndefVarError: call not defined`

in Julia 0.6. I think I have missed something there ?

#2

`Base.call` was deprecated in v0.5, it has been removed in v0.6.
I guess you could do something like this:

`@generated function (::SavitzkyGolayFilter{M,N})(data::AbstractVector{T}) where {M, N, T}`

#3

Thanks, I did not know about that.

I tried the piece of code you suggested but got an error: UndefVarError: M not defined

I don’t understand how I should declare the generated function there… Any idea?

#4
``````immutable SavitzkyGolayFilter{M,N} end
@generated function (::SavitzkyGolayFilter{M,N})(data::AbstractVector{T}) where {M, N, T}
#Create Jacobian matrix
J = zeros(2M+1, N+1)
for i=1:2M+1, j=1:N+1
J[i, j] = (i-M-1)^(j-1)
end
e₁ = zeros(N+1)
e₁[1] = 1.0

#Compute filter coefficients
C = J' \ e₁

#Evaluate filter on data matrix

To = typeof(C[1] * one(T)) #Calculate type of output
expr = quote
n = size(data, 1)
smoothed = zeros(\$To, n)
@inbounds for i in eachindex(smoothed)
smoothed[i] += \$(C[M+1])*data[i]
end
smoothed
end

for j=1:M
insert!(expr.args[6].args[2].args[2].args, 1,
:(if i - \$j ≥ 1
smoothed[i] += \$(C[M+1-j])*data[i-\$j]
end)
)
push!(expr.args[6].args[2].args[2].args,
:(if i + \$j ≤ n
smoothed[i] += \$(C[M+1+j])*data[i+\$j]
end)
)
end

return expr
end
``````

This snippet works fine in julia-v0.6. Here are some tests:

``````julia> sgf = SavitzkyGolayFilter{3,2}()
SavitzkyGolayFilter{3,2}()

julia> sgf(1:10)
10-element Array{Float64,1}:
0.952381
1.90476
3.0
4.0
5.0
6.0
7.0
9.04762
8.57143
6.38095
``````

is this what you were looking for?

#5

Yes, indeed, it works in Julia V0.6, but not in v0.5.2… I got a first error:

syntax: space before “{” not allowed in “where {”

and if I correct it by removing the space I get the error

UndefVarError: M not defined

#6

`where` is a new syntax introduced in v0.6. In v0.5.2, your original version should work.

#7

Yes, it works in 0.5.2, but is there any chance to make it work for both 0.5.2 and 0.6?

#8

the corresponding version of `where` in v0.5 is `@generated function (::SavitzkyGolayFilter{M,N}){M,N,T}(data::AbstractVector{T})` which works fine in both v0.5 and v0.6