www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Transients or scoped immutability

reply bearophile <bearophileHUGS lycos.com> writes:
This post contains uncooked ideas.

I'd like to create data structures:
- That once created are immutable, so there is no risk to write on them, etc;
- On the stack too, avoiding slower heap allocations and avoiding copying them
from the mutable to the immutable version;
- Avoiding to keep in the function name space a dead name of the mutable
version of the data structure;
- Avoiding calls to functions that may contain loops that DMD doesn't inline;
- Avoiding too much complex code for the programmer.

A syntax idea, a do{}transient(name1, name2, ...);:


void foo(char[] data) {
    do {
        int[256] count;
        foreach (char c; data)
            count[c]++;
        int x = ...
        auto bar = map!(...)(...x...);
    } transient(const count, const bar);
    // Here x is not visible.
    // Here count and bar are visible but read-only.
}
void main() {
    foo("this is a string");
}


A different syntax, that inverts the precedent idea and uses a sub-scope (it's
a bit like a with(){}, but its purpose is not to access fields of a struct):


void foo(char[] data) {
    int[256] count;
    foreach (char c; data)
        count[c]++;
    int x = ...
    auto bar = map!(...)(...x...);
    // Here x, count, data and bar are visible and mutable.
    scope (const count, const bar, data) {
        // Here x is not visible.
        // Here count and bar are visible but read-only.
        // Here data is visible and mutable
    }
    // Here x, count, data and bar are visible and mutable.
}
void main() {
    foo("this is a string");
}


I think the first idea is a bit less bug-prone, and it avoids too much
indenting of the code. Probably there are ways to invent a better syntax.

They have added the idea of "transients" is Clojure too:
http://clojure.org/transients?responseToken=07a82a51e4651b10f3a8ee4be09fe1f9f

This idea is good and it will help, but it needs a function call:
http://d.puremagic.com/issues/show_bug.cgi?id=5081

Bye,
bearophile
Apr 22 2011
parent reply Jesse Phillips <jessekphillips+D gmail.com> writes:
bearophile Wrote:

 This post contains uncooked ideas.
 
 I'd like to create data structures:
 - That once created are immutable, so there is no risk to write on them, etc;
 - On the stack too, avoiding slower heap allocations and avoiding copying them
from the mutable to the immutable version;
 - Avoiding to keep in the function name space a dead name of the mutable
version of the data structure;
 - Avoiding calls to functions that may contain loops that DMD doesn't inline;
 - Avoiding too much complex code for the programmer.

There was talk in the past of allowing a pure function create and modify a class and return that class as immutable. This was a suggestion on how to create immutable classes. The details were never really hashed out, but maybe it is possible for any returned value (of a pure function) to be implicitly converted to immutable. To me it sounds really nice an clean, do you think it would work for you?
Apr 22 2011
parent reply bearophile <bearophileHUGS lycos.com> writes:
Jesse Phillips:

 To me it sounds really nice an clean, do you think it would work for you?

Maybe you have missed the last two lines of my post:
 This idea is good and it will help, but it needs a function call:
 http://d.puremagic.com/issues/show_bug.cgi?id=5081

I like that idea and I think it will be good to have in D. But I think it's not enough, to solve the problem I have shown it requires a not simple function signature, you need to instantiate the static array before the call point (that's not nice and asks for two names for the same array), to use ref both in input and output, etc. Bye, bearophile
Apr 22 2011
parent reply Don <nospam nospam.com> writes:
bearophile wrote:
 Jesse Phillips:
 
 To me it sounds really nice an clean, do you think it would work for you?

Maybe you have missed the last two lines of my post:
 This idea is good and it will help, but it needs a function call:
 http://d.puremagic.com/issues/show_bug.cgi?id=5081

I like that idea and I think it will be good to have in D. But I think it's not enough, to solve the problem I have shown it requires a not simple function signature, you need to instantiate the static array before the call point (that's not nice and asks for two names for the same array), to use ref both in input and output, etc.

Just use a delegate literal (with a fix to 5081).
Apr 26 2011
parent reply bearophile <bearophileHUGS lycos.com> writes:
Don:

 Just use a delegate literal (with a fix to 5081).

So I think you are suggesting a solution to my original problem similar to: void foo(char[] data) { const count_bar = pure { int[256] count; foreach (char c; data) count[c]++; int x = ... auto bar = map!(...)(...x...); return tuple(count, bar); }(); const count = count_bar[0]; const bar = count_bar[1]; // Here x is not visible. // Here count and bar are visible but read-only. } void main() { foo("this is a string"); } This is less nice looking than possible alternatives, but it's not terrible, expecially if the tuple unpacking syntax sugar gets added to D: (How do you create pure delegates? A syntax like this doesn't work: const x= pure {return 0;}) void foo(char[] data) { const (count, bar) = pure { int[256] count; foreach (char c; data) count[c]++; int x = ... auto bar = map!(...)(...x...); return tuple(count, bar); }(); // Here x is not visible. // Here count and bar are visible but read-only. } void main() { foo("this is a string"); } Bye, bearophile
Apr 26 2011
parent KennyTM~ <kennytm gmail.com> writes:
On Apr 26, 11 19:43, bearophile wrote:
 This is less nice looking than possible alternatives, but it's not terrible,
expecially if the tuple unpacking syntax sugar gets added to D:
 (How do you create pure delegates? A syntax like this doesn't work: const x=
pure {return 0;})

auto x = delegate () pure /*nothrow*/ { return 0; }; but 'x' cannot be 'const' due to bug 5875.
Apr 26 2011