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
>>>>>>>>>
>>>>>>>>
>>>>>>
>

Reply via email to