Kevin, I just announced https://github.com/Jeffrey-Sarnoff/Delegate.jl <https://www.google.com/url?q=https%3A%2F%2Fgithub.com%2FJeffrey-Sarnoff%2FDelegate.jl&sa=D&sntz=1&usg=AFQjCNHTBYGzcvaZidLimgK3JlXU8s14Zg> -- it does what you want.
On Saturday, June 11, 2016 at 12:15:23 PM UTC-4, Kevin Squire wrote: > > Hi Kevin, > > As you're gleaming, you will need to implement a set of basic functions, > and that set isn't tiny. That said, once you implement this minimal set, > your type should be usable everywhere else that a Real is accepted (even > when that doesn't always make sense). > > For some idea of what is needed, check out: > > https://github.com/JeffBezanson/FixedPointNumbers.jl > https://github.com/JuliaDiff/DualNumbers.jl > > You also might check out the @delegate macro in DataStructures.jl: > > https://github.com/JuliaLang/DataStructures.jl/blob/master/src/delegate.jl > > https://github.com/JuliaLang/DataStructures.jl/blob/master/src/default_dict.jl#L52-L54 > > As for why this isn't more straightforward, check out the section of the > docs on Types (especially the 4th paragraph): > > http://docs.julialang.org/en/release-0.4/manual/types/#types > > That said, I'm curious how you would define a new bitstype (Int, Float, > etc.) in other languages? In Julia, this is at least possible, and when > you define the things you need, these are as first class and efficient as > Int, Float64, etc. (Of course, using them with non-Julia libraries might > not work if these types don't exist in the language those libraries were > written in.) > > In fact, all of these (Int64, Float64, etc.) are defined in Julia--none > are actually "built-in", so to speak. As far as I know, there are very few > other languages which allow you to define types at this level. (Examples, > anyone?) > > Anyway, good luck in your explorations! > > Cheers, > Kevin > > On Sat, Jun 11, 2016 at 8:42 AM, Jeffrey Sarnoff <[email protected] > <javascript:>> wrote: > >> This way of which you speak, there are whispers ... Let me become strong >> with milk of Yak, for I must swim with the Platypus of Insight as dawn >> is drawn from glimmer to glisten. >> ... . .... ..... ..... ...... ... .. . (writing becomes written) >> >> >> On Saturday, June 11, 2016 at 11:09:34 AM UTC-4, Kevin Kunzmann wrote: >>> >>> Taking your last example to the console, still I cannot add two >>> "Probabilities" despite them being instances of a subtype of "Real". What I >>> was looking for is the Julian way of thinking about inherited behaviour >>> from numeric types. Now, I slowly wrap my mind around the idea that there s >>> nothing to inherit... >>> But srsly, is there no way of making all functions that accept Reals >>> also accept Probabilities? I can't reimplement them all, can I? Think of >>> *(a,b), sin(a), /(a,b) >>> >>> On Saturday, 11 June 2016 09:40:38 UTC+2, Jeffrey Sarnoff wrote: >>>> >>>> , as 'Real' is expecting it to be named 'val'? Jeez, >>>> >>>> No, Real is an abstract type that is closer to being a label sewn to >>>> the root of a tree -- Real does not have any investment in how you name >>>> the >>>> fields of your type. >>>> >>>> There is no way of telling which fileds are accessed how by all methods >>>>> operating on that type x >>>> >>>> One scenario, you designed the type and determine the sorts of >>>> information to be held as fields of the type. You write specializations >>>> of >>>> generic methods that pertain to using the type. In that situation, your >>>> actively maintained documentation knows and tells or you revisit your own >>>> source code for that knowledge. In any event, Julia is happy to help, >>>> providing you with easily introduced method specific notes. Another >>>> scenario, you did the same thing and I want to use the type. Well, I'd >>>> look at the README.md file and if any, other docs. Then, knowing the care >>>> you take with programming, and seeing from a few simples examples you >>>> provide that values of this Probability type are floating point >>>> representations of independent likelihoods ... >>>> I would use the type without any desire to know which field(s) are read >>>> or altered in the process of determining the probability than any one of >>>> my >>>> five experts in origami will hand me a paper swan to drop from up here >>>> before the building closes. >>>> >>>> the cleanest way to ensure that I pass a valid probability to my >>>>> function (figure between 0 and 1) >>>> >>>> Do you want to raise an exception if a value is neither zero nor one >>>> nor between zero and one? >>>> Do you want to clamp negative values to zero and clamp positive values >>>> above one to one? >>>> Or do you want to clamp values that are within, say, -1//4096 .. >>>> +4097//4096, and throw an exception outside of that range? >>>> >>>> (in this circumstance, for 'type' use 'immutable' and your typed values >>>> will live and move in memory just like Float64 values. without interposed >>>> indiirection.) >>>> >>>> immutable Probability >>>> val::Float64 >>>> >>>> Probability(val::Float64) = ( 0.0 <= val <= 1.0 ) ? new(val) : >>>> throw(ErrorException("Probabilities must be within 0..1")) >>>> end >>>> >>>> (do you prefer the field name 'p' and to clamp the value?) >>>> >>>> immutable Probability >>>> p::Float64 >>>> >>>> Probability(p::Float64) = new( max(0.0. min(p, 1.0)) ) >>>> end >>>> >>>> Probability{T<:Real}(x::T) = Probability( convert(Float64, x) ) >>>> >>>> >>>> >>>> >>>> On Saturday, June 11, 2016 at 1:54:42 AM UTC-4, Kevin Kunzmann wrote: >>>>> >>>>> Hey, >>>>> >>>>> thanks for sticking with me ;) >>>>> >>>>> I am, however, a little bit confused now (seems that oo and >>>>> parallelism are the hardest to grasp in julia). >>>>> >>>>> I see that '+' was a bad example. So my error was, that I did not name >>>>> the field correctly, as 'Real' is expecting it to be named 'val'? Jeez, >>>>> if >>>>> this is true then how is one ever going to 'inherit correctly' from a >>>>> complicated abstract type? There is no way of telling which fileds are >>>>> accessed how by all methods operating on that type x) >>>>> >>>>> So, put simply: What is the Julia way of ensuring that I pass a valid >>>>> probability to my function (figure between 0 and 1). Please do not tell >>>>> me >>>>> that I am supposed to use @assert statements x) >>>>> I would feel that a new type would be the cleanest way to do so? >>>>> >>>>> Best, >>>>> >>>>> Kevin >>>>> >>>>> On Saturday, 11 June 2016 04:37:32 UTC+2, Jeffrey Sarnoff wrote: >>>>>> >>>>>> Hi Kevin, >>>>>> >>>>>> Right questions, different way. >>>>>> >>>>>> Julia's type system is >>>>>> of shared behavior for sharing behaviors. >>>>>> for specialization as constructive delegation >>>>>> >>>>>> Real is an abstract type that is supertype to some other abstract >>>>>> types >>>>>> (Integer, Rational, FloatingPoint, FixedPoint, Probability, ...). >>>>>> >>>>>> [all kinds of] >>>>>> >>>>>> Each immediate subtype of the Real is an abstract type that is >>>>>> supertype to some type[s]. >>>>>> For every individual immediate subtype of Real, that individual is >>>>>> supertype to abstract types and/or/orelse to concrete types. >>>>>> Bool >>>>>> <: Integer <: Real >>>>>> Union{ Int32, Int64 } <: Signed <: Integer <: >>>>>> Real >>>>>> Union{ Rational{Int32}, Rational{Int64} } <: Rational <: Real >>>>>> >>>>>> *note that ..currently.. there is not* Integer <: >>>>>> Rational <: Real, >>>>>> as ..currently.. all type-based inheritance may associate a >>>>>> concrete type with an abstraction >>>>>> and that abstraction may be elaborated as a long chain >>>>>> linking single supertypes >>>>>> or may associate a concrete type with the concretion of >>>>>> concrete constituents given as its field's types >>>>>> orelse carry some of both manner of information, an enfolding >>>>>> of the elaborative and the constitutive. >>>>>> >>>>>> in the early Summer of 2016: >>>>>> Single inheritance of abstract type, and an inheriting abstract >>>>>> type may itself be inherited. >>>>>> One single inheritance of an abstract type by a Concrete type, >>>>>> and the same, jointly or independently for each of its >>>>>> concretely typed fields. >>>>>> Any type, abstract or concrete can be defined with one or more >>>>>> parameters (a parameterized type), >>>>>> each distinct value(s of the tuple) of the parameter >>>>>> constitutes a uniquely defined type, >>>>>> there is support for specifying manner of co-action and >>>>>> interaction for parameterized type 'siblings', >>>>>> as there is for specifying the interworking of types and >>>>>> intraworkings of values of a single type. >>>>>> >>>>>> The architects know how to let abstract types be functionally >>>>>> dispatchable into, just as sqrt(x::Int64) and sqrt(x::Float64) are >>>>>> dispatched into specializations of sqrt() for a Int64 or for a Float64 >>>>>> argument. >>>>>> The mechanism is being rethought so that a better, more widely useful >>>>>> way obtain (does this and makes >>>>>> it easy to process with and fully support software interface >>>>>> protocols -- and enforce api constraints). >>>>>> >>>>>> Meanwhile "inheriting from Real" does give the type fallback >>>>>> processing for basic mathematical handling, >>>>>> and also encourages some reimplementation, if only to delegate the >>>>>> calculation to the type's value field. >>>>>> Multiplying two probabilities as reals gives a result that smaller >>>>>> than either (or equal to smaller of the two), >>>>>> which is not what happens to the probability of a win when more >>>>>> skilled players join in the effort. >>>>>> >>>>>> Enjoy, >>>>>> >>>>>> Jeffrey >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> There is desire and activity intending >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> which is not the same as red marbles are a color of Marbleness >>>>>> sculpted of a Material inheritance. >>>>>> types >>>>>> Integers are Real, Rationals are Real Integers are not >>>>>> Rationals >>>>>> >>>>>> >>>>>> (you are reading how it is >>>>>> >>>>>> On Fri, Jun 10, 2016 at 6:15 PM, Kevin Kunzmann <[email protected]> >>>>>> wrote: >>>>>> >>>>>>> Hey Jeffrey, >>>>>>> >>>>>>> it's been a while, thx for the answer. I see that this would be >>>>>>> working. However, what about min, max, sin, etc.? I do not want to >>>>>>> re-implement all elementary functions for the Probability type. There >>>>>>> must >>>>>>> be some way to inherit the behaviour of the abstract supertype "Real". >>>>>>> I >>>>>>> guess I am missing something fundamental about the type system here. >>>>>>> >>>>>>> I felt tat something like >>>>>>> >>>>>>> type Probability{T<:Real} <:Real >>>>>>> p::T >>>>>>> end >>>>>>> >>>>>>> import Base.convert >>>>>>> >>>>>>> convert{T<:Real}(::Type{T}, x::Probability) = convert(T, x.p) >>>>>>> convert{T1<:Real, T2<:Real}(::Type{Probability{T1}}, x::T2) = >>>>>>> Probability(convert(T1, x)) >>>>>>> >>>>>>> >>>>>>> should do the job as now any Probability can be converted to any >>>>>>> concrete subtype of Real and "+" shoud be implemented there ;) >>>>>>> Very strange, how does Julia handle inheritance at all??? >>>>>>> >>>>>>> Best, >>>>>>> >>>>>>> Kevin >>>>>>> >>>>>>> >>>>>>> On Monday, 29 February 2016 23:45:35 UTC+1, Jeffrey Sarnoff wrote: >>>>>>>> >>>>>>>> Kevin, >>>>>>>> >>>>>>>> If all that you ask of this type is that it does arithmetic, clamps >>>>>>>> any negative values to zero, and clamps any values greater than one to >>>>>>>> one, >>>>>>>> that is easy enough. Just note that arithmetic with probabilities >>>>>>>> usually >>>>>>>> is more subtle than that. >>>>>>>> >>>>>>>> import Base: +,-,*,/ >>>>>>>> >>>>>>>> immutable Probability <: Real >>>>>>>> val::Float64 >>>>>>>> >>>>>>>> Probability(x::Float64) = min(1.0, max(0.0, x)) >>>>>>>> end >>>>>>>> >>>>>>>> (+){T<:Probability}(a::T, b::T) = Probability( a.val + b.val ) >>>>>>>> (-){T<:Probability}(a::T, b::T) = Probability( a.val - b.val ) >>>>>>>> (*){T<:Probability}(a::T, b::T) = Probability( a.val * b.val ) >>>>>>>> (/){T<:Probability}(a::T, b::T) = Probability( a.val / b.val ) >>>>>>>> >>>>>>>> You need conversion and promotion if you want to mix Float64 values >>>>>>>> and Probability values: 2.0 * Probability(0.25) == Probability(0.5). >>>>>>>> >>>>>>>> On Sunday, February 28, 2016 at 10:33:07 AM UTC-5, Kevin Kunzmann >>>>>>>> wrote: >>>>>>>>> >>>>>>>>> Hey, >>>>>>>>> >>>>>>>>> I have a (probably) very simple question. I would like to define >>>>>>>>> 'Probability' as a new subtype of 'Real', only with the additional >>>>>>>>> restriction that the value must be between 0 and 1. How would I >>>>>>>>> achieve >>>>>>>>> that 'Julia-style'? This should be possible without having to rewrite >>>>>>>>> all >>>>>>>>> these promotion rules and stuff, is it not? >>>>>>>>> >>>>>>>>> Best Kevin >>>>>>>>> >>>>>>>> >>>>>> >
