Why Explore.myRow(::Int64) instead of UInt8


#1
  1. In the following snippet, why does the error message report "Explore.myRow(::Int64) " rather than UInt8? (Ignoring the inexactness, that was deliberate to provoke an error message.) I am trying to reduce memory usage, so I’d like to make sure myTable is not wasting memory when it will have a million rows. Is the ‘whos’ command sufficient for verifying this?

  2. What difference does it make if I code myTable as a Vector instead of Array? Are they the same?

‘’'
immutable myRow
secId::UInt8
end

myTable=Array{myRow}()

push!(myTable,myRow(-1))
’’'
LoadError: InexactError()
while loading /Users/mymachine/Projects/juliaNLP/explore.jl, in expression starting on line 35
in Explore.myRow(::Int64) at explore.jl:30
in include_string(::String, ::String) at loading.jl:441
in include_string(::String, ::String) at sys.dylib:?
in include_string(::Module, ::String, ::String) at eval.jl:32
in (::Atom.##59#62{String,String})() at eval.jl:81
in withpath(::Atom.##59#62{String,String}, ::String) at utils.jl:30
in withpath(::Function, ::String) at eval.jl:46
in macro expansion at eval.jl:79 [inlined]
in (::Atom.##58#61{Dict{String,Any}})() at task.jl:60


#2

I believe it’s because you’ve called myRow() with an input of type Int64. Julia doesn’t parse the literal -1 differently just because you’re calling a function that will eventually expect a UInt8, so that -1 becomes an Int64 as usual.

  1. What difference does it make if I code myTable as a Vector instead of Array? Are they the same?

Vector is an alias for a 1-dimensional array:

julia> immutable Foo
       end

julia> Vector{Foo} === Array{Foo, 1}
true

Note that your code declares myTable as an Array{myRow}(), which actually creates a zero-dimensional array (since you haven’t specified the number of dimensions):

julia> Array{Foo}()
0-dimensional Array{Foo,0}:
Foo()

You can explicitly put the number of dimensions, or just use the Vector shorthand:

julia> Vector{Foo}()
0-element Array{Foo,1}

julia> Array{Foo, 1}()
0-element Array{Foo,1}

As for memory consumption, I’m afraid I don’t know.


#3

Thanks for the info about vector being an alias of a 1-dim array.

Back to my first question: do I need to explicity call convert on the parse result to ensure that it becomes UInt8 when stored, or is that happening behind-the-scenes, or is myRow itself being converted to hold Int64s intead of UInt8s?


#4
julia> immutable myRow
       secId::UInt8
       end

julia> myRow(-1)
ERROR: InexactError()

The problem is that the default constructor is trying to convert -1 into a UInt8 in order to go into that field. However, convert throws an inexact error because it’s nonsensical:

julia> convert(UInt8,1)
0x01

julia> convert(UInt8,-1)
ERROR: InexactError()

That’s the method you are invoking. You are invoking myRow on an Int64 (so, you’re on a 64-bit computer). It’s saying that function is returning an error.

It will only store UInt8's, because that’s what you told it to do. Immutables are value types and, other than a small tag, just store your values. It’s not dynamic: it won’t keep extra room just in case you put in more. An immutable, as a value type, also just holds the values, not pointers. When you put them in a vector, the vector will specialize to the type if everything is concretely typed, making it efficient in memory. Many times a function can compile away the abstraction of the immutable too.

Yes, whos will tell you the memory usage.