@vchuravy, sounds good. I just use what’s in the language, if I can get enough books, documentation, and help. I’m just starting on some things. There’s plenty of work to do before these features get added.
Below I include a more expanded example, which I worked out because of the type inference tip from @mauro3. I show how I check the signature of a function r
in the constructor.
My example leads to two questions, which you may or may not have time to answer.
- Because I define an inner constructor, using the inner constructor
Foo
doesn’t work unless I annotate it with types, as shown below at #(3).
- My workaround, if I wanted to use the inner constructor, would be to put a dummy variable in the inner constructor, and define an outer constructor that’s the same, except for the dummy var.
- Is there something I need so that the inner constructor can be used without having to use
Foo{Int, Function, Function}
?
- The runtime check in the constructor for
r
actually greatly improves the LLVM code, as shown at (1). That’s one more lesson for me, related to this thread, that type inference is everything. This is not really a question, just an observation that may warrant an informative comment from someone.
The code
type Foo{T, F1<:Function, F2<:Function}
v::T
R::F1 # F1 :: T -> Bool, domain restriction
r::Nullable{F2} # F2 :: () -> T, random value generator
function Foo(v::T, R::F1, r::Nullable{F2})
if !isnull(r) && !(get(r)()|>typeof == T)
error("BAD 'r' return type")
end
R(v) ? new(v,R,r) : error("BAD R(v)")
end
end
function Foo{T, F<:Function}(v::T, R::F)
Foo{T,F,Function}(v, R, Nullable{Function}())
end
function Foo{T, F1<:Function, F2<:Function}(v::T, R::F1, f2::F2)
Foo{T,F1,F2}(v, R, Nullable{F2}(f2))
end
#(1) GOOD LLVM: but not if I remove the use of 'r' in the inner constructor.
@code_llvm Foo(1, t::Int -> t > 0, () -> 0)
#(2) DOESN'T WORK: but it will work if I remove the inner constructor.
#Foo(1, t::Int -> t > 0, Nullable{Function}())
# ERROR: LoadError: MethodError: no method matching
# Foo(::Int, ::##5#6, ::Nullable{Function})
#(3) DOES WORK: but I lose good type inference and get bad LLVM.
Foo{Int, Function, Function}(1, t::Int -> t > 0, Nullable{Function}())
@code_llvm Foo{Int, Function, Function}(1, t::Int -> t > 0, Nullable{Function}())