* Re: Reprise: 'in out' parameters for functions [not found] <u4qrv5hwr.fsf@acm.org> @ 2004-04-08 17:19 ` Alexander E. Kopilovich [not found] ` <bRecOT0TxF@VB1162.spb.edu> 1 sibling, 0 replies; 90+ messages in thread From: Alexander E. Kopilovich @ 2004-04-08 17:19 UTC (permalink / raw) To: comp.lang.ada Stephen Leake wrote: > > > This is what I wanted to declare: > > > > > > function Parse > > > (Error_Label : in String; > > > Token : in out Token_List.List_Iterator) > > > return String; > > > -- Process Token, which should contain '([Config_File =>] <string>)'. > > > -- Return the string. > > > -- Delete parsed tokens from Token. > > > > > One thing is missing in this your explanation: why exactly you don't want to > > make that List_Iterator global (instead of passing it as IN OUT argument) ? > My answer is "I never make anything global unless it has to be, > because that usually leads to trouble". Yes, but this is general attitude, and it says nothing definite about particular case - it can be that detailed analysis of this particular case will show reasons to make it global. > In this case, Token is actually the contents of an aggregate, part of > a larger statement that is dynamically allocated. It must be modified > in place; copying it to a global to pass it to this routine would be a > maintenance nightmare. I did not think about copying. I think that real question may be whether Parse conceptually deals with Token_List.List_Iterator or with the whole List_Iterator. In the latter case a global is generally possible without any copying. > And no, I don't consider "Ada doesn't allow 'in out' in functions" a > good reason to make something global; I'll change it to a procedure > first. Certainly. But there may be other reasons (originated from detailed design). Alexander Kopilovich aek@vib.usr.pu.ru Saint-Petersburg Russia ^ permalink raw reply [flat|nested] 90+ messages in thread
[parent not found: <bRecOT0TxF@VB1162.spb.edu>]
* Re: Reprise: 'in out' parameters for functions [not found] ` <bRecOT0TxF@VB1162.spb.edu> @ 2004-04-08 23:46 ` Stephen Leake 2004-04-09 9:23 ` Florian Weimer 2004-04-09 13:12 ` Wojtek Narczynski 0 siblings, 2 replies; 90+ messages in thread From: Stephen Leake @ 2004-04-08 23:46 UTC (permalink / raw) To: comp.lang.ada "Alexander E. Kopilovich" <aek@VB1162.spb.edu> writes: > Stephen Leake wrote: > > > > > This is what I wanted to declare: > > > > > > > > function Parse > > > > (Error_Label : in String; > > > > Token : in out Token_List.List_Iterator) > > > > return String; > > > > -- Process Token, which should contain '([Config_File =>] <string>)'. > > > > -- Return the string. > > > > -- Delete parsed tokens from Token. > > > > > > > One thing is missing in this your explanation: why exactly you don't want to > > > make that List_Iterator global (instead of passing it as IN OUT argument) ? > > In this case, Token is actually the contents of an aggregate, part of > > a larger statement that is dynamically allocated. It must be modified > > in place; copying it to a global to pass it to this routine would be a > > maintenance nightmare. > > I did not think about copying. I think that real question may be whether > Parse conceptually deals with Token_List.List_Iterator or with the whole > List_Iterator. In the latter case a global is generally possible without any > copying. Yes, there are times when globals are appropriate. No, this is not one of those times. You'll just have to take my word for it. Ada has a wart. Let's admit it, and move on. -- -- Stephe ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-08 23:46 ` Stephen Leake @ 2004-04-09 9:23 ` Florian Weimer 2004-04-09 10:04 ` Dmitry A. Kazakov ` (2 more replies) 2004-04-09 13:12 ` Wojtek Narczynski 1 sibling, 3 replies; 90+ messages in thread From: Florian Weimer @ 2004-04-09 9:23 UTC (permalink / raw) Stephen Leake <stephen_leake@acm.org> writes: > Ada has a wart. Let's admit it, and move on. Can't we fix that one without breaking backwards compatibility? Or are politics involved? -- Current mail filters: many dial-up/DSL/cable modem hosts, and the following domains: postino.it, tiscali.co.uk, tiscali.cz, tiscali.it, voila.fr. ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-09 9:23 ` Florian Weimer @ 2004-04-09 10:04 ` Dmitry A. Kazakov 2004-04-09 11:23 ` Martin Krischik 2004-04-09 22:47 ` Florian Weimer 2004-04-09 11:27 ` Stephen Leake 2004-04-09 22:46 ` Randy Brukardt 2 siblings, 2 replies; 90+ messages in thread From: Dmitry A. Kazakov @ 2004-04-09 10:04 UTC (permalink / raw) Florian Weimer wrote: > Stephen Leake <stephen_leake@acm.org> writes: > >> Ada has a wart. Let's admit it, and move on. > > Can't we fix that one without breaking backwards compatibility? procedure Has_A_Result (...) return Result; > Or are politics involved? I think so. But there also is the problem of evaluation order, though simply ignored for access parameters of functions. -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-09 10:04 ` Dmitry A. Kazakov @ 2004-04-09 11:23 ` Martin Krischik 2004-04-09 12:44 ` Dmitry A. Kazakov 2004-04-09 22:47 ` Florian Weimer 1 sibling, 1 reply; 90+ messages in thread From: Martin Krischik @ 2004-04-09 11:23 UTC (permalink / raw) Dmitry A. Kazakov wrote: > Florian Weimer wrote: > >> Stephen Leake <stephen_leake@acm.org> writes: >> >>> Ada has a wart. Let's admit it, and move on. >> >> Can't we fix that one without breaking backwards compatibility? > > procedure Has_A_Result (...) return Result; This solution would call for precise documentation (advantages, disadvantages) etc. pp. Plus a quick summary ("functions are faster") for the beginner. Otherwise the same problems as with "access all" will arise. Many programers use "access all" all the time - even when not needed, ignoring the diadvantages. >> Or are politics involved? > > I think so. But there also is the problem of evaluation order, though > simply ignored for access parameters of functions. See above. Have you heard of GNATs "pragma Pure_Function"? Prehaps making function even more restive plus procedures with return plus a "functions are faster" statement might do the trick. With Regards Martin -- mailto://krischik@users.sourceforge.net http://www.ada.krischik.com ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-09 11:23 ` Martin Krischik @ 2004-04-09 12:44 ` Dmitry A. Kazakov 2004-04-09 22:48 ` Randy Brukardt 0 siblings, 1 reply; 90+ messages in thread From: Dmitry A. Kazakov @ 2004-04-09 12:44 UTC (permalink / raw) Martin Krischik wrote: > Dmitry A. Kazakov wrote: > >> Florian Weimer wrote: >> >>> Stephen Leake <stephen_leake@acm.org> writes: >>> >>>> Ada has a wart. Let's admit it, and move on. >>> >>> Can't we fix that one without breaking backwards compatibility? >> >> procedure Has_A_Result (...) return Result; > > This solution would call for precise documentation (advantages, > disadvantages) etc. pp. Plus a quick summary ("functions are faster") for > the beginner. > > Otherwise the same problems as with "access all" will arise. Many > programers use "access all" all the time - even when not needed, ignoring > the diadvantages. This is very true. And there is also a nasty problem with specific access types for beginners: type Root is tagged ...; type Handle is access Root'Class; type Derived is new Root with ...; type Derived_Ptr is access Derived; function Factory return Handle is Ptr : Derived_Ptr := new Derived; begin Prepare (Ptr.all); return Handle (Ptr); -- Error! end Factory; Should cast: function Factory return Handle is Ptr : Handle := new Derived; begin Prepare (Derived (Ptr.all)); return Ptr; end Factory; >>> Or are politics involved? >> >> I think so. But there also is the problem of evaluation order, though >> simply ignored for access parameters of functions. > > See above. Have you heard of GNATs "pragma Pure_Function"? Yes, it is a very good thing. I'd like to see it in the standard and moreover not as a pragma, but as a part of the syntax (in the contract). It could be very useful, for example, to declare an abstract function as pure, to force any implementation to conform. Even more useful would be to allow pure functions in static expressions. The compiler could get an advantage from knowing that a function is pure: while Match (Pattern ("..."), Standard_Input) loop ... -- Pattern is pure, so the result is a constant end loop; > Prehaps making function even more restive plus procedures with return plus > a "functions are faster" statement might do the trick. I think that one should also either 1) fix evaluation order for non-pure functions and procedures with results or, better, but backward incompatible, 2) disallow them where the order is not fixed. -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-09 12:44 ` Dmitry A. Kazakov @ 2004-04-09 22:48 ` Randy Brukardt 2004-04-14 14:40 ` Robert I. Eachus 0 siblings, 1 reply; 90+ messages in thread From: Randy Brukardt @ 2004-04-09 22:48 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message news:c565si$2qlp6q$1@ID-77047.news.uni-berlin.de... > Martin Krischik wrote: > > See above. Have you heard of GNATs "pragma Pure_Function"? > > Yes, it is a very good thing. I'd like to see it in the standard and > moreover not as a pragma, but as a part of the syntax (in the contract). It > could be very useful, for example, to declare an abstract function as pure, > to force any implementation to conform. Even more useful would be to allow > pure functions in static expressions. The compiler could get an advantage > from knowing that a function is pure: I agree with all of this too. Also not going to happen. See AI-290, also voted "No Action". Randy. ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-09 22:48 ` Randy Brukardt @ 2004-04-14 14:40 ` Robert I. Eachus 2004-04-14 21:20 ` Randy Brukardt 0 siblings, 1 reply; 90+ messages in thread From: Robert I. Eachus @ 2004-04-14 14:40 UTC (permalink / raw) Randy Brukardt wrote: > I agree with all of this too. Also not going to happen. See AI-290, also > voted "No Action". On pragma Pure and static expressions, I think that you (Randy) are being a little premature. It may come up again for Ada 1Z. AI-290 is about pragma Pure_Function. Of course, I think that in out for functions is never going to happen. (The idea of making 'Access implicit in some contexts is interesting, and may end up allowing the reality without changing the rule.) If you want in out parameters for functions, use GNAT and modify it, or use the existing GNAT value returning proceedure pragma. -- Robert I. Eachus "The terrorist enemy holds no territory, defends no population, is unconstrained by rules of warfare, and respects no law of morality. Such an enemy cannot be deterred, contained, appeased or negotiated with. It can only be destroyed--and that, ladies and gentlemen, is the business at hand." -- Dick Cheney ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-14 14:40 ` Robert I. Eachus @ 2004-04-14 21:20 ` Randy Brukardt 0 siblings, 0 replies; 90+ messages in thread From: Randy Brukardt @ 2004-04-14 21:20 UTC (permalink / raw) "Robert I. Eachus" <rieachus@comcast.net> wrote in message news:kf2dnS2GIr_00ODdRVn-hA@comcast.com... > Randy Brukardt wrote: > > > I agree with all of this too. Also not going to happen. See AI-290, also > > voted "No Action". > > On pragma Pure and static expressions, I think that you (Randy) are > being a little premature. It may come up again for Ada 1Z. AI-290 is > about pragma Pure_Function. Well, I'm not considering what may or may not happen in Ada 1Z. If it has the same ground rules as Ada 0Y has, then "not going to happen" is probably accurate. But, in any case, in a business that moves as fast as the computer business, the difference between "not sooner than 12-15 years from now" and "not going to happen" is not particularly interesting. Randy. ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-09 10:04 ` Dmitry A. Kazakov 2004-04-09 11:23 ` Martin Krischik @ 2004-04-09 22:47 ` Florian Weimer 2004-04-10 10:49 ` Dmitry A. Kazakov 1 sibling, 1 reply; 90+ messages in thread From: Florian Weimer @ 2004-04-09 22:47 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > > Can't we fix that one without breaking backwards compatibility? > > procedure Has_A_Result (...) return Result; Well, this is solution is obviously quite bad because "procedure" and "function" are now almost (but not quite) interchangeable. > > Or are politics involved? > > I think so. But there also is the problem of evaluation order, > though simply ignored for access parameters of functions. Does making parameters "in out" really make things considerably worse? -- Current mail filters: many dial-up/DSL/cable modem hosts, and the following domains: postino.it, tiscali.co.uk, tiscali.cz, tiscali.it, voila.fr. ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-09 22:47 ` Florian Weimer @ 2004-04-10 10:49 ` Dmitry A. Kazakov 2004-04-10 11:11 ` Florian Weimer 0 siblings, 1 reply; 90+ messages in thread From: Dmitry A. Kazakov @ 2004-04-10 10:49 UTC (permalink / raw) Florian Weimer wrote: > "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > >> > Can't we fix that one without breaking backwards compatibility? >> >> procedure Has_A_Result (...) return Result; > > Well, this is solution is obviously quite bad because "procedure" and > "function" are now almost (but not quite) interchangeable. Isn't an access parameter almost interchangeable with an "in out" parameter? The word "procedure" tells that there are many results. "Return" tells that among them there is one dedicated. >> > Or are politics involved? >> >> I think so. But there also is the problem of evaluation order, >> though simply ignored for access parameters of functions. > > Does making parameters "in out" really make things considerably worse? Let me use your argument: what would be the difference between "function" and "procedure" then? -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-10 10:49 ` Dmitry A. Kazakov @ 2004-04-10 11:11 ` Florian Weimer 2004-04-10 13:26 ` Dmitry A. Kazakov 0 siblings, 1 reply; 90+ messages in thread From: Florian Weimer @ 2004-04-10 11:11 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > > Well, this is solution is obviously quite bad because "procedure" and > > "function" are now almost (but not quite) interchangeable. > > Isn't an access parameter almost interchangeable with an "in out" > parameter? No, it isn't. You can't obtain an access value for most objects. > Let me use your argument: what would be the difference between "function" > and "procedure" then? Its use. A procedure call is a statement, a function call is a name (and thus part of an expression). -- Current mail filters: many dial-up/DSL/cable modem hosts, and the following domains: postino.it, tiscali.co.uk, tiscali.cz, tiscali.it, voila.fr. ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-10 11:11 ` Florian Weimer @ 2004-04-10 13:26 ` Dmitry A. Kazakov 2004-04-10 20:50 ` Georg Bauhaus 0 siblings, 1 reply; 90+ messages in thread From: Dmitry A. Kazakov @ 2004-04-10 13:26 UTC (permalink / raw) Florian Weimer wrote: > "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > >> > Well, this is solution is obviously quite bad because "procedure" and >> > "function" are now almost (but not quite) interchangeable. >> >> Isn't an access parameter almost interchangeable with an "in out" >> parameter? > > No, it isn't. You can't obtain an access value for most objects. So what? The only reasonable use of an access parameter is to have "in out" where it is not allowed. [I do not count circumventing by-copy parameter passing for reasonable] >> Let me use your argument: what would be the difference between "function" >> and "procedure" then? > > Its use. A procedure call is a statement, a function call is a name > (and thus part of an expression). Expression is a part of a statement, so I see as much difference as between + and "+". -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-10 13:26 ` Dmitry A. Kazakov @ 2004-04-10 20:50 ` Georg Bauhaus 2004-04-11 10:31 ` Dmitry A. Kazakov 0 siblings, 1 reply; 90+ messages in thread From: Georg Bauhaus @ 2004-04-10 20:50 UTC (permalink / raw) Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote: : The only reasonable use of an access parameter is to have "in out" : where it is not allowed. Access parameters go well with access discriminants...? ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-10 20:50 ` Georg Bauhaus @ 2004-04-11 10:31 ` Dmitry A. Kazakov 0 siblings, 0 replies; 90+ messages in thread From: Dmitry A. Kazakov @ 2004-04-11 10:31 UTC (permalink / raw) Georg Bauhaus wrote: > Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote: > > : The only reasonable use of an access parameter is to have "in out" > : where it is not allowed. > > Access parameters go well with access discriminants...? Yes, but 1) .all works fine. If that is too much to type one could make access types more transparent. 2) why don't we have discriminants of any type? In many cases discriminants are used just because of absence of MI. -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-09 9:23 ` Florian Weimer 2004-04-09 10:04 ` Dmitry A. Kazakov @ 2004-04-09 11:27 ` Stephen Leake 2004-04-09 22:46 ` Randy Brukardt 2 siblings, 0 replies; 90+ messages in thread From: Stephen Leake @ 2004-04-09 11:27 UTC (permalink / raw) To: comp.lang.ada Florian Weimer <fw@deneb.enyo.de> writes: > Stephen Leake <stephen_leake@acm.org> writes: > > > Ada has a wart. Let's admit it, and move on. > > Can't we fix that one without breaking backwards compatibility? We could; simply permit 'in out' in functions. > Or are politics involved? Yes. There are some people (members of the ARG included) who don't want 'in out' in functions. I have only talked seriously with one person who holds that view (Rod Chapman, at the last SigAda). I can't really do justice to his view here, so I won't try, but it was based on serious considerations. I had the impression that if I spent enough time, I could convince him to change. On the other hand, he may have had the same impression about me :). As Robert Dewar says, there are no new arguments here, so there is no reason to reopen the discussion. I was just venting :). -- -- Stephe ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-09 9:23 ` Florian Weimer 2004-04-09 10:04 ` Dmitry A. Kazakov 2004-04-09 11:27 ` Stephen Leake @ 2004-04-09 22:46 ` Randy Brukardt 2 siblings, 0 replies; 90+ messages in thread From: Randy Brukardt @ 2004-04-09 22:46 UTC (permalink / raw) "Florian Weimer" <fw@deneb.enyo.de> wrote in message news:87brm1pksa.fsf@deneb.enyo.de... > Stephen Leake <stephen_leake@acm.org> writes: > > > Ada has a wart. Let's admit it, and move on. > > Can't we fix that one without breaking backwards compatibility? Or > are politics involved? Sure. But there is no will. So it won't be fixed. (See AI-323, voted "No Action"). Randy. ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-08 23:46 ` Stephen Leake 2004-04-09 9:23 ` Florian Weimer @ 2004-04-09 13:12 ` Wojtek Narczynski 2004-04-09 15:48 ` Expressing physical units (Was: Reprise: 'in out' parameters for functions) Jacob Sparre Andersen ` (2 more replies) 1 sibling, 3 replies; 90+ messages in thread From: Wojtek Narczynski @ 2004-04-09 13:12 UTC (permalink / raw) Hello, > Ada has a wart. Let's admit it, and move on. Several warts. For example, abstraction inversion (just look at ACT PolyOrb code, or try to implement tree crabbing), type system unable to express physical units, very limited standard library (compare it to say CM3 Modula, or Java). But the problem real problem IMO is that the development of the language has stagnated. Regards, Wojtek ^ permalink raw reply [flat|nested] 90+ messages in thread
* Expressing physical units (Was: Reprise: 'in out' parameters for functions) 2004-04-09 13:12 ` Wojtek Narczynski @ 2004-04-09 15:48 ` Jacob Sparre Andersen 2004-04-10 13:07 ` Wojtek Narczynski 2004-04-09 16:17 ` Reprise: 'in out' parameters for functions Georg Bauhaus 2004-04-09 17:09 ` Pascal Obry 2 siblings, 1 reply; 90+ messages in thread From: Jacob Sparre Andersen @ 2004-04-09 15:48 UTC (permalink / raw) Wojtek Narczynski wrote: > Several warts. For example, [...] type system unable to express > physical units, [...]. The type system is not _unable_ to express physical units. It just has some limitations in how you can do it. And although I am annoyed by the limitations, I still haven't seen a description of how the language can make it easier, without introducing problems outweighing the benefits [1]. > But the problem real problem IMO is that the development of the > language has stagnated. What to one programmer appears as stagnation, appears as stability to another programmer. IMO change is grossly overrated. It is fine to use GNAT to do experiments with possible changes to Ada. And it is also fine to merge the experiments with sensible results into the standard, but I don't want to have to reread the LRM every six month. In general, change means cost (learning and tools). If the cost isn't exceeded by the benefits, then the change is bad. Jacob [1] I have tried to formulate such a modification to Ada myself, but ended up with something that appeared to be (provably) impossible to compile. -- "Computer Science is to Science, as Plumbing is to Hydrodynamics" ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions) 2004-04-09 15:48 ` Expressing physical units (Was: Reprise: 'in out' parameters for functions) Jacob Sparre Andersen @ 2004-04-10 13:07 ` Wojtek Narczynski 2004-04-10 13:52 ` Jacob Sparre Andersen 0 siblings, 1 reply; 90+ messages in thread From: Wojtek Narczynski @ 2004-04-10 13:07 UTC (permalink / raw) Jacob, > The type system is not _unable_ to express physical units. It just > has some limitations in how you can do it. It depends on how exactly you phrase out the task. If you define it as having a static check on physical units, I believe Ada type system is not able to do this. You are left with paper and pencil. > And although I am annoyed by the limitations, I still haven't seen > a description of how the language can make it easier, without introducing > problems outweighing the benefits. I have tried to formulate such > a modification to Ada myself, but ended up with something that appeared > to be (provably) impossible to compile. (I converged your note here) I find this subject fascinating. I remember matchcad doing units check for me 10 years ago when I was in secondary school, yet I have not seen any compiler capable of doing the same. I was thinking that a term rewriting system for partial evaluation of the program would do the job. Or maybe are there problems with modularization? Could you point me at your results, if they are public? >> But the problem real problem IMO is that the development of the >> language has stagnated. > > What to one programmer appears as stagnation, appears as stability > to another programmer. Point taken. > It is fine to use GNAT to do experiments with possible changes to > Ada. I was trying, but it turned out that I am not smart enough. The codebase is just too large for me to comprehend. For example the (in)famous 'in out' for functions. I really have no idea where to look at in those megabytes. I had hoped that maybe GPS as a code comprehension aid, would help, but GNAT seems to be too large for GPS, which I find a bit ironic. Regards, Wojtek ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions) 2004-04-10 13:07 ` Wojtek Narczynski @ 2004-04-10 13:52 ` Jacob Sparre Andersen 2004-04-11 2:45 ` Hyman Rosen 2004-04-13 9:53 ` Wojtek Narczynski 0 siblings, 2 replies; 90+ messages in thread From: Jacob Sparre Andersen @ 2004-04-10 13:52 UTC (permalink / raw) Wojtek Narczynski wrote: > Jacob Sparre Andersen wrote: > > The type system is not _unable_ to express physical units. It > > just has some limitations in how you can do it. > > It depends on how exactly you phrase out the task. If you define it > as having a static check on physical units, I believe Ada type > system is not able to do this. You are left with paper and pencil. One of my programs disagrees somewhat with your statement. I switched from run-time to compile-time checking of unit mismatches, when a recent version of Macks made it practical to start using compile-time checks. It is though correct that physical units are not a specific Ada type, but rather have to be implemented using the basic type system. With a tool like Macks, it is reasonably fast to implement the necessary types for compile-time checking of unit mismatch. Before Macks matured sufficiently, I either used run-time checks or hand-coded the types I needed. > > And although I am annoyed by the limitations, I still haven't seen > > a description of how the language can make it easier, without > > introducing problems outweighing the benefits. I have tried to > > formulate such a modification to Ada myself, but ended up with > > something that appeared to be (provably) impossible to compile. > > (I converged your note here) > > I find this subject fascinating. I remember matchcad doing units > check for me 10 years ago when I was in secondary school, yet I have > not seen any compiler capable of doing the same. I was thinking that > a term rewriting system for partial evaluation of the program would > do the job. Or maybe are there problems with modularization? Could > you point me at your results, if they are public? They are unfortunately not published (and they are written in Danish). Also, I stopped once _I_ was certain it couldn't be done, so I never wrote down a complete proof, but just enough to convince a colleague. It should be noted that my analysis was tied rather strongly to Ada, and a more relaxed programming language might be able to do something that would be sufficiently close to full compile-time unit checking. Are you sure that "matchcad" actually did full compile-time unit checking? Jacob -- �USA fights for the right of the individual.� �Yes. Those of the individual George W. Bush.� -- with thanks to Olfax ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions) 2004-04-10 13:52 ` Jacob Sparre Andersen @ 2004-04-11 2:45 ` Hyman Rosen 2004-04-11 10:14 ` Expressing physical units Jacob Sparre Andersen 2004-04-12 6:58 ` Expressing physical units (Was: Reprise: 'in out' parameters for functions) Russ 2004-04-13 9:53 ` Wojtek Narczynski 1 sibling, 2 replies; 90+ messages in thread From: Hyman Rosen @ 2004-04-11 2:45 UTC (permalink / raw) Jacob Sparre Andersen wrote: > It should be noted that my analysis was tied rather strongly to Ada, > and a more relaxed programming language might be able to do something > that would be sufficiently close to full compile-time unit checking. C++ can do full compile-time unit checking with no runtime overhead as long as all units needed by the program are known at compile-time. The technique uses templates, requires automatic instantiation of templates for usability (and so cannot be done in Ada), and was published in Barton & Nackman, _Scientific and Engineering C++_. I've often posted the technique, but here goes again, in a simplified version: template <int Mass, int Distance, int Time> struct Unit { double value; Unit(double value = 0.0) : value(value) { } Unit operator+(Unit other) { return Unit(value + other.value); } }; template <int M1, int D1, int T1, int M2, int D2, int T2> Unit<M1+M2,D1+D2,T1+T2> operator*(Unit<M1,D1,T1> l, Unit<M2,D2,T2> r) { return Unit<M1+M2,D1+D2,T1+T2>(l.value * r.value); } This supports positive and negative whole number powers. For those rare applications which require fractional powers, you can move to using pairs of numerator/denominator template parameters to represent fractions. The full implementation will include the other operators, and may have the value type as a template parameter as well, but this is enough of a guide to see how it works. Here's how you might write the output operator: template <typename OStream, int M, int D, int T> Ostream &operator<<(Ostream &o, const Unit<M, D, T> &v) { o << v.value; if (M > 0) o << " g"; if (M > 1) o << "^" << M; if (D > 0) o << " cm"; if (D > 1) o << "^" << D; if (T > 0) o << " s"; if (T > 1) o << "^" << T; if (M < 0 || D < 0 || T < 0) o << " /"; if (M < 0) o << " g"; if (M < 1) o << "^" << -M; if (D < 0) o << " cm"; if (D < 1) o << "^" << -D; if (T < 0) o << " s"; if (T < 1) o << "^" << -T; return o; } Because M, D, T are template parameters, their values are all known at compile time, and the output routine instantiated for a particular unit will contain only the code needed, without any tests at runtime. ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Expressing physical units 2004-04-11 2:45 ` Hyman Rosen @ 2004-04-11 10:14 ` Jacob Sparre Andersen 2004-04-11 16:05 ` Hyman Rosen 2004-04-12 6:58 ` Expressing physical units (Was: Reprise: 'in out' parameters for functions) Russ 1 sibling, 1 reply; 90+ messages in thread From: Jacob Sparre Andersen @ 2004-04-11 10:14 UTC (permalink / raw) Hyman Rosen wrote: > Jacob Sparre Andersen wrote: > > It should be noted that my analysis was tied rather strongly to > > Ada, and a more relaxed programming language might be able to do > > something that would be sufficiently close to full compile-time > > unit checking. > > C++ can do full compile-time unit checking with no runtime overhead > as long as all units needed by the program are known at > compile-time. Yes. I am aware of that. - And that it is a much more elegant solution than the one I use do to do the same thing in Ada (in Ada you actually have to specify _each_ of the units you are going to use explicitly). > The technique uses templates, requires automatic instantiation of > templates for usability (and so cannot be done in Ada), Yes. I don't understand C++ templates well enough to be able to see if it is realistic to copy enough of it to Ada, to allow the easier handling of compile-time unit checking available in C++. I am afraid it would give too many unwanted possibilities in Ada, but it is very tempting. > and was published in Barton & Nackman, _Scientific and Engineering > C++_. I've often posted the technique, but here goes again, in a > simplified version: [...] Thanks. Jacob -- �USA fights for the right of the individual.� �Yes. Those of the individual George W. Bush.� -- with thanks to Olfax ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Expressing physical units 2004-04-11 10:14 ` Expressing physical units Jacob Sparre Andersen @ 2004-04-11 16:05 ` Hyman Rosen 0 siblings, 0 replies; 90+ messages in thread From: Hyman Rosen @ 2004-04-11 16:05 UTC (permalink / raw) Jacob Sparre Andersen wrote: > I don't understand C++ templates well enough to be able to see if it > is realistic to copy enough of it to Ada, to allow the easier handling > of compile-time unit checking available in C++. I am afraid it would > give too many unwanted possibilities in Ada, but it is very tempting. The main problem with adopting this feature in Ada is Ada's lack of automatic instantiation of generics. This arises in the multiplicative operators. If you look at how I wrote operator*, you'll see that it synthesizes a return type by adding the corresponding template parameters of the operands. In use, you simply multiply a pair of units together and the result has the correct type and can participate in further operations. The MACKS package that people talk about here uses the same techniques to represent units without overhead, but it does a whole bunch of explicit instantiations to make them ready for use. If it happens to miss some needed versions, it needs to be reconfigured to generate them. ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions) 2004-04-11 2:45 ` Hyman Rosen 2004-04-11 10:14 ` Expressing physical units Jacob Sparre Andersen @ 2004-04-12 6:58 ` Russ 2004-04-12 10:29 ` Dmitry A. Kazakov 1 sibling, 1 reply; 90+ messages in thread From: Russ @ 2004-04-12 6:58 UTC (permalink / raw) Hyman Rosen <hyrosen@mail.com> wrote in message news:<ij2ec.22694$1y1.20221@nwrdny03.gnilink.net>... > Jacob Sparre Andersen wrote: > > It should be noted that my analysis was tied rather strongly to Ada, > > and a more relaxed programming language might be able to do something > > that would be sufficiently close to full compile-time unit checking. > > C++ can do full compile-time unit checking with no runtime overhead > as long as all units needed by the program are known at compile-time. > The technique uses templates, requires automatic instantiation of > templates for usability (and so cannot be done in Ada), and was published > in Barton & Nackman, _Scientific and Engineering C++_. I've often posted > the technique, but here goes again, in a simplified version: Just for my own education, would you mind explaining why it cannot be done in a usable way in Ada? Is it because you need a sizable chunk of instantiation code at the top of each source file that is to use it? If so, isn't there some trick to get around it? By the way, I work in the field of air traffic management (ATM), and I'd really like to see a practical way to guarantee units consistency. The general mks system is inappropriate for ATM. The traditional units for ATM are nautical miles (nmi) for horizontal length, and feet (ft) for altitude. That won't change in our lifetimes -- and probably never. As for time, it can be in seconds, minutes, or hours. Horizontal speed in usually given in terms of knots (kn), which is nmi/hr, but altitude rate is usually given in terms of ft/min. Heading is normally given in degrees. In my experience, the most common units problem is confusion between degrees and radians. Radians are preferable for use inside programs, but degrees are preferable for I/O. This problem really needs to be licked once and for all. The next most common problem I find is that altitude is alternately expressed in terms of ft, hundreds of ft, or thousands of feet. Standard "Flight Levels" are at multiples of 1000 ft, but they are expressed in units of 100 ft. For example, "FL310" is a pressure altitude of 31,000 ft. If a practical way could be developed to deal with these basic units, and perhaps a few others (such as weight), the integrity of ATM software could be enhanced considerably, I believe. I was working on a scheme a couple of years ago involving the standard Ada type system, but I was (and still am) an Ada programming newbie. I think it would have worked reasonably well, but who am I to say? In any case, my friggin' hard drive died and I didn't have that particular work backed up, so its gone. ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions) 2004-04-12 6:58 ` Expressing physical units (Was: Reprise: 'in out' parameters for functions) Russ @ 2004-04-12 10:29 ` Dmitry A. Kazakov 2004-04-13 6:52 ` Russ 0 siblings, 1 reply; 90+ messages in thread From: Dmitry A. Kazakov @ 2004-04-12 10:29 UTC (permalink / raw) Russ wrote: > By the way, I work in the field of air traffic management (ATM), and > I'd really like to see a practical way to guarantee units consistency. > The general mks system is inappropriate for ATM. The traditional units > for ATM are nautical miles (nmi) for horizontal length, and feet (ft) > for altitude. That won't change in our lifetimes -- and probably > never. As for time, it can be in seconds, minutes, or hours. > Horizontal speed in usually given in terms of knots (kn), which is > nmi/hr, but altitude rate is usually given in terms of ft/min. Heading > is normally given in degrees. > > In my experience, the most common units problem is confusion between > degrees and radians. Radians are preferable for use inside programs, > but degrees are preferable for I/O. This problem really needs to be > licked once and for all. It does not differ from [m] vs. [ft]. The dimension of radian is [1] = m**0*A**0*s**0... The dimension of degree is [Pi/180]. No magic here. More difficult is Celsius degree vs. K, which AFAIK cannot be solved using C++ templates. > The next most common problem I find is that > altitude is alternately expressed in terms of ft, hundreds of ft, or > thousands of feet. Standard "Flight Levels" are at multiples of 1000 > ft, but they are expressed in units of 100 ft. For example, "FL310" is > a pressure altitude of 31,000 ft. See above. -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions) 2004-04-12 10:29 ` Dmitry A. Kazakov @ 2004-04-13 6:52 ` Russ 2004-04-13 10:55 ` Dmitry A. Kazakov 0 siblings, 1 reply; 90+ messages in thread From: Russ @ 2004-04-13 6:52 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message news:<c5dr33$gkic$3@ID-77047.news.uni-berlin.de>... > Russ wrote: > > > By the way, I work in the field of air traffic management (ATM), and > > I'd really like to see a practical way to guarantee units consistency. > > The general mks system is inappropriate for ATM. The traditional units > > for ATM are nautical miles (nmi) for horizontal length, and feet (ft) > > for altitude. That won't change in our lifetimes -- and probably > > never. As for time, it can be in seconds, minutes, or hours. > > Horizontal speed in usually given in terms of knots (kn), which is > > nmi/hr, but altitude rate is usually given in terms of ft/min. Heading > > is normally given in degrees. > > > > In my experience, the most common units problem is confusion between > > degrees and radians. Radians are preferable for use inside programs, > > but degrees are preferable for I/O. This problem really needs to be > > licked once and for all. > > It does not differ from [m] vs. [ft]. The dimension of radian is [1] = > m**0*A**0*s**0... The dimension of degree is [Pi/180]. No magic here. More > difficult is Celsius degree vs. K, which AFAIK cannot be solved using C++ > templates. I know it can be done in C++, but I thought we were talking about doing it in Ada. By the way, what the heck is "m**0*A**0*s**0..."? > > The next most common problem I find is that > > altitude is alternately expressed in terms of ft, hundreds of ft, or > > thousands of feet. Standard "Flight Levels" are at multiples of 1000 > > ft, but they are expressed in units of 100 ft. For example, "FL310" is > > a pressure altitude of 31,000 ft. > > See above. ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions) 2004-04-13 6:52 ` Russ @ 2004-04-13 10:55 ` Dmitry A. Kazakov 2004-04-14 4:50 ` Hyman Rosen 2004-04-14 7:10 ` Russ 0 siblings, 2 replies; 90+ messages in thread From: Dmitry A. Kazakov @ 2004-04-13 10:55 UTC (permalink / raw) Russ wrote: > "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message > news:<c5dr33$gkic$3@ID-77047.news.uni-berlin.de>... >> Russ wrote: >> >> > By the way, I work in the field of air traffic management (ATM), and >> > I'd really like to see a practical way to guarantee units consistency. >> > The general mks system is inappropriate for ATM. The traditional units >> > for ATM are nautical miles (nmi) for horizontal length, and feet (ft) >> > for altitude. That won't change in our lifetimes -- and probably >> > never. As for time, it can be in seconds, minutes, or hours. >> > Horizontal speed in usually given in terms of knots (kn), which is >> > nmi/hr, but altitude rate is usually given in terms of ft/min. Heading >> > is normally given in degrees. >> > >> > In my experience, the most common units problem is confusion between >> > degrees and radians. Radians are preferable for use inside programs, >> > but degrees are preferable for I/O. This problem really needs to be >> > licked once and for all. >> >> It does not differ from [m] vs. [ft]. The dimension of radian is [1] = >> m**0*A**0*s**0... The dimension of degree is [Pi/180]. No magic here. >> More difficult is Celsius degree vs. K, which AFAIK cannot be solved >> using C++ templates. > > I know it can be done in C++, but I thought we were talking about doing it > in Ada. > > By the way, what the heck is "m**0*A**0*s**0..."? Any unit system is built upon some standard set of measures (base units). This set is pretty arbitrary from a physics point of view, but in SI it was selected to be m, A, s, kg, K, cd, mol. A dimension of any derived unit is then a product of powers of the base units. For example, the dimension of acceleration is m*s**(-2). When all powers are 0, we have a "dimensionless" unit, like radian is. Now to templates and C++. You are wrong thinking that units can be properly done in C++. What indeed can be, is a tiny part of what is really necessary. Consider the following issues: 1. Shifted units, like Celsius degree. 2. Dealing with units unknown at compile time. How would you communicate with a data base, or develop a gauge widget, or write a unit calculator? How to write a unit I/O package? 3. Dealing with multiple unit systems. The C++ solution actually works in SI. It means that a measure in [ft] has to be converted to [m]. It is OK as long as: 3.a. There is no range problems. In an emedded system one could use a fixed arithmetics with would overflow if the distance is measured in [m], but work fine for [km]. 3.b. One can ignore inevitable precission loss caused by unit conversions. This might be critical for some applications. 5. How to handle logarithmic units and other non-linear scales? 6. Container problem. Surely a vector, matrix etc of dimensioned values should have a dimension. Possibly it could be handled by templates, but I am afraid it would not be so easy. 7. Any generic (template) solution would make everything based upon it also generic. -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions) 2004-04-13 10:55 ` Dmitry A. Kazakov @ 2004-04-14 4:50 ` Hyman Rosen 2004-04-14 8:49 ` Dmitry A. Kazakov 2004-04-14 7:10 ` Russ 1 sibling, 1 reply; 90+ messages in thread From: Hyman Rosen @ 2004-04-14 4:50 UTC (permalink / raw) Dmitry A. Kazakov wrote: > 1. Shifted units, like Celsius degree. This can be done by adding an extra shift prameter. You would also need to describe the units system more thoroughly. The standard units can appear in positive or negative powers, but you obviously cannot do this with shifted units. > 2. Dealing with units unknown at compile time. How would you communicate > with a data base, or develop a gauge widget, or write a unit calculator? This requires a different solution. But that's OK. If many applications do not need this dynamic behavior, then they stand to benefit from the zero-overhead of the given solution. > How to write a unit I/O package? I demonstrated that in another post. You write a bunch of 'if' statements whose conditions depend on the template parameters, and they are all known at compile-time for a given unit. > 3. Dealing with multiple unit systems. You can add a scale factor template parameter for each dimension, and then they will be different types, so the compiler will prevent you from adding mm to cm, say. You can also code the conversions as templates. I suspect it's unwieldy and people would be just as happy to pick one unit system, but it could be done. > 5. How to handle logarithmic units and other non-linear scales? By specializing the templates for these units to do the appropriate operations. Ada does not have the concept of specialized templates, but C++ does. > 6. Container problem. Surely a vector, matrix etc of dimensioned values > should have a dimension. I don't see why, but that's certainly not a problem for C++. All of the standard container templates export the type of the object they hold as a named type called "value_type" so the units of the contained objects are available if needed. > 7. Any generic (template) solution would make everything based upon it also > generic. Modern C++ programmers see that as an opportunity, not a problem! ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions) 2004-04-14 4:50 ` Hyman Rosen @ 2004-04-14 8:49 ` Dmitry A. Kazakov 2004-04-14 16:49 ` Hyman Rosen 0 siblings, 1 reply; 90+ messages in thread From: Dmitry A. Kazakov @ 2004-04-14 8:49 UTC (permalink / raw) Hyman Rosen wrote: > Dmitry A. Kazakov wrote: >> 1. Shifted units, like Celsius degree. > > This can be done by adding an extra shift prameter. But C++ does not allow double as a template parameter. > You would also need > to describe the units system more thoroughly. The standard units can > appear in positive or negative powers, but you obviously cannot do this > with shifted units. Why? It is no matter. Shifted units represent linear scales: x = a * y + b The dimension of a and b may have any powers. >> 2. Dealing with units unknown at compile time. How would you communicate >> with a data base, or develop a gauge widget, or write a unit calculator? > > This requires a different solution. But that's OK. If many applications > do not need this dynamic behavior, then they stand to benefit from the > zero-overhead of the given solution. Because there can be a universal solution with zero-overhead in static case. >> How to write a unit I/O package? > > I demonstrated that in another post. You write a bunch of 'if' statements > whose conditions depend on the template parameters, and they are all known > at compile-time for a given unit. (:-)) >> 3. Dealing with multiple unit systems. > > You can add a scale factor template parameter for each dimension, and then > they will be different types, so the compiler will prevent you from adding > mm to cm, say. Not that is the problem. One can add 1 [mm] and 1 [cm], it is legal. The question is in which unit system the arguments are and the result will be. There could be a need to have both m,s,A,... and mm,h,kA,..., for reasons I explained before. >> 5. How to handle logarithmic units and other non-linear scales? > > By specializing the templates for these units to do the appropriate > operations. Ada does not have the concept of specialized templates, but > C++ does. I do not see how you could add x in meters of SI with y in ft of logarithmic scale using specialized templates. To represent scale you will probably need some pointer to the scale descriptor in your template. >> 7. Any generic (template) solution would make everything based upon it >> also generic. > > Modern C++ programmers see that as an opportunity, not a problem! I do not see any way of making a GUI or DB interface based on templates. Consider a distributed system with should have a communication protocol to exchange physical measures. How would you do it using templates? Consider a large finite element library. If that has to be used for physical values, then the whole library has to be generic. -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions) 2004-04-14 8:49 ` Dmitry A. Kazakov @ 2004-04-14 16:49 ` Hyman Rosen 2004-04-15 10:37 ` Dmitry A. Kazakov 0 siblings, 1 reply; 90+ messages in thread From: Hyman Rosen @ 2004-04-14 16:49 UTC (permalink / raw) Dmitry A. Kazakov wrote: > But C++ does not allow double as a template parameter. That's merely an implementation detail; you simply use a pair of integers to represent a fraction. > Why? It is no matter. Shifted units represent linear scales: > x = a * y + b > The dimension of a and b may have any powers. No matter? What is the meaning of multiplying degrees Celsius by degrees Farenheit, or squaring degrees Celsius? > Because there can be a universal solution with zero-overhead in static case. Zero overhead in space as well? I assume this is another one of those cases which will require object tags to live in the classwide pointers instead of in the objetcs themselves? > (:-)) Why is my unit output procedure funny? > Not that is the problem. One can add 1 [mm] and 1 [cm], it is legal. The > question is in which unit system the arguments are and the result will be. You need to guide the type of the result, since it could be either. So it's simpler to forbid the addition of differently scaled units, and require the user to convert one operand to the type of the other. Or, given that you're doing it in C++, it's easy to write traits templates that would represent rules for preferring one scale over another. > I do not see how you could add x in meters of SI with y in ft of logarithmic > scale using specialized templates. To represent scale you will probably > need some pointer to the scale descriptor in your template. You represent scale and logness as template parameters. Then you just need to be able to convert one type to another (and if we're talking about addition of log-scaled quantities, we have to convert out anyway) for addition, and to write a specialized multiplication routine that takes two log-scaled units and adds their values, for example. I doubt that anyone is going to build such a complicated system of units, but it could be done in principle. > I do not see any way of making a GUI or DB interface based on templates. > Consider a distributed system with should have a communication protocol to > exchange physical measures. How would you do it using templates? As I have already said, we are relying on knowing a fixed set of units within the program. Then the problem is no different than communicating any other fixed set of record types. > Consider a large finite element library. If that has to be used for > physical values, then the whole library has to be generic. So? ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions) 2004-04-14 16:49 ` Hyman Rosen @ 2004-04-15 10:37 ` Dmitry A. Kazakov 0 siblings, 0 replies; 90+ messages in thread From: Dmitry A. Kazakov @ 2004-04-15 10:37 UTC (permalink / raw) Hyman Rosen wrote: > Dmitry A. Kazakov wrote: >> But C++ does not allow double as a template parameter. > > That's merely an implementation detail; you simply use a > pair of integers to represent a fraction. Ooch. >> Why? It is no matter. Shifted units represent linear scales: >> x = a * y + b >> The dimension of a and b may have any powers. > > No matter? What is the meaning of multiplying degrees Celsius > by degrees Farenheit, It is ambigous. But you can multiply Kelvin by Kelvin. For example, heat flux has the dimension: m**2 * kg / K**3 > or squaring degrees Celsius? >> Because there can be a universal solution with zero-overhead in static >> case. > > Zero overhead in space as well? I assume this is another one of those > cases which will require object tags to live in the classwide pointers > instead of in the objetcs themselves? Right. The idea is to have the powers as a discriminant and unit arithmetics as pure routines. When the discriminant (unit) is statically known, it is removed and we have a full equivalent of the template solution. When it is unknown, we have run-time checks with space penalty. I belive it is a doable approch, which has an additional advantage, that this mechanism could be made available for all user types. >> (:-)) > > Why is my unit output procedure funny? It is still static and may no input counterpart. >> Not that is the problem. One can add 1 [mm] and 1 [cm], it is legal. The >> question is in which unit system the arguments are and the result will >> be. > > You need to guide the type of the result, since it could be either. > So it's simpler to forbid the addition of differently scaled units, > and require the user to convert one operand to the type of the other. This does not solve the problem. These conversions either explicit or implicit has to be done and thus checked. We have a geometrically exploding number of cross conversions. > Or, given that you're doing it in C++, it's easy to write traits > templates that would represent rules for preferring one scale over > another. Too uncontrollable. The choice depends on the target value, so one cannot say if lightyear is better than micrometer. >> I do not see how you could add x in meters of SI with y in ft of >> logarithmic scale using specialized templates. To represent scale you >> will probably need some pointer to the scale descriptor in your template. > > You represent scale and logness as template parameters. Then you just > need to be able to convert one type to another (and if we're talking > about addition of log-scaled quantities, we have to convert out anyway) > for addition, and to write a specialized multiplication routine that > takes two log-scaled units and adds their values, for example. You have to do it for each of seven powers, representing each parameter by a number of integers. I am afraid that the list of template arguments will be longer than the source code. To have enough RAM to compile it, you would need to made sand of all beaches into memory chips. And I am not sure if the compiler will finish before the Entropic Death (:-)) > I doubt that anyone is going to build such a complicated system of > units, but it could be done in principle. Yes, it is Turing complete. (:-)) >> I do not see any way of making a GUI or DB interface based on templates. >> Consider a distributed system with should have a communication protocol >> to exchange physical measures. How would you do it using templates? > > As I have already said, we are relying on knowing a fixed set of units > within the program. Then the problem is no different than communicating > any other fixed set of record types. The problem is that you cannot have one piece of code dealing with all units (though from a fixed set). You probably will be able to create a template for this code, but the number of variants will be far greater than any computer may hold. You need to instantiate all of them, because you do not know which of them will be used at tun time. And after all, who will be able to maintain this code? Finding an error in C++ template instantiations is a work requiring a lot of experience, much patience and great luck. And we want to give it engineers, who else needs units so much? Even in Ada dealing with generics imposes much more difficulties for a programmer than regular code. The price is to high. >> Consider a large finite element library. If that has to be used for > > physical values, then the whole library has to be generic. > > So? Absolutely unrealistic. -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions) 2004-04-13 10:55 ` Dmitry A. Kazakov 2004-04-14 4:50 ` Hyman Rosen @ 2004-04-14 7:10 ` Russ 2004-04-14 8:53 ` tmoran 2004-04-14 9:21 ` Dmitry A. Kazakov 1 sibling, 2 replies; 90+ messages in thread From: Russ @ 2004-04-14 7:10 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message news:<c5gh04$1ba02$1@ID-77047.news.uni-berlin.de>... > Russ wrote: > > > "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message > > news:<c5dr33$gkic$3@ID-77047.news.uni-berlin.de>... > >> Russ wrote: > >> > >> > By the way, I work in the field of air traffic management (ATM), and > >> > I'd really like to see a practical way to guarantee units consistency. > >> > The general mks system is inappropriate for ATM. The traditional units > >> > for ATM are nautical miles (nmi) for horizontal length, and feet (ft) > >> > for altitude. That won't change in our lifetimes -- and probably > >> > never. As for time, it can be in seconds, minutes, or hours. > >> > Horizontal speed in usually given in terms of knots (kn), which is > >> > nmi/hr, but altitude rate is usually given in terms of ft/min. Heading > >> > is normally given in degrees. > >> > > >> > In my experience, the most common units problem is confusion between > >> > degrees and radians. Radians are preferable for use inside programs, > >> > but degrees are preferable for I/O. This problem really needs to be > >> > licked once and for all. > Now to templates and C++. You are wrong thinking that units can be properly > done in C++. What indeed can be, is a tiny part of what is really > necessary. Consider the following issues: > > 1. Shifted units, like Celsius degree. > 2. Dealing with units unknown at compile time. How would you communicate > with a data base, or develop a gauge widget, or write a unit calculator? > How to write a unit I/O package? > 3. Dealing with multiple unit systems. The C++ solution actually works in > SI. It means that a measure in [ft] has to be converted to [m]. It is OK as > long as: > 3.a. There is no range problems. In an emedded system one could use a fixed > arithmetics with would overflow if the distance is measured in [m], but > work fine for [km]. > 3.b. One can ignore inevitable precission loss caused by unit conversions. > This might be critical for some applications. > 5. How to handle logarithmic units and other non-linear scales? > 6. Container problem. Surely a vector, matrix etc of dimensioned values > should have a dimension. Possibly it could be handled by templates, but I > am afraid it would not be so easy. > 7. Any generic (template) solution would make everything based upon it also > generic. You're talking about the Grand Unified system of units. That's fine, but I'm just talking about something that can make air traffic management (ATM) software more robust. As I wrote before, the most important units in ATM are few in number. Here is an outline of what I was working on in my free time before my hard drive died. You define a dozen or so Ada types for commonly used units, such as nmi (nautical miles) feet FL (flight level, or 100 ft) kft (1000 ft) deg rad (radian) knots fpm (feet per minute, for altitude rate) klb (1000 pounds) sec (second) minute hour and perhaps a few others. You then define operators for all the likely operations among these types. Each type can be added to or subtracted from its own type, for example. When you divide a type by the same type, you get a dimensionless number. Multiplication of like types is prohibited unless it really makes sense. If you divide nmi by hour, you get knots. If you divide nmi by sec, the compiler coughs and tells you that you can't do that -- so you go and convert the seconds to hours (using a predefined conversion function). You get the idea. As new units or combinations come up, you add them into the repertoire. Perhaps the total number of units and reasonable combinations would be managable. The idea here is not to have all units converted automagically but rather simply to have the compiler catch any potentially inconsistent use of units. The days of using degrees for radians, or dividing nmi by sec and adding it to knots, would be mercifully over. And no generics are needed. Is this a reasonable approach? ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions) 2004-04-14 7:10 ` Russ @ 2004-04-14 8:53 ` tmoran 2004-04-14 9:01 ` Vinzent 'Gadget' Hoefler 2004-04-14 9:21 ` Dmitry A. Kazakov 1 sibling, 1 reply; 90+ messages in thread From: tmoran @ 2004-04-14 8:53 UTC (permalink / raw) >example. When you divide a type by the same type, you get a >dimensionless number. Multiplication of like types is prohibited A "dimensionless number" still has a specific type so that alpha : degrees; x,y : feet; beta : radians := x/y+alpha; is illegal. So the type system does more than simply keep track of a set of exponents. >You then define operators for all the likely operations among these >types. Each type can be added to or subtracted from its own type, for See, for instance, chapter 2 of "Ada in Action" by Do-While Jones, ISBN 0-471-6078-8, Wiley, 1989 (also available on the internet but I don't have the URL). ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions) 2004-04-14 8:53 ` tmoran @ 2004-04-14 9:01 ` Vinzent 'Gadget' Hoefler 0 siblings, 0 replies; 90+ messages in thread From: Vinzent 'Gadget' Hoefler @ 2004-04-14 9:01 UTC (permalink / raw) tmoran@acm.org wrote: > See, for instance, chapter 2 of "Ada in Action" by Do-While Jones, >ISBN 0-471-6078-8, Wiley, 1989 (also available on the internet but I don't >have the URL). <URL:http://www.cs.kuleuven.ac.be/~dirk/ada-belgium/aia/> Vinzent. ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions) 2004-04-14 7:10 ` Russ 2004-04-14 8:53 ` tmoran @ 2004-04-14 9:21 ` Dmitry A. Kazakov 1 sibling, 0 replies; 90+ messages in thread From: Dmitry A. Kazakov @ 2004-04-14 9:21 UTC (permalink / raw) Russ wrote: > "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message > news:<c5gh04$1ba02$1@ID-77047.news.uni-berlin.de>... >> Russ wrote: >> >> > "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message >> > news:<c5dr33$gkic$3@ID-77047.news.uni-berlin.de>... >> >> Russ wrote: >> >> >> >> > By the way, I work in the field of air traffic management (ATM), and >> >> > I'd really like to see a practical way to guarantee units >> >> > consistency. The general mks system is inappropriate for ATM. The >> >> > traditional units for ATM are nautical miles (nmi) for horizontal >> >> > length, and feet (ft) for altitude. That won't change in our >> >> > lifetimes -- and probably never. As for time, it can be in seconds, >> >> > minutes, or hours. Horizontal speed in usually given in terms of >> >> > knots (kn), which is nmi/hr, but altitude rate is usually given in >> >> > terms of ft/min. Heading is normally given in degrees. >> >> > >> >> > In my experience, the most common units problem is confusion between >> >> > degrees and radians. Radians are preferable for use inside programs, >> >> > but degrees are preferable for I/O. This problem really needs to be >> >> > licked once and for all. > >> Now to templates and C++. You are wrong thinking that units can be >> properly done in C++. What indeed can be, is a tiny part of what is >> really necessary. Consider the following issues: >> >> 1. Shifted units, like Celsius degree. >> 2. Dealing with units unknown at compile time. How would you communicate >> with a data base, or develop a gauge widget, or write a unit calculator? >> How to write a unit I/O package? >> 3. Dealing with multiple unit systems. The C++ solution actually works in >> SI. It means that a measure in [ft] has to be converted to [m]. It is OK >> as long as: >> 3.a. There is no range problems. In an emedded system one could use a >> fixed arithmetics with would overflow if the distance is measured in [m], >> but work fine for [km]. >> 3.b. One can ignore inevitable precission loss caused by unit >> conversions. This might be critical for some applications. >> 5. How to handle logarithmic units and other non-linear scales? >> 6. Container problem. Surely a vector, matrix etc of dimensioned values >> should have a dimension. Possibly it could be handled by templates, but I >> am afraid it would not be so easy. >> 7. Any generic (template) solution would make everything based upon it >> also generic. > > You're talking about the Grand Unified system of units. Yes. > That's fine, > but I'm just talking about something that can make air traffic > management (ATM) software more robust. As I wrote before, the most > important units in ATM are few in number. AFAIK, ATM does not much differ from other MMI. For them run-time unit checking fits at best, because performance/space requirements are not that strict. Here is my implementation: http://www.dmitry-kazakov.de/ada/units.htm > Here is an outline of what I was working on in my free time before my > hard drive died. You define a dozen or so Ada types for commonly used > units, such as > > nmi (nautical miles) > feet > FL (flight level, or 100 ft) > kft (1000 ft) > deg > rad (radian) > knots > fpm (feet per minute, for altitude rate) > klb (1000 pounds) > sec (second) > minute > hour > > and perhaps a few others. You do not need that much of types. Internally you should work in SI units. The only place where units appear is MMI readings and controls. A usual way is to make widgets unit aware and tunable at run time. Here your problems end. The operator will use ft, m, km, lightyear, whatsoever. It is the widget property. The result will be always in the corresponding SI unit. > You then define operators for all the likely operations among these > types. Each type can be added to or subtracted from its own type, for > example. When you divide a type by the same type, you get a > dimensionless number. Multiplication of like types is prohibited > unless it really makes sense. If you divide nmi by hour, you get > knots. If you divide nmi by sec, the compiler coughs and tells you > that you can't do that -- so you go and convert the seconds to hours > (using a predefined conversion function). You get the idea. Yes, you are trying to keep several unit system separate. Like meter-second, knot-hour etc. I only do not see any reason why it should make any sense in your case. > As new units or combinations come up, you add them into the > repertoire. Perhaps the total number of units and reasonable > combinations would be managable. You want to manage a geometric explosion... > The idea here is not to have all units converted automagically but > rather simply to have the compiler catch any potentially inconsistent > use of units. Dividing miles by seconds has a clear physical sense. > The days of using degrees for radians, or dividing nmi > by sec and adding it to knots, would be mercifully over. > And no > generics are needed. > > Is this a reasonable approach? It is a possible approach, but I think that for your case run-time checks are more suitable (for MMI). Only if you have some additional safety requirements, explicitly stating that all formulae shall be statically checked, then you can additionally use a compile-time approach, see: http://home.T-Online.de/home/Christ-Usch.Grein/Ada/Dimension.html But in any case, you have to switch to SI. Then 80% of your problems will disappear. -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Expressing physical units (Was: Reprise: 'in out' parameters for functions) 2004-04-10 13:52 ` Jacob Sparre Andersen 2004-04-11 2:45 ` Hyman Rosen @ 2004-04-13 9:53 ` Wojtek Narczynski 2004-04-15 21:27 ` Expressing physical units Jacob Sparre Andersen 1 sibling, 1 reply; 90+ messages in thread From: Wojtek Narczynski @ 2004-04-13 9:53 UTC (permalink / raw) Jacob, > One of my programs disagrees somewhat with your statement. I switched > from run-time to compile-time checking of unit mismatches, when a > recent version of Macks made it practical to start using compile-time > checks. Macks is not Ada, okay? But I will take a closer look at how it works. > Are you sure that "matchcad" actually did full compile-time unit > checking? Hehe, I am sure that it did not. Regards, Wojtek ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Expressing physical units 2004-04-13 9:53 ` Wojtek Narczynski @ 2004-04-15 21:27 ` Jacob Sparre Andersen 2004-04-16 11:40 ` Dmitry A. Kazakov 0 siblings, 1 reply; 90+ messages in thread From: Jacob Sparre Andersen @ 2004-04-15 21:27 UTC (permalink / raw) Wojtek Narczynski wrote: > Macks is not Ada, okay? I am tempted to say that it is, but no, it is a tool that helps me write my Ada code for handling physical units. > But I will take a closer look at how it works. Do that. It still has some quirks, but it is a useful tool anyway. One thing you have too be aware of is that it can generate code according to more than one principle for handling physical units (at least in the version I have). Jacob -- "Then, after a second or so, nothing continued to happen." ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Expressing physical units 2004-04-15 21:27 ` Expressing physical units Jacob Sparre Andersen @ 2004-04-16 11:40 ` Dmitry A. Kazakov 0 siblings, 0 replies; 90+ messages in thread From: Dmitry A. Kazakov @ 2004-04-16 11:40 UTC (permalink / raw) Jacob Sparre Andersen wrote: > Wojtek Narczynski wrote: > >> Macks is not Ada, okay? > > I am tempted to say that it is, but no, it is a tool that helps me > write my Ada code for handling physical units. I would say that Macks is as Ada as generics are, or as templates are C++. In my view all of them constitute a kind of meta language. -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-09 13:12 ` Wojtek Narczynski 2004-04-09 15:48 ` Expressing physical units (Was: Reprise: 'in out' parameters for functions) Jacob Sparre Andersen @ 2004-04-09 16:17 ` Georg Bauhaus 2004-04-10 2:28 ` Wojtek Narczynski 2004-04-09 17:09 ` Pascal Obry 2 siblings, 1 reply; 90+ messages in thread From: Georg Bauhaus @ 2004-04-09 16:17 UTC (permalink / raw) Wojtek Narczynski <wojtek@power.com.pl> wrote: : Several warts. For example, abstraction inversion (just look at ACT : PolyOrb code, or try to implement tree crabbing), I take it Ada forces abstraction in version in cases? Could you name an example unit to look at? : type system unable : to express physical units, Still, you might have type Quantity is abstract tagged private; function in_meters (x: Quantity) return Units.meter; function in_yards (x: Quantity) return Units.yard; -- etc... : But the problem real problem IMO is that : the development of the language has stagnated. What's missing? ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-09 16:17 ` Reprise: 'in out' parameters for functions Georg Bauhaus @ 2004-04-10 2:28 ` Wojtek Narczynski 2004-04-10 9:46 ` Georg Bauhaus ` (3 more replies) 0 siblings, 4 replies; 90+ messages in thread From: Wojtek Narczynski @ 2004-04-10 2:28 UTC (permalink / raw) Hello, > I take it Ada forces abstraction in version in cases? > Could you name an example unit to look at? 'Inversion' not 'in version' incase it were more than a typo. When you implement a semaphore over a protected object, or in general when you need to lock / unlock by yourself. Classic example: polyorb-tasking-profiles-full_tasking-mutexes.adb Or try to implement tree crabbing. Hell, try to implement a list updateable concurrently from multiple tasks. You _will_ end up implementing a semaphore over a protected, over a semaphore. Or the simplest possible: two protected counters, try to get the sum atomically. > : type system unable > : to express physical units, > > Still, you might have > > type Quantity is abstract tagged private; > > function in_meters (x: Quantity) return Units.meter; > function in_yards (x: Quantity) return Units.yard; > -- etc... Sure, let us continue: function in_kilograms (x: Quantity) return Units.yard; -- Blows at runtime This just cannot be done right in Ada. > : But the problem real problem IMO is that > : the development of the language has stagnated. > > What's missing? From the language? For example parameters for exceptions. Regards, Wojtek ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-10 2:28 ` Wojtek Narczynski @ 2004-04-10 9:46 ` Georg Bauhaus 2004-04-10 10:49 ` Dmitry A. Kazakov ` (2 subsequent siblings) 3 siblings, 0 replies; 90+ messages in thread From: Georg Bauhaus @ 2004-04-10 9:46 UTC (permalink / raw) Wojtek Narczynski <wojtek@power.com.pl> wrote: : Hello, : :> I take it Ada forces abstraction in version in cases? :> Could you name an example unit to look at? : : 'Inversion' not 'in version' incase it were more than a typo. A typo, sorry. : When you : implement a semaphore over a protected object, or in general when you : need to lock / unlock by yourself. Classic example: : : polyorb-tasking-profiles-full_tasking-mutexes.adb Thanks. Given that mutex and semaphores have been known when Ada was made, I wonder whether there aren't some external forces at work which lead to the requirement of using tasking constructs below language level. Not Ada's fault from this perspective. Incidentally, there is some abstraction inversion criticism quoting Ada, mutex, and tasks. But has not been brought up to date where date refers to 1995. So there is another meaning of "classic". : function in_kilograms (x: Quantity) return Units.yard; : -- Blows at runtime I don't think so. How do you write an expression expecting Unis.kilogram, where the compiler sees a function returning Units.yard, such that the compiler does not reject? : This just cannot be done right in Ada. :> What's missing? : : From the language? For example parameters for exceptions. Not a good idea I think, though practical for use in quick and dirty fixes of design errors. Programm logic can be programmed. ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-10 2:28 ` Wojtek Narczynski 2004-04-10 9:46 ` Georg Bauhaus @ 2004-04-10 10:49 ` Dmitry A. Kazakov 2004-04-10 15:35 ` Wojtek Narczynski 2004-04-14 15:57 ` Robert I. Eachus 2004-04-10 12:32 ` Wojtek Narczynski 2004-04-14 15:46 ` Robert I. Eachus 3 siblings, 2 replies; 90+ messages in thread From: Dmitry A. Kazakov @ 2004-04-10 10:49 UTC (permalink / raw) Wojtek Narczynski wrote: >> I take it Ada forces abstraction in version in cases? >> Could you name an example unit to look at? > > 'Inversion' not 'in version' incase it were more than a typo. When you > implement a semaphore over a protected object, or in general when you > need to lock / unlock by yourself. Classic example: > > polyorb-tasking-profiles-full_tasking-mutexes.adb > > Or try to implement tree crabbing. Hell, try to implement a list > updateable concurrently from multiple tasks. You _will_ end up > implementing a semaphore over a protected, over a semaphore. > > Or the simplest possible: two protected counters, try to get the sum > atomically. This has nothing to do with abstraction inversion. The problem here is that Ada does not have multiple protected actions. Same problem with tasks, there cannot be rendezvous with multiple tasks. It is much work to solve that. Especially to convince people that prefix notation is inherently bad. >> : type system unable >> : to express physical units, >> >> Still, you might have >> >> type Quantity is abstract tagged private; >> >> function in_meters (x: Quantity) return Units.meter; >> function in_yards (x: Quantity) return Units.yard; >> -- etc... > > Sure, let us continue: > > function in_kilograms (x: Quantity) return Units.yard; > -- Blows at runtime > > This just cannot be done right in Ada. This is wrong: http://home.t-online.de/home/Christ-Usch.Grein/Ada/Dimension.html The type system is capable to express dimensioned units. The major problem here is not the type system, but inability to get rid of statically known discriminants, which makes an implementation inefficient. >> : But the problem real problem IMO is that >> : the development of the language has stagnated. >> >> What's missing? > > From the language? For example parameters for exceptions. How they could have parameters? There are only two ways for dealing with exceptions. Either 1) all of them are of one [specific] type (maybe an implicit one) or 2) they are of different types (maybe rooted in the same root type [class-wide approach]). Ada has 1), which excludes parameters. If you think that 2) would be better for Ada then solve the following: generic package Crazy is type Virtual is new Exception with ...; -- Note that Virtual exists in an instance of Crazy only. -- It is finalized together with the instance. procedure Show_Me (Object : Virtual); end Crazy; package body Crazy is Local : Integer := 0; procedure Show_Me (Object : Virtual) is begin Put_Line (Integer'Image (Local)); end Show_Me; begin raise Virtual (your fine parameters); end Crazy; declare package Catch_It is new Crazy; begin null; exception when Error : others => -- What sort of type has Error? -- Can I dispatch to Show_Me? -- What it will print? -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-10 10:49 ` Dmitry A. Kazakov @ 2004-04-10 15:35 ` Wojtek Narczynski 2004-04-10 21:01 ` Georg Bauhaus ` (2 more replies) 2004-04-14 15:57 ` Robert I. Eachus 1 sibling, 3 replies; 90+ messages in thread From: Wojtek Narczynski @ 2004-04-10 15:35 UTC (permalink / raw) Dimitry, > This has nothing to do with abstraction inversion. Would you please take care to explain to me, what abstraction inversion is, according to you? For me abstraction inversion is when you need to build low level primitives from high level primitives (built on low level primitives), because the high level primitives are not expressive enough. > The problem here is that Ada does not have multiple > protected actions. Google has not heard of "multiple protected actions", neither have I. But I think know what you mean, for my own needs I was calling this "compound protected". It seems to require proper tail recursion to work. At least we seem to agree that Ada concurrency features also have warts. --- > This is wrong: > > http://home.t-online.de/home/Christ-Usch.Grein/Ada/Dimension.html > > The type system is capable to express dimensioned units. By "express" I don't mean bent over in an such a way that your compiler checked your units for you, nor have your compiler mostly check your units for you, nor write yet another compiler to work on top of your compiler. I mean have your compiler statically check your units for you. I am afraid that this link show exactly that I am, unfortunately, right. The two compile time solutions are: 1. "Checks in assignments concerning physical dimensions are not performed.", 2. From what I've been able to understand Macks has a language, which compiles to Ada. --- > > From the language? For example parameters for exceptions. > > How they could have parameters? There are only two ways for dealing > with exceptions. Either 1) all of them are of one [specific] type > (maybe an implicit one) or 2) they are of different types (maybe > rooted in the same root type [class-wide approach]). You seem to be very well educated in Matematics. Thus you know that inexistence proofs are among the hardest. Please don't provoke me to ask you to proove that there are only two ways of dealing with exceptions. And once you assume false, you can prove anything. > Ada has 1), which excludes parameters. If you think that 2) would be > better for Ada then solve the following: You assumed that the root type for Exception would be tagged record. Indeed with this assumption it may be hard to maintain the conceptual integrity of the language. But I think this level of parametrization is an overkill. I'd rather use something like "discriminated records with discriminants only". Here is a version to start with (which actually compiles and "works"): generic package Crazy is Bang: exception; function T return Boolean; end Crazy; package body Crazy is function T return Boolean is begin return True; end T; begin raise Bang; end Crazy; with Crazy; procedure Sample is package Catch_It is new Crazy; begin null; exception when Catch_It.Bang => null; end Sample; Here is a parametrized version: generic package Crazy is type Severity_Type is (Hard, Tough, Difficult, Killer, ...); type Urgency_Type is (Urgent, Immediate, Now, Asap, ...); type Native_Code_Type is new Integer; exception Bang (Severity : Severity_Type; Urgency : Urgency_Type; Native_Code : Native_Code_Type) function T return Boolean; end Crazy; package body Crazy is function T return Boolean is begin return True; end T; begin raise Bang( Hard, Urgent, -1); end Crazy; with Crazy; procedure Sample is package Catch_It is new Crazy; begin null; exception when B : Catch_It.Bang => -- Here you'd be are able to access the values, -- but not to call anything from the already gone package. -- Regarding scope it is not any differnt from the previous -- example - we were also accessing Bang in hander. Put_Line (B.Severity); Put_Line (B.Urgency); Put_Line (B.Native_Code); end Sample; Please note that this actually works in Modula-3, but you are only limited to one parameter. Well, all languages have their warts. GNAT.Sockets is perhaps the best example how the code could benefit from parametrized exceptions. There you have Socket_Error and that's it. You need to use compiler specific tricks to extract more info. Or you can declare a coule dozen of different exceptions. Or a couple hundred, it depends. Regards, Wojtek ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-10 15:35 ` Wojtek Narczynski @ 2004-04-10 21:01 ` Georg Bauhaus 2004-04-10 21:16 ` Georg Bauhaus 2004-04-11 10:31 ` Reprise: 'in out' parameters for functions Dmitry A. Kazakov 2 siblings, 0 replies; 90+ messages in thread From: Georg Bauhaus @ 2004-04-10 21:01 UTC (permalink / raw) Wojtek Narczynski <wojtek@power.com.pl> wrote: : I mean have your compiler statically check your : units for you. IIRC, Hyman Rosen has demonstrated, a few month ago, how this can be done with C++ templates. ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-10 15:35 ` Wojtek Narczynski 2004-04-10 21:01 ` Georg Bauhaus @ 2004-04-10 21:16 ` Georg Bauhaus 2004-04-11 13:20 ` exception parameters Stephen Leake 2004-04-11 10:31 ` Reprise: 'in out' parameters for functions Dmitry A. Kazakov 2 siblings, 1 reply; 90+ messages in thread From: Georg Bauhaus @ 2004-04-10 21:16 UTC (permalink / raw) Wojtek Narczynski <wojtek@power.com.pl> wrote: : raise Bang( Hard, Urgent, -1); Isn't this just a work around a message passing technique? If I have a task that may fail in a few hundred ways, and I know another service task that can deal with these errors, I just say attention_please( Hard, Urgent, -1); to this task, and then abort the first, for example. Absent tasks, if I jump long with parameters, doesn't this parameter passing mechanism for "exceptional gotos" create a situation where program flow is just as hard to follow, or even more so because the tasking protocol won't be taken into account? ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: exception parameters 2004-04-10 21:16 ` Georg Bauhaus @ 2004-04-11 13:20 ` Stephen Leake 2004-04-12 10:29 ` Dmitry A. Kazakov 2004-04-13 8:04 ` Jean-Pierre Rosen 0 siblings, 2 replies; 90+ messages in thread From: Stephen Leake @ 2004-04-11 13:20 UTC (permalink / raw) To: comp.lang.ada Georg Bauhaus <sb463ba@l1-hrz.uni-duisburg.de> writes: > Wojtek Narczynski <wojtek@power.com.pl> wrote: > : raise Bang( Hard, Urgent, -1); > > Absent tasks, if I jump long with parameters, doesn't this parameter > passing mechanism for "exceptional gotos" create a situation where > program flow is just as hard to follow, or even more so because > the tasking protocol won't be taken into account? Yes, it could be abused. But there are places where it would be useful. For example, I'm working on a database GUI. The low-level database interface raises Database_Error with a string parameter. I have to parse the string to get the actual database error code. It would be simpler, and actually clearer, if the error code were avaialble as a parameter. I understand there are lots of difficult implementation issues with general exception parameters, and it can certainly be carried too far. Ada allows one string parameter for exceptions. If it also allowed one integer parameter, that might be a nice compromise :). -- -- Stephe ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: exception parameters 2004-04-11 13:20 ` exception parameters Stephen Leake @ 2004-04-12 10:29 ` Dmitry A. Kazakov 2004-04-13 0:58 ` Stephen Leake 2004-04-13 8:04 ` Jean-Pierre Rosen 1 sibling, 1 reply; 90+ messages in thread From: Dmitry A. Kazakov @ 2004-04-12 10:29 UTC (permalink / raw) Stephen Leake wrote: > Georg Bauhaus <sb463ba@l1-hrz.uni-duisburg.de> writes: > >> Wojtek Narczynski <wojtek@power.com.pl> wrote: >> : raise Bang( Hard, Urgent, -1); >> >> Absent tasks, if I jump long with parameters, doesn't this parameter >> passing mechanism for "exceptional gotos" create a situation where >> program flow is just as hard to follow, or even more so because >> the tasking protocol won't be taken into account? > > Yes, it could be abused. > > But there are places where it would be useful. > > For example, I'm working on a database GUI. The low-level database > interface raises Database_Error with a string parameter. I have to > parse the string to get the actual database error code. It would be > simpler, and actually clearer, if the error code were avaialble as a > parameter. A database connection type may have a primitive operation Get_Last_Error. So when you catch Database_Error and the connection object is still here (why should it disappear?), you can get a detailed error description from it. Get_Last_Error could be made task unique, if connection object will be used concurrently. > I understand there are lots of difficult implementation issues with > general exception parameters, and it can certainly be carried too far. > > Ada allows one string parameter for exceptions. If it also allowed one > integer parameter, that might be a nice compromise :). But the exception is already a sort of number. Why not to allow ranges? Connection_Lost_Error, SQL_Syntax_Error, Unknown_DB_Error : exception; -- A consequent set of exceptions Database_Error renames range Connection_Lost_Error..Unknown_DB_Error; or subtype Database_Error is range Connection_Lost_Error..Unknown_DB_Error; -- A range of exceptions -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: exception parameters 2004-04-12 10:29 ` Dmitry A. Kazakov @ 2004-04-13 0:58 ` Stephen Leake 2004-04-13 1:30 ` Randy Brukardt 0 siblings, 1 reply; 90+ messages in thread From: Stephen Leake @ 2004-04-13 0:58 UTC (permalink / raw) To: comp.lang.ada "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > A database connection type may have a primitive operation Get_Last_Error. So > when you catch Database_Error and the connection object is still here (why > should it disappear?), you can get a detailed error description from it. > Get_Last_Error could be made task unique, if connection object will be used > concurrently. Yes, you _could_ do it that way. But embedding the information in the exception message is better; there are no global variables involved, so there are no tasking issues. It would be even better if you could embed a type other than string, but that's not as much gain. > > I understand there are lots of difficult implementation issues > > with general exception parameters, and it can certainly be carried > > too far. > > > > Ada allows one string parameter for exceptions. If it also allowed one > > integer parameter, that might be a nice compromise :). > > But the exception is already a sort of number. Why not to allow ranges? > > Connection_Lost_Error, SQL_Syntax_Error, Unknown_DB_Error : exception; > -- A consequent set of exceptions > Database_Error renames range Connection_Lost_Error..Unknown_DB_Error; > > or > > subtype Database_Error is range Connection_Lost_Error..Unknown_DB_Error; > -- A range of exceptions An actual 64 bit number encodes much more information. -- -- Stephe ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: exception parameters 2004-04-13 0:58 ` Stephen Leake @ 2004-04-13 1:30 ` Randy Brukardt 0 siblings, 0 replies; 90+ messages in thread From: Randy Brukardt @ 2004-04-13 1:30 UTC (permalink / raw) "Stephen Leake" <stephen_leake@acm.org> wrote in message news:mailman.247.1081817939.327.comp.lang.ada@ada-france.org... ... > Yes, you _could_ do it that way. But embedding the information in the > exception message is better; there are no global variables involved, > so there are no tasking issues. It would be even better if you could > embed a type other than string, but that's not as much gain. Right, which is why the ARG decided not to pursue enhancements in this area. There was a nice proposal, but it ran into the lifetime issues mentioned previously, and also had bizzare effects on the Ada.Exceptions package (we don't want to make existing Ada code wrong!) and we ran out of energy to address this. The "range of exceptions" idea was part of that proposal, and I was sorry to see that go, but it just didn't seem important enough. Randy. ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: exception parameters 2004-04-11 13:20 ` exception parameters Stephen Leake 2004-04-12 10:29 ` Dmitry A. Kazakov @ 2004-04-13 8:04 ` Jean-Pierre Rosen 1 sibling, 0 replies; 90+ messages in thread From: Jean-Pierre Rosen @ 2004-04-13 8:04 UTC (permalink / raw) [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 800 bytes --] "Stephen Leake" <stephen_leake@acm.org> a �crit dans le message de news:mailman.240.1081689629.327.comp.lang.ada@ada-france.org... > For example, I'm working on a database GUI. The low-level database > interface raises Database_Error with a string parameter. I have to > parse the string to get the actual database error code. It would be > simpler, and actually clearer, if the error code were avaialble as a > parameter. > If my program is not multi-tasked, I just store the error context in some global variables of the package, with accessor functions. If it is multi-tasked, I use task attributes. No need for exception parameters here. -- --------------------------------------------------------- J-P. Rosen (rosen@adalog.fr) Visit Adalog's web site at http://www.adalog.fr ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-10 15:35 ` Wojtek Narczynski 2004-04-10 21:01 ` Georg Bauhaus 2004-04-10 21:16 ` Georg Bauhaus @ 2004-04-11 10:31 ` Dmitry A. Kazakov 2004-04-12 22:02 ` Randy Brukardt 2004-04-13 9:30 ` Wojtek Narczynski 2 siblings, 2 replies; 90+ messages in thread From: Dmitry A. Kazakov @ 2004-04-11 10:31 UTC (permalink / raw) Wojtek Narczynski wrote: >> This has nothing to do with abstraction inversion. > > Would you please take care to explain to me, what abstraction > inversion is, according to you? For me abstraction inversion is when > you need to build low level primitives from high level primitives > (built on low level primitives), because the high level primitives are > not expressive enough. or because of using them in an inappropriate way? However it is questionable, whether protected objects have a higher level of abstraction than semaphores. They are more generic but no less fundamental. >> The problem here is that Ada does not have multiple >> protected actions. > > Google has not heard of "multiple protected actions", neither have I. ARM 9.5.1 defines "protected action" > But I think know what you mean, for my own needs I was calling this > "compound protected". It seems to require proper tail recursion to > work. What I meant is the following. Presently one can define an entry to only of one protected object or task. Provided that: 1) protected object and tasks would be tagged (inheritable from); 2) multiple inheritance would be supported; 3) entries, procedures and functions would be primitive operations; 4) functional notation would be permitted (instead of prefix notation) one could have entries of multiple protected objects and tasks. A call to such entry would start multiple protected actions (one per each protected object parameter) and multiple rendezvous (one per each task object parameter). Could we agree that 1-4 is a damn *lot* of work? BTW, for your protected counters example, (4) would be enough: protected type Counter is procedure Inc; -- Increments this counter private Value : Integer := 0; end Counter; procedure Inc_One (First : in out Counter); -- Same as Inc, but uses functional notation procedure Inc_Two (First, Second : in out Counter); -- Increments two counters atomically, starts two protected actions, -- one per argument > At least we seem to agree that Ada concurrency features also have > warts. I do not see them as warts. Nothing is inherently wrong with them. They might be extended in a consistent way to make the language more regular (see 1-4). Make an AI and send it to ARG! (:-)) >> This is wrong: >> >> http://home.t-online.de/home/Christ-Usch.Grein/Ada/Dimension.html >> >> The type system is capable to express dimensioned units. > > By "express" I don't mean bent over in an such a way that your > compiler checked your units for you, nor have your compiler mostly > check your units for you, nor write yet another compiler to work on > top of your compiler. I mean have your compiler statically check your > units for you. > > I am afraid that this link show exactly that I am, unfortunately, > right. The two compile time solutions are: 1. "Checks in assignments > concerning physical dimensions are not performed.", 2. From what I've > been able to understand Macks has a language, which compiles to Ada. First of all I do not count compile time solutions for true solutions. A true one would include an ability to work with dimensioned values which units are unknown at compile time. A simpliest possible example is to write a physicist calculator. So to solve the problem one should either use tagged types or discriminated ones. And this indeed works in Ada. Now to static checks. Nothing in Ada prevents a compiler to from checking discriminants or type tags statically. What I see as a real problem is that neither discriminants nor type tags can be removed from an object if they are statically known. On the contrary array bounds are indeed removed. So again, we have more fundamental and complex problem than just "let's remove a wart". >> > From the language? For example parameters for exceptions. >> >> How they could have parameters? There are only two ways for dealing >> with exceptions. Either 1) all of them are of one [specific] type >> (maybe an implicit one) or 2) they are of different types (maybe >> rooted in the same root type [class-wide approach]). > > You seem to be very well educated in Matematics. Thus you know that > inexistence proofs are among the hardest. Please don't provoke me to > ask you to proove that there are only two ways of dealing with > exceptions. OK, there are only two ways I know of, if you find a third way... > And once you assume false, you can prove anything. > >> Ada has 1), which excludes parameters. If you think that 2) would be >> better for Ada then solve the following: > > You assumed that the root type for Exception would be tagged record. See above, either you derive a new type or not. There is no third way. > Indeed with this assumption it may be hard to maintain the conceptual > integrity of the language. But I think this level of parametrization > is an overkill. I'd rather use something like "discriminated records > with discriminants only". How it differs from (2)? You just replaced the official mechanism of inheritance with some hard-wired other. Discriminants are just special kind of members. > Here is a version to start with (which actually compiles and "works"): > > generic > package Crazy is > Bang: exception; > function T return Boolean; > end Crazy; > [...] > > package body Crazy is > function T return Boolean is begin return True; end T; > begin > raise Bang( Hard, Urgent, -1); > end Crazy; > > with Crazy; > procedure Sample is > package Catch_It is new Crazy; > begin > null; > exception > when B : Catch_It.Bang => This won't work. The exception out of Catch_It will be propagated *after* "end Sample". So you cannot catch it here! In any point you could, the type B will be already finalized. So you would have a zombie object of an unexisting type. > -- Here you'd be are able to access the values, > -- but not to call anything from the already gone package. > -- Regarding scope it is not any differnt from the previous > -- example - we were also accessing Bang in hander. > Put_Line (B.Severity); > Put_Line (B.Urgency); > Put_Line (B.Native_Code); > end Sample; As I said, because it is in fact (2) it has all its problems: generic package Crazy is exception Bang (Times : access Integer); end Crazy; package body Crazy is I : aliased Integer := 0; begin raise Bang (I'Access); end Crazy; > Please note that this actually works in Modula-3, but you are only > limited to one parameter. Well, all languages have their warts. This works in C++ too, because all functions and types are global there. I'd better stick to Ada's way. > GNAT.Sockets is perhaps the best example how the code could benefit > from parametrized exceptions. There you have Socket_Error and that's > it. You need to use compiler specific tricks to extract more info. Or > you can declare a coule dozen of different exceptions. Or a couple > hundred, it depends. Why (1) cannot work here? The only real problem with (1) I can see, is that the exception type does not have ranges or other forms of subsets. One need some syntactic suggar to define a set of exceptions which could be then named in "when". -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-11 10:31 ` Reprise: 'in out' parameters for functions Dmitry A. Kazakov @ 2004-04-12 22:02 ` Randy Brukardt 2004-04-13 10:56 ` Dmitry A. Kazakov 2004-04-13 9:30 ` Wojtek Narczynski 1 sibling, 1 reply; 90+ messages in thread From: Randy Brukardt @ 2004-04-12 22:02 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message news:c5b6pt$2pcs4d$2@ID-77047.news.uni-berlin.de... ... > Provided that: > > 1) protected object and tasks would be tagged (inheritable from); > 2) multiple inheritance would be supported; > 3) entries, procedures and functions would be primitive operations; > 4) functional notation would be permitted (instead of prefix notation) See AI-345, which extends the interface mechanism (itself a Ada 200y proposal) to cover task and protected types. (1) is true if the PT or TT inherits from one or more interfaces; (2) follows from the definition of interfaces; (3) is true for calls through interfaces (as opposed to directly to the PO or TOs); (4) is true for calls through interfaces. > one could have entries of multiple protected objects and tasks. I don't see how this follows from (1) to (4), though. Each call is just a dispatching call to a single operation; there is no implementation inheritance. > A call to such entry would start multiple protected actions (one per each protected > object parameter) and multiple rendezvous (one per each task object > parameter). Could we agree that 1-4 is a damn *lot* of work? Not really. *Interfaces* is a lot of work, but presuming that we're going to have those anyway, adding protected and task support to them is not a significant increment. Randy. ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-12 22:02 ` Randy Brukardt @ 2004-04-13 10:56 ` Dmitry A. Kazakov 2004-04-14 21:12 ` Randy Brukardt 0 siblings, 1 reply; 90+ messages in thread From: Dmitry A. Kazakov @ 2004-04-13 10:56 UTC (permalink / raw) Randy Brukardt wrote: > "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message > news:c5b6pt$2pcs4d$2@ID-77047.news.uni-berlin.de... > ... >> Provided that: >> >> 1) protected object and tasks would be tagged (inheritable from); >> 2) multiple inheritance would be supported; >> 3) entries, procedures and functions would be primitive operations; >> 4) functional notation would be permitted (instead of prefix notation) > > See AI-345, which extends the interface mechanism (itself a Ada 200y > proposal) to cover task and protected types. (1) is true if the PT or TT > inherits from one or more interfaces; (2) follows from the definition of > interfaces; (3) is true for calls through interfaces (as opposed to > directly to the PO or TOs); (4) is true for calls through interfaces. > >> one could have entries of multiple protected objects and tasks. > > I don't see how this follows from (1) to (4), though. Each call is just a > dispatching call to a single operation; there is no implementation > inheritance. Yes, but if I could have two dispatching parameters of same protected type (no MD involved) in a primitive operation, then a call to it should start two protected actions. Same with task entries, (4) should allow something like: task type Foo is ... end Foo; entry Double_Rendezvous (X, Y : in out Foo); -- Declared after "end Foo"; task body Foo is begin loop accept Double_Rendezvouz; -- Cannot give the body here end loop; end Foo; entry Double_Rendezvouz (X, Y : in out Foo) is begin ... end Double_Rendezvouz; [ I cannot see any direct use of things like that, except for demonstrating race conditions to students (:-)), but who knows... ] >> A call to such entry would start multiple protected actions (one per each > protected >> object parameter) and multiple rendezvous (one per each task object >> parameter). Could we agree that 1-4 is a damn *lot* of work? > > Not really. *Interfaces* is a lot of work, but presuming that we're going > to have those anyway, adding protected and task support to them is not a > significant increment. I am glad to hear it from you, because of course, you know it better. -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-13 10:56 ` Dmitry A. Kazakov @ 2004-04-14 21:12 ` Randy Brukardt 2004-04-15 10:37 ` Dmitry A. Kazakov 0 siblings, 1 reply; 90+ messages in thread From: Randy Brukardt @ 2004-04-14 21:12 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message news:c5gh0e$1ba02$3@ID-77047.news.uni-berlin.de... > Randy Brukardt wrote: > > > "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message > > news:c5b6pt$2pcs4d$2@ID-77047.news.uni-berlin.de... > > ... ... > > I don't see how this follows from (1) to (4), though. Each call is just a > > dispatching call to a single operation; there is no implementation > > inheritance. > > Yes, but if I could have two dispatching parameters of same protected type > (no MD involved) in a primitive operation, then a call to it should start > two protected actions. Same with task entries, (4) should allow something > like: > > task type Foo is ... end Foo; > entry Double_Rendezvous (X, Y : in out Foo); > -- Declared after "end Foo"; This isn't allowed by AI-345; entries can only be declared inside a task (with the current rules). An interface can have procedures that match entries (and interface procedure calls can be used in select statements), but there is no separate existence to entries. You could declare a procedure like that procedure Double_Rendezvous (X, Y : in out Foo); but of course it doesn't have any special semantics. ... > >> A call to such entry would start multiple protected actions (one per each protected > >> object parameter) and multiple rendezvous (one per each task object > >> parameter). Could we agree that 1-4 is a damn *lot* of work? > > > > Not really. *Interfaces* is a lot of work, but presuming that we're going > > to have those anyway, adding protected and task support to them is not a > > significant increment. > > I am glad to hear it from you, because of course, you know it better. I should point out that not everyone agrees with my assessment here. But it's not clear to me that everyone understands the implementation model for these, so they may be trying a harder-than-necessary implementation approach. Randy. ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-14 21:12 ` Randy Brukardt @ 2004-04-15 10:37 ` Dmitry A. Kazakov 0 siblings, 0 replies; 90+ messages in thread From: Dmitry A. Kazakov @ 2004-04-15 10:37 UTC (permalink / raw) Randy Brukardt wrote: > An interface can have procedures that match > entries (and interface procedure calls can be used in select statements), > but there is no separate existence to entries. I see, it is a one-way road. (:-)) -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-11 10:31 ` Reprise: 'in out' parameters for functions Dmitry A. Kazakov 2004-04-12 22:02 ` Randy Brukardt @ 2004-04-13 9:30 ` Wojtek Narczynski 2004-04-13 12:00 ` Dmitry A. Kazakov 1 sibling, 1 reply; 90+ messages in thread From: Wojtek Narczynski @ 2004-04-13 9:30 UTC (permalink / raw) Dimitry, You silently refused to say what abstraction inversion is according to you :-) > However it is questionable, whether protected objects have a higher level of > abstraction than semaphores. They are more generic but no less fundamental. Well, let's look at them as manual (semaphores) vs. automated (protected objects). > BTW, for your protected counters example, (4) would be enough: > > protected type Counter is > procedure Inc; -- Increments this counter > private > Value : Integer := 0; > end Counter; > > procedure Inc_One (First : in out Counter); > -- Same as Inc, but uses functional notation > procedure Inc_Two (First, Second : in out Counter); > -- Increments two counters atomically, starts two protected actions, > -- one per argument Cool. > First of all I do not count compile time solutions for true solutions. A > true one would include an ability to work with dimensioned values which > units are unknown at compile time. A simpliest possible example is to write > a physicist calculator. Then we're talking about two distinct things. I am talking about a compile time solution only. > OK, there are only two ways I know of, if you find a third way... The first way can be viewed as an incarnation of the second. Or you can ensure that there are no runtime exceptions. > How it differs from (2)? You just replaced the official mechanism of > inheritance with some hard-wired other. Discriminants are just special kind > of members. It differst in that it can be implemented, because there are no pointers to inexistent trampolines, only (immutable, integer) values. > This won't work. The exception out of Catch_It will be propagated *after* > "end Sample". So you cannot catch it here! In any point you could, the type > B will be already finalized. So you would have a zombie object of an > unexisting type. Well, this is how it goes with exceptions. That's why the "type" should be limited (in ordinary sense) to only: declaration, raising / construction, catching and extracting immutable values in handlers. > Why (1) cannot work here? The only real problem with (1) I can see, is that > the exception type does not have ranges or other forms of subsets. One need > some syntactic suggar to define a set of exceptions which could be then > named in "when". Feel free to perceive my 'code' as syntactic sugar. Regards, Wojtek ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-13 9:30 ` Wojtek Narczynski @ 2004-04-13 12:00 ` Dmitry A. Kazakov 2004-04-13 22:41 ` Wojtek Narczynski 0 siblings, 1 reply; 90+ messages in thread From: Dmitry A. Kazakov @ 2004-04-13 12:00 UTC (permalink / raw) Wojtek Narczynski wrote: > Dimitry, > > You silently refused to say what abstraction inversion is according to > you :-) We can use your definition if you want. (:-)) >> First of all I do not count compile time solutions for true solutions. A >> true one would include an ability to work with dimensioned values which >> units are unknown at compile time. A simpliest possible example is to >> write a physicist calculator. > > Then we're talking about two distinct things. I am talking about a > compile time solution only. Why should they be distinct? The key advantage of Ada strings as compared to Pascal ones, is that they works in both static and dynamic cases. Why units should be handled otherwise? How would you then mix both approaches in one program? In my view a real solution should respond the requirements I mentioned in another thread answering Russ. >> OK, there are only two ways I know of, if you find a third way... > > The first way can be viewed as an incarnation of the second. Surely the second way is more general. > Or you can ensure that there are no runtime exceptions. I didn't say that (2) is not solvable. I just invited you to think about it more deeply, before making some final statements. For example, one could make the exception object mutating to its parent type, when the exception type goes out of scope. This would then influnce the language. In which way? What are the consequences, I mean all consequences, etc. >> How it differs from (2)? You just replaced the official mechanism of >> inheritance with some hard-wired other. Discriminants are just special >> kind of members. > > It differst in that it can be implemented, because there are no > pointers to inexistent trampolines, only (immutable, integer) values. Discriminants can be of access types. >> This won't work. The exception out of Catch_It will be propagated *after* >> "end Sample". So you cannot catch it here! In any point you could, the >> type B will be already finalized. So you would have a zombie object of an >> unexisting type. > > Well, this is how it goes with exceptions. That's why the "type" > should be limited (in ordinary sense) to only: declaration, raising / > construction, catching and extracting immutable values in handlers. Here you create a new class of types, limited in some particular way. Doing so, you have to precisely define this class, you have to name it, you have to consider types other than exceptions of being of this class, you have to give it a formal name for generics and so on and so far. And in the end you have to answer some newbie, why Ada does it that complex! >> Why (1) cannot work here? The only real problem with (1) I can see, is >> that the exception type does not have ranges or other forms of subsets. >> One need some syntactic suggar to define a set of exceptions which could >> be then named in "when". > > Feel free to perceive my 'code' as syntactic sugar. It is not (1) it is (2), which has a lot of problems. -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-13 12:00 ` Dmitry A. Kazakov @ 2004-04-13 22:41 ` Wojtek Narczynski 2004-04-14 8:49 ` Dmitry A. Kazakov 0 siblings, 1 reply; 90+ messages in thread From: Wojtek Narczynski @ 2004-04-13 22:41 UTC (permalink / raw) Dimitry, >> You silently refused to say what abstraction inversion is according >> to you :-) > We can use your definition if you want. (:-)) My impression was that, according to you, mine was wrong. Certainly, I would prefer to use the right one. --- >> Then we're talking about two distinct things. I am talking about a >> compile time solution only. > Why should they be distinct? Checking physical units statically would be helpful for high integrity software. I don't see any practical use for runtime unit checks. --- > I didn't say that (2) is not solvable. I just invited you to think about it > more deeply, before making some final statements. It is unclear to me what final statements you are referring to. --- > Discriminants can be of access types. Good point, my bad. --- > Here you create a new class of types, limited in some particular way. Doing > so, you have to precisely define this class, you have to name it, you have > to consider types other than exceptions of being of this class, you have to > give it a formal name for generics and so on and so far. And in the end you > have to answer some newbie, why Ada does it that complex! Fortunately a distinct class already exists, and it's called exceptions. I'd only extend it to be able to convey some additional info down the callstack, but the added complexity is, of course, a valid point. Regards, Wojtek ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-13 22:41 ` Wojtek Narczynski @ 2004-04-14 8:49 ` Dmitry A. Kazakov 2004-04-14 15:03 ` Wojtek Narczynski 0 siblings, 1 reply; 90+ messages in thread From: Dmitry A. Kazakov @ 2004-04-14 8:49 UTC (permalink / raw) Wojtek Narczynski wrote: >>> You silently refused to say what abstraction inversion is according >>> to you :-) > >> We can use your definition if you want. (:-)) > > My impression was that, according to you, mine was wrong. Certainly, I > would prefer to use the right one. I did not disagree with your definition. I did with your statement that Ada's protected objects are wrong way. They might have problems, though. But it appeared, as you treating them as completely wrong. >>> Then we're talking about two distinct things. I am talking about a >>> compile time solution only. > >> Why should they be distinct? > > Checking physical units statically would be helpful for high integrity > software. I don't see any practical use for runtime unit checks. Only because I see no smiley... How would you implement: procedure Put (Stream : File, Value : Measurement); procedure Get (Stream : File, Value : out Measurement); For example, a requirement of one of our customer was to have a button in his MMI to switch between European and American units in all visual elements and printouts. Now go, figure out, how would you solve that using templates. BTW, European /= SI, because of km/h, ps, Celsius degree etc. Not to forget dozens of external devices all working with units of their own, all need to be hot pluggable etc. >> I didn't say that (2) is not solvable. I just invited you to think about >> it more deeply, before making some final statements. > > It is unclear to me what final statements you are referring to. That Ada exception model should be replaced by some other. -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-14 8:49 ` Dmitry A. Kazakov @ 2004-04-14 15:03 ` Wojtek Narczynski 2004-04-15 10:37 ` Dmitry A. Kazakov 0 siblings, 1 reply; 90+ messages in thread From: Wojtek Narczynski @ 2004-04-14 15:03 UTC (permalink / raw) > I did not disagree with your definition. I did with your statement that > Ada's protected objects are wrong way. They might have problems, though. > But it appeared, as you treating them as completely wrong. "Wrong" seems to be one of your favourite words. I merely said that Ada concurrency features are not expressive enough not to require abstraction inversion in many cases. --- >> Checking physical units statically would be helpful for high integrity >> software. I don't see any practical use for runtime unit checks. > Only because I see no smiley... How would you implement: > > procedure Put (Stream : File, Value : Measurement); > procedure Get (Stream : File, Value : out Measurement); > > For example, a requirement of one of our customer was to have a button in > his MMI to switch between European and American units in all visual > elements and printouts. Now go, figure out, how would you solve that using > templates. Huhm, we are talking about _checks_, then we are suddenly talking about _conversions_. But even for conversions, even though they are most certainly useful in many cases at runtime, the idea to hardcode the external representation of values with units into the compiler and runtime, is unfortunate. --- >>> I didn't say that (2) is not solvable. I just invited you to think about >>> it more deeply, before making some final statements. >> >> It is unclear to me what final statements you are referring to. > > That Ada exception model should be replaced by some other. I hate it when somebody puts words I have not said in my mouth. I suggest that you proofread your own posts for final statements instead. Regards, Wojtek ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-14 15:03 ` Wojtek Narczynski @ 2004-04-15 10:37 ` Dmitry A. Kazakov 2004-04-16 0:29 ` Wojtek Narczynski 0 siblings, 1 reply; 90+ messages in thread From: Dmitry A. Kazakov @ 2004-04-15 10:37 UTC (permalink / raw) Wojtek Narczynski wrote: >> I did not disagree with your definition. I did with your statement that >> Ada's protected objects are wrong way. They might have problems, though. >> But it appeared, as you treating them as completely wrong. > > "Wrong" seems to be one of your favourite words. I merely said that > Ada concurrency features are not expressive enough not to require > abstraction inversion in many cases. Sorry, but I still do not get your point. Either Ada features are 1) beyond any help; 2) OK, but has to be impoved in some definite way; 3) Excellent. It seems that you do not agree with (3). So either (1) or (2) remain. Which one? >>> Checking physical units statically would be helpful for high > integrity >>> software. I don't see any practical use for runtime unit checks. > >> Only because I see no smiley... How would you implement: >> >> procedure Put (Stream : File, Value : Measurement); >> procedure Get (Stream : File, Value : out Measurement); >> >> For example, a requirement of one of our customer was to have a button in >> his MMI to switch between European and American units in all visual >> elements and printouts. Now go, figure out, how would you solve that >> using templates. > > Huhm, we are talking about _checks_, then we are suddenly talking > about _conversions_. I gave you an example of a *real* application requiring units (and units checks, because surely in any place where the system expects, say, a velocity, the operator may give it in any compatible unit: knot, km/h, m/s, mph, whatsoever, but not in kPa. So units are indeed checked.) > But even for conversions, even though they are > most certainly useful in many cases at runtime, the idea to hardcode > the external representation of values with units into the compiler and > runtime, is unfortunate. I do not follow you here. My example shows that static *only* checks are insufficient. Period. This does not imply that it is impossible to create a unit system which would be statically checkable. I already mentioned in my previous post that Ada designers managed to do a similar job with the type String. Carefully observe how Ada deals with statically constrained String subtypes. In my view it is quite possible to deal this way with dimensioned values too. -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-15 10:37 ` Dmitry A. Kazakov @ 2004-04-16 0:29 ` Wojtek Narczynski 2004-04-16 11:36 ` Dmitry A. Kazakov 0 siblings, 1 reply; 90+ messages in thread From: Wojtek Narczynski @ 2004-04-16 0:29 UTC (permalink / raw) Hello, > Sorry, but I still do not get your point. Either Ada features are 1) beyond > any help; 2) OK, but has to be impoved in some definite way; 3) Excellent. > It seems that you do not agree with (3). So either (1) or (2) remain. Which > one? Depends on the application. For highly concurrent data structures that would be 1, for tutorials 3. For many applications they are probably okay. I am talking about concurrency features only now, but other parts of the language also have their problems. Still, with all the problems, Ada is overall the best procedural language I've seen. --- > I gave you an example of a *real* application requiring units (and units > checks, because surely in any place where the system expects, say, a > velocity, the operator may give it in any compatible unit: knot, km/h, m/s, > mph, whatsoever, but not in kPa. So units are indeed checked.) You could make it unable to enter a wrong unit in the interface. So this would be ensuring that 'Unit_Error' cannot be raised, rather than catching and handling it. But it is not always possible, for example when reading from an untrusted file, so you are right. > I already mentioned in my previous post that Ada designers managed to do a > similar job with the type String. Carefully observe how Ada deals with > statically constrained String subtypes. In my view it is quite possible to > deal this way with dimensioned values too. I've studied your code on units, I admit I should have done that before engaging in discussion about units with you. Regards, Wojtek ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-16 0:29 ` Wojtek Narczynski @ 2004-04-16 11:36 ` Dmitry A. Kazakov 2004-04-16 19:25 ` Wojtek Narczynski 0 siblings, 1 reply; 90+ messages in thread From: Dmitry A. Kazakov @ 2004-04-16 11:36 UTC (permalink / raw) Wojtek Narczynski wrote: >> Sorry, but I still do not get your point. Either Ada features are 1) >> beyond any help; 2) OK, but has to be impoved in some definite way; 3) >> Excellent. It seems that you do not agree with (3). So either (1) or (2) >> remain. Which one? > > Depends on the application. For highly concurrent data structures that > would be 1, for tutorials 3. Does it mean that 1.a) there is a better approach, or that 1.b) parallel applications are hard to develop? I would definitely disagree with the first and agree with the second. > For many applications they are probably > okay. I am talking about concurrency features only now, but other > parts of the language also have their problems. Any language has problems. -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-16 11:36 ` Dmitry A. Kazakov @ 2004-04-16 19:25 ` Wojtek Narczynski 0 siblings, 0 replies; 90+ messages in thread From: Wojtek Narczynski @ 2004-04-16 19:25 UTC (permalink / raw) Dimitry, > Does it mean that 1.a) there is a better approach, or that 1.b) parallel > applications are hard to develop? I would definitely disagree with the > first and agree with the second. Clearly parallel applications extremely hard to develop. Regarding better approach (than protected for highly concurrent data structures). It depends on what "better" means in a given context. For example, there are more time and space efficient, allowing higher concurrency, approaches. Regards, Wojtek ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-10 10:49 ` Dmitry A. Kazakov 2004-04-10 15:35 ` Wojtek Narczynski @ 2004-04-14 15:57 ` Robert I. Eachus 2004-04-15 8:04 ` Dmitry A. Kazakov 1 sibling, 1 reply; 90+ messages in thread From: Robert I. Eachus @ 2004-04-14 15:57 UTC (permalink / raw) Dmitry A. Kazakov wrote: > This has nothing to do with abstraction inversion. The problem here is that > Ada does not have multiple protected actions. Same problem with tasks, > there cannot be rendezvous with multiple tasks. It is much work to solve > that. Especially to convince people that prefix notation is inherently bad. Not quite right. A decision was made early in the development of Ada that a CALLING task can only rendezvous with a single task. A task can accept arbitrarily many calls simultaneously. You might prefer that the rule worked the other way around, but we felt that we had to choose one or the other. Many-to-many rendezvous looked just too messy to contemplate. AFAIK, the only pattern that uses this feature is the one where you have multiple servers and a task that allocates requesting tasks to servers. I have actually used this pattern. -- Robert I. Eachus "The terrorist enemy holds no territory, defends no population, is unconstrained by rules of warfare, and respects no law of morality. Such an enemy cannot be deterred, contained, appeased or negotiated with. It can only be destroyed--and that, ladies and gentlemen, is the business at hand." -- Dick Cheney ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-14 15:57 ` Robert I. Eachus @ 2004-04-15 8:04 ` Dmitry A. Kazakov 0 siblings, 0 replies; 90+ messages in thread From: Dmitry A. Kazakov @ 2004-04-15 8:04 UTC (permalink / raw) Robert I. Eachus wrote: > Dmitry A. Kazakov wrote: > >> This has nothing to do with abstraction inversion. The problem here is >> that Ada does not have multiple protected actions. Same problem with >> tasks, there cannot be rendezvous with multiple tasks. It is much work to >> solve that. Especially to convince people that prefix notation is >> inherently bad. > > Not quite right. A decision was made early in the development of Ada > that a CALLING task can only rendezvous with a single task. A task can > accept arbitrarily many calls simultaneously. You might prefer that the > rule worked the other way around, but we felt that we had to choose one > or the other. Many-to-many rendezvous looked just too messy to > contemplate. Right, I do not know how difficult it would be to implement, but definitely, it would make statical analysis more complicated. So it is not clear whether this feature would give any real advantage. > AFAIK, the only pattern that uses this feature is the one where you have > multiple servers and a task that allocates requesting tasks to servers. > I have actually used this pattern. Thank you for the example, because I never needed multiple rendezvous. -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-10 2:28 ` Wojtek Narczynski 2004-04-10 9:46 ` Georg Bauhaus 2004-04-10 10:49 ` Dmitry A. Kazakov @ 2004-04-10 12:32 ` Wojtek Narczynski 2004-04-14 15:46 ` Robert I. Eachus 3 siblings, 0 replies; 90+ messages in thread From: Wojtek Narczynski @ 2004-04-10 12:32 UTC (permalink / raw) > function in_kilograms (x: Quantity) return Units.yard; > -- Blows at runtime Oops :-) "The morning is wiser than the evening." Regards, Wojtek ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-10 2:28 ` Wojtek Narczynski ` (2 preceding siblings ...) 2004-04-10 12:32 ` Wojtek Narczynski @ 2004-04-14 15:46 ` Robert I. Eachus 2004-04-16 1:52 ` Wojtek Narczynski 3 siblings, 1 reply; 90+ messages in thread From: Robert I. Eachus @ 2004-04-14 15:46 UTC (permalink / raw) Wojtek Narczynski wrote: > Or the simplest possible: two protected counters, try to get the sum > atomically. Since this is trivial, I can only assume that you have two protected counters with no support for external locking in mind. Actually, you can even do that, by having one counter have a Sum operation that calls the other. The fact that two arbitrary counters cannot be added atomically in all cases is a feature of the real world, not of Ada. Certainly any two counters that can be managed with a P,V protocol can be added atomically. It is also possible if only one counter has P, V support. However, this whole subject is probably silly. If I give you a total outside of any locking which is guaranteed to have been correct at some point in the past, how do you know whether it was atomic or not? The answer has to be that it was possible to increment both counters with an atomic operation. (For example, any odd sum could be invalid.) But once we postulate atomic joint increments, atomic sums are obviously also possible. Reminds me of a lot of improvement requests for Ada 9X. "We want to do such and such." "Well, here is a simple example of how to do it in current Ada." "Oh, but our software development plan doesn't allow us to use Unchecked_Conversion." Well, fix your bloody SDP, you nit! Hmm. It sounds harsh said like that, but what they wanted to do was exactly the reason that their SDP forbid Unchecked_Conversion. Whether the SDP or the guy writing the improvement request was "right" in the context of a particular project was irrelevant to the design of Ada 9X. Ada, as designed, allowed SDPs to easily allow or forbid use of some features. (Right now the best example of this is the SPARK checker that forbids exceptions and dynamic allocations.) The intent was exactly to allow projects to "tailor" the subset they used. (I just ran into another CS professor who didn't understand that the Ada 83 "no subsets" rule was for validated compilers, not for projects. Sigh.) Back to the example that started all this. Either it "makes sense" to atomically lock both counters, or it doesn't. This is a design criteria, and will affect how the counters are implemented. If a later change adds this requirement, you may have to change the implementation of the counters. Said like that, it sounds so _obvious_. -- Robert I. Eachus "The terrorist enemy holds no territory, defends no population, is unconstrained by rules of warfare, and respects no law of morality. Such an enemy cannot be deterred, contained, appeased or negotiated with. It can only be destroyed--and that, ladies and gentlemen, is the business at hand." -- Dick Cheney ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-14 15:46 ` Robert I. Eachus @ 2004-04-16 1:52 ` Wojtek Narczynski 2004-04-16 5:40 ` Robert I. Eachus 0 siblings, 1 reply; 90+ messages in thread From: Wojtek Narczynski @ 2004-04-16 1:52 UTC (permalink / raw) >> Or the simplest possible: two protected counters, try to get the >> sum atomically. > Since this is trivial, I can only assume that you have two protected > counters with no support for external locking in mind. I had in mind implementing it without the need to resort to abstraction inversion, which I understand as -for example- implementing semaphores over protected objects, which are implemented over semaphores. > Actually, you can even do that, by having one counter have a Sum operation > that calls the other. However, this whole subject is probably silly. Yes, this is silly because I oversimplifed the problem. The original problem I run into was how to implement a highly concurrent, space and time efficient list, tree, and finally lock manager. And before that, I wanted to grab a ready implementation of this (list, tree) from some library, but I could not find such a thing... > Reminds me of a lot of improvement requests for Ada 9X. "We want to do > such and such." > > "Well, here is a simple example of how to do it in current Ada." > > "Oh, but our software development plan doesn't allow us to use > Unchecked_Conversion." Yes, I should probably have dropped protected type in favor of raw semaphores. Regards, Wojtek ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-16 1:52 ` Wojtek Narczynski @ 2004-04-16 5:40 ` Robert I. Eachus 2004-04-16 11:38 ` Wojtek Narczynski 0 siblings, 1 reply; 90+ messages in thread From: Robert I. Eachus @ 2004-04-16 5:40 UTC (permalink / raw) Wojtek Narczynski wrote: > I had in mind implementing it without the need to resort to > abstraction inversion, which I understand as -for example- > implementing semaphores over protected objects, which are implemented > over semaphores. Protected objects _may_ be implemented using semaphores, or mutexes, or counters, or any viable atomic action. But when you are programming in Ada, you have to take the tasking model, complex as it seems, as the fundamental primitive for concurrency. Protected objects were added to Ada 9X to eliminate some of the baggage that most implementations of Ada tasking carried. And to some extent they did just that. But if I need fast semaphores, I use a semaphore abstraction, then I try various implementations of the abstraction to find one which has the performance I need. If implementing a semaphore portably as a protected object works? Done. > Yes, I should probably have dropped protected type in favor of raw > semaphores. Protected objects are a very useful model for a lot of jobs that require management of concurrency. But it is a characteristic of protected objects that they manage _their_own_ concurrency, and nothing else. As long as that model fits what you are doing, great protected objects have great advantages over other techniques, such as semaphores. But there are two important points. First you _must_ as part of your analysis of the problem domain identify the objects that need to be managed. For lists and trees, two of the examples you mentioned, what usually needs to be managed is the list, or the tree: protected type List is procedure Append(E: in Element); procedure Prepend(E: in Element); ... function Is_Empty return Boolean; function Length return Natural; private ... end List; Should you expect to find a ready made implementation that meets your needs? Possibly. But you almost certainly won't find it by looking for libraries of protected objects. The usual in Ada is to provide a generic package abstraction where the protected object is hidden from the user's sight. This allows it to "reuse" the interface of a List that doesn't need protection from concurrent access. In fact, one of the changes in Ada 95 was intended to make it easier to 'hide' such a protected type in the body of a (generic) package. To go back to the example that sparked the discussion, it is not that difficult to create a protected type which protects an array of counters. It then seems natural to have both a set of atomic operations on a single counter and on a set of counters: type Index is (<>); generic package Counters is type Set is array (Index) of Boolean; type Count_Array is (Index range <>) of Integer; protected type Counters is procedure Reset(I: Index); procedure Reset(S: Set); procedure Reset; -- Zero all counters. function Count(I: Index) return Integer; function Count(S: Set) return Count_Array; function Count return Count_Array; --return a snapshot of all counts private ... end Counters; Now you may think that this is an abstraction inversion, but I don't. That is really a comment on thinking Ada. Even with Ada 83, it was _hard_ to correctly identify the 'right' objects to make the rest of the project easy, and Ada 95 has made those choices much harder. But the way it has done that is by making the object calculus much more powerful. I used to have a fully worked out example that demonstrated the issue. It was a simulation of a barber shop, with multiple chairs and barbers, customers who decided to return later if there were too many other customers waiting, and so on. But none of that was the point of the example. There was a simple elegant object-oriented solution. The insight you needed to find it though, was that the key objects were the haircuts! You could also probably come up with just as clean a model if you made the customers the key objects, but somehow _trying_ to do that leads you astray. If a parent comes into the barber shop with a child, who is the customer? Much easier to get it right, if you are thinking that a father comes into the barber shop to get _haircuts_ for both himself and his son, or only his son, or whatever. There are lots of ways to identify the potential objects in a program. Grady Booch's method of describing the problem space and underlining all the nouns is probably as good as any. But that is where the hard work begins. As in the barber shop example, there is some minimal set of objects that need to be modelled, or perhaps a better way to say that is that there is a minimal set of expensive objects that does the job. What makes objects expensive? It can be storage space, allocation and deallocation, active state, or some combination of the above. But you often don't know what cost function for the project will be at that stage of the analysis. You have to try strawmen, see which project constraints bind hardest, then start looking for opportunties to trade one resource for another. Sometimes, as in the barber shop example, there will be one elegant model which minimizes the cost in all dimensions. Other times, the engineering tradeoffs need to be decided before you can actually start coding. -- Robert I. Eachus "The terrorist enemy holds no territory, defends no population, is unconstrained by rules of warfare, and respects no law of morality. Such an enemy cannot be deterred, contained, appeased or negotiated with. It can only be destroyed--and that, ladies and gentlemen, is the business at hand." -- Dick Cheney ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-16 5:40 ` Robert I. Eachus @ 2004-04-16 11:38 ` Wojtek Narczynski 2004-04-16 16:30 ` Robert I. Eachus ` (2 more replies) 0 siblings, 3 replies; 90+ messages in thread From: Wojtek Narczynski @ 2004-04-16 11:38 UTC (permalink / raw) Robert, First of all, thanks for writing me an essay. One day you might think of gathering all your c.l.a posts into a book. I would definitely buy a copy. But let me push it a bit more. > But there are two important points. First you _must_ as part of your > analysis of the problem domain identify the objects that need to be > managed. Analysis for generic data structures has been done decades ago. I'd prefer to use something readily available and not redo the analysis at this level. But let's grant that, as a result of throughout analysis, you conclude that you need a list that is sorted, space efficient, time efficient, updateable from many tasks at the same time. Any hint on how to implement this? > protected type List is > procedure Append(E: in Element); > procedure Prepend(E: in Element); > ... > function Is_Empty return Boolean; > function Length return Natural; > private > ... > end List; If you do this, only one task / thread will be able to update the data structure. > Should you expect to find a ready made implementation that meets your > needs? Possibly. But you almost certainly won't find it by looking for > libraries of protected objects. I found no examples of data structures with lock granularity lower than the whole data structure. Regards, Wojtek ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-16 11:38 ` Wojtek Narczynski @ 2004-04-16 16:30 ` Robert I. Eachus 2004-04-16 18:38 ` Randy Brukardt 2004-04-16 19:28 ` Wojtek Narczynski 2 siblings, 0 replies; 90+ messages in thread From: Robert I. Eachus @ 2004-04-16 16:30 UTC (permalink / raw) Wojtek Narczynski wrote: > I found no examples of data structures with lock granularity lower > than the whole data structure. That is what I would expect you would find. Why would you expect anything different? For a list you might be able to prepend and append at the same time, but the more complex organization just doesn't seem worth it. For trees you can have one lock per object, and insertions, for example, would only hold the locks on those nodes needed for the insertion. From experience it is _possible_ but the performance of one lock per data structure instance performs much better. (Look at it this way. If you have one lock per node, then every query needs to start by locking the root node, so your transactions are going to be serialized anyway. As long as the whole tree _structure_ is in memory, doing the tree walk inside that one lock is more efficient than having to acquire and release a dozen locks, even though the first lock will serialize everything. If you have a situation where you need to lock a node for the duration of a transaction, the best choice--again from experience--is to have one lock for the tree structure, and one lock for the _contents_ of each node. That way you can have many transactions walking the tree at the same time (many readers) but the time consuming part of the transaction, which may require waiting for human interaction has a write lock on the content, not on the tree. Deleting or inserting a new node does require a write lock on the tree as a whole, but for AVL trees or B-trees the difference between that and locking 'just' the part of the tree which is potentially changing just isn't worth the extra overhead. To sum up, in theory there is no difference between theory and practice, but in practice there is. Oh one last observation, it may seem that to do an update of a tree node only requires a lock on the node contents, but this is not true in all cases. If the update of the contents changes the key, you have to delete the entry from the tree and reinsert it. This means you want to choose a key which is not often changed. (Just one reason why so many things are keyed by SSAN.) -- Robert I. Eachus "The terrorist enemy holds no territory, defends no population, is unconstrained by rules of warfare, and respects no law of morality. Such an enemy cannot be deterred, contained, appeased or negotiated with. It can only be destroyed--and that, ladies and gentlemen, is the business at hand." -- Dick Cheney ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-16 11:38 ` Wojtek Narczynski 2004-04-16 16:30 ` Robert I. Eachus @ 2004-04-16 18:38 ` Randy Brukardt 2004-04-16 22:15 ` Wojtek Narczynski 2004-04-16 19:28 ` Wojtek Narczynski 2 siblings, 1 reply; 90+ messages in thread From: Randy Brukardt @ 2004-04-16 18:38 UTC (permalink / raw) "Wojtek Narczynski" <wojtek@power.com.pl> wrote in message news:5ad0dd8a.0404160338.5a1c9116@posting.google.com... ... > I found no examples of data structures with lock granularity lower > than the whole data structure. That's because it would be hard to avoid deadlock in such data structures. (And, as Robert points out, the cost of grabbing a lot of locks would be very high.) The usual way of avoiding deadlock is the use the onion-skin model of locking. But that would serialize the data structure anyway, so there wouldn't be much point in separate locks. To see the problem, consider a tree struction. You'd have to lock many nodes if an insertion caused a rebalancing. If a second task tried to do a nearby insertion at the same time, it also could lock a number nodes. It would be quite likely for the second task to lock the nodes that it is going to insert into, then the first task try to lock the same nodes to do a rebalancing. So it would have to wait. Then the second task would discover that it, too needs to do a rebalancing - but it can't, because the first task already has locked some of the nodes that it needs to change for the rebalancing. Classic deadlock. To avoid this situation, you have to lock the whole data structure. The only place where you could get parallel operation is in modifying the elements once inserted. (And in a library like Ada.Containers, that's done updating a copy of the element, then calling the library to replace the previous element.) Randy. ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-16 18:38 ` Randy Brukardt @ 2004-04-16 22:15 ` Wojtek Narczynski 2004-04-17 1:20 ` Robert I. Eachus 0 siblings, 1 reply; 90+ messages in thread From: Wojtek Narczynski @ 2004-04-16 22:15 UTC (permalink / raw) Randy, > That's because it would be hard to avoid deadlock in such data structures. Yes, it is hard to avoid deadlocks. > The usual way of avoiding deadlock is the use the onion-skin model of > locking. With acyclic strucutres you do "crabbing" to avoid deadlocks. > To see the problem, consider a tree struction. You'd have to lock many nodes > if an insertion caused a rebalancing. If a second task tried to do a nearby > insertion at the same time, it also could lock a number nodes. It would be > quite likely for the second task to lock the nodes that it is going to > insert into, then the first task try to lock the same nodes to do a > rebalancing. So it would have to wait. Then the second task would discover > that it, too needs to do a rebalancing - but it can't, because the first > task already has locked some of the nodes that it needs to change for the > rebalancing. Classic deadlock. To avoid this situation, you have to lock the > whole data structure. This is not easy but solveable. For example ADABAS (and forks) relational database is organized as one large B* tree. It can be edited concurrently, it rebalances, and does not deadlock. One more example: Java heap, millions of objects, 64 CPUs, thousands of threads. Would you like to have one lock for the whole data strucutre? Regards, Wojtek ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-16 22:15 ` Wojtek Narczynski @ 2004-04-17 1:20 ` Robert I. Eachus 2004-04-17 11:42 ` Wojtek Narczynski 0 siblings, 1 reply; 90+ messages in thread From: Robert I. Eachus @ 2004-04-17 1:20 UTC (permalink / raw) Wojtek Narczynski wrote: > This is not easy but solveable. For example ADABAS (and forks) > relational database is organized as one large B* tree. It can be > edited concurrently, it rebalances, and does not deadlock. > > One more example: Java heap, millions of objects, 64 CPUs, thousands > of threads. Would you like to have one lock for the whole data > strucutre? You are missing the point. The answer is no, one lock per storage pool. How many storage pools do you have? At least one per CPU, more usually two or three due to different storage management protocols. But the major insight is that you either update a copy of an object and then swap it in atomically as Randy said, or (my preference) the lock for the data structure controls the data structure and a separate per object lock controls the object updates. (Except changing index keys, which has to be done Randy's way.) The simplest data structure locking protocol is usually by far the most efficient. Spending a dozen times as many CPU cycles on lock management to double or triple the effective concurrency is a joke, and you will find that holding complex schemes to only a dozen times as long is difficult. Factor in memory caches, and anything else is crazy. What is important, in real cases, is memory management. Having any part of a data structure paged to disk can kill performance. (The data structure now, not the actual data.) This is why I tend to implement the tree or whatever with a pointer (excuse me access value) designating the data. That way the next data structure entry you need will be in main memory, and is much more likely to be in cache. (If you also figure from this that I am one of those people who designs large objects and not that many of them, you are right. Complex data dictionaries are all right for the theoretical part of design, but when it comes to practice, you want to merge data nodes to the maximum extent possible.) -- Robert I. Eachus "The terrorist enemy holds no territory, defends no population, is unconstrained by rules of warfare, and respects no law of morality. Such an enemy cannot be deterred, contained, appeased or negotiated with. It can only be destroyed--and that, ladies and gentlemen, is the business at hand." -- Dick Cheney ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-17 1:20 ` Robert I. Eachus @ 2004-04-17 11:42 ` Wojtek Narczynski 2004-04-17 14:14 ` Robert I. Eachus 0 siblings, 1 reply; 90+ messages in thread From: Wojtek Narczynski @ 2004-04-17 11:42 UTC (permalink / raw) Robert, > What is important, in real cases, is memory management. Having any part > of a data structure paged to disk can kill performance. (The data > structure now, not the actual data.) Another problem of this kind is that the lock owner thread can get preempted by the operating system. This is more frequent, but less devastating than a page fault. > (Complex data dictionaries are all right for the theoretical part of design, > but when it comes to practice, you want to merge data nodes to the maximum > extent possible.) Okay, practitioners speaking, so I will just listen. Should I ask for a refunt for "Transaction Processing: Concept and Techniques" by J.Gray & A. Reuter? :-) Regards, Wojtek ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-17 11:42 ` Wojtek Narczynski @ 2004-04-17 14:14 ` Robert I. Eachus 0 siblings, 0 replies; 90+ messages in thread From: Robert I. Eachus @ 2004-04-17 14:14 UTC (permalink / raw) Wojtek Narczynski wrote: > Another problem of this kind is that the lock owner thread can get > preempted by the operating system. This is more frequent, but less > devastating than a page fault. There are "tricks" to minimize this. Even if I am programming at system independent level, I try to insure that all pages that may be needed inside a lock have been referenced outside the lock first. In a formal sense, this won't improve things, but in practice it can make the difference between good performance and bad. The best of all possible worlds is a compiler that wraps protected actions in an interrupt-deferred region. Like all real-time features, this is a two-edged sword, but one you have to use in some cases. > Okay, practitioners speaking, so I will just listen. Should I ask for > a refunt for "Transaction Processing: Concept and Techniques" by > J.Gray & A. Reuter? :-) Theory is important, so is practice. Without the theory you don't know what is and isn't correct in a formal sense. But in real-time programming, too late is just as bad as any other error, and it is an emergent property of the whole system. It is very frustrating to design a race free and deadlock free system, then find that to meet the performance requirements you have to violate some of the assumptions necessary to make the system deadlock free. Yes, you can often go "back to the drawing board" and come up with a more complex solution that works and meets the requirements. But far more often, you end up with a solution which is only deadlock free because it occasionally aborts lower priority transactions. -- Robert I. Eachus "The terrorist enemy holds no territory, defends no population, is unconstrained by rules of warfare, and respects no law of morality. Such an enemy cannot be deterred, contained, appeased or negotiated with. It can only be destroyed--and that, ladies and gentlemen, is the business at hand." -- Dick Cheney ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-16 11:38 ` Wojtek Narczynski 2004-04-16 16:30 ` Robert I. Eachus 2004-04-16 18:38 ` Randy Brukardt @ 2004-04-16 19:28 ` Wojtek Narczynski 2 siblings, 0 replies; 90+ messages in thread From: Wojtek Narczynski @ 2004-04-16 19:28 UTC (permalink / raw) Hello, > I found no examples of data structures with lock granularity lower > than the whole data structure. ...lock granularity higher than... Sorry, Wojtek ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-09 13:12 ` Wojtek Narczynski 2004-04-09 15:48 ` Expressing physical units (Was: Reprise: 'in out' parameters for functions) Jacob Sparre Andersen 2004-04-09 16:17 ` Reprise: 'in out' parameters for functions Georg Bauhaus @ 2004-04-09 17:09 ` Pascal Obry 2004-04-10 2:37 ` Wojtek Narczynski 2 siblings, 1 reply; 90+ messages in thread From: Pascal Obry @ 2004-04-09 17:09 UTC (permalink / raw) wojtek@power.com.pl (Wojtek Narczynski) writes: > to say CM3 Modula, or Java). But the problem real problem IMO is that > the development of the language has stagnated. This seems just strange to me! Latest Ada standard has moved forward a lot and all this is many aspects of the language. And Ada0Y is another step (admitedly smaller one) in this direction! Or maybe you are just trolling :) Pascal. -- --|------------------------------------------------------ --| Pascal Obry Team-Ada Member --| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE --|------------------------------------------------------ --| http://www.obry.org --| "The best way to travel is by means of imagination" --| --| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595 ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-09 17:09 ` Pascal Obry @ 2004-04-10 2:37 ` Wojtek Narczynski 0 siblings, 0 replies; 90+ messages in thread From: Wojtek Narczynski @ 2004-04-10 2:37 UTC (permalink / raw) Hello, > Or maybe you are just trolling :) Indeed I might have been, but only a litte. Regards, Wojtek ^ permalink raw reply [flat|nested] 90+ messages in thread
[parent not found: <u8yh75y33.fsf@acm.org>]
* Re: Reprise: 'in out' parameters for functions [not found] <u8yh75y33.fsf@acm.org> @ 2004-04-07 23:54 ` Alexander E. Kopilovich [not found] ` <WLZI9T09aE@VB1162.spb.edu> 1 sibling, 0 replies; 90+ messages in thread From: Alexander E. Kopilovich @ 2004-04-07 23:54 UTC (permalink / raw) To: comp.lang.ada Stephen Leake wrote: > I just ran across a need for an 'in out' parameter in a function, in > "real code", so I thought I post it here "just for fun" :). > > This is what I wanted to declare: > > function Parse > (Error_Label : in String; > Token : in out Token_List.List_Iterator) > return String; > -- Process Token, which should contain '([Config_File =>] <string>)'. > -- Return the string. > -- Delete parsed tokens from Token. > > Token must be 'in out', because the next parse function called wants > to work on the stuff after the config file. > > Parse must be a function, because I'm returning a String. > > The work-around is to use a procedure and a bounded string: > > procedure Parse > (Error_Label : in String; > Token : in out Token_List.List_Iterator; > Config_File_Name : out OpenToken.Buffers.Bounded_String); > > In this instance, the body of Parse deals with > OpenToken.Buffers.Bounded_String anyway, so there's no actual new > overhead introduced. But the user interface is not as clean as it > could be. One thing is missing in this your explanation: why exactly you don't want to make that List_Iterator global (instead of passing it as IN OUT argument) ? Alexander Kopilovitch aek@vib.usr.pu.ru Saint-Petersburg Russia ^ permalink raw reply [flat|nested] 90+ messages in thread
[parent not found: <WLZI9T09aE@VB1162.spb.edu>]
* Re: Reprise: 'in out' parameters for functions [not found] ` <WLZI9T09aE@VB1162.spb.edu> @ 2004-04-08 2:21 ` Stephen Leake 0 siblings, 0 replies; 90+ messages in thread From: Stephen Leake @ 2004-04-08 2:21 UTC (permalink / raw) To: comp.lang.ada "Alexander E. Kopilovich" <aek@VB1162.spb.edu> writes: > Stephen Leake wrote: > > > This is what I wanted to declare: > > > > function Parse > > (Error_Label : in String; > > Token : in out Token_List.List_Iterator) > > return String; > > -- Process Token, which should contain '([Config_File =>] <string>)'. > > -- Return the string. > > -- Delete parsed tokens from Token. > > > One thing is missing in this your explanation: why exactly you don't want to > make that List_Iterator global (instead of passing it as IN OUT argument) ? Hmm. I suppose that is a legitimate question. My answer is "I never make anything global unless it has to be, because that usually leads to trouble". In this case, Token is actually the contents of an aggregate, part of a larger statement that is dynamically allocated. It must be modified in place; copying it to a global to pass it to this routine would be a maintenance nightmare. And no, I don't consider "Ada doesn't allow 'in out' in functions" a good reason to make something global; I'll change it to a procedure first. -- -- Stephe ^ permalink raw reply [flat|nested] 90+ messages in thread
* Reprise: 'in out' parameters for functions @ 2004-04-07 20:31 Stephen Leake 2004-04-08 18:42 ` Georg Bauhaus 2004-04-13 14:45 ` Robert I. Eachus 0 siblings, 2 replies; 90+ messages in thread From: Stephen Leake @ 2004-04-07 20:31 UTC (permalink / raw) To: comp.lang.ada I just ran across a need for an 'in out' parameter in a function, in "real code", so I thought I post it here "just for fun" :). This is what I wanted to declare: function Parse (Error_Label : in String; Token : in out Token_List.List_Iterator) return String; -- Process Token, which should contain '([Config_File =>] <string>)'. -- Return the string. -- Delete parsed tokens from Token. Token must be 'in out', because the next parse function called wants to work on the stuff after the config file. Parse must be a function, because I'm returning a String. The work-around is to use a procedure and a bounded string: procedure Parse (Error_Label : in String; Token : in out Token_List.List_Iterator; Config_File_Name : out OpenToken.Buffers.Bounded_String); In this instance, the body of Parse deals with OpenToken.Buffers.Bounded_String anyway, so there's no actual new overhead introduced. But the user interface is not as clean as it could be. -- -- Stephe ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-07 20:31 Stephen Leake @ 2004-04-08 18:42 ` Georg Bauhaus 2004-04-08 20:32 ` Randy Brukardt 2004-04-08 23:48 ` Stephen Leake 2004-04-13 14:45 ` Robert I. Eachus 1 sibling, 2 replies; 90+ messages in thread From: Georg Bauhaus @ 2004-04-08 18:42 UTC (permalink / raw) Stephen Leake <stephen_leake@acm.org> wrote: : Token : in out Token_List.List_Iterator) Is Token : access Token_List.List_Iterator) not an option? ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-08 18:42 ` Georg Bauhaus @ 2004-04-08 20:32 ` Randy Brukardt 2005-01-12 15:15 ` okellogg 2004-04-08 23:48 ` Stephen Leake 1 sibling, 1 reply; 90+ messages in thread From: Randy Brukardt @ 2004-04-08 20:32 UTC (permalink / raw) "Georg Bauhaus" <sb463ba@l1-hrz.uni-duisburg.de> wrote in message news:c546fd$lkb$3@a1-hrz.uni-duisburg.de... > Stephen Leake <stephen_leake@acm.org> wrote: > > : Token : in out Token_List.List_Iterator) > Is > Token : access Token_List.List_Iterator) > not an option? It's rarely an option, because it (a) forces a particular declaration ('aliased') on users that have no need to know and (b) makes a messy call with the need to use '[Unchecked_]Access in every call. I prefer to simply make the List_Iterator a type that internally contains indirection. (That usually requires it to be a controlled type). Then the actual data can be manipulated. But whether that solution is worth the extra work depends on how much the interface is going to be used. (It isn't worth the effort for a rarely used interface.) Randy. ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-08 20:32 ` Randy Brukardt @ 2005-01-12 15:15 ` okellogg 2005-01-12 20:14 ` Randy Brukardt 0 siblings, 1 reply; 90+ messages in thread From: okellogg @ 2005-01-12 15:15 UTC (permalink / raw) On Apr 8 2004, 1:32 pm, Randy Brukardt wrote: > > "Georg Bauhaus" <sb463ba@l1-hrz.uni-duisburg.de> wrote in message > news:c546fd$lkb$3@a1-hrz.uni-duisburg.de... > > Stephen Leake <stephen_leake@acm.org> wrote: > > > > : Token : in out Token_List.List_Iterator) > > Is > > Token : access Token_List.List_Iterator) > > not an option? > > It's rarely an option, because it (a) forces a particular declaration > ('aliased') on users that have no need to know and (b) makes a messy call > with the need to use '[Unchecked_]Access in every call. > This triggers a different question: With Ada2005's support for object-dot-operation notation, will it be possible to write the following? package test is type obj_t is tagged private; function f (self : access obj_t) return integer; -- need 'access' mode here because f modifies self private -- ... end test; with test; procedure main is object : test.obj_t; retval : integer; begin retval := object.f; end main; My point here is whether main.object need be declared aliased or not. I would much prefer if it needn't be. Thanks, Oliver M. Kellogg ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2005-01-12 15:15 ` okellogg @ 2005-01-12 20:14 ` Randy Brukardt 0 siblings, 0 replies; 90+ messages in thread From: Randy Brukardt @ 2005-01-12 20:14 UTC (permalink / raw) "okellogg" <okellogg@freenet.de> wrote in message news:1105542923.381339.189580@z14g2000cwz.googlegroups.com... ... > This triggers a different question: > > With Ada2005's support for object-dot-operation notation, will it be > possible to write the following? > > package test is > type obj_t is tagged private; > function f (self : access obj_t) return integer; > -- need 'access' mode here because f modifies self > private > -- ... > end test; > > with test; > procedure main is > object : test.obj_t; > retval : integer; > begin > retval := object.f; > end main; > > > My point here is whether main.object need be declared aliased or not. > I would much prefer if it needn't be. I agree with you, but I lost that discussion. It was felt that it was important that this notation was just syntactic sugar, and didn't have any effect on semantics. I would have prefered that "aliased" be not required for tagged objects at all, given that they are always by reference anyway (and you can always take 'access of them once they're passed as a parameter), so there isn't much point to the declaration. But some people thought that "aliased" was useful for readers. I didn't press the point... Randy. ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-08 18:42 ` Georg Bauhaus 2004-04-08 20:32 ` Randy Brukardt @ 2004-04-08 23:48 ` Stephen Leake 1 sibling, 0 replies; 90+ messages in thread From: Stephen Leake @ 2004-04-08 23:48 UTC (permalink / raw) To: comp.lang.ada Georg Bauhaus <sb463ba@l1-hrz.uni-duisburg.de> writes: > Stephen Leake <stephen_leake@acm.org> wrote: > > : Token : in out Token_List.List_Iterator) > Is > Token : access Token_List.List_Iterator) > not an option? Good point. I had not actually considered that. In general, access types are as much a pain (in different ways) than globals. List_Iterator itself is a private access type, so it's not much of a stretch here. -- -- Stephe ^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: Reprise: 'in out' parameters for functions 2004-04-07 20:31 Stephen Leake 2004-04-08 18:42 ` Georg Bauhaus @ 2004-04-13 14:45 ` Robert I. Eachus 1 sibling, 0 replies; 90+ messages in thread From: Robert I. Eachus @ 2004-04-13 14:45 UTC (permalink / raw) Stephen Leake wrote: > This is what I wanted to declare: > > function Parse > (Error_Label : in String; > Token : in out Token_List.List_Iterator) > return String; ... > The work-around is to use a procedure and a bounded string: > > procedure Parse > (Error_Label : in String; > Token : in out Token_List.List_Iterator; > Config_File_Name : out OpenToken.Buffers.Bounded_String); IMHO a better workaround is to use an access parameter: function Parse (Error_Label : in String; Token : access Token_List.List_Iterator) return String; Yeah, I know, access is not a parameter mode. But it certainly works like one which is why I tend to align access as if it were a mode. -- Robert I. Eachus "The terrorist enemy holds no territory, defends no population, is unconstrained by rules of warfare, and respects no law of morality. Such an enemy cannot be deterred, contained, appeased or negotiated with. It can only be destroyed--and that, ladies and gentlemen, is the business at hand." -- Dick Cheney ^ permalink raw reply [flat|nested] 90+ messages in thread
end of thread, other threads:[~2005-01-12 20:14 UTC | newest] Thread overview: 90+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- [not found] <u4qrv5hwr.fsf@acm.org> 2004-04-08 17:19 ` Reprise: 'in out' parameters for functions Alexander E. Kopilovich [not found] ` <bRecOT0TxF@VB1162.spb.edu> 2004-04-08 23:46 ` Stephen Leake 2004-04-09 9:23 ` Florian Weimer 2004-04-09 10:04 ` Dmitry A. Kazakov 2004-04-09 11:23 ` Martin Krischik 2004-04-09 12:44 ` Dmitry A. Kazakov 2004-04-09 22:48 ` Randy Brukardt 2004-04-14 14:40 ` Robert I. Eachus 2004-04-14 21:20 ` Randy Brukardt 2004-04-09 22:47 ` Florian Weimer 2004-04-10 10:49 ` Dmitry A. Kazakov 2004-04-10 11:11 ` Florian Weimer 2004-04-10 13:26 ` Dmitry A. Kazakov 2004-04-10 20:50 ` Georg Bauhaus 2004-04-11 10:31 ` Dmitry A. Kazakov 2004-04-09 11:27 ` Stephen Leake 2004-04-09 22:46 ` Randy Brukardt 2004-04-09 13:12 ` Wojtek Narczynski 2004-04-09 15:48 ` Expressing physical units (Was: Reprise: 'in out' parameters for functions) Jacob Sparre Andersen 2004-04-10 13:07 ` Wojtek Narczynski 2004-04-10 13:52 ` Jacob Sparre Andersen 2004-04-11 2:45 ` Hyman Rosen 2004-04-11 10:14 ` Expressing physical units Jacob Sparre Andersen 2004-04-11 16:05 ` Hyman Rosen 2004-04-12 6:58 ` Expressing physical units (Was: Reprise: 'in out' parameters for functions) Russ 2004-04-12 10:29 ` Dmitry A. Kazakov 2004-04-13 6:52 ` Russ 2004-04-13 10:55 ` Dmitry A. Kazakov 2004-04-14 4:50 ` Hyman Rosen 2004-04-14 8:49 ` Dmitry A. Kazakov 2004-04-14 16:49 ` Hyman Rosen 2004-04-15 10:37 ` Dmitry A. Kazakov 2004-04-14 7:10 ` Russ 2004-04-14 8:53 ` tmoran 2004-04-14 9:01 ` Vinzent 'Gadget' Hoefler 2004-04-14 9:21 ` Dmitry A. Kazakov 2004-04-13 9:53 ` Wojtek Narczynski 2004-04-15 21:27 ` Expressing physical units Jacob Sparre Andersen 2004-04-16 11:40 ` Dmitry A. Kazakov 2004-04-09 16:17 ` Reprise: 'in out' parameters for functions Georg Bauhaus 2004-04-10 2:28 ` Wojtek Narczynski 2004-04-10 9:46 ` Georg Bauhaus 2004-04-10 10:49 ` Dmitry A. Kazakov 2004-04-10 15:35 ` Wojtek Narczynski 2004-04-10 21:01 ` Georg Bauhaus 2004-04-10 21:16 ` Georg Bauhaus 2004-04-11 13:20 ` exception parameters Stephen Leake 2004-04-12 10:29 ` Dmitry A. Kazakov 2004-04-13 0:58 ` Stephen Leake 2004-04-13 1:30 ` Randy Brukardt 2004-04-13 8:04 ` Jean-Pierre Rosen 2004-04-11 10:31 ` Reprise: 'in out' parameters for functions Dmitry A. Kazakov 2004-04-12 22:02 ` Randy Brukardt 2004-04-13 10:56 ` Dmitry A. Kazakov 2004-04-14 21:12 ` Randy Brukardt 2004-04-15 10:37 ` Dmitry A. Kazakov 2004-04-13 9:30 ` Wojtek Narczynski 2004-04-13 12:00 ` Dmitry A. Kazakov 2004-04-13 22:41 ` Wojtek Narczynski 2004-04-14 8:49 ` Dmitry A. Kazakov 2004-04-14 15:03 ` Wojtek Narczynski 2004-04-15 10:37 ` Dmitry A. Kazakov 2004-04-16 0:29 ` Wojtek Narczynski 2004-04-16 11:36 ` Dmitry A. Kazakov 2004-04-16 19:25 ` Wojtek Narczynski 2004-04-14 15:57 ` Robert I. Eachus 2004-04-15 8:04 ` Dmitry A. Kazakov 2004-04-10 12:32 ` Wojtek Narczynski 2004-04-14 15:46 ` Robert I. Eachus 2004-04-16 1:52 ` Wojtek Narczynski 2004-04-16 5:40 ` Robert I. Eachus 2004-04-16 11:38 ` Wojtek Narczynski 2004-04-16 16:30 ` Robert I. Eachus 2004-04-16 18:38 ` Randy Brukardt 2004-04-16 22:15 ` Wojtek Narczynski 2004-04-17 1:20 ` Robert I. Eachus 2004-04-17 11:42 ` Wojtek Narczynski 2004-04-17 14:14 ` Robert I. Eachus 2004-04-16 19:28 ` Wojtek Narczynski 2004-04-09 17:09 ` Pascal Obry 2004-04-10 2:37 ` Wojtek Narczynski [not found] <u8yh75y33.fsf@acm.org> 2004-04-07 23:54 ` Alexander E. Kopilovich [not found] ` <WLZI9T09aE@VB1162.spb.edu> 2004-04-08 2:21 ` Stephen Leake 2004-04-07 20:31 Stephen Leake 2004-04-08 18:42 ` Georg Bauhaus 2004-04-08 20:32 ` Randy Brukardt 2005-01-12 15:15 ` okellogg 2005-01-12 20:14 ` Randy Brukardt 2004-04-08 23:48 ` Stephen Leake 2004-04-13 14:45 ` Robert I. Eachus
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox