September 23, 2010
On Thu, 23 Sep 2010 08:47:36 -0400, Robert Jacques <sandford@jhu.edu> wrote:

> On Thu, 23 Sep 2010 02:51:28 -0400, Don <nospam@nospam.com> wrote:
>
>> Jesse Phillips wrote:
>>> Steven Schveighoffer Wrote:
>>>> If we can define weakly pure functions this way, they most likely will be  way more common than unpure functions.  I know I avoid accessing global  variables in most of my functions.  Think about a range, almost all the  methods in a range can be weakly pure.  So that means you need to mark  every function as pure.
>>
>> I think that's true. I/O is impure, but most other things are not.
>
> The GC also impure :)

The GC must be assumed to be pure even though it's not.  Otherwise, pure functions can't do any heap allocation, and that makes them pretty useless in a garbage collected languages.

In functional languages, allocating memory is usually considered pure.

-Steve
September 23, 2010
On Wed, 22 Sep 2010 21:48:19 -0400, Robert Jacques <sandford@jhu.edu> wrote:

> On Wed, 22 Sep 2010 13:10:36 -0400, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
>
>> On Wed, 22 Sep 2010 12:00:16 -0400, Robert Jacques <sandford@jhu.edu> wrote:
>>> What about value types?
>>
>> Value types are implicitly convertable to immutable, so they can be strongly-pure.
>
> No their not. Remember, arrays and other structs are value types in the type system. Logically, they may be reference types, but as far as their type signature goes, they are value types.

Arrays are not value types.  A value type is one that contains no references, no matter how deep.  It is irrelevant if you have to spell out the references or not.

another example of something that is not a value type:

alias int * iptr;

foo(iptr p);

iptr is not a value type just because you don't see any * in the signature.

>>
>> But the compiler will be able to tell.  I think adding a __traits(isStronglyPure, symbol) will be good for those rare occasions where you really want to ensure purity.
>>
>> static assert(__traits(isStronglyPure, foo));
>>
>> -Steve
>
> This would work, but it wouldn't be self-documenting, etc.

Hm... OK, well I disagree, it looks like it's documented to me.  I don't see a difference between tagging something as strongly pure and putting in the static assert (except verbosity of course).  I will note that I think the above would be a rare situation.

-Steve
September 23, 2010
Don wrote:

> Don wrote:
>> The docs currently state that:
> 
>> PROPOSAL:
>> Drop the first requirement. Only one requirement is necessary:
>> 
>> A pure function does not read or write any global mutable state.
>> 
> 
> Wow. It seems that not one person who has responded so far has understood this proposal! I'll try again. Under this proposal:
> 
> If you see a function which has mutable parameters, but is marked as 'pure', you can only conclude that it doesn't use global variables. That's not much use on it's own. Let's call this a 'weakly-pure' function.
> 
> However, if you see a function maked as 'pure', which also has only immutable parameters, you have the same guarantee which 'pure' gives us as the moment. Let's call this a 'strongly-pure' function.
> 
> The benefit of the relaxed rule is that a strongly-pure function can
> call a weakly-pure functions, while remaining strongly-pure.
> This allows very many more functions to become strongly pure.
> 
> The point of the proposal is *not* to provide the weak guarantee. It is to provide the strong guarantee in more situations.

I understand now, this is a great proposal! What confused me was the label of 'pure functions' for functions that actually aren't pure in the usual way that purity is defined.
September 23, 2010
Gary Whatmore Wrote:

> We could use these proposals as a base for D 2.5 or D 3.0. Now that a better purity/constness system seems to solve problems more easily, D 2.0 seems too limited for modern systems programming. Is it finally time to put D 1.0 to rest, D 2.0 in maintenance mode, and concentrate on D 3? The TDPL book was finally published and D 2.0 has been in bugfix mode for a while. Once we have a 64-bit compiler ready, it would be time to move on.

I think the question is would this break any code? Don't think so. Would 'pure' ever be used with its current restrictions? To an extent, but I think it may result in multiple functions for the same thing. Don't know. And last if we start work on D3 which has ... such features over D2 who will be using D2? They'll still be waiting for the language to be finished.

If it is decided to be the right thing I think we should do it now, not later.

Lastly D1 will not be shot. D2 is already placed in maintenance mode, DMD just doesn't have everything implemented. But really, what is this obsession with thinking D1 has to go, or that it is slowing the progress of D2? Walter is running a business, he must support his products or clients won't buy/use them.
September 23, 2010
Michel Fortin napisał:

> The interesting thing with this change is that you can now call mutators functions on the local variables inside the pure function, because those can be made pure. You can't even iterate over a range inside a pure function without this!
> 
> pure int test() {
> int result;
> auto r = iota(0, 10);
> while (!r.empty) {
> result += r;
> r.popFront(); // can't be pure by current rules!
> }
> return result;
> }

It's because popFront() can't be made pure. It could be if there was @tail immutable in the language -- pure functions would mark their arguments with @tail immutable instead of immutable. That allows popFront() to advance the range.

