This could help if both parts of the union were plain old data like Int64
and Float64, but in the case of Int and BigInt, one of them is a more
complex type, which would currently force the whole thing to be boxed and
live in the heap anyway. What's needed here is the ability to
stack-allocate objects that refer to the heap. We cannot do that now, but
it is an important planned CG improvement.

On Fri, Apr 8, 2016 at 11:28 AM, Scott Jones <scott.paul.jo...@gmail.com>
wrote:

> I like very much the idea of a discriminated union - that would help
> enormously with some of the stuff I work on.
>
>
> On Friday, April 8, 2016 at 8:47:59 AM UTC-4, Erik Schnetter wrote:
>
>> Laurent
>>
>> I'm afraid you can't use `reinterpret` with a type such as `BigInt`.
>>
>> I think what you want is an extension of `Nullable`: A nullable type
>> represents an object of a particular type that might or might not be
>> there; there's hope that this would be done efficiently, e.g. via an
>> additional bit. What you want is an efficient representation of a
>> discriminated union -- a type that can represent either of two types,
>> but without the overhead from boxing the types as is currently done in
>> a `Union`. Unfortunately, Julia currently doesn't provide this, but it
>> would make sense to have a feature request for this.
>>
>> This might look like this:
>> ```Julia
>> immutable FastInt
>>     val::DiscriminatedUnion{Int, BigInt}
>> end
>> function (+)(a::FastInt, b::FastInt)
>>     if typeindex(a.val) == 1 & typeindex(b.val) == 1
>>         ov,res = add_with_overflow(a.val[1], b.val[1])
>>         ov && return FastInt(BigInt(res))
>>         return FastInt(res)
>>     end
>>     # TODO: handle mixed case
>>     FastInt(a.val[2] + b.val[2])
>> end
>> ```
>>
>> This would be the same idea as yours, but the `reinterpret` occurs
>> within Julia, in a type-safe and type-stable manner, in a way such
>> that the compiler can optimize better.
>>
>> You could try defining a type that contains two fields, both an `Int`
>> and a `BigInt` -- maybe `BigInt` will handle the case of a value that
>> is never used in a more efficient manner that doesn't require
>> allocating an object.
>>
>> -erik
>>
>> On Fri, Apr 8, 2016 at 2:07 AM, Laurent Bartholdi
>> <laurent....@gmail.com> wrote:
>> > Dear all,
>> > How hard would it be to code arbitrary-precision integers in Julia with
>> at
>> > worst 2x performance loss over native Ints?
>> >
>> > This is what I have in mind: have a bitstype structure, say 64 bits,
>> which
>> > is either the address of a BigInt (if even), or an Int64 (if odd).
>> Addition
>> > would be something like:
>> >
>> > function +(a::FastInt,b::FastInt)
>> >     if a&b&1
>> >         (result,obit) = @llvm.sadd.with.overflow.i64(a,b&~1)
>> >         obit ? reinterpret(FastInt,BigInt(a>>1)+(b>>1)) : result
>> >     elseif a&1
>> >         reinterpret(FastInt,(a>>1) + reinterpret(BigInt,b))
>> >     elseif b&1
>> >         reinterpret(FastInt,reinterpret(BigInt,a) + b>>1)
>> >     else
>> >         reinterpret(FastInt,reinterpret(BigInt,a) +
>> reinterpret(BigInt,b))
>> >     end
>> > end
>> >
>> > (code not meant to be run, just a skeleton)
>> >
>> > This would be very useful in the development of computer algebra
>> systems, in
>> > which BigInts are too slow and eat up too much memory, but one is ready
>> to
>> > pay a small price for guard against arithmetic overflows.
>> >
>> > If this is too complicated, then perhaps at least a type of integers
>> that
>> > would raise an error in case of over/underflows? Those could be caught
>> in
>> > throw/catch enclosures, so the user could restart the operation with
>> > BigInts.
>> >
>> > TIA, Laurent
>>
>>
>>
>> --
>> Erik Schnetter <schn...@gmail.com>
>> http://www.perimeterinstitute.ca/personal/eschnetter/
>>
>

Reply via email to