Resolving Julia 0.4 deprecation of Uint64 - julia

I want to create a 2D array of Uint64s in Julia 0.4. This worked in 0.3:
s = 128
a = zeros(Uint64, s, s)::Array{Uint64,2}
It continues to compile but gives me the notice
WARNING: Base.Uint64 is deprecated, use UInt64 instead.
I don't know what this message means. I've tried googling the error message but haven't found anything helpful. What is an equivalent line of code that will not produce any warnings?

s = 128
a = zeros(UInt64, s, s)::Array{UInt64,2}
Watch out for capitals!

Doug's answer is correct, except that you can simplify it to
s = 128
a = zeros(UInt64, s, s)
You don't need the type annotation ::Array{UInt64,2}. Defining a = zeros(UInt64, s, s) will create a variable which knows its type.
Note that the Julia error message was telling you what you had to do -- replace Uint64 by UInt64. If you can think of a better way of rephrasing the message to be clearer, that would be useful to hear.
In general, type annotations are at best redundant when defining variables in Julia -- the type is automatically inferred from the type of the right-hand side, and this will be the type assigned to the variable being created.
Type annotations are used in Julia in two circumstances:
1. to define the type of variables inside a composite type
2. for multiple dispatch in function definitions, to specify which types a given method applies to.

Related

Why does 'get' method of class 'Map' enable sending a not relevant key without a compilation error?

I just had a bug in my program, but i don't understand how the program was compiled at all!
I have the following variable:
gamesPerCountriesMap: MutableMap<Long, MutableMap<Long, MutableList<AllScoresGameObj>>>?
and i had the following line of code:
var gamesList = gamesPerCountriesMap?.get(countryItem.id)?.get(competitionItem)
the correct line should be:
var gamesList = gamesPerCountriesMap?.get(countryItem.id)?.get(competitionItem.id)
i have looked at the prototype of the Map class and the method is declared as following:
public inline operator fun <#kotlin.internal.OnlyInputTypes K, V> Map<out K, V>.get(key: K): V?
As we can see it can get K and it's subtype, but competitionItem which is an instacne of class CompetitionObj isn't inherit the Long class.
So why the compiler didn't prevent this error? I solved the issue but i am very couries of what is didn't prevent the code from being compiled?
There are two get methods for Map interface.
One is defined directly in the body of the interface:
Map<K, V> { fun get(key: K): V? }
Another (which you cite in your question) - as an extention function:
fun <K, V> Map<out K, V>.get(key: K): V?
The overload resolution on call depends on whether or not you explicitly specify generic parameters, and on relationship between type of map K generic parameter & type of passed key argument:
If you specify explicit generic parameter, the second version will be called (and it wouldn't have compiled in your case, if you've wrote .get()<Long, MutableList<AllScoresGameObj>.(competitionItem), although .get()<CompetitionObj, MutableList<AllScoresGameObj>.(competitionItem)) would've worked, cause there is unsafe cast inside this get overload).
If you omit explicit generic parameter, passing as a key:
an instance of K type (or its subtype) - the first overload will be called
anything else - the second overload (cause the first overload will not compile). In this case Kotlin will try to infer omitted generic parameters, so that original map could be represented as a Map<out inferredK, V> and inferredK type parameter was a supertype of passed key argument. Eventually, it will come up with inferredK = Any. Indeed Any is a supertype of everything, and it's perfectly legal to do val x: Map<out Any, V> = mapOf<K, V>() for any K. Actually compiler realizes that this is a trivial solution and issues a compilation warning Type inference failed. The value of the type parameter K should be mentioned in input types (argument types, receiver type or expected type). Try to specify it explicitly.(I believe in your case this warning should've been too). Why this still works in runtime? Because of type erasure.
So, why this overloaded version was added to stdlib?
Don't know for sure, maybe for some legal cases like:
val k : Base = Derived()
val v = mapOf<Derived, String>().get(k) // will call overloaded variant; will infer K as Base
without this overload you'd have to manually cast back:
val v = mapOf<Derived, String>().get(k as Derived)
Why two get methods?
Kotlin wants to inherit Java type system.
val x: kotlin.collections.List<String>= java.util.ArrayList<>()
Kotlin type system is different. One of the differences is declaration-site variance
Having
open class A
class B
It is illegal in Java
List<A> x = new ArrayList<B>();
But absolutely normal in Kotlin
val x: List<A> = ArrayList<B>()
As of the Map example I would expect
Error: Type inference failed. The value of the type parameter K should be mentioned in input types (argument types, receiver type or expected type). Try to specify it explicitly
whenever type inference is broken since Kotlin 1.0.0
If it's really a problem, it would be great to see a code paste and kotlin compiler version you are using.

