Re: DIP 1009--Improve Contract Usability--Formal Review

2017-08-30 Thread MysticZach via Digitalmars-d

On Wednesday, 30 August 2017 at 14:05:40 UTC, Mark wrote:
I see that in the previous review rounds some people suggested 
various keywords for designating the return value of a function 
("return", "result", ...) in an `out` contract. What about 
using a plain old underscore? For example:


int abs(int x)
out(_ >= 0)
{
return x>0 ? x : -x;
}


I think it's good to be consistent with existing out contracts 
which require declaring the variable first. The identifier 
`__result` currently works, but the thing is, it takes fewer 
characters to write `out(r; r >= 0)` than to write `out(;__result 
>= 0)` (or `out(__result >= 0)`). The possibility of using a 
single character as the return identifier makes it hard, in my 
opinion, to justify complaints about the syntax being "too 
verbose."


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 2 Begins

2017-08-01 Thread MysticZach via Digitalmars-d

On Monday, 31 July 2017 at 09:55:22 UTC, Nick Treleaven wrote:
This is subjective. If you put `do` on the end of the line, it 
is trivial:


in(x > 4)
out(works)
out(r; r.test)
out(flag) do
{
  // body
}


The common case is for `out` contracts to test for the return 
variable. Something like 90% will therefore look like:


int fun(int x)
out(r; r > 0)
{

}

So it's the uncommon case we're trying to solve for. Requiring 
`do` in precisely one case, which is the rare case in which the 
`out` test has only one identifier, and therefore can't be 
disambiguated from existing `out` contracts, is a solution to 
that problem. It's seems like a complicated one. To me, it's 
simpler to simply require the `;` because it's the uncommon case 
to begin with, and everyone will know what it means because 
they'll be used to seeing `out(r; r > 0)`.


That said, `do` can solve the loophole with the alternative 
ambiguous syntax. For example:


int fun(ref int x, ref int y, ref int z)
out(x) // fine, followed by another contract
out(y != 0) // fine, multiple tokens, unambiguous
out(z) do   // fine, followed by `do`
{
}

If you forget to add the `do` there is an inevitable parsing 
error, so it's not that bad even in the worst case. The error can 
be fixed by changing `out(z)` to `out(z != 0)`, or to `out(z) do` 
as you suggest. `do` is only going to be valuable in that one 
case, though. I'd say it depends where the language designers 
want to pay the cost of solving the problem. Either pay it up 
front with the ugliness of the foreach syntax, or pay it in 
complexity with the different cases of the ambiguous syntax. 
Because it's a programming language and not a sports car, I'd 
probably  choose the consistency of the foreach syntax over the 
attractiveness of the ambiguous syntax. But there's no clear 
winner, IMO.


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 2 Begins

2017-07-28 Thread MysticZach via Digitalmars-d

On Friday, 28 July 2017 at 11:04:23 UTC, Nick Treleaven wrote:
One option to solve the out contract ambiguity and aid parsing 
by tools is to require 'do' after out contract expressions. It 
allows the syntax `out(expression) do {...}`, even when 
expression is a single identifier that should be interpreted as 
a boolean expression.


One of the main goals of this DIP is to eliminate the need for 
`body/do` in the common case. It would significantly reduce this 
DIP's value if it couldn't do that, IMO.


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 2 Begins

2017-07-26 Thread MysticZach via Digitalmars-d

On Tuesday, 25 July 2017 at 07:48:39 UTC, Andrea Fontana wrote:
I don't like it so much but also something like this could be 
considered:


out!(x => x>0)
or maybe:
out!x(x > 0)

that can't collide with current syntax

Andrea


It's another viable option, but it doesn't seem to stand out much 
from the crowd. Most people, including me, seem to think `out(x; 
x > 0)` and `out(; y > 0)` are the "least imperfect" option. I 
suspect they would win if put to a vote. Maybe the leadership can 
come up with something better. People will get used to whatever 
is selected. I just like the foreach version because it's simple 
and concise. I also don't think the ambiguous `out(x > 0)` syntax 
is that bad for non-return variables. But I can also see why 
that's suboptimal from a design point of view.


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 2 Begins

2017-07-26 Thread MysticZach via Digitalmars-d

On Wednesday, 26 July 2017 at 08:12:39 UTC, Olivier FAURE wrote:
I... think you misunderstood me? I shouldn't have used the word 
'proposals', I should have said 'suggestions'.


What I meant was "I think it would be better for the current 
version of DIP 1009 to include a 'Rejected alternative 
syntaxes' that would include a summary of the previously 
discussed suggestions for improving contract readability."


MysticZach argues that such a section would be pointless since 
the language authors read the previous version of DIP 1009, but 
I still think adding it would be a good idea (for posterity and 
to streamline discussions in this thread).


I don't know. DIPs have both a forward-looking and a 
backward-looking aspect. The forward is to convince the language 
authors of the need/value of a specific language change. The 
backward is to record a history of discussions so that people can 
learn why things are the way they are. They are both valuable in 
their own way, but I think the forward-looking aspect is more 
valuable. I'd like some guidance from the leadership as to the 
important of the backward-looking aspect of DIPs. For example, 
DIP1003 was actually rewritten to excise the alternatives and 
keep only the one adopted. The motive given was that people 
looking for the history could examine prior versions of the DIP. 
I guess the motive is that too much history can end up cluttering 
the important information.


That said, I think that making good decisions for the language 
far outweighs any concerns about DIPs themselves. So we should 
really be focusing on that.


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 2 Begins

2017-07-22 Thread MysticZach via Digitalmars-d

On Friday, 21 July 2017 at 19:36:08 UTC, H. S. Teoh wrote:
However, I think the presentation of the DIP needs some work. 
For example, the rationales and lines of reasoning that 
eventually led to the currently proposed syntax, both from the 
original draft of this DIP and from the ensuing discussion in 
the previous review thread, ought to be included (of course, in 
summarized form -- no need to repeat the back-and-forth of the 
original discussions, but just the eventual line of thought). 
If possible, some of the discarded alternatives could be 
mentioned along with the reasons why they were eventually 
decided against.


The first draft of the current proposal actually started with 
this approach: 
https://github.com/dlang/DIPs/commit/677c4e2bd5ff9b4bcbca35a28831560d5ce06f8c


Hopefully this will help:

https://github.com/dlang/DIPs/pull/88


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 2 Begins

2017-07-21 Thread MysticZach via Digitalmars-d

On Friday, 21 July 2017 at 19:36:08 UTC, H. S. Teoh wrote:
In short, I feel that a more substantial discussion of how we 
arrived at the current form of the proposal is important so 
that Walter & Andrei can have the adequate context to 
appreciate the proposed syntax changes, and not feel like this 
is just one possibility out of many others that haven't been 
adequately considered.


I think we have to assume they've been reading the prior threads. 
If they have specific questions or concerns, then we have to hope 
they'll express them here, rather than just reject the proposal. 
I'll put you in the author line as a co-author if you want, as 
this _is_ essentially your proposal.


And there should be at least one example of a body-less 
function declaration with contracts, just to see what it looks 
like in that case.


Right now, such declarations are only legal in interfaces. That 
might change if the implementation changes. Here's how one would 
look with the new syntax:


interface I {
   void fun(int a) in(a);
}




Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 2 Begins

2017-07-21 Thread MysticZach via Digitalmars-d

On Saturday, 22 July 2017 at 03:05:55 UTC, aberba wrote:

