Julia : Make method take array as parameter - julia

I'm currently programming in Julia and I want a method (The constructor of class ProbData) to take an array of a defined type as its parameter. What I'm currently doing is:
function ProbData(variables::AbstractArray{BaseVariable, 1})
instance = new()
instance.numPara = size(variables, 1)
instance.numRand = 0
for x = variables
if x.variableType != "Det"
instance.numRand += 1
end
end
instance.getNumPara = function()
return instance.numPara
end
instance.getNumRand = function()
return instance.numRand
end
return instance
end
BaseVariable is an abstract that has three subtypes. When I try to:
x = DetVariable("test", 0.15)
P = ProbData([x])
I get this error message:
ERROR: LoadError: MethodError: 'convert' has no method matching convert(::Type{ProbData}, ::Array{DetVariable.jl,1})
How can I fix this? I've just learned this language for a few days, so if you can point out what I shouldn't have done, I would appreciate it as well.
Edit: I've found out that if I defined the parameter array of the constructor to be an array of a certain type rather than an array of an abstract, the code would work properly. However, I need the parameter to be an array, whose elements could be of any subtype of BaseVariable.

Just change the function declaration to:
function ProbData{T<:BaseVariable}(variables::AbstractArray{T, 1})

Related

'UndefVarError: x not defined' when calling a macro outside of its module (Julia v1.1)

I'm trying to code a macro which calls a function defined within the same module (with Julia v1.1). I always get the ERROR: LoadError: UndefVarError: myModel not defined.
The code of the module is the following (Models.jl):
module Models
export Model
export createmodel
export add_variable
export #add_variable
mutable struct Model
variable_symbols::Dict{String, Symbol}
variable_data::Dict{Symbol, Array{Int64, 1}}
Model(; variable_symbols = Dict([]), variable_data = Dict([])) =
new(variable_symbols, variable_data)
Model(variable_symbols, variable_data) = new(variable_symbols,
variable_data)
end
function createmodel()
model = Model()
return model
end
function add_variable(model, label::String, value::Array{Int64, 1})
symbol = Symbol(label)
model.variable_symbols[label] = Symbol(symbol)
model.variable_data[symbol] = value
end
macro add_variable(model, var)
quote
add_variable($model, $(string(var)), $var)
end
end
end
The macro is called as following:
include("Models.jl")
using .Models
x = [1, 2, 3]
myModel = createmodel()
#add_variable(myModel, x)
show(myModel)
I know that this is an escaping/hygiene problem, but after trying many ideas I don't get the expected result. Up to now, my only way to get the expected result was to define the macro outside of the module to get: Model(Dict("x"=>:x), Dict(:x=>[1, 2, 3]))
You just need to escape the variables that get passed into the macro:
macro add_variable(model, var)
quote
add_variable($(esc(model)), $(string(var)), $(esc(var)))
end
end
All names in a macro are resolved in the context of the module its defined in unless you esc them — with an esc they're resolved in the context of the caller. You almost always want to esc the arguments to the macro. Names like add_variable, though, you want to resolve in the place where the macro itself was defined.

Check if a type implements an interface in Julia

How to check that a type implements an interface in Julia?
For exemple iteration interface is implemented by the functions start, next, done.
I need is to have a specialization of a function depending on wether the argument type implements a given interface or not.
EDIT
Here is an example of what I would like to do.
Consider the following code:
a = [7,8,9]
f = 1.0
s = Set()
push!(s,30)
push!(s,40)
function getsummary(obj)
println("Object of type ", typeof(obj))
end
function getsummary{T<:AbstractArray}(obj::T)
println("Iterable Object starting with ", next(obj, start(obj))[1])
end
getsummary(a)
getsummary(f)
getsummary(s)
The output is:
Iterable Object starting with 7
Object of type Float64
Object of type Set{Any}
Which is what we would expect since Set is not an AbstractArray. But clearly my second method only requires the type T to implement the iteration interface.
my issue isn't only related to the iteration interface but to all interfaces defined by a set of functions.
EDIT-2
I think my question is related to
https://github.com/JuliaLang/julia/issues/5
Since we could have imagined something like T<:Iterable
Typically, this is done with traits. See Traits.jl for one implementation; a similar approach is used in Base to dispatch on Base.iteratorsize, Base.linearindexing, etc. For instance, this is how Base implements collect using the iteratorsize trait:
"""
collect(element_type, collection)
Return an `Array` with the given element type of all items in a collection or iterable.
The result has the same shape and number of dimensions as `collection`.
"""
collect{T}(::Type{T}, itr) = _collect(T, itr, iteratorsize(itr))
_collect{T}(::Type{T}, itr, isz::HasLength) = copy!(Array{T,1}(Int(length(itr)::Integer)), itr)
_collect{T}(::Type{T}, itr, isz::HasShape) = copy!(similar(Array{T}, indices(itr)), itr)
function _collect{T}(::Type{T}, itr, isz::SizeUnknown)
a = Array{T,1}(0)
for x in itr
push!(a,x)
end
return a
end
See also Mauro Werder's talk on traits.
I would define a iterability(::T) trait as follows:
immutable Iterable end
immutable NotIterable end
iterability(T) =
if method_exists(length, (T,)) || !isa(Base.iteratorsize(T), Base.HasLength)
Iterable()
else
NotIterable()
end
which seems to work:
julia> iterability(Set)
Iterable()
julia> iterability(Number)
Iterable()
julia> iterability(Symbol)
NotIterable()
you can check whether a type implements an interface via methodswith as follows:
foo(a_type::Type, an_interface::Symbol) = an_interface ∈ [i.name for i in methodswith(a_type, true)]
julia> foo(EachLine, :done)
true
but I don't quite understand the dynamic dispatch approach you mentioned in the comment, what does the generic function looks like? what's the input & output of the function? I guess you want something like this?
function foo(a_type::Type, an_interface::Symbol)
# assume bar baz are predefined
if an_interface ∈ [i.name for i in methodswith(a_type, true)]
# call function bar
else
# call function baz
end
end
or some metaprogramming stuff to generate those functions respectively at compile time?

