April 15, 2014
On Monday, 14 April 2014 at 15:16:07 UTC, bearophile wrote:
> Steven Schveighoffer:
>
>> For that reason, I would disallow out parameters from casting implicitly.

A number of things perplex me here.

1) If I attempt to compile foo2() more or less as presented with 2.065, the compiler tells me:

Error: '_adDupT' is not nothrow
Error: function 'mu.foo2' is nothrow yet may throw

What version is the discussion about?

2) If I have a simple program as follows, the compiler does not complain about me altering the value of global a.

import std.stdio;
string a = "aaa";

void foo2(in string s, ref string sOut) pure {
    auto s2 = s.dup;
    s2[0] = 'a';
    sOut = cast(string) s2; // Error: cannot implicitly convert
}

void main() {
{
   foo2("xyz", a);
   writeln(a);
}

3) Using a ref parameter for a pure function seems to me to be a clear indication of intended side effect. Wikipedia on pure functions says it's not allowed. Out does seem somehow different to me, since it's initial value is by definition throw-away.

Steve
April 15, 2014
Steve Teale:

> 1) If I attempt to compile foo2() more or less as presented with 2.065, the compiler tells me:
>
> Error: '_adDupT' is not nothrow
> Error: function 'mu.foo2' is nothrow yet may throw
>
> What version is the discussion about?

This rather fastidious limitation was finally removed in the latest D alpha (and if you look in Bugzilla you see it has created few regressions).


> 2) If I have a simple program as follows, the compiler does not complain about me altering the value of global a.
>
> import std.stdio;
> string a = "aaa";
>
> void foo2(in string s, ref string sOut) pure {
>     auto s2 = s.dup;
>     s2[0] = 'a';
>     sOut = cast(string) s2; // Error: cannot implicitly convert
> }
>
> void main() {
> {
>    foo2("xyz", a);
>    writeln(a);
> }

Yes, foo2 is weakly pure, but main is not tagged as pure, so main is free to use a global reference. If you mark main pure, your code will not compile even if you comment out the writeln. D is working as designed here.


> 3) Using a ref parameter for a pure function seems to me to be a clear indication of intended side effect.

In D you can also have "const ref". A mutable ref makes the function "weakly pure" at best.


> Wikipedia on pure functions says it's not allowed.

