July 16, 2015
On Thursday, 16 July 2015 at 08:26:58 UTC, Marc Schütz wrote:
> On Wednesday, 15 July 2015 at 19:28:13 UTC, Jacob Carlborg wrote:
>> On 2015-07-13 09:12, Atila Neves wrote:
>>
>>> https://www.reddit.com/r/programming/comments/3d3ooa/behaviourdriven_development_with_d_and_cucumber/
>>>
>>>
>>> Also on HN, but as usual can't post the link.
>>
>> The comment about not having to name the steps. One way to do that could be something like this:
>>
>> step("foo bar", {
>>     // step implementation
>> });
>>
>> There are two problems with that:
>>
>> 1. D doesn't support module level code like this. Which could be solved by either using a unit test block, a module constructor or some other function the framework knows about to call.
>
> Do mixin templates work on module level? They can even have an identifier.

Yes. But it doesn't make it pretty to use:

    mixin When!(`...`, { });

Atila

July 16, 2015
On Wednesday, 15 July 2015 at 19:28:13 UTC, Jacob Carlborg wrote:
> On 2015-07-13 09:12, Atila Neves wrote:
>
>> https://www.reddit.com/r/programming/comments/3d3ooa/behaviourdriven_development_with_d_and_cucumber/
>>
>>
>> Also on HN, but as usual can't post the link.
>
> The comment about not having to name the steps. One way to do that could be something like this:
>
> step("foo bar", {
>     // step implementation
> });
>
> There are two problems with that:
>
> 1. D doesn't support module level code like this. Which could be solved by either using a unit test block, a module constructor or some other function the framework knows about to call.
>
> 2. That syntax is not as nice as in Ruby. It would be really nice if the following could be supported:
>
> step("foo bar") {
>     // step implementation
> }
>
> A trailing delegate syntax, where the delegate is passed after the regular argument list.

I tried out something like this to see how I'd like it before the talk, and I didn't. I mentioned it but I should've drawn more attention to it, it'd look like this:

@When!(`...`, { ... }) {}

The empty block needed at the end was just too ugly.

Atila

July 17, 2015
On Thursday, 16 July 2015 at 08:59:43 UTC, Jacob Carlborg wrote:
> On 2015-07-16 10:26, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm@gmx.net>" wrote:
>
>> Do mixin templates work on module level? They can even have an identifier.
>
> Yes. But a mixin template seems only be able to contain declarations. How did you plan to use it?

As Atila posted.

>
>> Unfortunately there are syntactical ambiguities:
>>
>>      step("foo bar") {
>>      }
>>      .foo();
>>
>> Is that a call chain, or two statements, with the second one calling a
>> function in the root scope? And I think there are other similar cases...
>
> Hmm, right. I have simple implementation of this. With you're example I get this error message:
>
> function main.foo () is not callable using argument types (void function() @safe)

I guess we could even live with that. If someone wants the latter interpretation (which is kind of infrequent), they could insert a semicolon.

Does your implementation support parameterized lambdas? I can already see the next ambiguity:

    someRange.each (element) {
        writeln(element);
    }

Do the parentheses belong to the lambda on the right or the function on the left?
July 17, 2015
On 2015-07-17 10:16, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm@gmx.net>" wrote:

> Does your implementation support parameterized lambdas? I can already
> see the next ambiguity:
>
>      someRange.each (element) {
>          writeln(element);
>      }
>
> Do the parentheses belong to the lambda on the right or the function on
> the left?

Currently, in the above example, "element" is interpreted as an argument to "each".

No, the current implementation does not support parameters. It's a really simple modification in the parser. If we really want to support this feature more work could be put in to this and make it work.

I would say that it should first try to interpret "element" as an argument to "each", if that doesn't work, try as a parameter for the delegate. Just going with the longest match, if that doesn't work try the next thing.

This feature has come up before, one of the suggestions back then was to do allow this syntax:

someRange.each(start; element) {
    writeln(element);
}

Everything after the semicolon would be interperted as parameters for the delegate.

-- 
/Jacob Carlborg
July 17, 2015
On 2015-07-16 13:55, Atila Neves wrote:

> I tried out something like this to see how I'd like it before the talk,
> and I didn't. I mentioned it but I should've drawn more attention to it,
> it'd look like this:
>
> @When!(`...`, { ... }) {}
>
> The empty block needed at the end was just too ugly.

Yeah, that looks quite weird.

-- 
/Jacob Carlborg
July 17, 2015
On Friday, 17 July 2015 at 11:28:45 UTC, Jacob Carlborg wrote:
> I would say that it should first try to interpret "element" as an argument to "each", if that doesn't work, try as a parameter for the delegate. Just going with the longest match, if that doesn't work try the next thing.

That could only happen after semantic analysis, but the ambiguity needs to be resolved during parsing.

>
> This feature has come up before, one of the suggestions back then was to do allow this syntax:
>
> someRange.each(start; element) {
>     writeln(element);
> }
>
> Everything after the semicolon would be interperted as parameters for the delegate.

That could work. But it would require an ugly `.each(; element)` if `each` should be called without arguments...
July 17, 2015
On 2015-07-17 15:00, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm@gmx.net>" wrote:

> That could only happen after semantic analysis, but the ambiguity needs
> to be resolved during parsing.

Aren't there other things in D that already have this problem:

auto a = foo;

Is "foo" a variable or a method?

> That could work. But it would require an ugly `.each(; element)` if
> `each` should be called without arguments...

That would not be required with the suggestion above. But that might not be feasible.

-- 
/Jacob Carlborg
July 18, 2015
On Friday, 17 July 2015 at 18:58:04 UTC, Jacob Carlborg wrote:
> On 2015-07-17 15:00, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm@gmx.net>" wrote:
>
>> That could only happen after semantic analysis, but the ambiguity needs
>> to be resolved during parsing.
>
> Aren't there other things in D that already have this problem:
>
> auto a = foo;
>
> Is "foo" a variable or a method?

The AST for this statement would look something like:

(DeclStatement type=(Keyword "auto") name=(Identifier "a") value=(AssignExpression exp=(VariableOrParenlessCall var=(Identifier "foo"))))

This would probably be considerably harder for trailing delegates...
July 18, 2015
On 2015-07-18 11:43, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm@gmx.net>" wrote:

> The AST for this statement would look something like:
>
> (DeclStatement type=(Keyword "auto") name=(Identifier "a")
> value=(AssignExpression exp=(VariableOrParenlessCall var=(Identifier
> "foo"))))
>
> This would probably be considerably harder for trailing delegates...

I think there are nine different ways a user could want write the code to call a method with a trailing delegate. Only two of them are ambiguous.

foo {
}

foo (a){ // ambiguous
}

foo (int a){
}

foo(a) { // ambiguous
}

foo(a) (b){
}

foo(a) (int b){
}

foo() (){
}

foo (){
}

foo() {
}

When it is ambiguous the compiler can always parse it as trailing delegate and store that in a variable in the call expression. The semantic analyze will then disambiguate the call. That would be similar to how my current implementation works like:

1. If the current expression is a call expression or an identifier
2. If the current token is an opening curly brace, parse an expression
3.1 If the current expression is a call expression, push the expression from step 2 to its argument list
3.2 If the current expression is an identifier, replace that with a call expression, go to 3.1

This could be extended to store the delegate expression in a new variable in the call expression instead.

-- 
/Jacob Carlborg
1 2
Next ›   Last »