Multiple dispatch in julia with the same variable type

Usually the multiple dispatch in julia is straightforward if one of the parameters in a function changes data type, for example Float64 vs Complex{Float64}. How can I implement multiple dispatch if the parameter is an integer, and I want two functions, one for even and other for odd values?
You may be able to solve this with a #generated function: https://docs.julialang.org/en/v1/manual/metaprogramming/#Generated-functions-1
But the simplest solution is to use an ordinary branch in your code:
function foo(x::MyType{N}) where {N}
if isodd(N)
return _oddfoo(x)
else
return _evenfoo(x)
end
end
This may seem as a defeat for the type system, but if N is known at compile-time, the compiler will actually select only the correct branch, and you will get static dispatch to the correct function, without loss of performance.
This is idiomatic, and as far as I know the recommended solution in most cases.
I expect that with type dispatch you ultimately still are calling after a check on odd versus even, so the most economical of code, without a run-time penatly, is going to be having the caller check the argument and call the proper function.
If you nevertheless have to be type based, for some reason unrelated to run-time efficiency, here is an example of such:
abstract type HasParity end
struct Odd <: HasParity
i::Int64
Odd(i::Integer) = new(isodd(i) ? i : error("not odd"))
end
struct Even <: HasParity
i::Int64
Even(i::Integer) = new(iseven(i) ? i : error("not even"))
end
parity(i) = return iseven(i) ? Even(i) : Odd(i)
foo(i::Odd) = println("$i is odd.")
foo(i::Even) = println("$i is even.")
for n in 1:4
k::HasParity = parity(n)
foo(k)
end
So here's other option which I think is cleaner and more multiple dispatch oriented (given by a coworker). Let's think N is the natural number to be checked and I want two functions that do different stuff depending if N is even or odd. Thus
boolN = rem(N,2) == 0
(...)
function f1(::Val{true}, ...)
(...)
end
function f1(::Val{false}, ...)
(...)
end
and to call the function just do
f1(Val(boolN))
As #logankilpatrick pointed out the dispatch system is type based. What you are dispatching on, though, is well established pattern known as a trait.
Essentially your code looks like
myfunc(num) = iseven(num) ? _even_func(num) : _odd_func(num)

In julia functions : passed by reference or value?

