I am able to define a type struct foo{N}
where N
is an Int
, but can I do this with N
being a BigInt
?
Yes, it should be possible with any type.
Or did you encounter an issue with it?
Yes. I’m still struggling. Is there a good example on the web?
struct MyType{T}
x:: T
end
MyType(big(42))
Here’s where I’m having a problem:
struct Mod{N}
val
function Mod(x::T, N::S) where {S<:Integer, T<:Integer}
new{N}(mod(x,N))
end
end
julia> Mod(10,20)
Mod{20}(10)
julia> Mod(10,big(20))
ERROR: TypeError: in Type, in parameter, expected Int64, got BigInt
Stacktrace:
[1] Mod(::Int64, ::BigInt) at ./REPL[1]:8
[2] top-level scope at REPL[14]:1
I don’t think this is true. The manual says:
Both abstract and concrete types can be parameterized by other types. They can also be parameterized by symbols, by values of any type for which
isbits
returns true (essentially, things like numbers and bools that are stored like C types orstruct
s with no pointers to other objects), and also by tuples thereof. Type parameters may be omitted when they do not need to be referenced or restricted.
Alas:
julia> isbits(big(100))
false
struct Mod{N}
val:: N
function Mod(x::T, N::S) where {S<:Integer, T<:Integer}
new{S}(mod(x,N))
end
end
Mod(10,big(20))
You need to give the type parameter S as type to new.
In addition, you shoud define the type of val to be N, otherwise it would be of type Any.
I’m pretty sure this is a solution to the wrong problem. Unless I’m mistaken, @scheinerman is trying to make the value big(20)
a type parameter, not the type BigInt
. That’s not possible for the reasons posted above.
Thanks for the clarification and sorry for the misunderstanding on my side!
BigInt
is technically mutable (because that’s how GMP works), so it can’t be used as a type parameter, which must be immutable. However, if you just need something slightly larger than 64 bits, you could look into https://github.com/rfourquet/BitIntegers.jl.
Technically, the problem is not that the type is mutable or immutable but that if it isbits
or not. An immutable type can return a false value for isbits
and therefore not be eligible to be a value parameter.
Yes, but the semantic problem is mostly mutability (or pointers to mutable things). The isbits
is a bit of an implementation detail that I would like to change: https://github.com/JuliaLang/julia/issues/33387
Very interesting. I did not consider the Union
case, in fact. I was just pointing that an immutable struct
can have, in fact, fields of types that are not isbits
, so by consequence it becomes not isbits
even being immutable itself. Unless you are using a recursive definition of immutability, of course.