digitalmars.D - Pure functions as initializers for immutable structures?
- =?iso-8859-2?B?VG9tZWsgU293afFza2k=?= (19/19) Oct 18 2010 Initializing immutable structures is a source of constant grief. Anythin...
- Steven Schveighoffer (5/10) Oct 18 2010 Aren't we supposed to get so-called immutable constructors?
- =?iso-8859-2?B?VG9tZWsgU293afFza2k=?= (16/25) Oct 18 2010 te:
- Steven Schveighoffer (20/38) Oct 18 2010 I think it's in TDPL, don't have a copy so I'm not sure how to refer you...
- =?iso-8859-2?B?VG9tZWsgU293afFza2k=?= (23/47) Oct 18 2010 te:
- Michel Fortin (42/44) Oct 18 2010 Well, it depends on the arguments of the pure function. Here's two
- Don (4/14) Oct 18 2010 Tomek stated that at the end of his original post. I think he is correct...
- Michel Fortin (7/22) Oct 18 2010 Hum, you're right. Seems I overlooked that "immutably pure" reference
- =?iso-8859-2?B?VG9tZWsgU293afFza2k=?= (19/32) Oct 18 2010 l =
- Michel Fortin (9/26) Oct 18 2010 The first one has one interesting property: if at the call site you
- =?iso-8859-2?B?VG9tZWsgU293afFza2k=?= (15/33) Oct 19 2010 =
- Steven Schveighoffer (5/7) Oct 19 2010 In this NG, no comments usually means nobody can find anything else wron...
- bearophile (4/6) Oct 19 2010 I didn't comment because I didn't have something useful to add to the di...
Initializing immutable structures is a source of constant grief. Anything non-trivial requires instancing a mutable structure, initializing it, and then either casting to immutable (it's up to you to ensure no alias leaked) or, not to violate the type system, duplicate the whole. Yet, if there was a situation where the alias leaking is under control, casting would be safe. Perhaps pure* functions are such a place. They can only touch the immutable world, whether through globals or through their parameters. So if one initializes the returned structure with a reference to the outside world, it will be immutable. And if you stuff the structure with anything mutable, it must have been created within the function's body, so no alias leaks. Call me crazy, but I think it is safe to implicitly convert a pure function's return value to immutable. What you think? * here by pure I mean either the old pure** when it still had immutable arguments, or Don's "immutably pure". ** BTW, http://www.digitalmars.com/d/2.0/function.html still says immutable, please update. -- Tomek
Oct 18 2010
On Mon, 18 Oct 2010 14:31:26 -0400, Tomek Sowiński <just ask.me> wrote:Initializing immutable structures is a source of constant grief. Anything non-trivial requires instancing a mutable structure, initializing it, and then either casting to immutable (it's up to you to ensure no alias leaked) or, not to violate the type system, duplicate the whole.Aren't we supposed to get so-called immutable constructors? If that's not what you mean, can you give an example of such grief? I admit I don't use immutable structs/objects in day-to-day coding. -Steve
Oct 18 2010
Dnia 18-10-2010 o 20:53:15 Steven Schveighoffer <schveiguy yahoo.com> = napisa=B3(a):On Mon, 18 Oct 2010 14:31:26 -0400, Tomek Sowi=F1ski <just ask.me> wro=te:Initializing immutable structures is a source of constant grief. =Anything non-trivial requires instancing a mutable structure, ==initializing it, and then either casting to immutable (it's up to you=to ensure no alias leaked) or, not to violate the type system, =Haven't heard, can you point to the discussion? Anyway, if these immutable ctors are defined inside the type, then the = library writer may not provide a ctor suitable for your case (very = possible). Plus, if the thing I wrote is correct, why not?duplicate the whole.Aren't we supposed to get so-called immutable constructors?If that's not what you mean, can you give an example of such grief?Build an immutable dictionary that would hold the program's options.I admit I don't use immutable structs/objects in day-to-day coding.Some time ago I tried, swore loud, took hours to isolate & file several = = bugs. But I'll try again, as soon as I get sufficient adrenaline lust. ;= ) -- = Tomek
Oct 18 2010
On Mon, 18 Oct 2010 15:20:39 -0400, Tomek Sowiński <just ask.me> wrote:Dnia 18-10-2010 o 20:53:15 Steven Schveighoffer <schveiguy yahoo.com> napisał(a):I think it's in TDPL, don't have a copy so I'm not sure how to refer you. I know the really really old pdf document that talks about the future direction of D2 had them.On Mon, 18 Oct 2010 14:31:26 -0400, Tomek Sowiński <just ask.me> wrote:Haven't heard, can you point to the discussion?Initializing immutable structures is a source of constant grief. Anything non-trivial requires instancing a mutable structure, initializing it, and then either casting to immutable (it's up to you to ensure no alias leaked) or, not to violate the type system, duplicate the whole.Aren't we supposed to get so-called immutable constructors?Anyway, if these immutable ctors are defined inside the type, then the library writer may not provide a ctor suitable for your case (very possible).Yes true. However with your method, it's also very possible they don't provide a pure ctor. I think an immutable ctor has different restrictions. In light of the new version of pure, perhaps your idea could obviate the need for immutable constructors. In other words, a pure constructor just got a *lot* easier to write, and almost all ctors should be pure. If that's the case, then many would be 'immutably pure' since they take only value types.Plus, if the thing I wrote is correct, why not?Not saying it's not correct, it sounds correct to me, but I think we need to verify we aren't creating too many ways to do the same thing here (which may even mean immutable constructors are redundant).This particular problem should be solvable by changing the type of all literals to immutable :) I think at some point, we need something like you propose -- where given the properties of a function, you can implicitly convert its return value to immutable. This makes things much easier to deal with. -SteveIf that's not what you mean, can you give an example of such grief?Build an immutable dictionary that would hold the program's options.
Oct 18 2010
Dnia 18-10-2010 o 21:38:07 Steven Schveighoffer <schveiguy yahoo.com> = napisa=B3(a):On Mon, 18 Oct 2010 15:20:39 -0400, Tomek Sowi=F1ski <just ask.me> wro=te: [snip]e =Anyway, if these immutable ctors are defined inside the type, then th=library writer may not provide a ctor suitable for your case (very =t =possible).Yes true. However with your method, it's also very possible they don'=provide a pure ctor. I think an immutable ctor has different restrictions. In light of the==new version of pure, perhaps your idea could obviate the need for =immutable constructors. In other words, a pure constructor just got a==*lot* easier to write, and almost all ctors should be pure. If that's==the case, then many would be 'immutably pure' since they take only val=ue =types.I'd have to know what are the restrictions on immutable ctors. But I = expect them to be very similar to restrictions that immutable(pure) = imposes, except for mutating 'this', of course.Plus, if the thing I wrote is correct, why not?Not saying it's not correct, it sounds correct to me, but I think we =need to verify we aren't creating too many ways to do the same thing =here (which may even mean immutable constructors are redundant).Thanks for support. Well, now you can create structs either with = constructors or with functions (especially when templatized, to infer ty= pe = from arguments). Immutable versions should cherish similar diversity.=This particular problem should be solvable by changing the type of all=If that's not what you mean, can you give an example of such grief?Build an immutable dictionary that would hold the program's options.literals to immutable :) I think at some point, we need something like you propose -- where giv=en =the properties of a function, you can implicitly convert its return =value to immutable. This makes things much easier to deal with.Yeah, *much* easier. Plus, I think what I proposed isn't much work to = implement. But Walter would know that better. -- Tomek
Oct 18 2010
On 2010-10-18 14:31:26 -0400, Tomek Sowiński <just ask.me> said:Call me crazy, but I think it is safe to implicitly convert a pure function's return value to immutable. What you think?Well, it depends on the arguments of the pure function. Here's two cases where it won't work. 1. With the new pure semantics, a pure function is allowed to mutate arguments passed to it, so a reference to the function's return value could escape through it. For instance: class C {} pure C func(C* c) { *c = new C; return *c; } C c1; immutable(C) c2 = func(*c1); // now you have mutable c1 and immutable c2 pointing to the same (mutable?) object. A pure function where all the arguments are const or immutable does not have this problem. But it could have the second one though... 2. If you pass mutable or const arguments (arguments that are not immutable) to the pure function, the function could put a reference to those arguments inside the struct, and casting it to immutable would cause someone to have an immutable reference while someone else has a mutable one to the same piece of memory: struct S { const(char)[] a; } pure S func(const(char)[] a) { S s; s.a = a; return s; } char[] someString = "hello".dup; immutable(S) s = func(someString); // now you have mutable someString and immutable s.a pointing to the same (mutable?) string. Basically, if all the arguments are immutable then it'd be guarantied that it's safe to cast the result as immutable. But a const argument can break this guaranty. So I'd precise your assertion by saying it is safe to implicitly convert a pure function's return value to immutable, but only when all the arguments you feed to it are immutable. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Oct 18 2010
Michel Fortin wrote:On 2010-10-18 14:31:26 -0400, Tomek Sowiński <just ask.me> said:[snip]Call me crazy, but I think it is safe to implicitly convert a pure function's return value to immutable. What you think?Well, it depends on the arguments of the pure function. Here's two cases where it won't work.So I'd precise your assertion by saying it is safe to implicitly convert a pure function's return value to immutable, but only when all the arguments you feed to it are immutable.Tomek stated that at the end of his original post. I think he is correct. And no, I don't think it would be difficult to implement.
Oct 18 2010
On 2010-10-18 17:05:27 -0400, Don <nospam nospam.com> said:Michel Fortin wrote:Hum, you're right. Seems I overlooked that "immutably pure" reference at the end of his post. -- Michel Fortin michel.fortin michelf.com http://michelf.com/On 2010-10-18 14:31:26 -0400, Tomek Sowiński <just ask.me> said:[snip]Call me crazy, but I think it is safe to implicitly convert a pure function's return value to immutable. What you think?Well, it depends on the arguments of the pure function. Here's two cases where it won't work.So I'd precise your assertion by saying it is safe to implicitly convert a pure function's return value to immutable, but only when all the arguments you feed to it are immutable.Tomek stated that at the end of his original post. I think he is correct. And no, I don't think it would be difficult to implement.
Oct 18 2010
Dnia 18-10-2010 o 23:05:27 Don <nospam nospam.com> napisa=B3(a):Michel Fortin wrote:=On 2010-10-18 14:31:26 -0400, Tomek Sowi=F1ski <just ask.me> said:Call me crazy, but I think it is safe to implicitly convert a pure =function's return value to immutable. What you think?Well, it depends on the arguments of the pure function. Here's two =cases where it won't work.[snip]So I'd precise your assertion by saying it is safe to implicitly =l =convert a pure function's return value to immutable, but only when al=ct.the arguments you feed to it are immutable.Tomek stated that at the end of his original post. I think he is corre=And no, I don't think it would be difficult to implement.Thanks for support. I see two ways to go about it: pure T make(Args args) { ... } unittest { T t =3D make(...); // good immutable T t =3D make(...); // also good } Or: pure immutable(T) make(Args args) { T t =3D ...; // initialize t return t; // conversion happens here } I like the first one. -- = Tomek
Oct 18 2010
On 2010-10-18 17:25:49 -0400, Tomek Sowiński <just ask.me> said:Thanks for support. I see two ways to go about it: pure T make(Args args) { ... } unittest { T t = make(...); // good immutable T t = make(...); // also good } Or: pure immutable(T) make(Args args) { T t = ...; // initialize t return t; // conversion happens here } I like the first one.The first one has one interesting property: if at the call site you know that all the arguments you're feeding the function with are immutable, then you can automatically cast the result to immutable, even if the function can also accept const arguments. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Oct 18 2010
Dnia 18-10-2010 o 20:31:26 Tomek Sowi=F1ski <just ask.me> napisa=B3(a):Initializing immutable structures is a source of constant grief. =Anything non-trivial requires instancing a mutable structure, =initializing it, and then either casting to immutable (it's up to you =to =ensure no alias leaked) or, not to violate the type system, duplicate ==the whole. Yet, if there was a situation where the alias leaking is under control=, =casting would be safe. Perhaps pure* functions are such a place. They ==can only touch the immutable world, whether through globals or through==their parameters. So if one initializes the returned structure with a ==reference to the outside world, it will be immutable. And if you stuff==the structure with anything mutable, it must have been created within ==the function's body, so no alias leaks. Call me crazy, but I think it is safe to implicitly convert a pure =function's return value to immutable. What you think? * here by pure I mean either the old pure** when it still had immutabl=e =arguments, or Don's "immutably pure". ** BTW, http://www.digitalmars.com/d/2.0/function.html still says =immutable, please update.OK, I see the interest is dying down (so boring, not even one duck to = name) so I filed an enhancement request so it won't be forgotten. http://d.puremagic.com/issues/show_bug.cgi?id=3D5081 -- Tomek
Oct 19 2010
On Tue, 19 Oct 2010 14:54:32 -0400, Tomek Sowiński <just ask.me> wrote:OK, I see the interest is dying down (so boring, not even one duck to name) so I filed an enhancement request so it won't be forgotten.In this NG, no comments usually means nobody can find anything else wrong with it, which is a good thing. I voted for the bug report. -Steve
Oct 19 2010
Tomek S.:OK, I see the interest is dying down (so boring, not even one duck to name)I didn't comment because I didn't have something useful to add to the discussion. But a clean way to initialize immutable data structures is needed in D. We have recently discussed this a little in the D.learn newsgroup. But those ideas are not boring. Bye, bearophile
Oct 19 2010