In julia how do we know if a type is manipulated by value or by reference?
In java for example (at least for the sdk):
the basic types (those that have names starting with lower case letters, like "int") are manipulated by value
Objects (those that have names starting with capital letters, like "HashMap") and arrays are manipulated by reference
It is therefore easy to know what happens to a type modified inside a function.
I am pretty sure my question is a duplicate but I can't find the dup...
EDIT
This code :
function modifyArray(a::Array{ASCIIString,1})
push!(a, "chocolate")
end
function modifyInt(i::Int)
i += 7
end
myarray = ["alice", "bob"]
modifyArray(myarray)
#show myarray
myint = 1
modifyInt(myint)
#show myint
returns :
myarray = ASCIIString["alice","bob", "chocolate"]
myint = 1
which was a bit confusing to me, and the reason why I submitted this question. The comment of #StefanKarpinski clarified the issue.
My confusion came from the fact i considred += as an operator , a method like push! which is modifying the object itself . but it is not.
i += 7 should be seen as i = i + 7 ( a binding to a different object ). Indeed this behavior will be the same for modifyArray if I use for example a = ["chocolate"].
The corresponding terms in Julia are mutable and immutable types:
immutable objects (either bitstypes, such as Int or composite types declared with immutable, such as Complex) cannot be modified once created, and so are passed by copying.
mutable objects (arrays, or composite types declared with type) are passed by reference, so can be modified by calling functions. By convention such functions end with an exclamation mark (e.g., sort!), but this is not enforced by the language.
Note however that an immutable object can contain a mutable object, which can still be modified by a function.
This is explained in more detail in the FAQ.
I think the most rigourous answer is the one in
Julia function argument by reference
Strictly speaking, Julia is not "call-by-reference" but "call-by-value where the value is a
reference" , or "call-by-sharing", as used by most languages such as
python, java, ruby...

Assert type information onto computed results in Julia

Problem
I read in an array of strings from a file.
julia> file = open("word-pairs.txt");
julia> lines = readlines(file);
But Julia doesn't know that they're strings.
julia> typeof(lines)
Array{Any,1}
Question
Can I tell Julia this somehow?
Is it possible to insert type information onto a computed result?
It would be helpful to know the context where this is an issue, because there might be a better way to express what you need - or there could be a subtle bug somewhere.
Can I tell Julia this somehow?
No, because the readlines function explicitly creates an Any array (a = {}): https://github.com/JuliaLang/julia/blob/master/base/io.jl#L230
Is it possible to insert type information onto a computed result?
You can convert the array:
r = convert(Array{ASCIIString,1}, w)
Or, create your own readstrings function based on the link above, but using ASCIIString[] for the collection array instead of {}.
Isaiah is right about the limits of readlines. More generally, often you can say
n = length(A)::Int
when generic type inference fails but you can guarantee the type in your particular case.
As of 0.3.4:
julia> typeof(lines)
Array{Union(ASCIIString,UTF8String),1}
I just wanted to warn against:
convert(Array{ASCIIString,1}, lines)
that can fail (for non-ASCII) while I guess, in this case nothing needs to be done, this should work:
convert(Array{UTF8String,1}, lines)

How to get generic type definition for CRTP type

Given the following CRTP type in C#:
public abstract class DataProviderBase<TProvider>
where TProvider : DataProviderBase<TProvider> { }
How would I get its generic type definition in F#?
let typeDef = typedefof<DataProviderBase<_>>
yields the error:
Type constraint mismatch when applying the default type 'DataProviderBase<'a>' for a type inference variable. The resulting type would be infinite when unifying ''a' and 'DataProviderBase<'a>' Consider adding further type constraints
In C#, it would be:
var typeDef = typeof(DataProviderBase<>);
UPDATE
I found a workaround:
[<AbstractClass>]
type DummyProvider() =
inherit DataProviderBase<DummyProvider>()
let typeDef = typeof<DummyProvider>.BaseType.GetGenericTypeDefinition()
Is there another way to do it, without the extra type?
I think this is actually a very good question. I didn't find a better workaround for this.
You can slightly simplify your workaround by using typedefof like this:
let typeDef = typedefof<DataProviderBase<DummyProvider>>
TECHNICAL DETAILS
The problem is that F#'s typedefof<'T> is just an ordinary function that takes a type argument (unlike typeof in C#, which is an operator). In order to call it, you need to give it an actual type and the function will then call GetGenericTypeDefinition under the cover.
The reason why typedefof<option<_>> works is that F# specifies a default type as an argument (in this case obj). In general, F# chooses the less concrete type that matches the constraints. In your case:
DataProviderBase<_> will become DataProviderBase<DataProviderBase<_>> and so on.
Unless you define a new type (as in your workaround), there is no concrete type that could be used as a type argument of typedefof<...>. In this case, the defaulting mechanism simply doesn't work...

Resources