NWCPP january talk

Bill Baxter wbaxter at gmail.com
Thu Dec 11 16:37:03 PST 2008


On Fri, Dec 12, 2008 at 8:12 AM, BCS <ao at pathlink.com> wrote:
> Reply to Walter,
>
>> Bartosz has signed me up to give a presentation at the January meeting
>> of the NWCPP. http://www.nwcpp.org/
>>
>> I am not sure what to talk about, though. Any particular D topics
>> you'd find particularly interesting?
>>

Probably the best would be to talk about what you find most
interesting right now.

Second to that is to ask us what we think C++ users who *don't know* D
would find interesting, since probably D users on this list are not
your target audience.  What we would find interesting isn't that
relevant.

>
> Hard core compile time reflection a.k.a D'iss'ection
>
> I'm thinking stuff like ripping about the the template arg types and doing
> magic on them. I'm planning on building a column-wise struct array type that
> would be a good example.

I like this suggestion.  Many C++'ers can probably recognize how
difficult it is to do anything interesting with templates in C++.  And
so they can appreciate the nice facilities that D brings to the table.

I've recently been using this pattern:  I have a template class that
needs a type T that supports various operations (like a-b
subtraction).  But I want the user to still be able to use the class
on the type T as-is as long as he can supply provide the missing
functions externally.   I allow this by writing the template so that
it will accept *either* a T that supports all the operations, *or* a
TypeTraits struct that might look like so:

struct TypeTraits {
   alias SomeT  DataType; // first thing - tells what the actual T
type should be
   alias float ScalarType; // the type of one DataType component, e.g.
   DataType subAssign(ref DataType a, DataType b) {
           // implement a-=b here somehow (assuming DataType doesn't support it
   }
   ...
}

The trick is that when the user makes a MyClass!(V), I don't use V
directly inside the class.  I use a TraitsDeducer!(V).  And
TraitsDeducer!(V) is something that supports all the interface
functions needed.  The implementation of TraitsDeducer uses a lot of
compile-time reflection to figure out what the type V can and can't do
by itself.  For instance if V supports a-b, but not a-=b it will
implement a-=b using a = a - b.

[[ Side note: What would make this a lot nicer would be if it were
possible to provide out-of-class operator overloads and out-of-class
extension methods.  Then instead of having to use  Traits.subAssign(a,
b) inside the class I could use a-=b.  In D2 OpDot could also be put
to good use here probably.  But this is D1 code.]]

There's a lot of nice variations on this pattern of using a secondary
"Traits" struct to let the user describe something about another type
that might lack certain properties itself.  But in the end it's hard
to get very fancy with it in C++ because checks like I said above (use
-= if it exists, otherwise use just minus) are such a pain to
implement in C++.  So Traits in C++ tend to just require you to supply
every bit of info needed.  In contrast, with D's static if and is()
deductions you can make it so the Traits struct supplied by the user
really only has to describe the bits that are lacking in the type.


Another neat template thing to talk about : the use of "a<b" string
literals for comparisons in std.algorithm is also neat, and provides a
good motivation for built-in strings and compile-time functions (to do
the parsing).

--bb


More information about the Digitalmars-d-announce mailing list