D has both strongly pure and weakly pure functions (and later the compiler has added "const-ly pure" and another category, all invisible.


> Out does seem somehow different to me, since it's initial
> value is by definition throw-away.

Yes, this is true in theory. I don't know if this is also true in D in practice, because D out has some problems.

Bye,
bearophile
April 15, 2014
On Tuesday, 15 April 2014 at 09:41:57 UTC, bearophile wrote:
> Yes, foo2 is weakly pure, but main is not tagged as pure, so main is free to use a global reference. If you mark main pure, your code will not compile even if you comment out the writeln. D is working as designed here.
>
>
>> 3) Using a ref parameter for a pure function seems to me to be a clear indication of intended side effect.
>
> In D you can also have "const ref". A mutable ref makes the function "weakly pure" at best.
>
>
>> Wikipedia on pure functions says it's not allowed.
>
> D has both strongly pure and weakly pure functions (and later the compiler has added "const-ly pure" and another category, all invisible.
>
>
>> Out does seem somehow different to me, since it's initial
>> value is by definition throw-away.
>
> Yes, this is true in theory. I don't know if this is also true in D in practice, because D out has some problems.
>
> Bye,
> bearophile

Since this is D-Learn, I can be indignant, and say that D needs to get its act together, and have a clean definition of 'pure'. What you describe is not only undocumented, but also far too complicated - pure weak nothrow dontpiss kissmyass @never, and so on if the direction continues.

Nontheless, thank you for your assiduous efforets to make D internally consistent.

Steve

April 15, 2014
Steve Teale:

> Since this is D-Learn, I can be indignant, and say that D needs to get its act together, and have a clean definition of 'pure'. What you describe is not only undocumented, but also far too complicated - pure weak nothrow dontpiss kissmyass @never, and so on if the direction continues.

There is a nice article on D purity that I suggest you to read. Unfortunately I don't remember the link.

To design a system language as complex as C++/D you need lot of mathematics and theory. Andrei is good in computer science theory and in complex programming too, but Walter is less mathematically-minded and this could be visible in the design of some parts of D. Anyway, everyone is doing their best, Walter is very good and he has all my respect. And in a real-world system language a clean definition of pure (like the original pure implementation of D) is not very useful. The current definition of pure of D is good enough and it's a part very near to be completely implemented (unlike many other parts of D like synchronized, scope, SIMD, vector operations, operator overloading, dynamic libraries, GC, and more). So please don't be too much indignant, we don't have the research laboratories of Microsoft :-)


> Nontheless, thank you for your assiduous efforets to make D internally consistent.

In the end I am not doing much. At best I can only hope to spot some sharp corners of the language, and ask for them to be smoothed. But it's very hard to make progress. And lately Andrei (perhaps rightfully) has raised the bar regarding the acceptable breaking changes. And people like Kenji have a mind better than mine (able to think about tens of corner cases, able to keep in mind many complex interactions, etc) even when they are sleeping :-)

Bye,
bearophile
April 16, 2014
On Tuesday, 15 April 2014 at 18:02:00 UTC, bearophile wrote:
> Steve Teale:
>
>> Since this is D-Learn, I can be indignant, and say that D needs to get its act together, and have a clean definition of 'pure'. What you describe is not only undocumented, but also far too complicated - pure weak nothrow dontpiss kissmyass @never, and so on if the direction continues.
>
> There is a nice article on D purity that I suggest you to read. Unfortunately I don't remember the link.
>
> To design a system language as complex as C++/D you need lot of mathematics and theory. Andrei is good in computer science theory and in complex programming too, but Walter is less mathematically-minded and this could be visible in the design of some parts of D. Anyway, everyone is doing their best, Walter is very good and he has all my respect. And in a real-world system language a clean definition of pure (like the original pure implementation of D) is not very useful. The current definition of pure of D is good enough and it's a part very near to be completely implemented (unlike many other parts of D like synchronized, scope, SIMD, vector operations, operator overloading, dynamic libraries, GC, and more). So please don't be too much indignant, we don't have the research laboratories of Microsoft :-)
>
>
>> Nontheless, thank you for your assiduous efforets to make D internally consistent.
>
> In the end I am not doing much. At best I can only hope to spot some sharp corners of the language, and ask for them to be smoothed. But it's very hard to make progress. And lately Andrei (perhaps rightfully) has raised the bar regarding the acceptable breaking changes. And people like Kenji have a mind better than mine (able to think about tens of corner cases, able to keep in mind many complex interactions, etc) even when they are sleeping :-)
>
> Bye,
> bearophile

Like I said, I allowed myself the luxury of being indignant because we were hidden away on D Learn. I have total respect for Walter. For one thing he is a self-taught programmer like me, though much more advanced, and I've known him on and off since the Zortech days in 1988. I don't much about Andrei and Kenji, except that they are out of my league.

I guess that rather than complain that the compiler does not appear to conform to the definition, I should help by trying to improve the documentation.

Anyway my view on the original subject is that the implicit conversion should be allowed for the out case, but not the ref.

Steve
April 16, 2014
On Tuesday, April 15, 2014 18:01:59 bearophile wrote:
> Steve Teale:
> > Since this is D-Learn, I can be indignant, and say that D needs to get its act together, and have a clean definition of 'pure'. What you describe is not only undocumented, but also far too complicated - pure weak nothrow dontpiss kissmyass @never, and so on if the direction continues.
> 
> There is a nice article on D purity that I suggest you to read. Unfortunately I don't remember the link.

http://klickverbot.at/blog/2012/05/purity-in-d/

The key thing to understand about pure though is that _all_ it guarantees is that the function cannot access mutable, global variables or call any other functions which are not pure. The only variables that it can access which are either global and guaranteed to never change their values after initialization (which generally means that they're immutable) and the ones which are passed in directly to the function or which can be accessed via the variables that are passed in.

So, really, pure has _nothing_ to do with mathematical purity. It's just protecting against access to global variables. Now, that restriction allows a number of other things to be derived from that, which allows us to do cool stuff - including optimizing functions which _are_ pure in the mathematical sense. The most basic distinction would be what is typically called weak or strong purity, where strongly pure functions have immutable parameters (and thus multiple calls with the same arguments can be optimized to a single call), and weakly pure functions are pure functions which aren't strongly pure. Strongly pure functions generally can be optimized, whereas weakly pure functions cannot, but the actual distinctions can get more complicated than that, so even talking about weak vs strong purity isn't actually clear enough.

So, it's certainly true that things get a bit complicated when discussing what can be inferred due to the fact that a function is pure. And it doesn't always come down to strong vs weak purity either. So, I wouldn't expect very many people to understand under what circumstances the compiler is able to do certain things with a pure function, and that's not necessarily a good thing.

However, the key thing to understand with pure itself is that all it means is that the function can't access global, mutable state or call other functions which aren't pure. Pretty much everything else about it is essentially either a compiler optimization based on that information or an implicit type conversion which is made legal based on that information.

Regardless, I'd advise reading David's blog post on the matter, which I linked to above.

- Jonathan M Davis

1 2
Next ›   Last »