How about this in current syntax? (that's what I do)

int func(int a)
in
{
assert(a >= 0);
}
out(result)
{
assert(result >= 2);
}
body
{
return 2 * a;
}


an improvement could be:

int func(int a)
in assert(a >= 0);
out(result) assert(result >= 2);
body
{
return 2 * a;
}

just like an in-line if-else statement


That was actually part of my original proposal [1]. People in 
that discussion [2] seemed more excited about the current 
proposal , and they won me over to it. If the syntax doesn't 
assume `assert`, probably 99% of contracts will use it 
explicitly, so it's really making it easier by just assuming it. 
And being allowed to omit the word `body` (now `do`) with the new 
syntax is an important feature. That said, I don't think your 
proposal is incompatible with the current one. It just might be 
made unnecessary by it.


[1] 
https://github.com/dlang/DIPs/blob/d2dc77802c74378cf4545069eced21f85fbf893f/DIPs/DIP1009.md


[2] 
http://forum.dlang.org/post/gjtsfysvtyxcfcmuu...@forum.dlang.org


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 2 Begins

2017-07-21 Thread MysticZach via Digitalmars-d

On Friday, 21 July 2017 at 18:55:08 UTC, Moritz Maxeiner wrote:

I really like how the syntax turned out. My only remaining 
peeve is the `ContractParameters` nomenclature in the grammar 
section, because it implies that asserts are contracts.


Maybe I should have stuck with AssertParameters. That can easily 
be fixed.


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 2 Begins

2017-07-21 Thread MysticZach via Digitalmars-d

On Friday, 21 July 2017 at 15:13:09 UTC, Timon Gehr wrote:
"in and out expressions must come at the end of the function 
declarator suffix, and before the regular contracts, if any"


The implementation actually allows all possible notations for 
contracts to be mixed freely. Whether or not 'do' is required 
depends on what notation is used by the last contract.


I decided that for grammar purposes it would be easier to require 
the contract expressions before the contract blocks. Contract 
blocks are currently conflated grammatically with FunctionBody 
[1]. An accurate grammar that describes the current 
implementation would be twice as complicated, because 
FunctionBody would have to be redefined. I want the feature to be 
as simple as possible to understand, so I didn't think it was 
worth it.


There has also been mention of the possibility of improving the 
implementation of contracts to allow separate compilation, in 
which case the signature, plus contracts, could some day appear 
without the body. I wanted to define the new expressions to 
accommodate this possibility.


[1] https://dlang.org/spec/grammar.html#FunctionBody


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-28 Thread MysticZach via Digitalmars-d

On Wednesday, 28 June 2017 at 14:33:52 UTC, Moritz Maxeiner wrote:
The DIP is still at pre-preliminary review round 1 (since it 
hasn't finished yet).
The current syntax proposal is effectively emergent through H. 
S. Teoh's general proposal [1], Solomon E's out enhancement 
[2], and Timon Gehr's implementation of the former two [3].
You can see in Timon's examples [4] how it looks (and contracts 
are part of a function's signature).


Yes, this thread has been incredibly productive, and has resulted 
in a complete metamorphosis of my original proposal, into a 
proposal that I think is very strong. I have to rewrite the 
existing DIP to reflect that.


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-27 Thread MysticZach via Digitalmars-d

On Wednesday, 28 June 2017 at 01:23:18 UTC, MysticZach wrote:

On Tuesday, 27 June 2017 at 09:18:11 UTC, Olivier FAURE wrote:
A bit late to the party, but I would recommend the following 
syntax:


out (void; myTest)

for argument-less tests. A casual reader would be less likely 
to see this in code and think it's some sort of typo; it would 
be easier to google; and it would make some semantic sense 
(functions that don't return anything return void).


It's a creative suggestion, and not a bad one. But it's 
verbose, and I'd like to be able to omit the identifier 
altogether. Currently, only `for` loops allow this, as when 
people write:


for( ; ; )

Theoretically, `foreach

foreach( ; a) ...
out( ; ...)

Currently `foreach` does not allow omitting


Sorry, clicked the `send` button too soon.

Anyway, currently `foreach` does not allow omitting the initial 
identifier, but in theory it _could_ be enhanced to do so. If 
`out` expressions also allow this, then we get the desired 
symmetry between `for`,`foreach`, and `out` expressions, with 
minimal verbosity. That's the solution I promote. It's better 
than requiring something to be there when nothing really has to 
be. I don't know why `foreach` isn't already this way.


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-27 Thread MysticZach via Digitalmars-d

On Tuesday, 27 June 2017 at 09:18:11 UTC, Olivier FAURE wrote:
A bit late to the party, but I would recommend the following 
syntax:


out (void; myTest)

for argument-less tests. A casual reader would be less likely 
to see this in code and think it's some sort of typo; it would 
be easier to google; and it would make some semantic sense 
(functions that don't return anything return void).


It's a creative suggestion, and not a bad one. But it's verbose, 
and I'd like to be able to omit the identifier altogether. 
Currently, only `for` loops allow this, as when people write:


for( ; ; )

Theoretically, `foreach

foreach( ; a) ...
out( ; ...)

Currently `foreach` does not allow omitting


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-27 Thread MysticZach via Digitalmars-d

On Monday, 26 June 2017 at 21:06:10 UTC, Timon Gehr wrote:

The DIP is missing the corresponding syntax for invariants:

class C{
private int x=1;
invariant(x>0, "x must stay positive");
}

Implementation:
https://github.com/dlang/dmd/compare/master...tgehr:contract-syntax


Well done. It seems to speak to the intuitive nature of the 
design that it's so easy to deduce how it would work in this 
context.


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-25 Thread MysticZach via Digitalmars-d

On Sunday, 25 June 2017 at 12:10:02 UTC, Timon Gehr wrote:
The path of least resistance is to use existing language 
constructs, i.e.


out result => assert(result > 0)


Andrei

This would face quite some resistance, on the following grounds:

out(result){ assert(result > 0); } // exists

out result => assert(result > 0) // more of the same

out(result; result > 0) // better


I also imagine we'll end up seeing quite a lot of:

out( ; __result > 0)

...even though `__result` is still undocumented, because it's 
DRY. That's actually an incentive, IMO, to go ahead and document 
it. It's just tighter.


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-24 Thread MysticZach via Digitalmars-d

On Saturday, 24 June 2017 at 12:26:57 UTC, Moritz Maxeiner wrote:
Should the need ever arise for (new) contract and assert 
grammar to diverge it can be dealt with then by whoever does 
the diverging.


Yes, I'll keep the grammar the same for now, because there is a 
benefit to doing so, in that any improvements to the assert 
grammar will immediately apply to the contract grammar too.


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-24 Thread MysticZach via Digitalmars-d

On Saturday, 24 June 2017 at 02:31:09 UTC, Solomon E wrote:
I think my proposal to add another use of semicolon in 
parentheses, like `foreach` or `for` but not the same as 
either, was needlessly complicated.


It's very popular, actually. :)


in (a)
out (result) (a)


This resembles template function declarations. Both proposals 
resemble something else that they are not. Your proposal for 
`out` is attractive, actually, because the semantics of foreach 
are closer to what we're looking for than are the semantics of 
template declarations.



as syntax sugar where each (a) lowers to
{assert(a);}
and in future can lower to something else, to renovate contract 
implementation


The foreach syntax can be just as easily lowered:

out(result; a)

...to:

out(result) {assert(a);}

That also includes the optional message.

out(result; result < 1, "alert!")

...lowers to:

out(result) { assert(result < 1, "alert!"); }


That's so much easier, in every way.


There's no intention of making it complicated!


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-23 Thread MysticZach via Digitalmars-d

On Friday, 23 June 2017 at 21:36:07 UTC, Moritz Maxeiner wrote:
Contracts within the DbC paradigm *are* abstractions that do 
not necessitate any particular implementation.


In practice, though, what must any such implementation actually 
achieve?


1. allow the source code to express its intent to the reader
2. prevent programs in invalid states from continuing
3. provide information about those invalid states after the fact

Goal 1 lies in the domain of the language grammar.
Goals 2 and 3 reflect the behind-the-scenes implementation of 
that grammar.


Most native languages simply (sensibly) choose to use asserts 
for that.


Which could mean that they use the grammar of asserts, e.g. 
`assert(a, "message");`, or that they use a specific 
behind-the-scenes implementation of that grammar, i.e. the code 
that such a grammar compiles to.


It would only couple the contracts with asserts if the DIP also 
specifies that asserts *must* be used for the lowering (which I 
would be against btw).


I think this reveals the sticking point. I think that the way D 
compiles assert expressions can and should be improved by making 
it more flexible behind the scenes. But that doesn't necessarily 
mean that the grammar needs to change. The problem is that we 
need to put *some* grammar into the new `in` expression design. 
If we allow, for example, a random sequence of function 
arguments, e.g.`in(a, b < 0, "yay!", myDvar)` there is no go-to 
way to implement it. The surface code would then require a 
particular backend implementation that could handle the grammar, 
and would furthermore now be coupled with that implementation. 
I'd rather not deal with that problem. It's vastly easier to just 
put my faith into the `assert` grammar, and hope that any 
improvements that it needs and receives will apply equally to 
`assert`s as well.


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-23 Thread MysticZach via Digitalmars-d

On Friday, 23 June 2017 at 20:49:35 UTC, Moritz Maxeiner wrote:
Normal usage of the new syntax? If asserts later on get a 
(possibly breaking) syntax overhaul that will affect (and 
forward breakage to) the contract syntax, as well, if it uses 
the same compiler infrastructure.


I believe this fear is irrational. A breaking change to the 
assert syntax would be extremely stupid. Imagine how much code 
would break if there were a breaking change to `assert`! The only 
possible changes to it must be additive.


My naive assumption is that any improvement in the in/out 
grammar would also apply to asserts, and vice versa.


Why should it? Contracts are not asserts or vice versa.


I 95% disagree. As far as I can tell, they are _very_ similar. 
The only difference I can see is that when you violate an `in` 
contract, the exit message should point to the caller instead of 
the callee as the source of the problem. Beyond that, they seem 
like little more than glorified `assert`s. I think their greatest 
benefit is in helping the programmer read and understand the 
logic of the program, rather than in anything the compiler can do 
with them.


I'm not sure what you're getting at here. With the proposal 
Timon implemented we have the following:
- the newer, decoupled contract syntax that separates contract 
specification and implementation from each other; Timon's 
implementation uses asserts as the internal contract 
implementation AFAIK


Not exactly. It actually _couples_ `in` expressions with assert 
expressions. In essence it just lowers


int fun(int a)
in(a)
{
}

...to:

int fun(int a)
in { assert(a); }
{
}

This is a sensible default. In the future, some logic could be 
added to provide a hook to a different implementation of the `in` 
function, so that it would lower instead to:


int fun(int a)
in { __userDefinedInContract(a); }
{
}

But I suspect the vast majority will stick with the default.



Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-23 Thread MysticZach via Digitalmars-d

On Friday, 23 June 2017 at 20:03:17 UTC, Moritz Maxeiner wrote:
No. Asserts are the meat of in/out contracts, these are 
actually asserts. Anything you do to the assert grammar 
should be done here as well.


I agree. I can understand wanting to pass in/out violations to 
a different handler behind the scenes. But I don't see why 
that should affect the grammar.


Because coupling the new contract syntax and assert syntax in 
the grammar means that changing assert syntax will affect the 
new contract syntax (when it shouldn't, as they are 
semantically decoupled).


By default, I assume they will not be semantically decoupled, 
that they will all just use regular asserts. I think the 
consistency the assert grammar will bring is worth a whole lot, 
as once it is understood in one place, it is understood 
everywhere. That's why it's so easy for Timon to implement, for 
example, because the assert logic is already available. So, for 
me to be convinced that the the grammar for in/out contracts 
should be different, I'd have to see a clear and compelling use 
case. What exactly did you have in mind? My naive assumption is 
that any improvement in the in/out grammar would also apply to 
asserts, and vice versa. I would go further and say that having 
consistency among all types of contracts is valuable enough to be 
worth sacrificing a considerable amount of flexibility in the 
grammar, even if a compelling use case were presented.


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-23 Thread MysticZach via Digitalmars-d
On Friday, 23 June 2017 at 18:42:55 UTC, Steven Schveighoffer 
wrote:

On 6/23/17 2:24 PM, Moritz Maxeiner wrote:

I'm all for this syntax, just one spec/implementation question:
If the new contract syntax (formally) shares grammar rules 
with assert, won't that cause more work for people who want to 
update the assert syntax later (since they will have to take 
contracts into account)?


No. Asserts are the meat of in/out contracts, these are 
actually asserts. Anything you do to the assert grammar should 
be done here as well.


I agree. I can understand wanting to pass in/out violations to a 
different handler behind the scenes. But I don't see why that 
should affect the grammar.


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-23 Thread MysticZach via Digitalmars-d

On Friday, 23 June 2017 at 18:20:23 UTC, Moritz Maxeiner wrote:

On Friday, 23 June 2017 at 18:03:26 UTC, Timon Gehr wrote:

On 23.06.2017 18:21, H. S. Teoh via Digitalmars-d wrote:

[...]



Agreed. Implementation:
https://github.com/dlang/dmd/compare/master...tgehr:contract-syntax

(At most one contract of each type is supported. It is not 
very hard to implement multiple contracts, but this requires 
touching semantic analysis.)


Holy ***. I set aside some time this weekend to try 
implementing this myself as an exercise, but oh well. Thanks!


I know! I'd say it'll take me a good deal longer to rewrite the 
DIP than he's taking to implement it!


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-23 Thread MysticZach via Digitalmars-d

On Friday, 23 June 2017 at 16:21:28 UTC, H. S. Teoh wrote:
On Fri, Jun 23, 2017 at 09:06:59AM +, Solomon E via 
Digitalmars-d wrote: [...]

T foo(T)(T x, T y)
in (x > 0, y > 0)
out (r; r > 0)
{
return x % y + 1;
}


Hmm, I like this syntax for out-contracts!  It borrows from 
existing foreach syntax, so it has some precedence, whereas the 
previous proposal of `out(...)(...)` looks uglier and also 
looks deceptively like a template function declaration.


`out (r; r > 0)` gets my vote.


OTOH, I don't like the comma in the in-contract.  Let's just 
keep it as either separate clauses:


in (x > 0)
in (y > 0)


Yeah, my take is that the grammar for `assert`s applies to the 
new syntax as well. If the grammar for asserts is this:


AssertExpression:
  assert ( AssertParameters )

... then the grammar for the new syntax is:

InExpression:
  in ( AssertParameters )

OutExpression:
  out ( ; AssertParameters )
  out ( Identifier ; AssertParameters )



Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-23 Thread MysticZach via Digitalmars-d

On Friday, 23 June 2017 at 13:58:38 UTC, Moritz Maxeiner wrote:
OT: Anyone interested in a DIP for more template constraint 
unfulfilled information in a consistent way to contracts (?) :

---
int myFunc(Args...)(Args args)
  if (Args.length > 0, "Starving!")
  if (Args.length > 1, "Still hungry!")
  if (Args.length > 2, "Just a little bit more!")
  in (args[0] != 0, "Yikes!")
  in (args[1] > 1, "Why you do this?")
  out (result; result > 0, "Oops...") { ... }
---


This would be a good question for a different thread.


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-23 Thread MysticZach via Digitalmars-d
On Friday, 23 June 2017 at 13:00:30 UTC, Steven Schveighoffer 
wrote:

On 6/23/17 5:06 AM, Solomon E wrote:
What I expected from my impression of existing D syntax was 
that something like this might be coming up:


T foo(T)(T x, T y)
 in (x > 0, y > 0)
 out (r; r > 0)
{
 return x % y + 1;
}


The out contract looks pretty good actually. The in contract, 
not as good. That looks like a comma expression. I'd rather see 
this be:


 in(x > 0)
 in(y > 0)

or

 in(x > 0 && y > 0)


I would assume the grammar for these expressions would be the 
same as for `assert`s. So you're right in pointing out the flaw 
above.


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-23 Thread MysticZach via Digitalmars-d

On Friday, 23 June 2017 at 09:06:59 UTC, Solomon E wrote:
What I expected from my impression of existing D syntax was 
that something like this might be coming up:


T foo(T)(T x, T y)
in (x > 0, y > 0)
out (r; r > 0)
{
return x % y + 1;
}

`out ()` has syntax similar to `foreach` and `for`, allowing 
mentioning something about the return type, or unpacking a 
return value, then testing it. (When there's no semicolon, an 
`out` block follows.)


This is a good idea, and I didn't think of it. Points:

* It would be great if you were allowed to omit the identifier 
before the semicolon in cases where you didn't need it. The 
existing foreach grammar does not allow this [1]. I'm not sure if 
that is intended to prevent bugs, or if it was just never thought 
to be useful.


* The grammar for what's inside the parens should also mimic 
what's inside `assert`s, allowing an error message. So the new 
grammar would actually be a mix of the existing `foreach` and 
`assert` grammars, e.g.


out(r; r >0, "contract violated!")

Comparing with the double parens solution:

out(result)(result > 0, "violation!")
out()(otherData > 0, "prohibited!")

vs.

out(result; result > 0, "violation!")
out(; otherData > 0, "prohibited!")

It's a close call. Nice job!

[1] https://dlang.org/spec/statement.html#foreach-statement



Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-22 Thread MysticZach via Digitalmars-d
On Friday, 23 June 2017 at 00:17:23 UTC, Steven Schveighoffer 
wrote:
We can call that contextual "keyword" result. Doesn't have to 
be a keyword, just the implied return value symbol name.


Another problem is that any given contextual reserved identifier 
you choose will run the risk of shadowing other variables. 
`result` could easily already be defined in an outer context. A 
solution to this is to use a variable starting with `__`, as 
those are the existing way of defining reserved identifiers. 
Maybe `__result`?





Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-22 Thread MysticZach via Digitalmars-d
On Friday, 23 June 2017 at 00:17:23 UTC, Steven Schveighoffer 
wrote:

int foo()
out(result)
{
}

what does this mean? Does it mean assert(result) on the out 
contract, or this is the old form of out?


If we didn't have contract syntax already, and many existing 
code bases that use it, I'd say this would be the way to go.


The current grammar is:

OutStatement:
   out ( Identifier ) { Statement }
   out { Statement }

So one way out is simply to demand that there be more than just 
an identifier when checking in the new way. So you'd have to 
require more tokens, e.g.`out(result !is null)` instead of just 
`out(result)` in order for the parser to easily distinguish 
between the two. It's a little messy. On the other hand, 
requiring two sets of parens is clean, but ugly. So it's a choice 
between ugly and messy, unless someone comes up with something 
more elegant.


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-22 Thread MysticZach via Digitalmars-d

On Thursday, 22 June 2017 at 21:56:29 UTC, Timon Gehr wrote:

On 22.06.2017 23:51, MysticZach wrote:

On Thursday, 22 June 2017 at 21:41:55 UTC, MysticZach wrote:
The whole double parentheses is a bit ugly to me. Is there 
any problem with

out(return > 0)
instead of
out(r) (r > 0)


I'm sorry, I didn't read closely. I think that's just asking 
for trouble, wanting to use `return` as an identifier. Timon 
found a specific reason why, but in general contextual 
keywords are frowned upon for precisely this type of ambiguity 
in the meaning of the code.



(It's not a contextual keyword. A contextual keyword is an 
identifier that is reserved in some contexts but not others.)


I would argue that the above suggestion promotes `return` 
precisely that way. It's now an identifier in precisely that one 
context, but is reserved as a keyword in all other contexts. Not 
sure what to call it. But we're a little off topic, as we both 
agree that the above solution to the double parens isn't viable, 
right?


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-22 Thread MysticZach via Digitalmars-d

On Thursday, 22 June 2017 at 21:41:55 UTC, MysticZach wrote:
The whole double parentheses is a bit ugly to me. Is there any 
problem with

out(return > 0)
instead of
out(r) (r > 0)


I'm sorry, I didn't read closely. I think that's just asking for 
trouble, wanting to use `return` as an identifier. Timon found a 
specific reason why, but in general contextual keywords are 
frowned upon for precisely this type of ambiguity in the meaning 
of the code.


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-22 Thread MysticZach via Digitalmars-d

On Thursday, 22 June 2017 at 20:02:17 UTC, jmh530 wrote:

On Thursday, 22 June 2017 at 18:57:40 UTC, MysticZach wrote:

[snip]


I don't mind that so much, but you made a good point earlier on 
how out would work with it.


The whole double parentheses is a bit ugly to me. Is there any 
problem with

out(return > 0)
instead of
out(r) (r > 0)


The current grammar for `out` is:

OutStatement:
   out { Statement(s) }
   out ( Identifier ) { Statement(s) }

If the out contract with the new syntax had only one assertion, 
and that assertion were a single identifier, there would be a 
parsing ambiguity:


int fun(int a) {
   int nested(int b)
   out (b) // out with a single assert, or out with identifier 
and brackets?

   {
  assert(b); // function body, or `out` contract?
   }
   do { ... } // function body, or do-while loop?
   while (true); // only here do we finally figure it out
}

There's probably an easy way to tidy this up, but I couldn't 
think of one off hand, so I suggested `out ( ) ( IfCondition )` 
as an unambiguous alternative. It would in fact be the rare case, 
since most `out` contracts will just want to check the return 
value.


Also, I can see the point of Critique 5 in the DIP for not 
including in/out anywhere and wanting to pin it to the top of 
the body. The suggestion in your post at least succeeds at that.


I assume you mean H.S. Teoh's suggestion? If it's as good as the 
others seem to think, hopefully it will succeed more than that... 
but preventing enhancement 5 is as simple as having the compiler 
issue an error if the user violates the rule that contracts must 
occur first and be grouped together in the body.


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-22 Thread MysticZach via Digitalmars-d

On Thursday, 22 June 2017 at 14:08:32 UTC, jmh530 wrote:
My recollection is that the most significant reason to use 
contracts in D is because of contract inheritance. There's a 
lot of focus in this discussion on normal functions, when I 
would say that contracts really aren't even needed.


So a more useful situation to consider then is:
[...]
I would say keep the current behavior for backwards 
compatibility (maybe with the body/do change), but also allow 
the following code:


class Foo
{
int fun(int a)
{
in {
assert(a > 0 && a < 10);
}
return a;
}
}

class Bar : Foo
{
int fun(int a)
{
in {assert(a > 0);}
return a;
}
}


The existing proposal allows this, and goes further and allows 
removing the unnecessary brackets after `in`:


class Foo
{
int fun(int a)
{
in assert(a > 0 && a < 10);
return a;
}
}
class Bar : Foo
{
// override
override int fun(int a)
{
in assert(a > 0);
return a;
}
}

Some people don't like the cognitive dissonance of seeing `in` 
inside the function. It really doesn't look that bad to me, and 
I'm glad to have a little support for the idea. But there are a 
couple more considerations. First, classes in D are not as 
popular as they are in some other languages, because of how 
powerful regular structs have become. I'd want to get more 
feedback on the value of improving a syntax (assuming it is 
clearly an improvement, which several people so far disagree 
with) that is only really valuable in cases that aren't used that 
much.


There are other questions too. The syntax is only one of three 
possible reasons contracts in D aren't that popular. The second 
reason is that the specific implementation, i.e. the  "backend", 
currently has limited support as described by H.S. Teoh [1]. The 
third reason is more abstract and harder to pin down, which is 
that some things are just more attractive in theory than they are 
in practice. The question is, even with the best possible syntax, 
and the best possible implementation, how much total value can 
`in` and `out` contracts add to language? How much more total use 
would they see?


If we knew in advance that the answer to the third question is, 
"People wouldn't use them that much," then we might spare 
ourselves the effort of improving them. We could more or less 
drop the issue as a lost cause. But I suppose the premise of this 
DIP is that it's worth it to try to find out. It also looks like 
there will be a separate DIP for reimplementing the backend, so 
this one will focus, as it already does, on the syntax.


That said, H.S. Teoh's version of the above code would look like 
this:


class Foo
{
int fun(int a)
in(a > 0 && a < 10)
{
return a;
}
}
class Bar : Foo
{
override int fun(int a)
in(a > 0)
{
return a;
}
}

I'm leaning towards pushing this one, as it simply hasn't gotten 
the pushback that mine has so far. I do have a problem with it, 
which is that the checking logic is mingled in with the grammar. 
This doesn't usually happen in D, which normally requires you to 
explicitly write `assert` in order to assert something. Here, 
`in` becomes grammatically equivalent to an `assert` expression, 
but one which is only allowed in the function signature. At 
minimum, I can say that the reception for this idea has been more 
positive than for mine. But I do appreciate the support :-}


[1] 
http://forum.dlang.org/post/mailman.3554.1498074198.31550.digitalmar...@puremagic.com


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-22 Thread MysticZach via Digitalmars-d

On Thursday, 22 June 2017 at 13:11:12 UTC, MysticZach wrote:
As long as one is doing this, maybe a proposal for user-defined 
`assert` should be provided too? It'd be interesting to have a 
dedicated file for user-defined assert and contract 
configuration. The core idea is to allow *everyone*, from large 
companies to individual hobbyists, to use `assert`, `in`, and 
`out`, and have it work the way they want. I would definitely 
need help writing that DIP.


:-)


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-22 Thread MysticZach via Digitalmars-d

On Thursday, 22 June 2017 at 12:54:00 UTC, MysticZach wrote:
On Thursday, 22 June 2017 at 10:59:18 UTC, Moritz Maxeiner 
wrote:
Again, that's not what H.S. Teoh's proposal would do. All it 
does is install an *implementation agnostic*, *abtract* way to 
specify contracts into the grammar. Whether that is lowered to 
assert, or anything else is an implementation detail and it 
certainly isn't fixed to asserts.


Okay. Then the proposal needs to be accompanied by an explicit 
description of how to hook into the new semantics. Which is 
what you provided, but I suppose it would need to be exactly 
specified. In particular, where exactly is the code for the 
(optional) user-defined hook to be found? In a separate file, 
maybe as indicated with a command line option, e.g. 
`-contractsConfig=myContracts.d`?


As long as one is doing this, maybe a proposal for user-defined 
`assert` should be provided too? It'd be interesting to have a 
dedicated file for user-defined assert and contract 
configuration. The core idea is to allow *everyone*, from large 
companies to individual hobbyists, to use `assert`, `in`, and 
`out`, and have it work the way they want. I would definitely 
need help writing that DIP.


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-22 Thread MysticZach via Digitalmars-d

On Thursday, 22 June 2017 at 10:59:18 UTC, Moritz Maxeiner wrote:
Again, that's not what H.S. Teoh's proposal would do. All it 
does is install an *implementation agnostic*, *abtract* way to 
specify contracts into the grammar. Whether that is lowered to 
assert, or anything else is an implementation detail and it 
certainly isn't fixed to asserts.


Okay. Then the proposal needs to be accompanied by an explicit 
description of how to hook into the new semantics. Which is what 
you provided, but I suppose it would need to be exactly 
specified. In particular, where exactly is the code for the 
(optional) user-defined hook to be found? In a separate file, 
maybe as indicated with a command line option, e.g. 
`-contractsConfig=myContracts.d`?


DIP1003 did not introduce an entirely new system, it merely 
slightly changed an existing sytem.
DIP1009 *does* introduce several new syntax forms, i.e. adding 
a whole new system, which means it *also* introduces the 
responsibility of maintaining backwards compatibility when 
someone tries to improve contracts again (and then we would 
have three systems to specify contracts).


Okay, I'm a convert. Although still one big downside is that DbC 
in D is somewhat impaired, as H.S. Teoh pointed out [1].


[1] 
http://forum.dlang.org/post/mailman.3554.1498074198.31550.digitalmar...@puremagic.com




Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-22 Thread MysticZach via Digitalmars-d

On Thursday, 22 June 2017 at 12:21:29 UTC, MysticZach wrote:
I start to get the nagging feeling that your point about the 
limitation in D's DbC implementation is actually the fatal flaw 
here. It's currently _illegal_ (outside of interface 
declarations) to expose the signature separately from the body, 
which, as you point out,  is more or less the whole point of 
DbC.  The existing system is itself distinctly _worse_ 
than just writing out asserts manually... and as far as I can 
tell,  none of the alternative syntaxes is a decisive 
improvement over it. Yours looks the best, but implying 
`assert` in the grammar seems to be going too far, especially 
for a DbC system that is only half functional. If the `assert` 
system were made more user-definable, it would make more sense. 
Do you agree with me on this?


