January 11, 2021
On Monday, 11 January 2021 at 14:06:01 UTC, Steven Schveighoffer wrote:
> ...
>
> I highly doubt we will remove body in that syntax. The DIP proposed that, but that was under the expectation that we couldn't remove body as a keyword without also removing its support in that position.
>
> Today, body is *not* a keyword, but can be used there. I don't think it will ever change. See the PR that was reverted because it affected a lot of code: https://github.com/dlang/dmd/pull/10763
>
> And I have to say, this is quite the overreaction. "body" vs. "do" is not the thing that makes contracts function, let alone should cause you to doubt the future of D.
>
> But this is kind of a side-thing, I'm glad you are loving the language, I share that emotion completely!
>
> -Steve

100,000 apologies, Steve. You're right: it was an overreaction.

The cause is not about do vs body (well, partly yes)... it is about an accepted DIP telling that Contract programming is not enough important in D community and can be belittled... I have to recognize that it was a shock for me (because it is,with scope, the basis of all scripting I'm working with D, and one of the most used arguments in some posts in quora or when I present D to other developers).

Thank you very much for clarifying the situation so quickly.
January 11, 2021
On Monday, 11 January 2021 at 13:48:06 UTC, Guillaume Piolat wrote:
> On Monday, 11 January 2021 at 13:43:38 UTC, ddcovery wrote:
>>
>> Seriously?... this is the kind of decisions that makes me doubt about D future.
>
> On the contrary :)
> in/out/body is barely more useful than simply... assert()
> hence it ended up not being used in a meaningful capacity, apart from curiosity

post-condition is hard to implement with asserts... basically you must "wrap" your function to check the result... I find out(result){ ... } or out(result; condition; message) an example of how programming theory can be applied to the real world... this proves (like with invariant implementation) that people under D (Walter in this case) appreciates this way of thinking to the point that they incorporate it into language.

