Hello,
I am new to Nim and try to find my way thru the manual and "Nim in Action". But I do not fully understand range types yet. I have experiences in Ada and try to use Nim's type system to check types to same degree.
I want to define a new range type that is different from all the other types. I do this by
type IndexRange = distinct range[-1 .. 1000]
Now I want to define a subtype of IndexRange but with a slight distinct range. Like this (not working):
type
ValidIndices = range[IndexRange(0) .. IndexRange(1000)]
IndicesArray = array[T, low(ValidIndices) .. high(ValidIndices)]
That means ValidIndexes will span the same range like IndexRange except for the -1.
My goal is to have an array IndicesArray that can only be indexed by values of ValidIndices. The value -1 of IndexRange will indicate that it does not index into a IndicesArray.
Is such a type definition possible in Nim?
Thanks for any enlightment ...
Ciao, chi :-)
Should work like this:
type
IndexRange = distinct range[-1 .. 1000]
ValidIndices = range[int(IndexRange(0)) .. int(IndexRange(1000))]
IndicesArray[T] = array[low(ValidIndices) .. high(ValidIndices), T]
You need to convert back to an int to get an ordinal value because your IndexRange is distinct. But this doesn't seem particularly useful because the value is not checked to be in the range of IndexRange anyway. That's probably a bug as it is checked for a variable, but not a range parameter.
Edit: My bad, seems to work, but only when the type is instantiated. Something to keep in mind, but not a bug.
Shouldn't this refer to IndexRange.high?
type
ValidIndices = range[0 .. int(high(IndexRange))]
Btw, how do we initialize an IndicesArray[int]?Btw, how do we initialize an IndicesArray[int]?
var x: IndicesArray[int]
x[0] = 0
x[1] = 10
# ...
Thank you all for your proposals. However they don't do what I have in mint unfortunately.
I would like to define ValidIndices to be a subtype of IndexRange. IndexRange is a distinct type. As such it cannot be mixed with other ordinal types. Fine! However ValidIndices should be a subtype of IndexRange and therefore can be mixed with IndexRange as long as the appropiate range definitions are observed.
I would like to declare a variable like this:
var arr : IndicesArray[int]
var idx : IndexRange
This variable idx would be set to -1 if it does not pointing into arr. However idx having any other value but -1 it should still be possible to use idx to index an element of arr as the base type of ValidIndices is also a IndexRange. For instance:
idx = IndexRange(12)
echo arr[idx]
without any conversion. The same time a simple arr[12] would not compile due to distinctness of IndexRange and its subtype ValidIndices.
Is it possible to model the types like that?
Ciao, chi.
@Chi
Being curious, how would you do it in Ada?
@ManfredLotz
In Ada I would define
type IndexRange is new Integer range -1 .. 1000;
subtype ValidIndices is IndexRange range 0 .. IndexRange'Last;
type IndicesArray is array(ValidIndices'Range) of Integer;
I can freely assign an IndexRange to a ValidRange as long as the value is within ValidRange's 0 .. 1000. Assignment vice versa is possible without problems anytime.
I try to achieve the same in Nim :-)
Ciao, chi :)
I meant, how do we initialize an IndicesArray[int] from an array?
E.g., with 1 instead of 1000 (and after fixing my typos):
var x: IndicesArray[int] = [5, 6]
That works. I expected to have to cast, but no.