Plans to improve `assert` are already in the air. Maybe we 
should wait on them before promoting your suggestion?


Conversely, as Moritz suggests, contracts could have their own 
separate logic, with optional user-defined hooks. Do you have a 
suggestion on how to implement this behind the scenes?


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-22 Thread MysticZach via Digitalmars-d

On Thursday, 22 June 2017 at 06:43:38 UTC, H. S. Teoh wrote:
On Thu, Jun 22, 2017 at 05:46:06AM +, MysticZach via 
Digitalmars-d wrote: [...]
As far as syntax subtrees not belonging to their parent, I can 
see where the cognitive dissonance comes from. But it just 
doesn't seem that bad to me, since contracts are always 
executed as if they are sequential statements anyway.

[...]

Then possibly you're missing the point behind DbC.  The idea of 
"executing" a contract seems to indicate that you're taking the 
current D implementation of it as normative.


I understand. Thus, a better DIP would suggest reimplementing D's 
DbC system altogether. Because as it is, they are little more 
than syntax dressing, which happens to be less convenient that 
just writing out the asserts in the first place. They're more 
like syntax _vinegar_ than sugar. Which explains why hardly 
anyone uses them. Why write this:


int fun(int a)
in { assert (a); }
do {
return a;
}

...when you could just do this:

int fun(int a) {
   assert(a);
   return a;
}

With your improvement, it's a little better,

int fun(int a)
in (a)
{
return a;
}

...but the cost is that `assert` is implied, and no other system 
of checking is allowed, which seems like a sufficient flaw to 
make it not decisively better. To solve this, you'd have to 
decouple `assert` from the contract, requiring this:


int fun(int a)
in (assert(a))
{
   return a;
}

This also looks good. But now the grammar is weird because it's 
just an expression in there without a statement, which doesn't 
happen anywhere else in D.


I start to get the nagging feeling that your point about the 
limitation in D's DbC implementation is actually the fatal flaw 
here. It's currently _illegal_ (outside of interface 
declarations) to expose the signature separately from the body, 
which, as you point out,  is more or less the whole point of DbC. 
 The existing system is itself distinctly _worse_ than 
just writing out asserts manually... and as far as I can tell,  
none of the alternative syntaxes is a decisive improvement over 
it. Yours looks the best, but implying `assert` in the grammar 
seems to be going too far, especially for a DbC system that is 
only half functional. If the `assert` system were made more 
user-definable, it would make more sense. Do you agree with me on 
this?


Plans to improve `assert` are already in the air. Maybe we should 
wait on them before promoting your suggestion?


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-22 Thread MysticZach via Digitalmars-d

On Wednesday, 21 June 2017 at 19:34:53 UTC, H. S. Teoh wrote:
This is a sticky point about D's current DbC implementation 
that myself and several others feel is a design flaw. In 
particular, that in-contracts are executed as part of the 
*callee*, when the intent of DbC is really that it is the 
obligation of the *caller* to fulfill its stipulations, and 
therefore the contract verification should happen at *caller* 
site rather than at the beginning of the callee.


This particular implementation detail causes problems with 
binary-only libraries: most library vendors would prefer to 
ship the library compiled with -release rather than not, but in 
-release, the asserts in any in-contracts would be elided, 
making them essentially non-existent by the user uses the 
library.  So you either have to dispense with DbC altogether, 
or be forced to ship two versions of your library, one with 
contracts compiled in and one without, in order for your users 
to benefit from DbC *and* not have to suffer performance 
penalties in their own release builds.


Had in-contracts been implemented on the caller's side instead, 
this would no longer be a problem: the contracts will still be 
part of the library API, so the user can benefit from them when 
not compiling with -release, but now the library itself can be 
shipped only with the binaries compiled with -release for best 
performance.


This is probably something outside the scope of this DIP, 
however.


It's related. A design flaw in D's DbC means that contracts on 
the whole are less important. Which means, unfortunately, that 
improving them is less important. Which could affect the final 
decision. But on the other side, binary-only libraries published 
in release mode are actually rare in D, right?




Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-21 Thread MysticZach via Digitalmars-d

On Thursday, 22 June 2017 at 00:27:38 UTC, Timon Gehr wrote:

On 21.06.2017 19:39, MysticZach wrote:
My counterargument to that is that it's possible that the 
cognitive dissonance only occurs because of what people are 
used to, rather than what is inherent to the syntax.


This is a purely philosophical distinction without empirical 
basis.


Well I never experienced the dissonance myself, and was surprised 
to find that others did experience it. I just thought my proposal 
was a better syntax for `in` and `out` contracts.


Well my impression was that Walter liked it too, although I 
could have misinterpreted his comment here:


http://forum.dlang.org/post/ogvt66$1bcp$1...@digitalmars.com


He is saying it is good that a DIP to improve contract syntax 
/exists/. I agree with that.


It's really not clear what he meant. I guessed that the highest 
probability of what he meant was that he actually liked the DIP, 
as opposed to the mere fact that it _was_ a DIP. But as I already 
said, I could have misinterpreted his comment. In the face of 
lack of knowledge, it's a sign of wisdom to admit that one might 
be wrong, I think.



If such an alternative checking system is utilized,


there should be a way to hook into the checking logic.

Improving the checking logic interface may solve at a higher 
level the problem I'm trying to solve at a very low one, with 
mere syntax changes, and it might be (is probably?) the best 
way forward.


Your proposal does not solve this problem, and there is no need 
for this DIP to do that.


The goal of this DIP, and the problem I'm trying to solve, is 
"Improve Contract Usability." And for this, H.S. Teoh's proposal 
is a very good one. But it still has a sticking point, which I 
want to resolve, namely that it elevates the existing `assert` 
functionality beyond the current requirement that one must 
explicitly write `assert`, going so far as to imply it in the 
grammar itself. But because of many complaints about the 
limitations of the assert mechanism as it currently exists, I 
would hesitate to install it into the grammar as the "One Chosen 
Way" to bail out of contracts with the new syntax.


However, if the functioning of the `assert` mechanism were more 
customizable, then it would be easier to entrust it, in my 
opinion, with the "sacred responsibility" of being installed into 
the grammar. H.S. Teoh's proposal would then stand on a firmer 
foundation, and my initial proposed syntax would become the 
inferior optionl. At that point, this DIP could be rewritten to 
advocate his syntax instead. (I think it would be better to just 
retain the number and title "DIP1009: Improve Contract Usability" 
than to make a new one for the same issue. Other DIPs have 
followed this pattern, where it was the goal and title that 
remained the same, while the specifics changed.)


We are looking for a significant improvement. Otherwise, what's 
the point? We need to justify the cost.


The intent of my proposal was to make a small improvement. The 
cost (or so I thought, and may still believe) was also small. 
Small improvements are still improvements. DIP1003 is an example 
of this.


https://github.com/dlang/DIPs/blob/master/DIPs/DIP1003.md

The point of contracts is assigning blame by documenting 
assumptions and guarantees. If something within the function 
body crashes, it's ideally the fault of the function 
implementation.

...
I like new as long as it is an improvement. This is not. Having 
syntax subtrees that do not actually logically belong to their 
parent in the grammar is awkward language design, especially if 
they affect the parent's signature.


I'm still wondering what, in practice, the difference really is. 
With existing syntax:


int fun(int a)
in { assert(a); } // 1
do {
assert(a); // 2
...
}

What will the compiler or programmer actually learn from 1 if it 
violates that they won't learn from 2 if it violates? What is the 
practical incentive for `in` contracts at all? All my new syntax 
does is assume that there is in fact a difference between 1 and 
2, and makes 1 easier to write, as:


int fun(int a) {
in assert(a); // 1
assert(a); // 2
...
}

As far as syntax subtrees not belonging to their parent, I can 
see where the cognitive dissonance comes from. But it just 
doesn't seem that bad to me, since contracts are always executed 
as if they are sequential statements anyway. I would imagine that 
new programmers who only ever encountered the new proposed syntax 
would be surprised that the old syntax ever existed in the first 
place, as it's so unnecessarily awkward.


But at this point, we might as well wait for more feedback from 
other people.





Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-21 Thread MysticZach via Digitalmars-d

On Wednesday, 21 June 2017 at 18:04:07 UTC, Moritz Maxeiner wrote:

On Wednesday, 21 June 2017 at 17:55:05 UTC, MysticZach wrote:
Question: If `assert` itself allowed a user-defined hook, what 
would the remaining justification be for decoupling `in` and 
`out` contracts from the `assert` logic?


Because then you won't have normal asserts and contracts be 
subject to different semantics?
If I use a library, I may very well want to disable the 
library's internal assert checks (because I have enough 
experience that it's working properly), but keep it's contracts 
alive, because my code is still shiny new and riddled with bugs.


Timon appears to think that the checking logic is more 
monolithic. From his reply above [1]:


"If [an alternative checking system is utilized], there should be 
a way to hook into the checking logic. This has nothing at all to 
do with contract syntax. asserts and contracts are coupled 
already, as in-contracts form a disjunction on override by 
catching AssertErrors."


So I'm hoping more people will weigh in on this issue. For 
example, how easy is it to separate a library's internal 
contracts from its external ones? Would you have to write 
internal contracts in a different way from the ones facing the 
user? How often is this distinction the one causing problems with 
productivity?


The way I'm thinking about it would be that if there were a 
pragma to turn off contracts in a particularly hot code path, 
then the rest of the program could remain safe, while the fast 
part was allowed to go as fast as possible, addressing the 
performance issue.


But regarding the information issue, what kind of error 
information is better delivered specifically through compiler 
knowledge of `in` and `out` contracts, versus what it would 
deliver in the same way via regular `assert`s? Or are all 
contracts basically just fancy sugar for asserts at the beginning 
and end of a function body? What can the compiler do with the 
extra information? What can it say to the user that the user 
wouldn't already be able to figure out if it were a regular 
assert?


[1] http://forum.dlang.org/post/oie2nt$emf$1...@digitalmars.com


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-21 Thread MysticZach via Digitalmars-d

On Wednesday, 21 June 2017 at 17:38:02 UTC, Moritz Maxeiner wrote:
But another option is simply to upgrade `assert` to make sure 
it offers what everyone wants.


That would be really cool, but I doubt it will be feasible 
here. I think that in this case it will more likely end up with 
everyone hating that universal solution equally.


Well the universal solution could be, for example, the 
suggestions from my post in the other thread:


3. Allow an additional compiler flag for more informative, but 
heavier asserts, e.g. `-release=informativeAsserts`.


 4. Allow a pragma in the code, e.g. `pragma(asserts, 
none/regular/informative)` for what kinds of asserts are to be 
used at a given moment.


This would be added flexibility, rather than a one-size-fits-all 
solution. So the word "universal" is a little deceptive. The 
options could also include a user-defined hook for assert.


Question: If `assert` itself allowed a user-defined hook, what 
would the remaining justification be for decoupling `in` and 
`out` contracts from the `assert` logic?


That's what I mean by thinking the problem might be fixable by 
upgrading `assert`.


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-21 Thread MysticZach via Digitalmars-d

On Wednesday, 21 June 2017 at 15:18:21 UTC, Timon Gehr wrote:

On 21.06.2017 02:51, MysticZach wrote:


I think people could get used to the cognitive dissonance.


That's really not what D is about.


My counterargument to that is that it's possible that the 
cognitive dissonance only occurs because of what people are used 
to, rather than what is inherent to the syntax.



I've already gotten used to it just by writing this DIP.


I think it is likely that you are an outlier.


Well my impression was that Walter liked it too, although I could 
have misinterpreted his comment here:


http://forum.dlang.org/post/ogvt66$1bcp$1...@digitalmars.com


If such an alternative checking system is utilized,


If so, there should be a way to hook into the checking logic. 
This has nothing at all to do with contract syntax. asserts and 
contracts are coupled already, as in-contracts form a 
disjunction on override by catching AssertErrors.


Improving the checking logic interface may solve at a higher 
level the problem I'm trying to solve at a very low one, with 
mere syntax changes, and it might be (is probably?) the best way 
forward.



the syntax for  writing contracts should be as easy
for them as for those using `assert`.


Maybe, but your DIP does not pull its own weight as long as the 
latter syntax is not a notable improvement over what we have 
now.


Well, my view is that my DIP is actually a very lightweight 
syntax change, and an equally lightweight improvement in contract 
syntax, so it's a lost-cost, mild improvement . The cognitive 
dissonance argument is the main one against it, and I really 
don't know if that dissonance is based on fundamental flaws in 
the way I'm thinking about it, or just the "Shock of the New" 
[1]. If allowing contracts in the function body really is a 
fundamentally flawed concept, then I won't keep advocating for it.


H. S. Teoh's counter-proposal is, and I think your DIP has a 
much higher chance of acceptance if you go with it.


I'm not actually worried about whether the proposal is accepted 
or not, as long the best ideas and arguments come forward and are 
heard. I have more faith in the process than I do in any 
particular proposal.


As far as Teoh's proposal, I would say that its quality is highly 
correlated to the percentage of projects that find built-in 
`assert` adequate to their needs, which is hard to assess 
precisely - the better `assert` is, or can be made to be, the 
better Teoh's proposal is, I'd say. Moritz [2] suggests solving 
the problem by decoupling `in` and `out` contract syntax from the 
checking logic. This seems like a good way to go too. But I'd 
like to see a little more justification for it.


[1] Robert Hughes documentary, "The Shock of the New" 
https://www.youtube.com/watch?v=J3ne7Udaetg
[2] 
http://forum.dlang.org/post/uzzwmgqoqxuxhusjv...@forum.dlang.org


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-21 Thread MysticZach via Digitalmars-d

On Wednesday, 21 June 2017 at 14:49:09 UTC, Moritz Maxeiner wrote:

On Wednesday, 21 June 2017 at 13:24:24 UTC, MysticZach wrote:


So weird how this discussion is happening in parallel with 
this other discussion :-) :


http://forum.dlang.org/post/rkdpuuggltowhqmcm...@forum.dlang.org


It is, though as I have pointer out over there, I would really 
like to decouple assert semantics from the new contract 
semantics to achieve the maximum elegance we can within the 
design limits of the language.


Well I'd be just as happy expanding the design limits of the 
language, i.e. `assert`, if that were a better option. The issue 
you raise is just how different are `in` and `out` contracts from 
regular `assert` contracts. They _are_ all listed in the same 
section of the documentation [1], for whatever that's worth.


The practical question is whether one can assume that the same 
semantics used for `assert`, whatever they may be, will in all 
cases be desirable for `in` and `out` too. The flexibility of 
decoupling them is one solution, if they are clearly sufficiently 
different. But another option is simply to upgrade `assert` to 
make sure it offers what everyone wants. I don't know what to 
suggest, because I don't if `assert` can be made good enough to 
warrant direct inclusion into the grammar. If it could, then all 
contracts, including plain `assert` statements, would benefit 
from them.


[1] https://dlang.org/spec/contracts.html


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-21 Thread MysticZach via Digitalmars-d

On Wednesday, 21 June 2017 at 14:22:52 UTC, Moritz Maxeiner wrote:
If you do accidentally forget the extra set of parens on the 
`out` contract, you would get "Error: `do` expected before 
function body after a bracketed `out` contract" at the end of 
the function.


(If, however, it a happens to be a nested function, and the 
next statement in that function happens to be `do`, then the 
parser will think the `do` loop is the function body... Mmmm, 
is this worth worrying about??)


Could you give a specific (short) example of what you think of?
I don't see any potential for ambiguity in the following at a 
quick glance, so I'm not sure I got where you think the problem 
lies:


---
void foo()
{
int bar(Args...)(Args args)
  if (Args.length > 2)
  in (args[0] != 0)
  in (args[1] > 1)
  out (result)(result > 0) { ... }
do {} while (true);
}
---


The only problem is if a programmer forgets to add the additional 
parentheses, in which case the bracketed block is then mistaken 
for the `out` contract, which will lead to a confusing error 
message. For example:


void foo()
{
   int bar(Args...)(Args args)
  if (Args.length > 2)
  in (args[0] != 0)
  in (args[1] > 1)
  out /*whoops, forgot `( )`*/(result) { ... }

   do { ... }
   while (true); // Error: while statement cannot contain just `;`
}

Honestly this doesn't seem like a big deal, as I'd imagine it'd 
be hard not to notice that code like this wasn't working as 
expected. And also extremely rare. So I'm still in favor.




Re: dmd -betterC

2017-06-21 Thread MysticZach via Digitalmars-d

On Wednesday, 21 June 2017 at 10:51:39 UTC, ketmar wrote:
there, of course, *IS* The difference. besides the aesthetical 
one (seeing failed condition immediately "clicks" in your head, 
and generic "assertion failed" message is only frustrating), 
there may be the case when source code changed since binary was 
built. here, line number gives you zero information, and you 
have to checkout that exact version, and go check the line. but 
when failed condition dumped, most of the time it allows you to 
see what is wrong even without switching to the old codebase 
(yes, "most of the time" is from RL -- it is literally *most* 
of the time for me, for example).


How would you solve this issue? By pure chance, we're debating 
this exact same issue right now in the DIP1009 thread [1].


Solutions:

 1. Make more informative asserts the compiler default. This 
threatens performance, which argues against it.


 2. Status quo. Make people use whatever asserts they want, e.g. 
fluent asserts [2]. This would mean that H.S Teoh's proposed 
syntax for DIP1009 [3] would carry less weight, and the existing 
proposal would carry more. Elegance is sacrificed for the sake of 
versatility.


 3. Allow an additional compiler flag for more informative, but 
heavier asserts, e.g. `-release=informativeAsserts`.


 4. Allow a pragma in the code, e.g. `pragma(asserts, 
none/regular/informative)` for what kinds of asserts are to be 
used at a given moment.


 5. ???

[1] 
http://forum.dlang.org/post/mailman.3531.1498022870.31550.digitalmar...@puremagic.com

[2] http://fluentasserts.szabobogdan.com/
[3] 
http://forum.dlang.org/post/mailman.3511.1497981037.31550.digitalmar...@puremagic.com


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-21 Thread MysticZach via Digitalmars-d

On Wednesday, 21 June 2017 at 09:10:33 UTC, MysticZach wrote:

On Wednesday, 21 June 2017 at 05:19:26 UTC, H. S. Teoh wrote:
Umm... I think we're not quite on the same page here.  What 
*else* are people supposed to use inside their contracts 
besides the built-in assert??


I believe `assert` would have to be extremely robust to merit 
being included directly into the syntax of the language. I'm 
not opposed to this in principle. But I'm no expert, and not 
willing to assume it's desirable. On the other hand, if 
`assert` were made so perfect as to ensure that no one would 
prefer a different method of bailing out of their programs, 
then you're right, and the problem of contract syntax could be 
solved at that level instead of the more "pedestrian" approach 
I'm taking.


So weird how this discussion is happening in parallel with this 
other discussion :-) :


http://forum.dlang.org/post/rkdpuuggltowhqmcm...@forum.dlang.org



Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-21 Thread MysticZach via Digitalmars-d

On Wednesday, 21 June 2017 at 12:05:55 UTC, Moritz Maxeiner wrote:

On Wednesday, 21 June 2017 at 09:53:40 UTC, meppl wrote:

On Wednesday, 21 June 2017 at 09:27:20 UTC, MysticZach wrote:

On Wednesday, 21 June 2017 at 08:15:34 UTC, MysticZach wrote:

On Wednesday, 21 June 2017 at 04:16:22 UTC, Moritz Maxeiner
Adding `if (...)` should not be different from adding `in 
(...)` or `out (...)` in terms of syntax rules: it's 
inconsistent. If you want to have that `do` there, I would 
argue that it should also become required if only an `if (...)` 
is present, so


---
 int myFunc(Args...)(Args args)
   if (Args.length > 2)
   { ... }
---

should then become illegal and must be rewritten as

---
 int myFunc(Args...)(Args args)
   if (Args.length > 2)
   do { ... }
---

I doubt that's going to happen, though (too much code 
breakage), and I also don't like it. Simply drop the `do`.


I tend to agree. I think the grammar for `out` contracts is still 
murky, though, because the normal existing case is:


OutStatement:
   out ( Identifier ) { OutContractsBody }
   out { OutContractsBody }

My fix would be to require two sets of parentheses for the new 
conditional, like so:


OutStatement:
   ...
   // new version
   out ( Identifier ) ( IfCondition )
   out ( ) ( IfCondition )

This makes the grammar unambiguous and clean. And because 
normally `out` contracts want to check the return value, the last 
case, `out ( ) ( ... )` will be the rare one. If you do 
accidentally forget the extra set of parens on the `out` 
contract, you would get "Error: `do` expected before function 
body after a bracketed `out` contract" at the end of the function.


(If, however, it a happens to be a nested function, and the next 
statement in that function happens to be `do`, then the parser 
will think the `do` loop is the function body... Mmmm, is this 
worth worrying about??)




Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-21 Thread MysticZach via Digitalmars-d

On Wednesday, 21 June 2017 at 08:15:34 UTC, MysticZach wrote:
On Wednesday, 21 June 2017 at 04:16:22 UTC, Moritz Maxeiner 
wrote:

int myFunc(Args...)(Args args)
  if (Args.length > 2)
  in (args[0] != 0)
  in (args[1] > 1)
  out (result => result > 0) { ... }
---

- in contracts take a parenthesis delimited bool expression
- out contracts take a parenthesis delimited bool function 
literal.


`out` contracts would also have to account for the case where 
they don't check the return value. This would confuse the 
grammar a little in the case of function literals as boolean 
expressions. A different possible grammar that wouldn't have 
this problem is:


OutStatement:
out ( IfCondition )
out ( Identifier ) ( IfCondition )

plus the existing ones:

OutStatement:
out BlockStatement
out ( Identifier ) BlockStatement


I may have spoke too soon. If the grammar were:

OutStatement:
out ( IfCondition )
out ( FunctionLiteral )

It might still work okay. A little hiccup in the semantics, 
figuring out that the first parameter to the function literal is 
meant to be the return identifier. Maybe it's not a big deal.


Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-21 Thread MysticZach via Digitalmars-d

On Wednesday, 21 June 2017 at 05:19:26 UTC, H. S. Teoh wrote:
On Wed, Jun 21, 2017 at 01:06:40AM +, MysticZach via 
Digitalmars-d wrote:
On Tuesday, 20 June 2017 at 21:04:16 UTC, Steven Schveighoffer 
wrote:
> This is much much better. The verbosity of contracts isn't 
> really the brace, it's the asserts.


I think it's both, and I think the brace is the only thing 
that can be improved upon. How could you justify insisting 
that everyone use the built-in asserts for their contracts?

[...]

Umm... I think we're not quite on the same page here.  What 
*else* are people supposed to use inside their contracts 
besides the built-in assert??


Many people have expressed discontent with existing asserts. In 
fact, they were just changed yesterday to address one of these 
concerns:


https://github.com/dlang/dmd/pull/6901

I believe `assert` would have to be extremely robust to merit 
being included directly into the syntax of the language. I'm not 
opposed to this in principle. But I'm no expert, and not willing 
to assume it's desirable. On the other hand, if `assert` were 
made so perfect as to ensure that no one would prefer a different 
method of bailing out of their programs, then you're right, and 
the problem of contract syntax could be solved at that level 
instead of the more "pedestrian" approach I'm taking.


While D currently gives you the flexibility of arbitrary code 
inside a contract, a contract is not supposed to do anything 
other than to verify that the caller has passed in arguments 
that are valid.[1]


