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