Re: get from tuple by type

2015-03-15 Thread Charles Cooper via Digitalmars-d-learn

http://dlang.org/phobos/std_variant.html#.Algebraic
Thanks! This is fascinating, really a breath of fresh air coming 
from the C++ way of doing things.


On Sunday, 15 March 2015 at 23:31:59 UTC, bearophile wrote:
If you are experiencing those problems it's probably the way 
D/Phobos to tell you to not use basic tuples for your purpose. 
Use tuples with named fields (or even structs).

Take also a look at Algebraic in std.variant.

Bye,
bearophile




Re: get from tuple by type

2015-03-15 Thread Charles Cooper via Digitalmars-d-learn
Not offended at all :), in fact it was not even my suggestion 
that it be included in the standard. I was just knee jerk 
reacting to the comment that, just because something is simple to 
do precludes it from getting standardized


On Sunday, 15 March 2015 at 23:28:18 UTC, ketmar wrote:


sorry if you feel offended, i never meant that. what i meant is 
that it's
hard in c++, but easy in D when one knows how to do that. i've 
learned D
mostly by reading other people code, and there is nothing wrong 
in asking

questions, quite the contrary.

but the requested solution is not "universal" enough to be 
included in
Phobos (what if i want an index instead of a value? or (index, 
value)
tuple? or just check if it is there? or find either `int` or 
`double`?).
it's easier to write specialized template for required cases 
than to try
to make it generic (and complex) enough. but it's much harder 
to write
that in c++, to the extent that it's easier to include that 
things in

standard.

just stay with us and you will see that D shines in such things 
(and in

many other areas too ;-).




Re: get from tuple by type

2015-03-15 Thread Charles Cooper via Digitalmars-d-learn
True. If I had to do something involving such an API I would 
first wrap the API with a type safe one before doing anything 
else.


void external_api_do_something(uint dollars, uint cents);
/* I think this could somehow be automated with staticMap and 
ParameterTypeTuple / ParameterIdentifierTuple */

alias dollars_t = Typedef!(uint, uint.init, "dollars");
alias cents_t = Typedef!(uint, uint.init, "cents");

void internal_api_do_something(dollars_t, cents_t);

On Sunday, 15 March 2015 at 23:20:22 UTC, anonymous wrote:

On Sunday, 15 March 2015 at 23:13:58 UTC, Charles Cooper wrote:

How would GetByType help here? Both members are uint, so you 
can't distinguish them by type. And if you gave them distinct 
types, the bad example here wouldn't compile anymore either.




Re: get from tuple by type

2015-03-15 Thread Charles Cooper via Digitalmars-d-learn

Thanks for the style recommendations.

On Sunday, 15 March 2015 at 23:14:32 UTC, anonymous wrote:
I don't think there is. I don't know if there should be. 
Distinguishing tuple fields by their type doesn't seem very 
useful to me, since multiple fields can have the same type.


Using combined syntax for function template.

Made the tuple a function parameter like in the C++ version. I 
don't see the point in having it a template alias parameter.


Dropped `nothrow @nogc @safe`, since copying the member might 
not be any of that. They are inferred when possible.


Employing inout and `auto ref`.

More tests. unittest block instead of `static assert`s.

Bikeshedding:

Changed name to "getFirst", since subsequent values of the same 
type are ignored.


Named things more like the C++ version: member_t -> T, 
tuple_instance -> t.


Use selective imports instead of static imports.

Use more common casing: types and type templates are 
PascalCased, everything else is camelCased.


Brace placement.




Re: get from tuple by type

2015-03-15 Thread Charles Cooper via Digitalmars-d-learn
Sure. It is also easy to write merge sort. Or 
std.typetuple.Erase. Or Tuple.opIndex(size_t). But that doesn't 
mean everybody does it. Some utilities (and I am not saying this 
is, but it could be) are widely used enough that it makes sense 
to put them in the standard.