To me, it's still a question of whether `assert` is the only 
valid way to bail out of a program. I agree that arbitrary other 
code inside contracts is bad practice, and that wanting to 
prohibit it makes sense.


Furthermore, contracts specify what constitutes valid input to 
the function -- this serves both as documentation to would-be 
callers, and also as specification to the compiler as to what 
are acceptable arguments.  The built-in assert mechanism serves 
both purposes -- especially the second purpose because the 
compiler understands it directly, as opposed to some other 
user-defined mechanism that the compiler wouldn't understand.


This wouldn't change just with a syntax rewrite. If the compiler 
wanted to use `assert` for optimization purposes, it could do 
that just as well with any of the proposed syntaxes. People who 
didn't want to use `assert` would be at a disadvantage in this 
regard. But at least they would have that option.


Besides, this is a matter of semantics, whereas this DIP is 
addressing the DbC syntax.  If people demand an alternative to 
the built-in assert, it's not hard to have the compiler lower 
the syntax into some globally-defined symbol that can be 
redefined by the user. Or, indeed, simply funnel the expression 
into a user-defined assert alternative, e.g.:


int myFunc(Args...)(Args args)
if (args.length > 1)
in (myAssert(args[0] > 0))
{
return doStuff(args);
}

bool myAssert(T)(T t) {
// do whatever alternative assert stuff you need to do
// here

return true; // bypass the built-in assert
}


I guess the optimizer can elide the assert if it knows it's 
always true. If this method was sure not to incur a performance 
penalty, then it may be better than my approach.


But the semantics is a different issue than the syntax, which 
is the scope of this DIP.


The scope of the DIP can change, if need be. My primary goal is 
in the title, to "Improve Contract Usability". I used this title 
on purpose because I didn't want to get stuck if my proposal 
turned out to be worse than some other one. If adding a new 
semantics is actually preferable I can rewrite the DIP (and give 
you credit — or you can do it yourself, if you want). It was just 
as important to me to get the ball rolling as to have my 
particular suggestion accepted. I wanted to stay close to the 
shore, because I thought it was a little outlandish to propose a 
whole new semantics. I still think it's a little outlandish, 
because I can imagine a large organization wanting to rig up its 
own bailout mechanism, and the new semantics would prevent them 
from doing that. But so far, the comments suggest that it's worth 
it to many people.




Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-21 Thread MysticZach via Digitalmars-d

On Wednesday, 21 June 2017 at 04:16:22 UTC, Moritz Maxeiner wrote:
What *I* need from a DIP that addresses DbC in D (to make it 
viable for me) is to make the simple case as easy as possible 
to read while not introducing language inconsistencies.
With that in mind I am strongly in favor of the syntax H. S. 
Teoh already proposed:


---
int myFunc(Args...)(Args args)
  if (Args.length > 2)
  in (args[0] != 0)
  in (args[1] > 1)
  out (result => result > 0);

int myFunc(Args...)(Args args)
  if (Args.length > 2)
  in (args[0] != 0)
  in (args[1] > 1)
  out (result => result > 0) { ... }
---

- in contracts take a parenthesis delimited bool expression
- out contracts take a parenthesis delimited bool function 
literal.


`out` contracts would also have to account for the case where 
they don't check the return value. This would confuse the grammar 
a little in the case of function literals as boolean expressions. 
A different possible grammar that wouldn't have this problem is:


OutStatement:
out ( IfCondition )
out ( Identifier ) ( IfCondition )

plus the existing ones:

OutStatement:
out BlockStatement
out ( Identifier ) BlockStatement



Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-20 Thread MysticZach via Digitalmars-d
On Tuesday, 20 June 2017 at 21:04:16 UTC, Steven Schveighoffer 
wrote:

On 6/20/17 1:42 PM, H. S. Teoh via Digitalmars-d wrote:

Here's my counter-proposal: since the sig constraint line uses
parentheses (and yes, I deliberately planted a sig constraint 
above just
to make this point), why not go for syntactical symmetry? 
I.e., like

this:

int myFunc(Args...)(Args args)
if (Args.length > 2)
in (args[0] != 0)
in (args[1] > 1);// one semicolon to end them all


This is much much better. The verbosity of contracts isn't 
really the brace, it's the asserts.


I think it's both, and I think the brace is the only thing that 
can be improved upon. How could you justify insisting that 
everyone use the built-in asserts for their contracts? If you 
can, then okay, and other avenues are worth exploring. Are there 
not, however, many reasons to want to use other types of 
contracts? That's the main reason I went with my design, because 
I thought it was going too far to imply `assert` when people 
might want or need to use other things.


This also gives the compiler a better handle on what causes the 
thing to fail (better error message).


I'm pretty sure that the reason asserts are so sparse in terms of 
error information is due to the fear of slowdown, were they to 
contain more information. This tradeoff would be present 
regardless of contract syntax.


IMO, this whole proposal doesn't carry enough weight, either 
your version or the DIP itself. I would not be in favor. 
Current syntax is understandable, and not too verbose IMO.


That's a fair opinion. I wish I had a crystal ball to see how 
many more people would use contracts if this DIP were accepted. I 
imagine a lot of people will agree with you. I also know that 
some people don't [1].


http://forum.dlang.org/post/mailman.2288.1494811099.31550.digitalmar...@puremagic.com



Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1

2017-06-20 Thread MysticZach via Digitalmars-d

On Tuesday, 20 June 2017 at 17:42:13 UTC, H. S. Teoh wrote:
What would a body-less declaration of a function look like 
under the new syntax? Hopefully not this:


int myFunc(Args...)(Args args)
if (Args.length > 2)
in assert(args[0] != 0);// semicolon: ouch
in assert(args[1] > 1);  // semicolon: ouch
// How do we end the declaration here? Another semicolon?
;   // ouch


Such declarations are only legal when declaring interfaces. An 
investigation reveals that the existing grammar actually does not 
require that extra semicolon [1]. Thus, the parser would check 
for `body` (or `do`) after the contract statement, like it 
already does anyway, and just keep parsing. That said, it's 
certainly reasonable to disallow the new syntax in virtual 
interface functions, as is also done for enhancement 3: "Virtual 
interface functions cannot use this syntax..."


But I think a more reasonable solution — and the one I prefer — 
is simply to disallow semicolon contracts outside the function 
body, which is also mentioned in enhancement 3: "Note that it's 
possible to allow enhancements 1 and 2 only within function 
bodies." What that would boil down to is that existing contracts 
remain the same. Within function bodies, they can now be 
expressed as one-liners.


Also, I don't like the idea of putting contracts inside the 
function body. As the DIP already mentions, this makes parsing 
of contracts more difficult. It also causes cognitive 
dissonance (contracts are a part of the function's signature, 
not its implementation).


I think people could get used to the cognitive dissonance. I've 
already gotten used to it just by writing this DIP.


As for the parsing, it isn't much more difficult. The compiler 
just adds any `in` or `out` statement to the list of statements 
in the contract, creating one when necessary. The only reason it 
_might_ be more difficult is in the case of a certain kind of 
documentation parsing which I'm not sure even exists as of yet 
(somebody tell me if it does!). Such documentation parsing is 
that which actually wants to publish the contracts verbatim, as 
part of the documentation. Normally if you're scanning for 
documentation, you can speed up parsing by skipping the function 
body. If you don't need to document the contracts verbatim, then 
you can still just skip them like you would the rest of the 
function body. Only if you _did_ want to parse the contracts 
verbatim would it get more complicated. But the problems aren't 
that bad. The easiest way to find the contracts is to require 
that they occur at the top of the function. This would allow 
searching for the tokens `in` and `out` to detect contracts. 
Anything other than `in` or `out` just gets skipped.


But remember, I don't even know if this will be a problem, as in 
any other scenario, you have to parse the whole program anyway. 
The compiler just has to add  any `in` and `out` statement to the 
existing contracts as it encounters them. With the alternative 
enhancement listed in the DIP as 4 (not part of the basic 
proposal), there is a little more difficulty with something like:


int fun(int x) {
static if(...) in assert(x);
}

...because in this case, there's no existing semantics for that 
construction, and the compiler will need to work a little magic. 
I suggested simply rewriting it as:


int fun(int x) {
in static if(...) assert(x);
}

which lowers to:

int fun(int x)
in { static if(...) assert(x); }
body { }

Which seems to work. But of course the compiler would need to be 
able to catch what was going on and lower the syntax as 
necessary, which may or may not be trivial.


It's even worse if you allow contracts in arbitrary places 
inside the function body -- then even somebody reading the code 
wouldn't know, at a glance, what the contracts are, without 
scanning the entire function body! That makes contracts 
*harder* to read and use, rather than easier, in direct 
contradiction of the purpose of this DIP.


This is a strong argument in favor of the existing proposal, 
which states, under enhancement 3, "They must occur at the 
beginning of the function..."


In the Alternatives section, as enhancement 5, I mentioned the 
possibility of allowing contracts anywhere in the function. I 
don't think it's a good idea. I think you're right. But I thought 
that it was worth mentioning, at least as an alternative.


Here's my counter-proposal: since the sig constraint line uses 
parentheses (and yes, I deliberately planted a sig constraint 
above just to make this point), why not go for syntactical 
symmetry? I.e., like this:


int myFunc(Args...)(Args args)
if (Args.length > 2)
in (args[0] != 0)
in (args[1] > 1);// one semicolon to end them all


This proposal has syntax and semantics too. The syntax is that 
contracts occur inside parentheses, which I have no problems 
with. The semantics, however, 

Re: Revised DIP Info

2017-06-14 Thread MysticZach via Digitalmars-d-announce

On Wednesday, 14 June 2017 at 12:53:21 UTC, MysticZach wrote:

On Wednesday, 14 June 2017 at 12:17:50 UTC, Mike Parker wrote:
In this thread, I'm specifically looking for feedback on my 
updates to the readme and the guidelines. Sorry for any 
confusion.


s/GUIDLINES.md/GUIDELINES.md/


In the readme file. The link is good, but the label is wrong.


Re: Revised DIP Info

2017-06-14 Thread MysticZach via Digitalmars-d-announce

On Wednesday, 14 June 2017 at 12:17:50 UTC, Mike Parker wrote:
In this thread, I'm specifically looking for feedback on my 
updates to the readme and the guidelines. Sorry for any 
confusion.


s/GUIDLINES.md/GUIDELINES.md/


Re: Revised DIP Info

2017-06-14 Thread MysticZach via Digitalmars-d-announce

On Wednesday, 14 June 2017 at 10:32:50 UTC, Andre Pany wrote:

[3] https://github.com/dlang/DIPs/pull/71


Hi,

the work on this dip is highly appreciated. For my AWS SDK this 
DIP would
make the coding much more readable and also smaller for several 
use cases.


At this point in the process, it's better to comment on the 
github page for that DIP than here on the forums. I'm sure your 
comments will be welcome there.


Re: Compile-Time Sort in D

2017-06-07 Thread MysticZach via Digitalmars-d-announce

On Tuesday, 6 June 2017 at 01:08:45 UTC, Mike Parker wrote:

On Monday, 5 June 2017 at 17:54:05 UTC, Jon Degenhardt wrote:



Very nice post!


Thanks! If it gets half as many page views as yours did, I'll 
be happy. Yours is the most-viewed post on the blog -- over 
1000 views more than #2 (my GC post), and 5,000 more than #3 (A 
New Import Idiom).


Seems like this crowd-editing stuff really works!


Re: DIP 1008 Preliminary Review Round 1

2017-06-05 Thread MysticZach via Digitalmars-d

On Friday, 19 May 2017 at 15:45:28 UTC, Mike Parker wrote:

DIP 1008 is titled "Exceptions and @nogc".

https://github.com/dlang/DIPs/blob/master/DIPs/DIP1008.md


I would like the DIP to fully articulate the choice that it's 
facing, that special-casing the language for `throw new` comes 
with some downsides, but that the alternative is to force 
programmers to rewrite all their exceptions if they want to mark 
their functions `@nogc`. This requires an analysis of the 
similarities and differences between `throw new` and other uses 
of `new`. My personal impression is that exceptions do indeed 
fall into a distinct category, where they are easier to contain 
and shorter-lived than ordinary `new` memory. But the downside is 
that the language loses a little elegance by having another 
special case, and there might be corner cases where the special 
case is undesirable. I can only assume that at minimum, should 
this DIP be _rejected_, it should be replaced by some official 
documentation and methods on how to properly throw exceptions in 
`@nogc` code.


Re: DIP 1003 (Remove body as a Keyword) Accepted!

2017-06-04 Thread MysticZach via Digitalmars-d-announce

On Sunday, 4 June 2017 at 03:01:41 UTC, Walter Bright wrote:

On 6/3/2017 5:20 PM, Mike Parker wrote:
There's currently a proposal in the PR queue to enhance the 
contract syntax.


https://github.com/dlang/DIPs/pull/66


I know. That's as it should be!


Well that's encouraging! Thanks!


Re: Value closures (no GC allocation)

2017-06-03 Thread MysticZach via Digitalmars-d

On Tuesday, 30 May 2017 at 19:29:38 UTC, deadalnix wrote:
What are your thoughts? Has something similar been proposed 
before?


https://wiki.dlang.org/DIP30

Also, while no syntax is provided, this is how SDC works 
internally and this is how it can handle multiple context 
pointers.


FWIW, I think your three DIPs are elegant. Aside from questions 
of backward compatibility with current D, I like the way you 
designed functions and delegates there. Does this design 
integrate with the OP of this thread? It seems to. That's a 
question for the author of this thread too, if he reads this.


Re: DIP 1003 (Remove body as a Keyword) Accepted!

2017-06-02 Thread MysticZach via Digitalmars-d-announce

On Friday, 2 June 2017 at 14:17:10 UTC, Mike Parker wrote:
Congratulations are in order for Jared Hanson. Walter and 
Andrei have approved his proposal to remove body as a keyword. 
I've added a summary of their decision to the end of the DIP 
for anyone who cares to read it. In short:


* body temporarily becomes a contextual keyword and is 
deprecated

* do is immediately allowed in its place
* body is removed and do replaces it fully

Congratulations, Jared!

https://github.com/dlang/DIPs/blob/master/DIPs/DIP1003.md


Yes, congratulations are in order. Although those of us who were 
questioning the need for any keyword at all in `body`s place may 
be a little disappointed that it has merely been replaced with 
`do`, I think no one can doubt the main thrust of the DIP, which 
is that `body` is an incredibly useful identifier, and that 
having it newly available makes D a better language.


Also, I've been following the forums for several years now, and 
this is the first DIP that I know of that was not written by the 
language authors, and yet was still accepted into the language. 
Correct me if I'm wrong, but that seems like a real landmark!


Also Mike Parker seems to be doing a very good job in his 
appointed position as DIP manager.




Re: DIP 1003 Formal Review

2017-05-25 Thread MysticZach via Digitalmars-d

On Friday, 26 May 2017 at 01:23:59 UTC, Timon Gehr wrote:

