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/lkcmqlpsdcopfebwg...@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.


Reply via email to