TypeFunction example: ImplictConvTargets
Adam D. Ruppe
destructionator at gmail.com
Wed Oct 7 03:12:46 UTC 2020
On Wednesday, 7 October 2020 at 01:27:17 UTC, claptrap wrote:
> IE. Whats the learning curve like?
It is hard to say right now because this is a brand new
technique. It has been possible in D ... basically forever, these
language features are all quite aged, but to my knowledge, nobody
has tried it this way before.
> See the point is even even though I understand that, it took me
> a while to grep it, and I couldn't just rattle that off the top
> of my head, it'd take me a fair while to figure out how to do
> that. (Maybe i wouldn't even be able to on my own)
That might just be because you've never seen a combination of
patterns like that before... and that's OK, I made up that
particular thing just a few hours ago. (Though it is based on
some ideas Andrei and I have been bouncing back and forth.)
But with a little library refinement and some tutorials, maybe it
would prove to be easy to learn and to use.
The usage of a string lambda reminded me of the early days of
std.functional and std.algorithm. Back then, a function literal
looked like `(args) { return thing; }`. They shortened to strings
since they liked the shortness and that's what we had, but it
wasn't great.
Right now, a template lambda doesn't exist. We don't even have a
short form literal like delegates did. So I'm using a string
there. Maybe we are walking down the same path.
> But with Type Functions it'd be something like this...
>
> // assuming type is synonym for alias or whatever.
>
> type convTargets(type[] args)
> {
> assert(args.length > 0);
> type result = void; // IIRC void.sizeof == 1?
> foreach(t; args)
> if (t.size > result.sizeof) result = t;
> return result;
> }
You could have also written that:
// normal boilerplate
template biggest(args...) {
int helper() {
// this stuff is really similar between the two!
assert(args.length > 0);
size_t result;
size_t bestSize; // just store the answer and the size
separate
foreach(idx, t; args)
if(t.sizeof > bestSize) {
result = idx;
bestSize = t;
}
return result;
}
// then this part always follows the same pattern again
alias biggest = args[helper];
}
That pattern btw is very useful to know regardless of if this
technique works out - it is also the same idea I used for
user-defined literals in D ages ago.
Anyway, that's where my young library constructs are coming from
- trying to recognize and abstract this pattern a little. But the
core of it IS just regular D code: just it returns indexes into
the array instead of the item itself because compiler tuples are
weird. (I've been telling Stefan in a separate chat if type
functions become compiler tuple functions, able to work with that
`args...` thing to its full potential, we'd have something
compelling in new functionality, not just speed. That can replace
some of the super-ugly string mixins in my jsvar and jni that
transform runtime argument lists! But idk if that will prove
possible yet. He's exploring it, though.)
The major problem with this pattern so far is it is slow. I was
actually going to abandon it after Phobos' existing
implementations and the typefunctions prototype both blew it out
of the water in speed terms.
But some people say using regular std.algorithm stuff is more
important to them than speed. So I'm still toying with it for
that sake.
More information about the Digitalmars-d
mailing list