I will look into Traits.jl -- interesting package.

To get traction and some of the great power of comparability, the base
library will need to be carefully decomposed into traits, which (as noted
in some of the issue conversations on github) takes you straight to the
great research Haskell is doing in this area.

*Sebastian Good*


On Fri, Nov 21, 2014 at 9:38 AM, John Myles White <johnmyleswh...@gmail.com>
wrote:

> This sounds a bit like a mix of two problems:
>
> (1) A lack of interfaces:
>
>  - a) A lack of formal interfaces, which will hopefully be addressed by
> something like Traits.jl at some point. (
> https://github.com/JuliaLang/julia/issues/6975)
>
>  - b) A lack of documentation for informal interfaces, such as the methods
> that AbstractArray objects must implement.
>
> (2) A lack of delegation when you make wrapper types:
> https://github.com/JuliaLang/julia/pull/3292
>
> The first has moved forward a bunch thanks to Mauro's work. The second has
> not gotten much further, although Kevin Squire wrote a different delegate
> macro that's noticeably better than the draft I wrote.
>
>  -- John
>
> On Nov 21, 2014, at 2:31 PM, Sebastian Good <
> sebast...@palladiumconsulting.com> wrote:
>
> In implementing new kinds of numbers, I've found it difficult to know just
> how many functions I need to implement for the general library to "just
> work" on them. Take as an example a byte-swapped, e.g. big-endian, integer.
> This is handy when doing memory-mapped I/O on a file with data written in
> network order. It would be nice to just implement, say, Int32BigEndian and
> have it act like a real number. (Then I could just reinterpret a mmaped
> array and work directly off it) In general, we'd convert to Int32 at the
> earliest opportunity we had. For instance the following macro introduces a
> new type which claims to be derived from $base_type, and implements
> conversions and promotion rules to get it into a native form ($n_type)
> whenever it's used.
>
> macro encoded_bitstype(name, base_type, bits_type, n_type, to_n, from_n)
>     quote
>         immutable $name <: $base_type
>             bits::$bits_type
>         end
>
>         Base.bits(x::$name) = bits(x.bits)
>         Base.bswap(x::$name) = $name(bswap(x.bits))
>
>         Base.convert(::Type{$n_type}, x::$name) = $to_n(x.bits)
>         Base.convert(::Type{$name}, x::$n_type) = $name($from_n(x))
>         Base.promote_rule(::Type{$name}, ::Type{$n_type}) = $n_type
>         Base.promote_rule(::Type{$name}, ::Type{$base_type}) = $n_type
>     end
> end
>
> I can use it like this
>
> @encoded_bitstype(Int32BigEndian, Signed, Int32, Int32, bswap, bswap)
>
> But unfortunately, it doesn't work out of the box because the conversions
> need to be explicit. I noticed that many of the math functions promote
> their arguments to a common type, but the following trick doesn't work,
> presumably because the promotion algorithm doesn't ask to promote types
> that are already identical.
>
>         Base.promote_rule(::Type{$name}, ::Type{$name}) = $n_type
>
> It seems like there are a couple of issues this raises, and I know I've
> seen similar questions on this list as people implement new kinds of
> things, e.g. exotic matrices.
>
> 1. One possibility would be to allow an implicit promotion, perhaps
> expressed as the self-promotion above. I say I'm a Int32BigEndian, or
> CompressedVector, or what have you, and provide a way to turn me into an
> Int32 or Vector implicitly to take advantage of all the functions already
> written on those types. I'm not sure this is a great option for the
> language since it's been explicitly avoided elsewhere. but I'm curious if
> there have been any discussions in this direction
>
> 2. If instead I want to say "this new type acts like an Integer", there's
> no canonical place for me to find out what all the functions are I need to
> implement. Ultimately, these are like Haskell's typeclasses, Ord, Eq, etc.
> By trial and error, we can determine many of them and implement them this
> way
>
> macro as_number(name, n_type)
>      quote
>         global +(x::$name, y::$name) = +(convert($n_type, x),
> convert($n_type, y))
>         global *(x::$name, y::$name) = *(convert($n_type, x),
> convert($n_type, y))
>         global -(x::$name, y::$name) = -(convert($n_type, x),
> convert($n_type, y))
>         global -(x::$name) = -convert($n_type, x)
>         global /(x::$name, y::$name) = /(convert($n_type, x),
> convert($n_type, y))
>         global ^(x::$name, y::$name) = ^(convert($n_type, x),
> convert($n_type, y))
>         global ==(x::$name, y::$name) = (==)(convert($n_type, x),
> convert($n_type, y))
>         global < (x::$name, y::$name) = (< )(convert($n_type, x),
> convert($n_type, y))
>         Base.flipsign(x::$name, y::$name) = Base.flipsign(convert($n_type,
> x), convert($n_type, y))
>     end
> end
>
> But I don't know if I've found them all, and my guesses may well change as
> implementation details inside the base library change. Gradual typing is
> great, but with such a powerful base library already in place, it would be
> good to have a facility to know which functions are associated with which
> named behaviors.
>
> Since we already have abstract classes in place, e.g. Signed, Number,
> etc., it would be natural to extract a list of functions which operate on
> them, or, even better, allow the type declarer to specify which functions
> *should* operate on that abstract class, typeclass or interface style?
>
> Are there any recommendations in place, or updates to the language
> planned, to address these sorts of topics?
>
>
>
>
>
>
>

Reply via email to