Julia: how to use type

struct MyData
data
# constructor
function MyData()
data = 1
end
end
myData = MyData()
myData.data #error
I assumed Julia's struct was just like struct in C. So I don't know why I get an error there:
type int64 has no field data
Functions in Julia return the last expression in them. In this case, it is data = 1, that is data is returned instead of new instance of MyData. Simply add line with new(data) after data = 1 to return new instance of MyData, and it will work properly.
Normally you want to use a so-called "outer constructor", i.e. a function of the same name that is defined outside the definition of the type itself. You also want to specify the type of each field as a concrete type, e.g. Int in this example:
struct MyType
data::Int
end
This has already defined, automatically, a couple of constructors:
x = MyType(3)
x.data
You can define new outer constructors, e.g. to have a default value:
MyType() = MyType(0) # defines a new constructor
x = MyType()
The kind of constructor you were trying to define is called an "inner constructor" (since it lives inside the type definition). It is used when there is something special that you want to force for each new object. For example, you could make sure that the data must be positive and throw and error if not:
struct MyType2
data::Int
function MyType2(x::Int)
if x <= 0
throw(ArgumentError("x must be positive"))
end
new(x)
end
end
x = MyType2(3)
y = MyType2(-17)
You should have a look at the documentation on constructors:
http://docs.julialang.org/en/release-0.4/manual/constructors/

Can I build a parameterless constructor for a parametric type in an outer constructor?

In order to instantiate a type like x = MyType{Int}()
I can define a inner constructor.
immutable MyType{T}
x::Vector{T}
MyType() = new(T[])
end
Is it possible to achieve the same objective using an outer constructor?
This can be done using the following syntax:
(::Type{MyType{T}}){T}() = MyType{T}(T[])
The thing in the first set of parentheses describes the called object. ::T means "of type T", so this is a definition for calling an object of type Type{MyType{T}}, which means the object MyType{T} itself. Next {T} means that T is a parameter of this definition, and a value for it must be available in order to call this definition. So MyType{Int} matches, but MyType doesn't. From there on, the syntax should be familiar.
This syntax is definitely a bit fiddly and unintuitive, and we hope to improve it in a future version of the language, hopefully v0.6.
I may be wrong, but if you cannot build parameterless function like this:
julia> f{T}() = show(T)
WARNING: static parameter T does not occur in signature for f at none:1.
The method will not be callable.
f (generic function with 1 method)
therefore you won't be able to do this:
julia> immutable MyType{T}
x::Vector{T}
end
julia> MyType{T}() = MyType{T}(T[])
WARNING: static parameter T does not occur in signature for call at none:1.
The method will not be callable.
MyType{T}
julia> x = MyType{Int}()
ERROR: MethodError: `convert` has no method matching convert(::Type{MyType{Int64}})
...
Every outer constructor is also a function.
You can say
f(T::Type) = show(T)
and also
MyType(T::Type) = MyType(T[])
But julia needs to see the type in the call to know which you want.

constrain argument to be in a set of values in Julia function signature

Is there a way in Julia to specify that a function argument can take one of a set of values through type annotations? For example, let's say I have function foo which accepts a single argument
function foo(x::String)
print(x)
end
the argument x can only be a String. Is there a way to further constrain it in the function signature so that it can only be for example one of the strings "right", "left", or "center"?
In Julia, the motto should be "There's a type for that!".
One way of handling this would be to create a type with a constructor that only allows the values you want (and possibly stores them in a more efficient manner).
Here is one example:
const directions = ["left", "right", "center"]
immutable MyDirection
Direction::Int8
function MyDirection(str::AbstractString)
i = findnext(directions, str, 1)
i == 0 && throw(ArgumentError("Invalid direction string"))
return new(i)
end
end
Base.show(io::IO, x::MyDirection) = print(io, string("MyDirection(\"",directions[x.Direction],"\")"))
function foo(x::MyDirection)
println(x)
end
function foo(str::AbstractString)
x = MyDirection(str)
println(x)
end
test = MyDirection("left")
foo(test)
foo("right")
Note: my example is written with Julia 0.4!
Edit:
Another approach would be to use symbols, such as :left, :right, and :center,
instead of strings.
These have the advantage of being interned (so that they can be compared simply by comparing their address), and they can also be used directly for type parameters.
For example:
immutable MyDirection{Symbol} ; end
function MyDirection(dir::Symbol)
dir in (:left, :right, :center) || error("invalid direction")
MyDirection{dir}()
end
MyDirection(dir::AbstractString) = MyDirection(symbol(dir))
That will let you do things like:
x = MyDirection("left")
which will create an immutable object of type MyDirection{:left}.
No, it is not. That would be dispatching on values, which isn't possible in Julia.
I'm not sure what your actual application is, but there are some possibly-appropriate workarounds to this, e.g.
abstract Sam81Args
type ArgRight <:Sam81Args end
type ArgLeft <:Sam81Args end
type ArgCenter <:Sam81Args end
function foo{T<:Sam81Args}(x::Type{T})
println(T)
end
foo(ArgCenter)

Resources