On 25.05.2017 20:57, MysticZach wrote:

struct body {}

interface I {
   int foo(int i)
   in { assert(i); }

   body bar();
}

The ambiguity is fixable by modifying the parser to look ahead 
after `body` for `{`. Since virtual interface functions are 
not even allowed to have bodies, if it finds `{`, then `body` 
should be interpreted as a keyword, and an error issued. In 
all other cases `body` should be interpreted as an identifier.


This is not a hard problem, but it is indeed a semantic 
ambiguity, so it bears mentioning.


There is no ambiguity, because only one valid interpretation 
exists.


Well the parser needs to be aware of `body` here both as a 
keyword and as an identifier, and to use context to determine 
which one it is. So to me, that counts as a semantic ambiguity, 
one that is resolved trivially, by a single additional token.


It doesn't seem like it lives up to a more generalized fear of 
having contextual keywords, unless it's like guy 
https://www.youtube.com/watch?v=tgj3nZWtOfA


Re: DIP 1003 Formal Review

2017-05-25 Thread MysticZach via Digitalmars-d

On Thursday, 25 May 2017 at 11:49:47 UTC, MysticZach wrote:
...there is no known possibility of semantic confusion between 
the two potential uses of `body`,


I spoke too soon. I found a place where such semantic ambiguity 
is possible. It can only occur in interface declarations, and 
will not exist in any currently compilable D code, as it requires 
`body` to be an identifier to be legal in the first place.


Currently, the only place in D where you can declare a function 
that has a contract, but no body, is in an interface. D syntax, 
it turns out, does not require a semicolon at the end of such 
declarations. Referencing 
https://dlang.org/spec/interface.html#interface-contracts we have:


interface I
{
int foo(int i)
in { assert(i); } // <-- no semicolon required

void bar();
}

Therefore, with `body` as an identifier, you might have this 
ambiguity:


struct body {}

interface I {
  int foo(int i)
  in { assert(i); }

  body bar();
}

The ambiguity is fixable by modifying the parser to look ahead 
after `body` for `{`. Since virtual interface functions are not 
even allowed to have bodies, if it finds `{`, then `body` should 
be interpreted as a keyword, and an error issued. In all other 
cases `body` should be interpreted as an identifier.


This is not a hard problem, but it is indeed a semantic 
ambiguity, so it bears mentioning.


Re: DIP 1003 Formal Review

2017-05-25 Thread MysticZach via Digitalmars-d

On Friday, 12 May 2017 at 16:17:03 UTC, Mike Parker wrote:
The first stage of the formal review for DIP 1003 [1], "Remove 
body as a Keyword", is now underway. From now until 11:59 PM ET 
on May 26 (3:59 AM GMT on May 27), the community has the 
opportunity to provide last-minute feedback. If you missed the 
preliminary review [2], this is your chance to provide input.


At the end of the feedback period, I will submit the DIP to 
Walter and Andrei for their final decision. Thanks in advance 
to those of you who participate.


[1] 
https://github.com/dlang/DIPs/blob/fbb797f61ac92300eda1d63202157cd2a30ba555/DIPs/DIP1003.md


[2] 
http://forum.dlang.org/thread/qgxvrbxrvkxtimzvn...@forum.dlang.org


I believe the relevant discussion for this DIP can be simplified 
to just these two questions:


1. Should `body` be allowed as an identifier?

2. Should the keyword `body` remain as it is?

But it's been demonstrated that these two issues do _not_ need to 
be decided together. Because there is no known possibility of 
semantic confusion between the two potential uses of `body`, the 
arguments against allowing `body` as a contextual keyword are 
reduced to two minor points:


A. syntax highlighters will get confused
B. some programmers consider contextual keywords to be "bad karma"

It's possible to answer Question 1 based on these points alone.

Only if one decides that the answer to Question 2 is "no" — i.e. 
that `body` as a keyword needs to change — does it open up the 
discussion on the various options for changing it. But that could 
technically be the subject of a different DIP.


Re: Value closures (no GC allocation)

2017-05-24 Thread MysticZach via Digitalmars-d

On Wednesday, 24 May 2017 at 20:15:37 UTC, Vittorio Romeo wrote:

On Monday, 22 May 2017 at 15:17:24 UTC, Stanislav Blinov wrote:

On Monday, 22 May 2017 at 14:06:54 UTC, Vittorio Romeo wrote:

On Sunday, 21 May 2017 at 20:25:14 UTC, Adam D. Ruppe wrote:
Blah. Well, let's go ahead and formally propose the C++ 
syntax, our library solutions are all fat.


Are you going to create a DIP for this? I would be happy to 
contribute, but I don't feel confident enough to create a DIP 
on my own (I just started learning the language) :)


The three of us could do it together through the magics of 
github.


I've created a very WIP draft here:
https://github.com/SuperV1234/DIPs/blob/master/DIPs/DIP1009.md

If you're interested in contributing, please let me know and 
I'll add you as a collaborator.


As a matter of procedure, you don't want to assign a DIP number 
to it yourself. I'm pretty sure that is for the DIP manager.


Re: DIP 1008 Preliminary Review Round 1

2017-05-24 Thread MysticZach via Digitalmars-d

On Tuesday, 23 May 2017 at 22:40:43 UTC, Martin Nowak wrote:
The proposal is a very mechanical fix, throwing several special 
cases at one specific problem.
Why does it have to be refcounted? Seems like there is only 
ever one reference to the current exception (the catch 
variable).
The only thing that seems necessary is to require scope on 
catch variable declarations, so that people do not escape the 
class reference, then this info might be used by the runtime to 
free exception objects after the catch handler is done.


Amaury put a bit more words into that.
http://forum.dlang.org/post/gtqsojgqqaorubcsn...@forum.dlang.org

Has staticError been considered? It has a potential issue with 
multiple nested exceptions, but otherwise works fine.

https://github.com/dlang/druntime/blob/bc832b18430ce1c85bf2dded07bbcfe348ff0813/src/core/exception.d#L683


I'm trying to understand your and Amaury's point. Normally, when 
you say `new` you get memory from the GC allocator. The @nogc 
attribute is supposed to prevent this, if I understand it 
correctly. Are you saying that `@nogc` as such is misconceived, 
because what a good language feature should really be doing is 
identifying and preventing new memory that _can't_ be 
deterministically destroyed? Is the problem here with the @nogc 
attribute? Because I think Walter's goal with this DIP is to make 
it so that you can put @nogc on _called_ functions that throw 
using `new`. Whereas your solution is to ignore that `new 
Exception` allocation, on account of the fact that you can 
deterministically destroy the Exception, provided you use `scope` 
catch blocks at, or above, the call site. Your solution might 
actually have its priorities straight, and `@nogc` may be 
designed badly because it clumps all GC allocations into one big 
basket. However, getting new memory from the GC still could 
trigger a collection cycle, which is what @nogc was created for, 
and simply knowing that you can reliably destroy the allocated 
memory doesn't change that.


Thus, if I understand correctly, you and Amaury are arguing that 
`@nogc` as currently designed is a false goal to be chasing, that 
the more important goal is memory that can be deterministically 
destroyed, and therefore it distresses you that the language may 
be altered to chase the false prize of `@nogc` everywhere, 
instead of focusing on a real prize worth attaining?




Re: new contract syntax DIP

2017-05-23 Thread MysticZach via Digitalmars-d

On Tuesday, 23 May 2017 at 19:04:46 UTC, arturg wrote:

how about @uda based contracts?

@in(x => x < 100)
@out((ret) { assert(ret > 0, "some text"); })
int fun(int i) { return someVal; }

they could also be used on type definitions,

@out((t) { assert(t); })
 class NotNull {}

or temporarly on instances

@in(t => t !is null) auto notNull = new NotNull;

you could also have @inout as a combination.
another feature would be that they could be introspected.


Well I was going for three things:

1. contracts simple to write, with minimal "extra plumbing", i.e. 
without brackets and parentheses

2. utilize existing contract infrastructure
3. minimal divergence from existing syntax and semantics.

While not having to write `assert` in contracts would save a 
little space, it reduces what you can do with them, and also 
introduces a whole new semantics. The @uda contract system you 
suggest would require extensive description, documentation, and 
probably implementation effort. It would have to demonstrate that 
there was no better way to solve the problems it solves. (I'm not 
even sure I can justify my little syntax change, let alone a 
whole new semantics. I don't even know if contracts in general 
are important enough to be worth improving their syntax.)


So yeah, one could do things differently. But just because you 
_can_ do things differently doesn't mean you should. And 
justifying _why_ you should is not easy. And if people are being 
reasonable, they should maintain very high standards for what 
goes into a general-purpose programming language. Because there 
are a lot of things you can't take back once they're in there. 
(On the other hand, you don't want to stagnate, and not change 
_anything_, just for fear of making a mistake. One should strive 
for a balance.)


Re: DIP 1003 Formal Review

2017-05-23 Thread MysticZach via Digitalmars-d

On Wednesday, 17 May 2017 at 01:01:29 UTC, MysticZach wrote:
I think there are several issues at hand, and they need to be 
dealt with individually:


1. `body` is a very useful identifier. It would be nice to have 
it available.


2. Contract syntax is too verbose.

3. a. Some people think code looks better with a keyword, e.g. 
`body`, `do`, etc. distinguishing the function from the 
contracts.


3. b. Other people think that such a keyword is unnecessarily 
redundant and does not justify its own existence.


I think the thread will be more productive if the posters 
commit to answering just one of these issues, and reserve other 
issues for other threads. As the DIP in question is directly 
meant to address issue #1, it makes sense to try to solve that 
problem and only that problem here.


I made a related DIP discussing issue 2, contract syntax is too 
verbose. The thread for discussing that one is here:


http://forum.dlang.org/post/tuzdqqpcoguatepgx...@forum.dlang.org


new contract syntax DIP

2017-05-23 Thread MysticZach via Digitalmars-d

I made a pull request for a new DIP dealing with contract syntax:

https://github.com/dlang/DIPs/pull/66

I write the DIP in response to the discussions for DIP 1003: 
http://forum.dlang.org/thread/wcqebjzdjxldeywlx...@forum.dlang.org


This DIP is not under any kind of formal review yet. I just 
wanted to let people know that it's there.




Re: DMD now has colorized syntax highlighting in error messages

2017-05-18 Thread MysticZach via Digitalmars-d-announce

On Thursday, 18 May 2017 at 01:52:17 UTC, Adam D. Ruppe wrote:

On Tuesday, 16 May 2017 at 14:17:41 UTC, Adam D. Ruppe wrote:
Similarly, what I want to see in the future is highlighting of 
specific parts of code where the error applies.



Fear me. I combined Walter's code with my own to form some kind 
of Voltron!


https://github.com/dlang/dmd/pull/6806


I think the compiler's error design could use a complete 
overhaul. I'm wondering if it wouldn't be wise to start a new git 
branch for all changes to error messages. Call it 
`stderr.experimental` or something cute like that. The idea is 
that D won't break people's test code that checks error output 
until a more complete design has been worked out and approved of. 
I'm not in favor of or against this idea. I just wanted to 
propose it.


Re: DIP 1003 Formal Review

2017-05-18 Thread MysticZach via Digitalmars-d
On Thursday, 18 May 2017 at 13:06:38 UTC, Petar Kirov 
[ZombineDev] wrote:

On Thursday, 18 May 2017 at 12:56:31 UTC, Meta wrote:
This is pretty much the same as option 2. The short-term 
contextual part is covered by Walter's suggestion.


No it's not. What MysticZach suggests, and what I suggested 
even earlier [0] is to make 'body' contextual and optional 
which is very different than replacing it with another keyword. 
The main difference is that it would make code that uses 
contracts cleaner and there would be no breakage. In contrast, 
deprecating 'body' is a breaking change.


IMO, option 2 and variations of it are *the worst* way forward.

[0]: 
http://forum.dlang.org/post/pmldhzgcpuoydllfr...@forum.dlang.org


Yes. Our proposal is actually a variation on option 3. Added to 
the current DIP, it would read: "Option 6: allow omitting `body`, 
and also allow it as an identifier"


The two known downsides to this option so far are:

1. Different code will continue include the keyword version of 
`body` or not based on arbitrary programmer preferences.


2. Syntax highlighters that choose to highlight the word `body` 
will have to be modified to detect its different uses.


Note that in the case of 1., strong preferences have been stated 
here for both styles, thus increasing the feeling that it's okay 
to allow both. Also note that the opposition to any inclusion of 
contextual keywords on principle is largely countered by the fact 
that there is no danger of semantic ambiguity between the two 
uses of `body` here.




Re: Weak Eco System?

2017-05-18 Thread MysticZach via Digitalmars-d

On Thursday, 18 May 2017 at 05:43:48 UTC, Manu wrote:
On 17 May 2017 at 00:51, Benro via Digitalmars-d < 
digitalmars-d@puremagic.com> wrote:



[...]

4 Hours work. Discouraged and gave up after this.



Visual Studio proper is the only IDE that 'just works' well, 
VisualD is

very good.
MonoDevelop also has good 'just works' support last I checked, 
but

debugging is much better in Visual Studio.


I think the lack of clear signals about what works and what 
doesn't in the most easily reached places on the website, forums, 
wiki, etc. is probably as big a problem as is any of those things 
not working in the first place...?


Re: DIP 1003 Formal Review

2017-05-18 Thread MysticZach via Digitalmars-d

On Thursday, 18 May 2017 at 03:59:49 UTC, MysticZach wrote:

http://forum.dlang.org/post/kybywnscisxpebezw...@forum.dlang.org ) represents 
yet another distinct option. i.e. continue to allow `body`, but make it 
optional, that is, you can simply omit it if you want, while also allowing it 
as an identifier.


For the record, this was first suggested by H. S. Teoh:
http://forum.dlang.org/post/mailman.2204.1494612727.31550.digitalmar...@puremagic.com


Re: DIP 1003 Formal Review

2017-05-17 Thread MysticZach via Digitalmars-d

On Thursday, 18 May 2017 at 02:13:52 UTC, Meta wrote:

On Wednesday, 17 May 2017 at 11:46:07 UTC, Meta wrote:

I'll add this option to the DIP.


https://github.com/dlang/DIPs/pull/65


I think ( 
http://forum.dlang.org/post/kybywnscisxpebezw...@forum.dlang.org 
) represents yet another distinct option. i.e. continue to allow 
`body`, but make it optional, that is, you can simply omit it if 
you want, while also allowing it as an identifier.


Re: DIP 1003 Formal Review

2017-05-17 Thread MysticZach via Digitalmars-d

On Wednesday, 17 May 2017 at 09:57:41 UTC, Basile B. wrote:

On Wednesday, 17 May 2017 at 09:53:49 UTC, MysticZach wrote:
Option 4) Keep `body`, but make it both contextual *and* 
optional. It becomes usable as an identifier, and those who 
think it's unnecessary are appeased. The downside is that 
different programmers will include it or not, based on 
arbitrary preferences.


