Article: Writing Julia style multiple dispatch code in D
data pulverizer via Digitalmars-d-announce
digitalmars-d-announce at puremagic.com
Thu Aug 24 16:50:21 PDT 2017
On Thursday, 24 August 2017 at 21:13:10 UTC, jmh530 wrote:
> On UDAs, at least in the current implementation, I think that
> the actual issue you are trying to address is to force the type
> in the distribution to be convertible to double in the
> continuous case and convertible to long in the discrete case.
> All things considered, that can be implemented with template
> constraints, as in
>
> class Gamma(T):
> if(isFloatingPoint!T)
> {
> immutable(T) shape;
> immutable(T) scale;
> this(T shape, T scale)
> {
> this.shape = shape;
> this.scale = scale;
> }
> }
>
Okay, I admit that I try to avoid using template constraints
whenever I can - i.e. unless the code breaks! It's a habit I am
trying to break. In reality I will have to have them everywhere
and the code will end up looking much less pretty, in reality, I
know I'll probably need one or two catchall functions that look
something like this
```
double density(D: UnivariateDistribution!Discrete, U =
getVariateType!D, T = GetDistributionParameterType!D)(D d, U x)
if(!is(D == Poisson!T))
{
assert(false, "density function unimplemented for this
distribution: " ~ D.stringof);
}
double density(D: UnivariateDistribution!Continuous, U =
getVariateType!D, T = GetDistributionParameterType!D)(D d, U x)
if(!is(D == Gamma!T) && !is(D == Gaussian!T) && !is(D ==
Uniform!T) && !is(D == Exponential!T))
{
assert(false, "density function unimplemented for this
distribution: " ~ D.stringof);
}
```
She's not so pretty anymore captain! This is why some time ago I
suggested introducing the Union keyword that Julia has
https://forum.dlang.org/post/lkcmqlpsdcopfebwgikj@forum.dlang.org
> though you could probably take a more abstract approach. (I'm
> also not 100% on having immutable member variables).
I am 100% sure that I want either the instantiated distribution
object to be immutable, or the parameters to be immutable once
instantiated. Its a safety feature that I don't see a need for
mutable distribution objects. Once the parameters change, its not
the same distribution. Ideally I want to be able to say
immutable class(T...){...}
that this class can only create immutable objects without having
to write immutable everywhere and or a UDA, but making every
member immutable accomplishes the same thing.
> Also, density's signature could then avoid the template
> constraint.
>
> auto density(D: Gamma!T, U : T, T)(D d, U x)
Sorry U is not T, T is the type of the parameters, U is the type
of the variate.
> Even better, if you're calling the dstats functions, you could
> re-write density as something like
>
> auto pdf(D: Dist!T, U : T, Dist, T)(U x, D d) {
> mixin("return x." ~ lookupdstatdensity!Dist ~ "(" ~
> stringmembersofd ~ ")";
> }
>
> and create a lookupdstatdensity function that returns a string
> of the relevant dstats function at compile-time (and a function
> returning a string of the members of d) (I also would re-name
> density to pdf and switch the order of x and d). This would
> probably be the most DRY approach.
Sounds like a reasonable approach, though I haven't looked at the
dstats package in great detail.
> Julia is a scripting language with a JIT compiler. So if you
> call a function with some types known at compile time and the
> overload exists, it will compile the correct version of the
> function for the relevant types.
Yes, I guess you could say that Julia is an interactive compiler,
where you can create new compiled types and methods in the same
session.
> So it's similar to what you're doing on that respect. However,
> there is a runtime dispatch component that would take something
> like openmethods to implement, I think.
I find OOP-polymorphic types ultimately unsatisfying, but I don't
know of anyway to write, compile and load a D script with new
types and methods on the fly into the same session.
More information about the Digitalmars-d-announce
mailing list