On 25.12.2015 13:10, Joakim Brännström wrote:
In http://forum.dlang.org/post/ojawnpggfaxevqpmr...@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".

Reply via email to