NaN and negative values in an undefined array / how to test for correct construction of a Type

#1

I’ve created a type:

struct MarketIndex <: Asset
value::Array{Float64}
end

Then I constructed an instance of it, like so:

market = MarketIndex(Array{Float64}(undef, 1000))

Although the entries of the array are said to be undefined, they actually hold values. Most of these values are just > 0, but a few are also NaN and others are <0.
Question 1: Why is that?

I’m trying test-driven development, so before writing the above wrote a test that all elements in MyType are non-negative:

@test all(market.value .>= 0)

I see now that this didn’t make much sense, since the array hasn’t been assigned any sensible values yet.
Questions2: What simple test should I have written to test for the construction of a MarketIndex?

#2

Documentation is here: https://docs.julialang.org/en/v1/base/arrays/index.html#Core.undef

Essentially, undef gives you random stuff - think of it as assigning some chunk of memory to hold your array, and showing whatever is there. To turn your question around: you say “the entries (…) actually hold values”, but what would you have expected undefined to look like?

I’m not sure I understand your question 2 - what do you mean by “testing for the construction of a MarketIndex”? Are you trying to work out whether your constructor works? Maybe something like

market = MarketIndex(Array{Float64}(undef, 1000))
isa(market, MarketIndex)
1 Like
#3

An undefined array’s contents are… undefined. Creating an undef array means Julia will allocate space for it in memory, but not write anything to that memory. The contents might be all zero bytes (in the case of freshly allocated pages of memory from the operating system), or they might be reused from some other object in your Julia process which has been recently destroyed. Your program should never rely on the contents of an undef array being any particular value.

I even wrote a little blog post about this a few years ago: http://blog.robindeits.com/2017/02/27/reading-raw-memory-with-julia/

2 Likes
#4

Thanks for the isa() suggestion. I was trying to write a test that requires me to construct a certain type for it to pass. The isa() approach seems a bit self-referential, but I guess it’s entirely appropriate. It looked to me like undefined creates random tiny values like those shown in the documentation and so I structured my test around there being an array of such values, but I see now why that’s not sensible. An easier opion might be to set zeros when constructing the array, I just thought that it would be more evident where the array remained untouched during the running of the programme if I used undefined values. (I’m clearly overcomplicating things in an effort to improve my work flow).