I wrote about it before but the idea didn't catch on: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=11 6475

-- 
Tomek
September 23, 2010
Steven Schveighoffer wrote:
> On Thu, 23 Sep 2010 08:47:36 -0400, Robert Jacques <sandford@jhu.edu> wrote:
> 
>> On Thu, 23 Sep 2010 02:51:28 -0400, Don <nospam@nospam.com> wrote:
>>
>>> Jesse Phillips wrote:
>>>> Steven Schveighoffer Wrote:
>>>>> If we can define weakly pure functions this way, they most likely will be  way more common than unpure functions.  I know I avoid accessing global  variables in most of my functions.  Think about a range, almost all the  methods in a range can be weakly pure.  So that means you need to mark  every function as pure.
>>>
>>> I think that's true. I/O is impure, but most other things are not.
>>
>> The GC also impure :)
> 
> The GC must be assumed to be pure even though it's not.  Otherwise, pure functions can't do any heap allocation, and that makes them pretty useless in a garbage collected languages.
> 
> In functional languages, allocating memory is usually considered pure.

In the D spec, it already says that 'new' is considered pure.
September 23, 2010
dsimcha napisał:

> 1.  The documentation that says that the parameters need to be convertible to immutable is outdated.  This was changed a while ago to only requiring const.

Good to know. Yet, I wonder why such changes are not discussed on this NG and at the very least announced in the change log...

On topic: this means a pure function can take a reference to data that can be mutated by someone else. So we're giving up on the "can parallelize with no dataraces" guarantee on pure functions?

-- 
Tomek
September 23, 2010
Lutger wrote:
> Don wrote:
> 
>> Don wrote:
>>> The docs currently state that:
>>> PROPOSAL:
>>> Drop the first requirement. Only one requirement is necessary:
>>>
>>> A pure function does not read or write any global mutable state.
>>>
>> Wow. It seems that not one person who has responded so far has
>> understood this proposal! I'll try again. Under this proposal:
>>
>> If you see a function which has mutable parameters, but is marked as
>> 'pure', you can only conclude that it doesn't use global variables.
>> That's not much use on it's own. Let's call this a 'weakly-pure' function.
>>
>> However, if you see a function maked as 'pure', which also has only
>> immutable parameters, you have the same guarantee which 'pure' gives us
>> as the moment. Let's call this a 'strongly-pure' function.
>>
>> The benefit of the relaxed rule is that a strongly-pure function can
>> call a weakly-pure functions, while remaining strongly-pure.
>> This allows very many more functions to become strongly pure.
>>
>> The point of the proposal is *not* to provide the weak guarantee. It is
>> to provide the strong guarantee in more situations.
> 
> I understand now, this is a great proposal! What confused me was the label of 'pure functions' for functions that actually aren't pure in the usual way that purity is defined.  

Yes. The fact that you can declare a mutable variable inside a pure function was always a bit unconventional. This pushes that even further. Maybe to the extent that 'pure' becomes a misnomer.
September 23, 2010
On Thu, 23 Sep 2010 16:35:23 -0400, Tomek Sowiński <just@ask.me> wrote:

> dsimcha napisał:
>
>> 1.  The documentation that says that the parameters need to be convertible
>> to immutable is outdated.  This was changed a while ago to only requiring
>> const.
>
> Good to know. Yet, I wonder why such changes are not discussed on this NG and at the very
> least announced in the change log...
>
> On topic: this means a pure function can take a reference to data that can be mutated by
> someone else. So we're giving up on the "can parallelize with no dataraces" guarantee on
> pure functions?

A const pointer to unshared data cannot be modified while inside a pure function.  The key is that it's unshared.

What it does disable is caching based on the reference value.

-Steve
September 23, 2010
On 9/23/10 15:25 CDT, Don wrote:
> Steven Schveighoffer wrote:
>> On Thu, 23 Sep 2010 08:47:36 -0400, Robert Jacques <sandford@jhu.edu>
>> wrote:
>>
>>> On Thu, 23 Sep 2010 02:51:28 -0400, Don <nospam@nospam.com> wrote:
>>>
>>>> Jesse Phillips wrote:
>>>>> Steven Schveighoffer Wrote:
>>>>>> If we can define weakly pure functions this way, they most likely
>>>>>> will be way more common than unpure functions. I know I avoid
>>>>>> accessing global variables in most of my functions. Think about a
>>>>>> range, almost all the methods in a range can be weakly pure. So
>>>>>> that means you need to mark every function as pure.
>>>>
>>>> I think that's true. I/O is impure, but most other things are not.
>>>
>>> The GC also impure :)
>>
>> The GC must be assumed to be pure even though it's not. Otherwise,
>> pure functions can't do any heap allocation, and that makes them
>> pretty useless in a garbage collected languages.
>>
>> In functional languages, allocating memory is usually considered pure.
>
> In the D spec, it already says that 'new' is considered pure.

Which is wrong :o(. new invokes the constructor, which may do a variety of impure things.

Andrei