From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,21960280f1d61e84 X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Newsgroups: comp.lang.ada Subject: Re: in defense of GC References: <1169531612.200010.153120@38g2000cwa.googlegroups.com> <1mahvxskejxe1$.tx7bjdqyo2oj$.dlg@40tude.net> <2tfy9vgph3.fsf@hod.lan.m-e-leypold.de> <1g7m33bys8v4p.6p9cpsh3k031$.dlg@40tude.net> <14hm72xd3b0bq$.axktv523vay8$.dlg@40tude.net> <4zwt33xm4b.fsf@hod.lan.m-e-leypold.de> <1j7neot6h1udi$.14vp2aos6z9l8.dlg@40tude.net> <1pzx3y7d2pide.y744copm0ejb$.dlg@40tude.net> From: Markus E Leypold Organization: N/A Date: Mon, 05 Feb 2007 01:55:15 +0100 Message-ID: <2pabzt1kzw.fsf@hod.lan.m-e-leypold.de> User-Agent: Some cool user agent (SCUG) Cancel-Lock: sha1:0XUDym0YUh/EOn3UJuv4tB3I610= MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii NNTP-Posting-Host: 88.72.198.57 X-Trace: news.arcor-ip.de 1170636613 88.72.198.57 (5 Feb 2007 01:50:13 +0200) X-Complaints-To: abuse@arcor-ip.de Path: g2news2.google.com!news2.google.com!news.germany.com!news.unit0.net!newsfeed.arcor-ip.de!news.arcor-ip.de!not-for-mail Xref: g2news2.google.com comp.lang.ada:8947 Date: 2007-02-05T01:55:15+01:00 List-Id: Robert A Duff writes: > Markus E Leypold > writes: > >> I do need that >> >> function Make_a_Stepper (K:Integer) return ... is >> >> N : Integer := Complicated_Function(K); >> >> function Stepper(F:Foo) return Foo is >> >> begin >> >> return Foo + N; >> >> end; >> >> begin >> return Stepper; >> end; >> >> would work. And no nitpicking, please, if I made syntax error here: The >> intention should be clear. > > I don't think this is nitpicking: > > I'm not sure what you mean by the above example. Is N intended to be > constant or variable (in Ada terms -- that's immutable/immutable in FP > terms)? Ah, you see, that is the point with closures. If we were talking about closures, N would be different for every invocation of Make_Stepper but every Stepper returned would refer to a constant N during its livetime. THis is why they are called closure (they enclose their environment at the instance of their instantiation which in this case would be (in a sense) between the invocation of Make_Stepper and before the body of Make_Stepper is executed. > > Do you mean this: > > function Make_a_Stepper (K:Integer) return ... is > N : constant Integer := Complicated_Function(K); -- I added "constant" here! **************** > function Stepper(F:Foo) return Foo is > begin > return Foo + N; > end; > begin > return Stepper; > end; > > Or this: > > function Make_a_Stepper (K:Integer) return ... is > N : Integer := Complicated_Function(K); > function Stepper(F:Foo) return Foo is > begin > N := N + 1; -- I added a modification of N here! **************** > return Foo + N; > end; > begin > return Stepper; > end; > > ? > > These two cases of so-called "upward closure" seem very different to me. Ah, yes, I see how that comes about, since we are not talking names and their bindings to values here, but variables in Ada. Actually I'd say both. The last case is no pure functional programming (just for the record) and in OCaml would b expressed like this: let make_stepper k = let n = ref (complicated k) in (fun f -> n := !n + 1; f + !n) and in the first case (just to show the difference) let make_stepper k = let n = (complicated k) in (fun f -> f + n) So in (impure) FP both cases are possible and if we go back to Ada syntax from that: Why not use the constant keyword to distinguish the cases? > (Both are of course illegal in Ada, but we're discussing what "ought" to be.) Ehm. And I'm thankful for you rather insightful input :-). > In the former case, we're returning a function that looks at some local > value (the value of N). In this case, you comment about returning > integer values is quite correct: > >>> Closure don't "make things global". They do it as much as returning an >>> Integer, makes, GOD FORBID!, a value global (don't return Integers >>> people, that makes a value global and we all know, global is bad -- >>> how nonsensical is that?). > > Right. What's the big deal? Returning a function that looks at integer > values is no worse than returning integer values. Integer values live > forever, and the value of N is certainly not tied to the lifetime of N. > But in the latter, case, the return of Stepper is causing the lifetime > of an integer VARIABLE (i.e. mutable) to be longer than one might > suspect for a local variable of Make_A_Stepper. That seems like a > problem to me. It's still only encapsulated _state_, the visibility of indentifiers (scope) is not extended by that. Outsiders can't look into the closure. And we already have encapsulate state like this, in tagged objects. Closure differ from objects only in 2 points: (1) they have only one method (apply) and (2) they can take (implicitely) values from their whole environment at the place of instantiation. Indeed the more I think about it, a bit compiler support (which knows which parts of the environment are actually used in the closures body), a new keyword (closure to distinguis them from ordinary procedures) and all the mechanisms already present in tagged types should be quite enough implement closure in Ada. (Well, OK, there are problems with sharing N in the non-constant case with other closures and other procedure which can see N, but in the constant case (which is perhaps in the presence of object the mor important one), 'constant N' can be just copied into a implementation object of the type tagged record N : Integer; end record; > You (Markus) seem to be an advocate of (possibly-upward) closures. Certainly. As I said in another post of the recent article storm, I _think_ (think, mind you, no hard data) that if too much thinks (narrowing of type w/o RTTI during method invocation, scope of access types and passing procedural parameters can only be "done downwards", some desirable structures become impossible. > And also an advocate of function programming. 'functional'. :-). > So how would you like a rule that says the former example is OK, but > the latter is illegal? I'd weep silently :-). > (That is, upward closures are allowed only when you're doing functional > (no side-effects) programming). > Note that the latter is not functional -- a call to the function that > Make_A_Stepper returns modifies N, which is the key difference! Yes. That is so. But Ada is not functional any way and impure closures have their value. Nonetheless: Since the encapsulation of mutable state can be done in tagged types forbidding the latter would probably not hurt as much as in languages w/o OO. Still, that requires further analysis of the most frequent use cases. Regards -- Markus