Thread overview | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
March 01, 2013 Chain two different struct specialization | ||||
---|---|---|---|---|
| ||||
I'm trying to do something like this. I don't know whether or not it's a good idea, i'm open to solutions and suggestions struct MyStruct(WEIGHTS) { string ... string ... alias WEIGHTS weights; } double likeness(T,T1)(ref in T1, ref in T2) { // Here i do some complex calculus using struct fields // and using weights consts } enum FirstWeights : double { } |
March 01, 2013 Re: Chain two different struct specialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrea Fontana | On Friday, 1 March 2013 at 14:27:40 UTC, Andrea Fontana wrote:
> I'm trying to do something like this. I don't know whether or not it's a good idea, i'm open to solutions and suggestions
>
> struct MyStruct(WEIGHTS)
> {
> string ...
> string ...
>
> alias WEIGHTS weights;
> }
>
> double likeness(T,T1)(ref in T1, ref in T2)
> {
> // Here i do some complex calculus using struct fields
> // and using weights consts
> }
>
> enum FirstWeights : double
> {
>
> }
Ops. Here the complete message:
I'm trying to do something like this. I don't know whether or not it's a good idea, i'm open to solutions and suggestions
struct MyStruct(WEIGHTS)
{
string ...
string ...
alias WEIGHTS weights;
}
double likeness(T,T1)(ref in T1, ref in T2)
{
// Here i do some complex calculus using struct fields
// and using weights consts
}
enum FirstWeights : double
{
double foo = 0.3,
double bar = 0.4
}
enum SecondWeights : double
{
double foo = 0.3,
double bar = 0.4
}
so:
auto s1 = MyStruct!FirstWeights ...
auto s2 = MyStruct!SecondWeights ...
likeness(s1,s2); // works
But I can't mix different type (s1,s2) on a single range or array, to check for likeness, is there a way? (or should I avoid template init a double[] weights field)
|
March 01, 2013 Re: Chain two different struct specialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrea Fontana | Andrea Fontana:
> double likeness(T,T1)(ref in T1, ref in T2)
==>
double likeness(T1, T2)(in ref T1, in ref T2)
Bye,
bearophile
|
March 01, 2013 Re: Chain two different struct specialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Friday, 1 March 2013 at 14:39:53 UTC, bearophile wrote:
> Andrea Fontana:
>
>> double likeness(T,T1)(ref in T1, ref in T2)
>
> ==>
>
> double likeness(T1, T2)(in ref T1, in ref T2)
>
> Bye,
> bearophile
Sure not the only error. I was writing "pseudo code". Real code it's quite complex.
Try this one (is a really reduced working example):
struct MyStruct(WEIGHTS)
{
this (int p, int p2) { prop = p; prop2 = p2; }
int prop;
int prop2;
alias WEIGHTS weights;
}
double likeness(T1,T2)(ref in T1 first, ref in T2 second)
{
double v = (first.prop - second.prop) * first.weights.foo * second.weights.foo;
v += (first.prop2 - second.prop2) * first.weights.bar * second.weights.bar;
return v;
}
enum FirstWeights : double
{
foo = 0.3,
bar = 0.4
}
enum SecondWeights : double
{
foo = 0.5,
bar = 0.2
}
void main(string[] args)
{
auto s1 = MyStruct!FirstWeights(10,8);
auto s2 = MyStruct!FirstWeights(9, 10);
auto s3 = MyStruct!SecondWeights(9,10);
writeln(likeness(s1,s2)); // works
writeln(likeness(s1,s3)); // works
}
How to put s1,s2,3... in a range/array or something similar/iterable? Probably there's no way (inside variant?)...
|
March 01, 2013 Re: Chain two different struct specialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrea Fontana | Andrea Fontana:
> How to put s1,s2,3... in a range/array or something similar/iterable? Probably there's no way (inside variant?)...
One solution is to not use templates:
immutable struct Weights {
double foo, bar;
}
enum Weights firstWeights = { foo: 0.3, bar: 0.4 },
secondWeights = { foo: 0.5, bar: 0.2 };
struct MyStruct {
int prop, prop2;
immutable Weights weights;
this ( Weights weights_, in int p, in int p2) pure nothrow {
prop = p;
prop2 = p2;
}
}
double likeness(in ref MyStruct first, in ref MyStruct second) {
double v = (first.prop - second.prop) * first.weights.foo *
second.weights.foo;
return v + (first.prop2 - second.prop2) * first.weights.bar *
second.weights.bar;
}
void main() {
immutable s1 = MyStruct(firstWeights, 10, 8);
immutable s2 = MyStruct(firstWeights, 9, 10);
immutable s3 = MyStruct(secondWeights, 9, 10);
import std.stdio;
writeln(likeness(s1, s2));
writeln(likeness(s1, s3));
const r = [s1, s2, s3];
}
Bye,
bearophile
|
March 01, 2013 Re: Chain two different struct specialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | > void main() {
> immutable s1 = MyStruct(firstWeights, 10, 8);
> immutable s2 = MyStruct(firstWeights, 9, 10);
> immutable s3 = MyStruct(secondWeights, 9, 10);
>
> import std.stdio;
> writeln(likeness(s1, s2));
Sorry for the mix of tabs and spaces. The crappy editor I have used now has not replaced your tabs with spaces...
Bye,
bearophile
|
March 01, 2013 Re: Chain two different struct specialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Friday, 1 March 2013 at 15:08:21 UTC, bearophile wrote:
>> void main() {
>> immutable s1 = MyStruct(firstWeights, 10, 8);
>> immutable s2 = MyStruct(firstWeights, 9, 10);
>> immutable s3 = MyStruct(secondWeights, 9, 10);
>>
>> import std.stdio;
>> writeln(likeness(s1, s2));
>
> Sorry for the mix of tabs and spaces. The crappy editor I have used now has not replaced your tabs with spaces...
>
> Bye,
> bearophile
That's right.
I think you missed an initialization on this(): I fixed it.
BTW, compiler can't guess s1 and s2 weights, should it?
if inside likeness() i write:
enum test = first.weights.foo * second.weights.foo;
it said that can't read first and second value at compile time.
Andrea
|
March 01, 2013 Re: Chain two different struct specialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrea Fontana | Andrea Fontana:
> BTW, compiler can't guess s1 and s2 weights, should it?
>
> if inside likeness() i write:
>
> enum test = first.weights.foo * second.weights.foo;
>
> it said that can't read first and second value at compile time.
firstWeights and secondWeights are compile-time constants, but the arguments you give to likeness are run-time values, so they are unknown at compile-time inside likeness.
There are ways to solve that problem, but I don't know how much good this is:
immutable struct Weights {
double foo, bar;
}
enum Weights firstWeights = { foo: 0.3, bar: 0.4 },
secondWeights = { foo: 0.5, bar: 0.2 };
struct MyStruct {
int prop, prop2;
immutable Weights weights;
this(Weights weights_, in int p, in int p2) pure nothrow {
this.weights = weights_;
this.prop = p;
this.prop2 = p2;
}
}
double likeness(alias first, alias second)() {
enum test = first.weights.foo * second.weights.foo;
double v = (first.prop - second.prop) *
first.weights.foo * second.weights.foo;
return v + (first.prop2 - second.prop2) *
first.weights.bar * second.weights.bar;
}
void main() {
enum s1 = MyStruct(firstWeights, 10, 8);
enum s2 = MyStruct(firstWeights, 9, 10);
enum s3 = MyStruct(secondWeights, 9, 10);
import std.stdio;
writeln(likeness!(s1, s2)());
writeln(likeness!(s1, s3)());
const r = [s1, s2, s3];
}
Bye,
bearophile
|
March 01, 2013 Re: Chain two different struct specialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Friday, 1 March 2013 at 16:03:58 UTC, bearophile wrote:
> Andrea Fontana:
>
>> BTW, compiler can't guess s1 and s2 weights, should it?
>>
>> if inside likeness() i write:
>>
>> enum test = first.weights.foo * second.weights.foo;
>>
>> it said that can't read first and second value at compile time.
>
> firstWeights and secondWeights are compile-time constants, but the arguments you give to likeness are run-time values, so they are unknown at compile-time inside likeness.
>
> There are ways to solve that problem, but I don't know how much good this is:
>
>
> immutable struct Weights {
> double foo, bar;
> }
>
> enum Weights firstWeights = { foo: 0.3, bar: 0.4 },
> secondWeights = { foo: 0.5, bar: 0.2 };
>
> struct MyStruct {
> int prop, prop2;
> immutable Weights weights;
>
> this(Weights weights_, in int p, in int p2) pure nothrow {
> this.weights = weights_;
> this.prop = p;
> this.prop2 = p2;
> }
> }
>
> double likeness(alias first, alias second)() {
> enum test = first.weights.foo * second.weights.foo;
> double v = (first.prop - second.prop) *
> first.weights.foo * second.weights.foo;
> return v + (first.prop2 - second.prop2) *
> first.weights.bar * second.weights.bar;
> }
>
> void main() {
> enum s1 = MyStruct(firstWeights, 10, 8);
> enum s2 = MyStruct(firstWeights, 9, 10);
> enum s3 = MyStruct(secondWeights, 9, 10);
>
> import std.stdio;
> writeln(likeness!(s1, s2)());
> writeln(likeness!(s1, s3)());
>
> const r = [s1, s2, s3];
> }
>
> Bye,
> bearophile
but:
enum s1 = MyStruct(firstWeights, 10, 8);
enum s2 = MyStruct(firstWeights, 9, 10);
writeln(likeness(s1, s2));
still gives error: and s1 and s2 are known at compile time, aren't them?
Your solution will create code for each item couple, isn't it? Not good in my case :) Other ideas?
|
March 01, 2013 Re: Chain two different struct specialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrea Fontana | Andrea Fontana: > but: > > enum s1 = MyStruct(firstWeights, 10, 8); > enum s2 = MyStruct(firstWeights, 9, 10); > > writeln(likeness(s1, s2)); > > still gives error: and s1 and s2 are known at compile time, aren't them? Right. But they are known at compile-time only outside likeness(). > Your solution will create code for each item couple, isn't it? Right. > Not good in my case :) Other ideas? Another solution is to use indirection, with classes or unsafe casts. Or to use variants. No solution is perfect. Why do you want to perform those computations at compile-time? Bye, bearophile |
Copyright © 1999-2021 by the D Language Foundation