Understand typeof trick
anonymous via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Fri Dec 25 06:55:04 PST 2015
On 25.12.2015 13:10, Joakim Brännström wrote:
> In http://forum.dlang.org/post/ojawnpggfaxevqpmrdww@forum.dlang.org Adam
> uses findSkip as an example and especially points out the "D idiom with
> is/typeof".
>
> I'm not quite sure I understand it correctly. Please correct me if I
> have misunderstood anything regarding the idiom.
>
> findSkip: http://dlang.org/phobos/std_algorithm_searching.html#.findSkip
> bool findSkip
> (alias pred = "a == b", R1, R2)
> (ref R1 haystack, R2 needle)
> if (isForwardRange!R1 &&
> isForwardRange!R2 &&
> is( [C]
> typeof( [B]
> binaryFun!pred( [A]
> haystack.front, needle.front))));
>
> [A]
> Nothing special. findSkip's pred is passed on to binaryFun. binaryFun's
> constraints thus apply to findSkip's pred.
> See http://dlang.org/phobos/std_functional.html#.binaryFun
Yup, and then the resulting function is called with arguments
`haystack.front, needle.front`. The template instantiation, and the
function call can fail compilation (more precisely: semantic analysis).
In that case, A is marked as being "broken".
> [B]
> Evaluates to the function type "constructed" by binaryFun.
Almost. It evaluates to the type of the expression. The expression is a
function call, so typeof evaluates to the return type of the generated
function.
If A has been marked broken, then B does not become a proper type, and
it's marked "broken" as well.
> [C]
> The is expression is true if A->B is valid "code".
It's true if the argument, i.e. B, is a proper type. In particular, B
must not be marked "broken".
If B is "broken", then C is false. Any error messages that would usually
be printed for the broken A/B are suppressed.
> It is used to convert any compiler errors to "false" (thus the
> constraint wouldn't be fulfilled).
Yes, but be aware that this only works on semantic errors, not on syntax
errors.
For example, `is(foo())` and `is(typeof(foo(); bar();))` don't give you
false, but they error out in the syntax checking phase.
That second one leads us to the longest form of the is-typeof idiom:
`is(typeof({foo(); bar();}))`. Wrapping the code in a delegate so that
it's an expression, which can be passed to typeof.
> Question:
> I guess that binaryFun is used in the implementation of findSkip.
Yeah, the constraint wouldn't make sense otherwise.
> The reason for using this type of idiom is to avoid "compilation errors"
> to occur in the implementation when pred/R1/R2 is "funky". It "confuses"
> the user.
> The idiom is thus used to move errors to the call site?
> "D idiom: constraint error at call site"?
I think Adam meant just the is(typeof(...)) thing itself, regardless of
where it appears.
Constraints are used to reject bad instantiations early on, yes. They're
also used to distinguish different template "overloads".
More information about the Digitalmars-d-learn
mailing list