The problem with this option is the IDEs. D syntax so far 
doesn't require parsing to highlight, i.e you have a token and 
you know what is it directly, and this without looking at the 
previous tokens (which is basically what parsing does, detect 
token patterns).


I don't feel like it's much of a problem:

1. I suspect a simple matching of the three tokens '}', 'body', 
'{' would detect it most of the time.


2. Without that, remove `body` from your highlighter's list of 
keywords. When used as a keyword, it's very conspicuous anyway. 
Code won't lose much readability with just this one word unlit.


3. If `body` were optional, probably a lot of people wouldn't be 
using it to begin with. I suspect that Jonathan and I are not 
alone in thinking that it's not just useless, it's annoying. 
Thus, only code that uses it would have this problem.




Re: DIP 1003 Formal Review

2017-05-17 Thread MysticZach via Digitalmars-d

On Wednesday, 17 May 2017 at 08:03:13 UTC, Mike Parker wrote:
* Is it a good idea to remove body's status as a reserved 
keyword?


* If so, which option is best?
  1) Make it contextual
  2) Replace it with another keyword (`function` was suggested 
in the DIP, `do` in this thread).
  3) A three-stage process of removal: make it optional, then 
deprecate it, then remove it completely (meaning, no keyword, 
reserved or contextual, is required for the function body in a 
contract).


Option 4) Keep `body`, but make it both contextual *and* 
optional. It becomes usable as an identifier, and those who think 
it's unnecessary are appeased. The downside is that different 
programmers will include it or not, based on arbitrary 
preferences.




Re: DIP 1003 Formal Review

2017-05-16 Thread MysticZach via Digitalmars-d

On Tuesday, 16 May 2017 at 18:57:37 UTC, H. S. Teoh wrote:
To me, it's actually worse, because now you have a visual 
conflation with do-loops.


Overall, what I don't like about contract syntax is that it is 
so unbearably verbose. It's not just the in and out blocks and 
the (IMO redundant) marking of the function body; it's also the 
repeated 'assert's that occur in the in and out blocks.


int foo(T, U)(T t, U u)
if (sigContraints!T && sigConstraints!U)
in
{
assert(t > 0 && u < 10);
}
out(val)
{
assert(val > 1 && val < 5);
}
body
{
// function body here
}

I understand this DIP is only to address the `body` part of 
this ugly verbosity, but imagine how much better it would be if 
we could write something like this instead:


int foo(T, U)(T t, U u)
if (sigConstraints!T && sigConstraints!U)
in (t > 0 && u < 10)
out(foo > 1 && foo < 5 )
{
// function body here
}

This is just tentative example syntax, of course.  We can argue 
over its fine points later, but the point is that the current 
syntax is far too verbose, and can easily be reduced to half 
the number of lines.  Merely changing `body` to `do` does 
nothing to address this, and seems to me to be just more 
useless churn, replacing one bit of verbosity with another bit 
of verbosity. (Not to mention the IMO very ugly syntax clash 
with do-loops, which will reduce code readability even more.)



T


I think there are several issues at hand, and they need to be 
dealt with individually:


1. `body` is a very useful identifier. It would be nice to have 
it available.


2. Contract syntax is too verbose.

3. a. Some people think code looks better with a keyword, e.g. 
`body`, `do`, etc. distinguishing the function from the contracts.


3. b. Other people think that such a keyword is unnecessarily 
redundant and does not justify its own existence.


I think the thread will be more productive if the posters commit 
to answering just one of these issues, and reserve other issues 
for other threads. As the DIP in question is directly meant to 
address issue #1, it makes sense to try to solve that problem and 
only that problem here.


Re: DIP 1003 Formal Review

2017-05-16 Thread MysticZach via Digitalmars-d

On Tuesday, 16 May 2017 at 17:42:11 UTC, MysticZach wrote:

On Tuesday, 16 May 2017 at 15:22:12 UTC, Timon Gehr wrote:

auto foo()in{
assert(true);
}out{
assert(true);
}{
return 3;
}

Are you really arguing for this?
I don't want to write code like this.


It's not any better than this:


I meant any worse.


Re: DIP 1003 Formal Review

2017-05-16 Thread MysticZach via Digitalmars-d

On Tuesday, 16 May 2017 at 15:22:12 UTC, Timon Gehr wrote:

auto foo()in{
assert(true);
}out{
assert(true);
}{
return 3;
}

Are you really arguing for this?
I don't want to write code like this.


It's not any better than this:

auto foo()in{
assert(true);
}out{
assert(true);
}body{
return 3;
}

They are both bad, but not because of the presence or absence of 
the `body` keyword, in my opinion.




Re: DIP 1003 Formal Review

2017-05-16 Thread MysticZach via Digitalmars-d

On Tuesday, 16 May 2017 at 13:50:59 UTC, Jonathan M Davis wrote:
All I'm arguing for is that if we're removing body as a 
keyword, there's no need to replace it with function or any 
other word in contracts. We can simply deprecate its use as a 
keyword and not replace it, letting it then be used as a normal 
identifier in whatever fashion makes the most sense.


+1, Makes total sense to me. So simple. I'm for this.

Actually changing the overall syntax of contracts is a whole 
other can of worms.


Yeah. One thing at a time.



Re: DIP 1003 Formal Review

2017-05-15 Thread MysticZach via Digitalmars-d

On Tuesday, 16 May 2017 at 03:44:54 UTC, MysticZach wrote:
It seems to me that the compiler could detect a presence or 
lack of a body simply by the presence or absence of any 
statement after the contracts, i.e.,


interface D {
  // fun is implicitly overridable here
  int fun() {
in assert(...);
  }
}

Also, does a final function with contracts, but no body, make 
any sense? What's the use case?


Even if there were some use case for it, I can think of two 
solutions. One is to keep and require the current syntax for an 
interface function without a body. This is the natural way to 
install contracts anyway, for a function with no body.


The other solution is to recommend the addition of an empty 
statement, for an empty final function, e.g.:


// final
int fun() {
  in assert(...);
  {}
}

Considering what Jonathan said about how he never uses 
contracts because they're so bulky, might it not be worth it to 
solve the interface problem in either of the above two ways?


I should have said *three* ways, because it's quite possible to 
conclude that there will never be a use case for a final function 
in an interface to have contracts, but no body, and therefore 
assume that contracts plus a lack of statements --> an 
overridable function.




Re: On the subject of error messages

2017-05-15 Thread MysticZach via Digitalmars-d

On Saturday, 13 May 2017 at 14:41:50 UTC, Stanislav Blinov wrote:
file(line): Error: template foo cannot deduce function from 
argument types !()(int, string), candidates are:
file(line): foo(Args...)(auto ref Args arg) if 
(!anySatisfy!(isString, Args))


Ya know, even a simple new line before "candidates are:" would 
improve this error message!


https://issues.dlang.org/show_bug.cgi?id=17400

I know it seems trivial, but attention to detail does make a 
difference, so I decided to make an issue for it anyway... :-/


Re: DIP 1003 Formal Review

2017-05-15 Thread MysticZach via Digitalmars-d

On Monday, 15 May 2017 at 02:02:42 UTC, Basile B. wrote:

On Monday, 15 May 2017 at 01:39:34 UTC, MysticZach wrote:
Not that a whole new way of doing things is called for... but 
I think a better design would have been to allow 'in' and 
'out' statements in the function itself, with no need for 
brackets if you only have one line's worth of contract, e.g.,


int fun(int a) {
  in assert(...);
  out(x) assert(...);

  // do stuff
}


It's nice, i like it but it cant work as simply. You're 
forgetting that interface member functions can have contracts. 
With this syntax interfaces member functions would always have 
a body BUT the current semantic is that interface member 
functions with bodies are final methods. Boom. Interfaces don't 
work anymore because there's no easy way to make the difference 
between an interface member function that's final and an 
interface member function that's not pre-implemented (so 
overridable) but has contracts.


It seems to me that the compiler could detect a presence or lack 
of a body simply by the presence or absence of any statement 
after the contracts, i.e.,


interface D {
  // fun is implicitly overridable here
  int fun() {
in assert(...);
  }
}

Also, does a final function with contracts, but no body, make any 
sense? What's the use case?


Even if there were some use case for it, I can think of two 
solutions. One is to keep and require the current syntax for an 
interface function without a body. This is the natural way to 
install contracts anyway, for a function with no body.


The other solution is to recommend the addition of an empty 
statement, for an empty final function, e.g.:


// final
int fun() {
  in assert(...);
  {}
}

Considering what Jonathan said about how he never uses contracts 
because they're so bulky, might it not be worth it to solve the 
interface problem in either of the above two ways?


Re: DIP 1003 Formal Review

2017-05-14 Thread MysticZach via Digitalmars-d

On Monday, 15 May 2017 at 01:39:34 UTC, MysticZach wrote:
Not that a whole new way of doing things is called for... but I 
think a better design would have been to allow 'in' and 'out' 
statements in the function itself, with no need for brackets if 
you only have one line's worth of contract, e.g.,


int fun(int a) {
  in assert(...);
  out(x) assert(...);

  // do stuff
}


You could even accumulate in statement if you want to save on 
brackets and indentation:

int fun() {
  in assert(...);
  in assert2(...);

  // etc.
}


Re: DIP 1003 Formal Review

2017-05-14 Thread MysticZach via Digitalmars-d

On Monday, 15 May 2017 at 01:18:02 UTC, Jonathan M Davis wrote:
Why would we want to introduce function as an alternative to 
body? Personally, I've always found the need to use body to be 
very odd and annoying. It doesn't need to be there when you 
don't have in or out contracts, and it just makes contracts 
that much more verbose. It's not even like you can put in our 
out contracts after the function body, so body is needed to 
indicate which block the function body is - the contracts have 
to go first. So, as far as I can tell, body serves no useful 
function. It just makes the code longer, and the amount of 
extra code required around in/out contracts is part of why I 
almost never use them. In most cases, it just makes more sense 
to put the assertions in the function body and not have all of 
that extra plumbing right after the function signature.


Not that a whole new way of doing things is called for... but I 
think a better design would have been to allow 'in' and 'out' 
statements in the function itself, with no need for brackets if 
you only have one line's worth of contract, e.g.,


int fun(int a) {
  in assert(...);
  out(x) assert(...);

  // do stuff
}



Re: DMD now has colorized syntax highlighting in error messages

2017-05-14 Thread MysticZach via Digitalmars-d-announce

On Sunday, 14 May 2017 at 16:25:36 UTC, Walter Bright wrote:

On 5/14/2017 9:04 AM, Andre Pany wrote:
Thanks a lot. In my opinion these kind of changes are small 
but have huge impact

on the acceptance of a language.


I agree. A couple other improvements needed for error messages:


In the PR you say that someone with a better color sense ought to 
choose the default colors. I don't have such a sense myself. But 
I recognize that as a real task for which help should be sought. 
Maybe this thread is a good place to get a volunteer?


Re: DConf 2017 Day 3 Livestream

2017-05-06 Thread MysticZach via Digitalmars-d-announce

On Saturday, 6 May 2017 at 22:12:10 UTC, Joshua Niehus wrote:

On Saturday, 6 May 2017 at 08:03:11 UTC, Mike Parker wrote:

https://www.youtube.com/watch?v=XTtruC3D2Ag


Is anyone else having issues viewing the livestream?


It's over. The video has already been take down. They will chop 
it into individual lectures and repost them on Monday or 
thereabouts, I think.


Re: [OT] Algorithm question

2017-05-04 Thread MysticZach via Digitalmars-d

On Thursday, 4 May 2017 at 13:19:43 UTC, MysticZach wrote:

On Thursday, 4 May 2017 at 08:04:22 UTC, Timon Gehr wrote:

On 03.05.2017 01:09, MysticZach wrote:
That's true. Two points, though: If the range of error is 
within

1/(n*(n-1)), with array length n,


It's not though. For example, [1,1,1,0,...,0] (length 29), you 
get 0 and 2 each with probability 43/116, but 1 only with 
probability 30/116.


It might be interesting to figure out how far from uniform the 
distribution can get.


Or how close it can get, depending on the range of intervals 
used. My math skill is shaky here.


Maybe there's no way to deterministically jump to every element 
of an array with equal probability of hitting any given element 
satisfying a given predicate first. It sure would be cool if 
there were.


Within a small range of error, I mean.


Re: [OT] Algorithm question

2017-05-04 Thread MysticZach via Digitalmars-d

On Thursday, 4 May 2017 at 08:04:22 UTC, Timon Gehr wrote:

On 03.05.2017 01:09, MysticZach wrote:




Counterexample: [1,1,1,0,0]

Your algorithm returns 0 with probability 7/20, 1 with 
probability

6/20 and 2 with probability 7/20.

Note that there is a simple reason why your algorithm cannot 
work for

this case: it picks one of 20 numbers at random. The resulting
probability mass cannot be evenly distributed among the three
elements, because 20 is not divisible by 3.


That's true. Two points, though: If the range of error is 
within

1/(n*(n-1)), with array length n,


It's not though. For example, [1,1,1,0,...,0] (length 29), you 
get 0 and 2 each with probability 43/116, but 1 only with 
probability 30/116.


It might be interesting to figure out how far from uniform the 
distribution can get.


Or how close it can get, depending on the range of intervals 
used. My math skill is shaky here.


Maybe there's no way to deterministically jump to every element 
of an array with equal probability of hitting any given element 
satisfying a given predicate first. It sure would be cool if 
there were.




Re: [OT] Algorithm question

2017-05-03 Thread MysticZach via Digitalmars-d

On Tuesday, 2 May 2017 at 23:09:54 UTC, MysticZach wrote:

On Tuesday, 2 May 2017 at 21:00:36 UTC, Timon Gehr wrote:

On 02.05.2017 22:42, MysticZach wrote:

On Tuesday, 2 May 2017 at 13:44:03 UTC, MysticZach wrote:
   for (;;) {
  if (P(a[i]))
 return i;
  ++count;
  if (count == length)
 return -1;
  i += hop;
  if (i < length)
 continue;
  if (i < skipLength)
 i += hop;


(I guess this should be 'while'.)


skipLength is determined modulo hop, thus it can't be more than 
one hop away.


Actually, I did botch the implementation. The hopping interval 
must be based on the prime rather than on n. But you could still 
short circuit the while loop, I think. `if (prime - n > hop) { 
skipLength = n + ((prime - n) % hop); }





Re: [OT] Algorithm question

2017-05-02 Thread MysticZach via Digitalmars-d

On Tuesday, 2 May 2017 at 21:00:36 UTC, Timon Gehr wrote:

On 02.05.2017 22:42, MysticZach wrote:

On Tuesday, 2 May 2017 at 13:44:03 UTC, MysticZach wrote:
   for (;;) {
  if (P(a[i]))
 return i;
  ++count;
  if (count == length)
 return -1;
  i += hop;
  if (i < length)
 continue;
  if (i < skipLength)
 i += hop;


(I guess this should be 'while'.)


skipLength is determined modulo hop, thus it can't be more than 
one hop away.



Counterexample: [1,1,1,0,0]

Your algorithm returns 0 with probability 7/20, 1 with 
probability 6/20 and 2 with probability 7/20.


Note that there is a simple reason why your algorithm cannot 
work for this case: it picks one of 20 numbers at random. The 
resulting probability mass cannot be evenly distributed among 
the three elements, because 20 is not divisible by 3.


That's true. Two points, though: If the range of error is within 
1/(n*(n-1)), with array length n, it may be close enough for a 
given real world use case. 2. n is known to be large, which makes 
1/(n*(n-1)) even smaller. You'd probably have to trade accuracy 
for performance. I wonder how much less performant a truly 
accurate algorithm would be. Also, whether there's a way to make 
an algorithm of this style completely accurate.




Re: [OT] Algorithm question

2017-05-02 Thread MysticZach via Digitalmars-d

On Tuesday, 2 May 2017 at 13:44:03 UTC, MysticZach wrote:
1. Test a random element in the array. If it satisfies P, 
return it.
2. Choose a hopper interval, h, that is relatively prime to the 
number of elements in the array, n. You could do this by 
randomly selecting from a pre-made list of primes of various 
orders of magnitude larger than n, with h = the prime % n.
3. Hop along the array, testing each element as you go. 
Increment a counter. If you reach the end of the array, cycle 
back to the beginning starting with the remainder of h that you 
didn't use. I think that h being relatively prime means it will 
thereby hit every element in the array.
4. Return the first hit. If the counter reaches n, return 
failure.


Taking this a step further, it occurred to me that you could use 
*any* hopping interval from 1 to array.length, if the length of 
the array were prime. So artificially extend the array and just 
skip a jump when you land in the extended area. And since you'd 
skip lots of jumps if the extension were any bigger that the 
hopping interval, reduce its length to modulo the hopping 
interval.


// returns a random index of array satisfying P(x), -1 if not 
found

int randomlySatisfy(A[] array) {
   auto length = array.length;
   if (!length)
  return -1;
   auto i = uniform(0, length);
   auto hop = uniform(1, length);

   // greatest prime < 2^^31, for simplicity
   enum prime = 2147483477;
   assert (length <= prime);

   auto skipLength = ((prime - length) % hop) + length;
   auto count = 0;

   for (;;) {
  if (P(a[i]))
 return i;
  ++count;
  if (count == length)
 return -1;
  i += hop;
  if (i < length)
 continue;
  if (i < skipLength)
 i += hop;
  i -= skipLength;
   }
   return -1;
}

This solution is stupidly simple and I haven't tested it. But I 
believe it's truly random, since the hopping interval is 
arbitrary. Who knows, it might work.




Re: [OT] Algorithm question

2017-05-02 Thread MysticZach via Digitalmars-d

On Tuesday, 2 May 2017 at 11:27:17 UTC, Ivan Kazmenko wrote:

On Tuesday, 2 May 2017 at 10:35:46 UTC, Ivan Kazmenko wrote:

I hope some part of the idea is still salvageable.
For example, what if we put the intervals in a queue instead 
of a stack?


I tried to implement a similar approach, but instead of a queue 
or a stack, I used a random-access array of intervals.


Sadly, it is still far from uniform, since it does not take 
interval lengths into account, and I don't see how to do that 
without at least O(log n) time per interval insertion or 
deletion.


Implementation and empiric frequencies for n=5 elements in a 
permutation: http://ideone.com/3zSxLN


Ivan Kazmenko.


Well, I thought of another idea that may not be technically 
random, but which I imagine would get pretty close in real world 
use cases:


1. Test a random element in the array. If it satisfies P, return 
it.
2. Choose a hopper interval, h, that is relatively prime to the 
number of elements in the array, n. You could do this by randomly 
selecting from a pre-made list of primes of various orders of 
magnitude larger than n, with h = the prime % n.
3. Hop along the array, testing each element as you go. Increment 
a counter. If you reach the end of the array, cycle back to the 
beginning starting with the remainder of h that you didn't use. I 
think that h being relatively prime means it will thereby hit 
every element in the array.

4. Return the first hit. If the counter reaches n, return failure.

The way I see it, with a random start position, and a *mostly* 
random interval, the only way to defeat the randomness of the 
result would be if the elements that satisfy P were dispersed 
precisely according to the random interval specified for that 
particular evocation of the function — in which case the first in 
the dispersed set would be chosen more often. This would require 
a rare convergence depending on both n and h, and would not 
repeat from one call to the next.





Re: [OT] Algorithm question

2017-05-01 Thread MysticZach via Digitalmars-d

On Monday, 1 May 2017 at 16:56:58 UTC, MysticZach wrote:
The goal is to have the first hit be the one you return. The 
method: if a random pick doesn't satisfy, randomly choose the 
partition greater than or less than based on 
uniform(0..array.length-1), and do the same procedure on that 
partition, reusing the random index to avoid having to call 
uniform twice on each recursion (one to choose a partition and 
one to choose an index within that partition). If the 
probability of choosing a partition is precisely proportional 
to the number of elements in that partition, it seems to me 
that the result will be truly random, but I'm not sure.


Now I'm questioning this, because if the positive cases are 
unevenly distributed, i.e., [11000100], the last one has 
about 50% chance to get picked instead of a 1 in 7 chance with my 
method. I guess you'd need to build a whole new array like the 
others are saying.


Re: [OT] Algorithm question

2017-05-01 Thread MysticZach via Digitalmars-d

On Monday, 1 May 2017 at 16:56:58 UTC, MysticZach wrote:

   // choose a random partition proportionally
   auto j = uniform(da.length - 1);
   if (j < i) {
  // the lower partition
  int a = randomlySatisfyImpl(da[0..i], j);
  if (a != -1) return a;
  else return randomlySatisfyImpl(da[i+1 .. da.length], j - 
(i + 1));

   }
   else {
  // higher partition, investigate in reverse order
  int a = randomlySatisfyImpl(da[i+1 .. da.length], j - (i 
+ 1));

  if (a != -1) return i +1 + a;
  else return i + 1 + randomlySatisfyImpl(da[0..i], j);


The line above has a bug. Replace it with:

   else {
  a = randomlySatisfyImpl(da[0..i], j);
  return (a == -1) ? -1 : i + 1 + a;
   }


   }
}


But the idea's the same. Hopefully it's clear.



Re: [OT] Algorithm question

2017-05-01 Thread MysticZach via Digitalmars-d

On Monday, 1 May 2017 at 04:15:35 UTC, H. S. Teoh wrote:
Given a set A of n elements (let's say it's a random-access 
range of

size n, where n is relatively large), and a predicate P(x) that
specifies some subset of A of elements that we're interested 
in, what's
the best algorithm (in terms of big-O time complexity) for 
selecting a
random element x satisfying P(x), such that elements that 
satisfy P(x)
have equal probability of being chosen? (Elements that do not 
satisfy

P(x) are disregarded.)


Here's how I would do it:

// returns a random index of array satisfying P(x), -1 if not 
found

int randomlySatisfy(A[] array) {
   if (array.length == 0)
  return -1;
   int i = uniform(0, array.length);
   return randomlySatisfyImpl(array, i);
}

// recursive function
private int randomlySatisfyImpl(A[] da, int i) {
   if (P(da[i]))
  return i;
   if (da.length == 1)
  return -1;

   // choose a random partition proportionally
   auto j = uniform(da.length - 1);
   if (j < i) {
  // the lower partition
  int a = randomlySatisfyImpl(da[0..i], j);
  if (a != -1) return a;
  else return randomlySatisfyImpl(da[i+1 .. da.length], j - 
(i + 1));

   }
   else {
  // higher partition, investigate in reverse order
  int a = randomlySatisfyImpl(da[i+1 .. da.length], j - (i + 
1));

  if (a != -1) return i +1 + a;
  else return i + 1 + randomlySatisfyImpl(da[0..i], j);
   }
}

The goal is to have the first hit be the one you return. The 
method: if a random pick doesn't satisfy, randomly choose the 
partition greater than or less than based on 
uniform(0..array.length-1), and do the same procedure on that 
partition, reusing the random index to avoid having to call 
uniform twice on each recursion (one to choose a partition and 
one to choose an index within that partition). If the probability 
of choosing a partition is precisely proportional to the number 
of elements in that partition, it seems to me that the result 
will be truly random, but I'm not sure.




Re: Proposal 2: Exceptions and @nogc

2017-04-15 Thread MysticZach via Digitalmars-d

On Sunday, 9 April 2017 at 20:14:24 UTC, Walter Bright wrote:
... a general mechanism for safe refcounting of classes has 
eluded us.


Regardless of my other comments, which are maybe a little 
uninformed, DIP74 seems pretty good:


https://wiki.dlang.org/DIP74

Manu started a thread asking about it, but that thread dissolved 
into a bitter dispute:


http://forum.dlang.org/post/mailman.1002.1444519548.22025.digitalmar...@puremagic.com

The only valuable information regarding the question was in this 
post of Andrei's, which did not say very much:


http://forum.dlang.org/post/mvgoa9$1gda$1...@digitalmars.com

So what are the corner cases of DIP74? What are the actual 
problems with it?


Re: Proposal 2: Exceptions and @nogc

2017-04-13 Thread MysticZach via Digitalmars-d

On Wednesday, 12 April 2017 at 19:01:25 UTC, Walter Bright wrote:

On 4/11/2017 10:24 AM, MysticZach wrote:
Hi guys. Hey Walter. So, about this point. On the lifetime 
study thread,
http://forum.dlang.org/post/56301a8c.1060...@erdani.com , the 
following two
problems were stated by Andrei, but I don't think they were 
adequately addressed

in the subsequent posts:


The way they will be addressed is to increment the reference 
count in the call to the function that takes a reference to an 
RC object.


Makes sense, and I thought the same thing until after I wrote my 
post — but now I realize it's not quite good enough. Merely 
incrementing the refcount (and decrementing it afterwards) has 
the following problem:


@rc class RC;

void fun(ref RC a, RC b) {
   a = new RC; // (1)
   // b...
}

void main() {
   auto r = new RC; // (2)
   --> r.opInc(); // compiler insert
   fun(r, r);
   --> r.opDec();
}

Let's assume the reference counting scheme involves the methods 
opInc and opDec, inserted automatically by the compiler as the 
result of detecting a duplicate parameter. If you read closely, 
you'll realize that at mark 1 above, the program will leak the 
data acquired at mark 2. The assign statement of the refcounted 
object will decrement the data it points to before it is 
reassigned. But since the data at (2)'s refcount was prematurely 
incremented, it will fall to 1 and never get deleted. 
Furthermore, the opDec in main() will decrement and delete the 
data acquired at mark 1, thinking it was the mark 2 data.


The problem is that the calling context at "fun(r,r);" fails to 
keep a real reference to the mark 2 data. If one of the 
parameters is sent by reference, we can't assume it points to the 
same data upon returning as when it was sent. And the mark 2 data 
can't be deleted before fun() returns, or it will invalidate 'b' 
in fun(). This suggests we need to save a real, separate 
reference to 'r' before sending two or more versions of it.


That said, I believe the following compiler inserts in main() 
would do the trick:


void main() {
   auto r = new RC; // (2)
   --> RC __rsave = r; // compiler insert
   --> scope(exit) __rsave = null;
   fun(r, r);
}

This solution uses only the assign method of RC to inc and dec 
the refcount, suggesting that opInc and opDec are ultimately 
unnecessary, except as (very rare) optimizations. But you still 
need for the compiler to distinguish a refcounted class from a 
regular one, so maybe the presence of an opDec() could indicate 
that, opDec being the quasi-destroyer that turns a refcounted 
class variable into an RAII type. Otherwise, you might need 
something like an @rc attribute.


At any rate, your original claim was, "a general mechanism for 
safe refcounting of classes has eluded us." Is this still the 
case, considering the above?


As far as the original post, even if a general mechanism were 
found, it doesn't mean you'd have to use it in the case of 
Exception anyway. To generalize the expression 'throw new ...', 
you'd have to redefine 'new' to be different with refcounted 
classes than with regular ones. Exceptions are probably worth a 
more specialized solution like the one you proposed. Otherwise 
everyone will have to change their 'throw new' code to 
accommodate '@nogc'. Adam D. Ruppe gave us his solution here:


http://arsdnet.net/exception.d

tl;dr Everyone would now have to say things like 'throw 
emplace!...' or 'raise!"my_exception"(...)'.


I guess the proposed hack of 'throw new Exception' is simply the 
shadow of D's original philosophy of wanting the GC to do too 
much.




Re: Proposal 2: Exceptions and @nogc

2017-04-11 Thread MysticZach via Digitalmars-d

On Sunday, 9 April 2017 at 20:14:24 UTC, Walter Bright wrote:

On 4/9/2017 1:16 AM, Daniel N wrote:
... but why not go all the way, making it "always" refcounted? 
(for any "new E",

not emplace).


Backwards compatibility, for one. For another, a general 
mechanism for safe refcounting of classes has eluded us.


Hi guys. Hey Walter. So, about this point. On the lifetime study 
thread, http://forum.dlang.org/post/56301a8c.1060...@erdani.com , 
the following two problems were stated by Andrei, but I don't 
think they were adequately addressed in the subsequent posts:


===
Widget global;
@rc class Widget {
   int x;
   void fun() {
 global = null;
 ++x;
   }
}

void main() {
   global = new Widget;
   global.fun();
}

In this example, if global has a refcount==1 upon entering fun(), 
the assignment "global = null" deletes the Widget object and ++x 
accesses dangling memory.


I should add here another pattern that turned problematic for our 
older attempts in DIP74:


C c = new C();
foo(c);

int foo(scope C d) {
 c = new C();// c's old instance gets deleted
 return d.i;// oops! d is invalid
}
===

So here's my analysis of both these problems.

When calling a function, the reference count for an object must 
increase by the total number of aliases created by the call — 
*minus the ones lost*. Globals are special in this regard, 
because access to them is not lost in the called function. Local 
variables, however, are lost to the called function — they cannot 
be accessed except through the new alias they receive as a 
parameter. Thus, only globals must modify the reference count 
when passed.


Thinking about this is made easier if we turn all accessible 
aliases into function parameters. For this, we need to consider 
the set of globals as a hidden parameter to the function. Any 
global is therefore already passed to all functions. If we pass 
it again via parameter, that amounts to two aliases, thus two 
references. The same logic applies, 1. to duplicating any given 
variable in the argument list, e.g. "fun(c, c);", 2. to 
duplicating the hidden 'this' parameter, 3. to recognizing and 
outer function's stack frame as an additional alias.


All these can be verified at compile time. Also, it is optimistic 
regarding the most common case, i.e. passing a local does not 
require increasing the reference count.


--Zach