On Sunday, 15 March 2015 at 22:44:21 UTC, ketmar wrote:
p.s. to be clear: it's freaking hard to do metaprogramming and 
template
functional programming in c++, that's why c++ committee accepts 
such
things. and it's very easy to write such code in D, so this is 
a good
excersise for newcomers and almost no-brainer for expirienced D 
user.




Re: get from tuple by type

2015-03-15 Thread Charles Cooper via Digitalmars-d-learn
foo[1] is sometimes better, but not always. One has to go back to 
the definition of the thing and literally calculate by hand which 
element of the tuple you want, and then try compiling it, and so 
forth. Although the type system will guarantee that you 
eventually get it right it is a waste of time.


void external_api1_react_to_event(meters_t, time_t);
void external_api2_react_to_event(time_t, meters_t);
alias event_t = Tuple!(time_t, meters_t)
// .. some time later..
external_api1_react_to_event(event_t.get(meters_t), 
event_t.get(time_t));


Yes, I could say
external_api1_react_to_event(event_t[1], event_t[0])
.. but that is barbaric. It's a productivity sink because I have 
to go back to the original definition, align the arguments, and 
then context switch back to whatever I was working on before.


And yes, I could use names. But then you are subject to name 
clashes and using strings instead of types as member identifiers 
is more prone to error anyways. Ever gotten this wrong before --

void CRITICAL_TO_GET_THIS_RIGHT(uint cents, uint dollars);

alias params_t = Tuple!(uint, "dollars", uint, "cents");

params_t params;
params.dollars = 0;
params.cents = 99;
CRITICAL_TO_GET_THIS_RIGHT(params.expand);
// compilation succeeds, bank fails.

In conclusion: this is an important feature because it allows you 
to enforce type safety when working with tuples (e.g. in function 
parameters) efficiently, without taking too much of the 
programmer's time.


On Sunday, 15 March 2015 at 22:32:48 UTC, bearophile wrote:

Charles Cooper:


Is there a better way to do this?


Can you show some use cases for this, and isn't "foo[1]" better?

Bye,
bearophile




get from tuple by type

2015-03-15 Thread Charles Cooper via Digitalmars-d-learn

C++14 has:
template constexpr T& 
get(tuple& t);
Which allows you to get a member of the tuple struct by type. Is 
there an idiomatic / library way to do this in D? Preferably by 
indexing.


Here is what I have, it is ugly but works:
/* CODE */
static import std.stdio;
static import std.typecons;
template GetByType(alias tuple_instance, member_t)
{
ref member_t GetByType() nothrow @nogc @safe {
alias tuple_t = typeof(tuple_instance);
static assert(std.typecons.isTuple!tuple_t);
enum long idx = std.typetuple.staticIndexOf!(member_t, 
tuple_instance.Types);

static if(-1 != idx)
return tuple_instance[idx];
else static assert(false); //better error message
}
}

static assert(2.5 == GetByType!(std.typecons.tuple(1,2.5), 
double));
static assert(2.5 == GetByType!(std.typecons.tuple(1,2.5,3.1), 
double));

void main() {
auto foo = std.typecons.tuple(1,2.5);
std.stdio.writeln(GetByType!(foo, double));
}
/* CODE */

Is there a better way to do this?


Re: 'strong types' a la boost

2015-03-14 Thread Charles Cooper via Digitalmars-d-learn
Interesting. I think in the second example there are pathological 
cases where one has similar declarations in two modules at the 
same line.


moduleA.d:100
alias dollars_t TypeDef!int;
moduleB.d:100
alias cents_t TypeDef!int;

main.d:
import moduleA;
import moduleB;
void write_dollars_to_database(dollars_t x) {
  /* code */
}
void main() {
  cents_t cents;
  write_dollars_to_database(cents); // compilation succeeds, bank 
fails

}

However, I see your point, I think it can be gotten around by 
using a combination of the __LINE__, __FILE__ and __MODULE__ 
directives!


Charles

On Saturday, 14 March 2015 at 16:01:15 UTC, Namespace wrote:

You can do it this way:

struct dollars_t {
uint _dollar;

this(uint d) {
_dollar = d;
}

alias _dollar this;
}

struct cents_t {
uint _cent;

this(uint c) {
_cent = c;
}

alias _cent this;
}

void do_something_with_dollars(dollars_t d) {
writeln(d);
}

void main() {
dollars_t d = 1;

do_something_with_dollars(d);

cents_t c = 2;

//do_something_with_dollars(c);
//do_something_with_dollars(2);
}


Or you can create your own small TypeDef:


struct TypeDef(T, size_t l = __LINE__) {
T _val;

this(T v) {
_val = v;
}

alias _val this;
}

alias dollars_t = TypeDef!(uint);
alias cents_t = TypeDef!(uint);


Thanks to the second template parameter 'l' the template 
instances of dollars_t and cents_t aren't equal.




Re: 'strong types' a la boost

2015-03-14 Thread Charles Cooper via Digitalmars-d-learn
I think I may have answered my own question. It seems std.typecon 
provides a facility for this.

http://dlang.org/phobos/std_typecons.html#.Proxy
http://dlang.org/phobos/std_typecons.html#.Typedef

Is this the 'right' way to do things? It seems that Proxy is used 
as a mixin whereas Typedef is used to create standalone types.


Thanks
Charles

On Saturday, 14 March 2015 at 14:55:06 UTC, Charles Cooper wrote:
I was wondering what the idiomatic D way of implementing strong 
types. Boost has something along these lines using classes:

http://www.boost.org/doc/libs/1_37_0/boost/strong_typedef.hpp

When programming in C++ I find that the compiler does not 
necessarily generate good code with these types, and I usually 
use C++11 enum class, e.g.


enum class dollars_t : uint32_t {}
enum class cents_t : uint32_t {}
/* .. code e.g. for converting between cents and dollars .. */
void do_something_with_dollars(dollars_t) {} // this will fail 
to compile if you try to pass it cents_t or uint32_t


This is obviously a gross abuse of the enum class feature.

I think there is also a way of doing this (in C++) using 
templates a la std::chrono


But enough about C++. Is there an idiomatic way of doing this 
in D, if so what is it?


Thanks!
Charles




Re: get struct member names

2015-03-14 Thread Charles Cooper via Digitalmars-d-learn

Wow, this is f***ing cool.
http://dlang.org/traits.html#allMembers

Thank you!

On Saturday, 14 March 2015 at 14:54:27 UTC, Adam D. Ruppe wrote:

__traits(allMembers, Struct) can do it.

Get the free sample chapter from my book: 
https://www.packtpub.com/application-development/d-cookbook and 
it goes into more detail (I'm in a bit of a rush right now!)


the sample link is under the picture




'strong types' a la boost

2015-03-14 Thread Charles Cooper via Digitalmars-d-learn
I was wondering what the idiomatic D way of implementing strong 
types. Boost has something along these lines using classes:

http://www.boost.org/doc/libs/1_37_0/boost/strong_typedef.hpp

When programming in C++ I find that the compiler does not 
necessarily generate good code with these types, and I usually 
use C++11 enum class, e.g.


enum class dollars_t : uint32_t {}
enum class cents_t : uint32_t {}
/* .. code e.g. for converting between cents and dollars .. */
void do_something_with_dollars(dollars_t) {} // this will fail to 
compile if you try to pass it cents_t or uint32_t


This is obviously a gross abuse of the enum class feature.

I think there is also a way of doing this (in C++) using 
templates a la std::chrono


But enough about C++. Is there an idiomatic way of doing this in 
D, if so what is it?


Thanks!
Charles


get struct member names

2015-03-14 Thread Charles Cooper via Digitalmars-d-learn

Hi all,
I am new to D and so far it is really great.

I am wondering how to get the names of member variables in a 
struct or class. I haven't worked it out yet but this would 
enable metaprogramming like iterating over the members of the 
struct.


I see in std.traits that you can get get MemberFunctionsTuple but 
nothing like MemberVariablesTuple.


Charles