And I really appreciate this.
January 11, 2021
On Monday, 11 January 2021 at 14:38:58 UTC, ddcovery wrote:
> On Monday, 11 January 2021 at 14:06:01 UTC, Steven Schveighoffer wrote:
>> ...
>>
>> I highly doubt we will remove body in that syntax. The DIP proposed that, but that was under the expectation that we couldn't remove body as a keyword without also removing its support in that position.
>>
>> Today, body is *not* a keyword, but can be used there. I don't think it will ever change. See the PR that was reverted because it affected a lot of code: https://github.com/dlang/dmd/pull/10763
>>
>> And I have to say, this is quite the overreaction. "body" vs. "do" is not the thing that makes contracts function, let alone should cause you to doubt the future of D.
>>
>> But this is kind of a side-thing, I'm glad you are loving the language, I share that emotion completely!
>>
>> -Steve
>
> 100,000 apologies, Steve. You're right: it was an overreaction.
>
> The cause is not about do vs body (well, partly yes)... it is about an accepted DIP telling that Contract programming is not enough important in D community and can be belittled... I have to recognize that it was a shock for me (because it is,with scope, the basis of all scripting I'm working with D, and one of the most used arguments in some posts in quora or when I present D to other developers).
>
> Thank you very much for clarifying the situation so quickly.

I am the author of that DIP, and you are grossly mis-interpreting what I'm saying there. I am not saying that contract programming is not important; on the contrary, I think it is very important and use D's contract programming features whenever possible. However, I seem to be in the minority in that regard in the D community, and people have been complaining for 10+ years about not being able to use `body` as the name for a symbol. In that context, it does not make sense to tie up a very commonly used symbol name for a relatively underused feature.

As for `do`, that was not my idea; I originally proposed using `function` instead of body, but Andrei opted for `do` instead.

Regardless, it doesn't matter much now, as was mentioned, because body is now only a keyword in the context of function contracts.
January 11, 2021
On 1/11/21 2:52 AM, ddcovery wrote:

> Is it possible to us in/out in a lambda expression?

I don't think so. I guess, if it has contracts, it deserves to be a proper function. :)

Ali

January 11, 2021
On Monday, 11 January 2021 at 16:53:42 UTC, Ali Çehreli wrote:
> On 1/11/21 2:52 AM, ddcovery wrote:
>
> > Is it possible to us in/out in a lambda expression?
>
> I don't think so. I guess, if it has contracts, it deserves to be a proper function. :)
>
> Ali

It seems that it does work, but you need to include the `function()` preamble; it doesn't seem to like including contracts with the short-form function literals.

void test(void function() f)
{
    f();
}

void main()
{
    test(function() in(1 == 0) out(; 1 == 0) {}); //Okay
}
January 11, 2021
On Monday, 11 January 2021 at 16:21:55 UTC, Meta wrote:

> ...
> I am the author of that DIP, and you are grossly mis-interpreting what I'm saying there. I am not saying that contract programming is not important; on the contrary, I think it is very important and use D's contract programming features whenever possible.
My apologies for the mis-interpreting.

> However, I seem to be in the minority in that regard in the D community, and people have been complaining for 10+ years about not being able to use `body` as the name for a symbol.
I understand... As long as I have seen, the own std library makes an intensive use of unitesting and avoids the in/out contract keywords (mainly, I suppose, because it is a "run-time" check with the obvious performance fault ).

> In that context, it does not make sense to tie up a very commonly used symbol name for a relatively underused feature.
>
> As for `do`, that was not my idea; I originally proposed using `function` instead of body, but Andrei opted for `do` instead.
>
> Regardless, it doesn't matter much now, as was mentioned, because body is now only a keyword in the context of function contracts.

Thank you very much Meta for the clarifications and the effort that as a community you have dedicated to me.
January 11, 2021
On Monday, 11 January 2021 at 10:14:36 UTC, ddcovery wrote:

[...]

> void zipTo(string srcFolder, string zipFile)
> in
> {
>   assert(srcFolder.exists());
> }
> out
> {
>   assert(zipPath.exists());
> }
> body
> {
>   scope (failure)
>     "Problems generating 7z file".writeln();
>
>   ...
> }

Just my 2 ¢: This is not DbC as I understand it. The conditions
do not reflect a program state one "can reason about". Furthermore
there is at least one race condition [1] which would be absent if
the file system operations just fail and throw an exception.

[1] https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use


January 11, 2021
On Monday, 11 January 2021 at 19:33:26 UTC, kdevel wrote:
> On Monday, 11 January 2021 at 10:14:36 UTC, ddcovery wrote:
>
> [...]
>
>> void zipTo(string srcFolder, string zipFile)
>> in
>> {
>>   assert(srcFolder.exists());
>> }
>> out
>> {
>>   assert(zipPath.exists());
>> }
>> body
>> {
>>   scope (failure)
>>     "Problems generating 7z file".writeln();
>>
>>   ...
>> }
>
> Just my 2 ¢: This is not DbC as I understand it. The conditions
> do not reflect a program state one "can reason about".
It's true.  I suppose you mainly refer to assertions over shared (not exclusive) resources: you can't "snapshot" a pre/post state and demonstrate that your function is the responsible of this transformation.

But the think here is I'm running a set of batch commands (not only 7z) over folders/files assuming that no other one is interested in.

It is a really relaxed scenery, but enough for the tasks.


> Furthermore
> there is at least one race condition [1] which would be absent if
> the file system operations just fail and throw an exception.
>
> [1] https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use

Absolutelly.  the pre-assert and post-assert are only "informative" (documentation) and a development help (I wrote assertions before code).  The zip (really a .7z) is performed using 7z command execution an response code is checked to raise the exception:  important I/O checking is performed as "athomic" as possible:

This is the complete method code:

...
void generateZip(string srcPath, string zipPath )
in
{
  assert(srcPath.exists());
}
out
{
  assert(zipPath.exists());
}
body
{
  import std.file : chdir, getcwd;
  import std.path: absolutePath;

  scope (failure)
    "Problems generating 7z file".writeln();

  auto dstPath = zipPath.absolutePath();
  auto actualDir = getcwd();
  scope (exit)
    chdir(actualDir);

  chdir(srcPath);
  format!"7z a %s"(dstPath).exec();
}
...
void exec(string cmd)
{
  import std.process : wait, spawnShell;

  auto result = cmd.spawnShell().wait(); //wait(spawnShell(cmd));
  if (result != 0)
    throw new object.Error(format!"Problems executing command. Exit code %d"(result));
}

January 12, 2021
On Monday, 11 January 2021 at 22:12:15 UTC, ddcovery wrote:

> It's true.  I suppose you mainly refer to assertions over shared (not exclusive) resources: you can't "snapshot" a pre/post state and demonstrate that your function is the responsible of this transformation.
>
> But the think here is I'm running a set of batch commands (not only 7z) over folders/files assuming that no other one is interested in.
>
> It is a really relaxed scenery, but enough for the tasks.

`assert` should be used to verify logical assumptions in your program. To verify things in the environment, exceptions should be used. You can drop the `in` and `out` contracts and use the `enforce` function the same way as `assert` is used. It will throw an exception if the condition doesn't hold.

Exceptions inheriting from the class `Exception` should be thrown when there's an error related to the environment. I.e. a missing file, failed to connect to a server and so on.

Exceptions inheriting from the class `Error` should be thrown when there's a logical error in the program, this is what `assert` does. This includes accessing an array outside of its bounds, failing to handle all cases in a `final switch` statement and so on.

`assert` and contracts can be removed from the code, depending on which compiler flags are being used. Exceptions will always stay.

In your case, there can be something like anti-virus software which is running in the background and decides to remove your files which the program is processing.

--
/Jacob Carlborg

January 12, 2021
On Monday, 11 January 2021 at 18:33:58 UTC, ddcovery wrote:

> I understand... As long as I have seen, the own std library makes an intensive use of unitesting and avoids the in/out contract keywords (mainly, I suppose, because it is a "run-time" check with the obvious performance fault ).

No, it's not a performance issue, contracts can be disabled at compile time and are in the standard library.

There are several problems with the implementation of contracts in D, which I think make them less useful and contribute to the reason why they're not very commonly used.

* in-contracts are not included in the generated documentation
* in-contracts are executed by the callee instead of the caller
* No compile time check of contracts are performed, if it would be possible
* DMD ships with a standard library compiled for release builds, i.e. without contracts and asserts. LDC on the other hand, ships both a with debug build and with a release build of the standard library

--
/Jacob Carlborg