* Re: Running a preprocessor from GPS?
2015-07-29 22:32 ` EGarrulo
@ 2015-07-29 23:51 ` Jeffrey R. Carter
2015-07-30 0:10 ` EGarrulo
2015-07-30 6:08 ` Dmitry A. Kazakov
` (4 subsequent siblings)
5 siblings, 1 reply; 175+ messages in thread
From: Jeffrey R. Carter @ 2015-07-29 23:51 UTC (permalink / raw)
On 07/29/2015 03:32 PM, EGarrulo wrote:
>
> If Ada offered runtime typing by means of a type `Any`, then `Printf`
> could be trivially written as:
>
> type Printf_Arguments is array (Positive range <>) of Any;
>
> procedure Printf (Format : String; Arguments : Printf_Arguments);
Luckily nothing this horrible will ever make it into Ada.
--
Jeff Carter
"Whatever it is, I'm against it."
Horse Feathers
46
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-29 23:51 ` Jeffrey R. Carter
@ 2015-07-30 0:10 ` EGarrulo
2015-07-30 6:01 ` Niklas Holsti
0 siblings, 1 reply; 175+ messages in thread
From: EGarrulo @ 2015-07-30 0:10 UTC (permalink / raw)
On Thursday, July 30, 2015 at 1:51:50 AM UTC+2, Jeffrey R. Carter wrote:
> On 07/29/2015 03:32 PM, EGarrulo wrote:
> >
> > If Ada offered runtime typing by means of a type `Any`, then `Printf`
> > could be trivially written as:
> >
> > type Printf_Arguments is array (Positive range <>) of Any;
> >
> > procedure Printf (Format : String; Arguments : Printf_Arguments);
>
> Luckily nothing this horrible will ever make it into Ada.
Who knows? But since the realm of Ada is limited to embedded
development, it makes sense that flexible formatted output will never
be a priority.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 0:10 ` EGarrulo
@ 2015-07-30 6:01 ` Niklas Holsti
2015-07-30 7:33 ` Björn Lundin
2015-07-30 18:35 ` Randy Brukardt
0 siblings, 2 replies; 175+ messages in thread
From: Niklas Holsti @ 2015-07-30 6:01 UTC (permalink / raw)
On 15-07-30 03:10 , EGarrulo wrote:
> On Thursday, July 30, 2015 at 1:51:50 AM UTC+2, Jeffrey R. Carter wrote:
>> On 07/29/2015 03:32 PM, EGarrulo wrote:
>>>
>>> If Ada offered runtime typing by means of a type `Any`, then `Printf`
>>> could be trivially written as:
>>>
>>> type Printf_Arguments is array (Positive range <>) of Any;
>>>
>>> procedure Printf (Format : String; Arguments : Printf_Arguments);
>>
>> Luckily nothing this horrible will ever make it into Ada.
I agree with Jeffrey.
> Who knows? But since the realm of Ada is limited to embedded
> development,
It isn't.
> it makes sense that flexible formatted output will never
> be a priority.
Having used both, in my opinion the Ada way is more flexible than the C
printf approach. As long as all variables are explicitly typed "int" or
"char" or "long", etc, as in classical C programming style, printf works
tolerably; as soon as one introduces some kind of type abstraction such
as "typedef ... apple_count_t", constructing the right format-string
becomes awful, especially if portability is a goal. Look at the standard
header <inttypes.h> in C99; to make a portable format string for
apple_count_t, one would also to define a specific format macro (perhaps
named PRI_APPLE_COUNT) and perhaps another macro for scanf, and use this
macro within the format string.
Not to mention the maintenance problems in keeping the format string and
the argument list consistent, even if C compilers nowadays have special
compile-time checks for this.
The only improvement in the basic Ada output facilities that I wish for
is a standardisation of the GNAT 'Img attribute and extension of this
attribute to cover record and array types. That would occasionally be
useful for quick-and-dirty outputs like tracing outputs. On the other
hand, tracing functions originally meant to be temporary often become
permanent and then a quick-and-dirty formatting may not be enough. I
usually write specific Image functions for my types anyway.
--
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
. @ .
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 6:01 ` Niklas Holsti
@ 2015-07-30 7:33 ` Björn Lundin
2015-07-30 8:03 ` EGarrulo
2015-07-30 18:35 ` Randy Brukardt
1 sibling, 1 reply; 175+ messages in thread
From: Björn Lundin @ 2015-07-30 7:33 UTC (permalink / raw)
On 2015-07-30 08:01, Niklas Holsti wrote:
> On 15-07-30 03:10 , EGarrulo wrote:
>> Who knows? But since the realm of Ada is limited to embedded
>> development,
>
> It isn't.
It is certainly not.
I've spent 18 years writing Ada in WMS/WCS systems -
Database intense system with 100+ concurrent users
Nothing embedded at all with them.
> The only improvement in the basic Ada output facilities that I wish for
> is a standardisation of the GNAT 'Img attribute and extension of this
> attribute to cover record and array types. That would occasionally be
> useful for quick-and-dirty outputs like tracing outputs.
This - I want dearly too
--
Björn
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 7:33 ` Björn Lundin
@ 2015-07-30 8:03 ` EGarrulo
2015-07-30 8:08 ` Jacob Sparre Andersen
` (4 more replies)
0 siblings, 5 replies; 175+ messages in thread
From: EGarrulo @ 2015-07-30 8:03 UTC (permalink / raw)
On Thursday, July 30, 2015 at 9:31:36 AM UTC+2, björn lundin wrote:
> On 2015-07-30 08:01, Niklas Holsti wrote:
> > On 15-07-30 03:10 , EGarrulo wrote:
> >> Who knows? But since the realm of Ada is limited to embedded
> >> development,
> >
> > It isn't.
>
> It is certainly not.
> I've spent 18 years writing Ada in WMS/WCS systems -
> Database intense system with 100+ concurrent users
> Nothing embedded at all with them.
That doesn't mean much. Ada doesn't offer any facility for
automatic resource management, and that makes it unsuitable for
applications that go beyond constrained embedded development. Who
wants to chase resource leaks in this day and age? Not to mention
the crippled support for exceptions in Ada.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 8:03 ` EGarrulo
@ 2015-07-30 8:08 ` Jacob Sparre Andersen
2015-07-30 8:37 ` EGarrulo
2015-07-30 8:23 ` Georg Bauhaus
` (3 subsequent siblings)
4 siblings, 1 reply; 175+ messages in thread
From: Jacob Sparre Andersen @ 2015-07-30 8:08 UTC (permalink / raw)
EGarrulo <egarrulo@gmail.com> writes:
> That doesn't mean much. Ada doesn't offer any facility for automatic
> resource management, and that makes it unsuitable for applications
> that go beyond constrained embedded development. Who wants to chase
> resource leaks in this day and age? Not to mention the crippled
> support for exceptions in Ada.
It really sounds like you haven't taken the time to understand Ada.
Ada programmers hardly ever have to chase resource leaks.
If you attempt to write C++ or Python in Ada, you may end up in big
trouble, but if you use the language (instead of fighting it), you will
hardly ever have to worry about access types or memory management.
Greetings,
Jacob
--
LDraw.org Parts Tracker FAQ:
http://www.ldraw.org/library/tracker/ref/faq/
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 8:08 ` Jacob Sparre Andersen
@ 2015-07-30 8:37 ` EGarrulo
2015-07-30 8:49 ` Georg Bauhaus
2015-07-30 19:29 ` Jeffrey R. Carter
0 siblings, 2 replies; 175+ messages in thread
From: EGarrulo @ 2015-07-30 8:37 UTC (permalink / raw)
On Thursday, July 30, 2015 at 10:08:09 AM UTC+2, Jacob Sparre Andersen wrote:
> EGarrulo writes:
>
> > That doesn't mean much. Ada doesn't offer any facility for automatic
> > resource management, and that makes it unsuitable for applications
> > that go beyond constrained embedded development. Who wants to chase
> > resource leaks in this day and age? Not to mention the crippled
> > support for exceptions in Ada.
>
> It really sounds like you haven't taken the time to understand Ada.
On the contrary: I have taken a lot of time to understand Ada (in
spite of scant documentation on why Ada does things the way it
does).
> Ada programmers hardly ever have to chase resource leaks.
Hence, where is the magic please? So far, I know that programming
languages either offer garbage collection (and that works only for
memory), or some kind of reference-counting (and that works for
everything, but it requires some planning).
> If you attempt to write C++ or Python in Ada, you may end up in big
> trouble, but if you use the language (instead of fighting it), you will
> hardly ever have to worry about access types or memory management.
I have often heard this argument about a programming language.
Yet, ironically, hardly ever somebody explains how a programming
language is meant to be used. You are always supposed to magically "get it".
The lesson of C++ is that memory is just one of the many possible
scarce resources. What if you have a shared resource that must be
released as soon as possible? Garbage collection will not help you
there.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 8:37 ` EGarrulo
@ 2015-07-30 8:49 ` Georg Bauhaus
2015-07-30 12:15 ` EGarrulo
2015-07-30 19:29 ` Jeffrey R. Carter
1 sibling, 1 reply; 175+ messages in thread
From: Georg Bauhaus @ 2015-07-30 8:49 UTC (permalink / raw)
On 30.07.15 10:37, EGarrulo wrote:
> scant documentation
I guess refusing to read the Rationale (for all Ada, it is
continued with every edition) or one of the recommended resources
might be a source of that view. Another recommended resource is
some of the GNAT.* packages, e.g. the Spitbol ones.
Did you find Riehle's Ada Distilled? It is among
http://www.adaic.org/learn/materials/
If that's not always a welcoming atmosphere, presenting everything
without implying effort, you might have a point. Some good bits
here, not structured yet, though:
http://www.adacore.com/adaanswers/gems/
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 8:49 ` Georg Bauhaus
@ 2015-07-30 12:15 ` EGarrulo
2015-07-30 14:11 ` G.B.
0 siblings, 1 reply; 175+ messages in thread
From: EGarrulo @ 2015-07-30 12:15 UTC (permalink / raw)
On Thursday, July 30, 2015 at 10:49:13 AM UTC+2, Georg Bauhaus wrote:
> On 30.07.15 10:37, EGarrulo wrote:
> > scant documentation
>
> I guess refusing to read the Rationale (for all Ada, it is
> continued with every edition) or one of the recommended resources
> might be a source of that view.
Not really. I wanted to read the Rationale, but each Rationale
builds upon the previous, and reading all the rationales from
the start, while mentally discarding all the concept that were
superseded by new concepts for each new version, would have made
for a very lengthy reading session. Now, I think that if a
language is conceptually sound, then it shouldn't take long
to explain its core concepts, don't you agree? Everything
else should follow naturally, either as acknowledged best
practices or as ways to cope with the accidental complexity of
real-world solutions.
> Did you find Riehle's Ada Distilled? It is among
> http://www.adaic.org/learn/materials/
Yes, I did. Although I am thankful for the effort that the
author has made and its generosity in making his book freely
available, I found the explanations somewhat obscure. Of
course, the renowned "curse of knowledge" phenomenon is at work
here.
> If that's not always a welcoming atmosphere, presenting everything
> without implying effort, you might have a point. Some good bits
> here, not structured yet, though:
> http://www.adacore.com/adaanswers/gems/
Yes, the gems were helpful. But -- as you acknowledge -- they
lack structure and it is difficult to get the big picture.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 12:15 ` EGarrulo
@ 2015-07-30 14:11 ` G.B.
0 siblings, 0 replies; 175+ messages in thread
From: G.B. @ 2015-07-30 14:11 UTC (permalink / raw)
On 30.07.15 14:15, EGarrulo wrote:
> Now, I think that if a
> language is conceptually sound, then it shouldn't take long
> to explain its core concepts, don't you agree?
Actually, I think there is a fallacy at work here.
Conceptually sound only if quickly explained?
Like C++, Ada has sets of core concepts, and their integration. It
shares this property with other bigger languages. Exciting as it
might be to see how everything in a language can be built on top of
very few things, more so if one already knows the few things, the
language designers did not choose to present everything in their
language this way. Mathematics doesn't teach 1 + 2 from set theoretic
definitions of 1 and 2, or even routinely perform "+" in this way;
neither will languages like C++, or Ada, do the equivalent.
That is, they all offer higher abstractions, and also their
integration. Both need some learning (and unlearning). (As regards
learning, consider how the computational power of C++ templates was
discovered only after the fact; they were not quickly explained
and understood at all!)
This was addressed by Jean Ichbiah in his 1984 interview. He said,
IIRC, that if two guys sitting in the corner do not understand
everything of a bigger language at once, that doesn't mean that the
language is unsound, or useless, or unmaintainable, or whatever. (It
seems likely that the two guys' last names were among Hoare, Dijkstra,
and Wirth.)
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 8:37 ` EGarrulo
2015-07-30 8:49 ` Georg Bauhaus
@ 2015-07-30 19:29 ` Jeffrey R. Carter
2015-07-30 20:53 ` EGarrulo
1 sibling, 1 reply; 175+ messages in thread
From: Jeffrey R. Carter @ 2015-07-30 19:29 UTC (permalink / raw)
On 07/30/2015 01:37 AM, EGarrulo wrote:
>
> Hence, where is the magic please? So far, I know that programming
> languages either offer garbage collection (and that works only for
> memory), or some kind of reference-counting (and that works for
> everything, but it requires some planning).
>
> Yet, ironically, hardly ever somebody explains how a programming
> language is meant to be used. You are always supposed to magically "get it".
And we're supposed to magically know what you think cannot be done in Ada
without manual memory management. You have mentioned "shared resources" a couple
of times without defining what a "resource" is or what it's shared between.
Maybe you mean sharing a data structure between tasks, though anyone who
understands Ada knows how to do that without access types or manual memory
management. In Ada one can implement many recursive data structures without
access types or manual memory management. Maybe that's what you mean.
It's clear you come from a C/++ background, and I suspect you are thinking in
C/++ terms.
--
Jeff Carter
"Pray that there's intelligent life somewhere up in
space, 'cause there's bugger all down here on earth."
Monty Python's Meaning of Life
61
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 19:29 ` Jeffrey R. Carter
@ 2015-07-30 20:53 ` EGarrulo
2015-07-30 22:52 ` Jeffrey R. Carter
` (4 more replies)
0 siblings, 5 replies; 175+ messages in thread
From: EGarrulo @ 2015-07-30 20:53 UTC (permalink / raw)
On Thursday, July 30, 2015 at 9:29:38 PM UTC+2, Jeffrey R. Carter wrote:
> On 07/30/2015 01:37 AM, EGarrulo wrote:
> >
> > Hence, where is the magic please? So far, I know that programming
> > languages either offer garbage collection (and that works only for
> > memory), or some kind of reference-counting (and that works for
> > everything, but it requires some planning).
> >
> > Yet, ironically, hardly ever somebody explains how a programming
> > language is meant to be used. You are always supposed to magically "get it".
>
> And we're supposed to magically know what you think cannot be done in Ada
> without manual memory management. You have mentioned "shared resources" a couple
> of times without defining what a "resource" is or what it's shared between.
> Maybe you mean sharing a data structure between tasks, though anyone who
> understands Ada knows how to do that without access types or manual memory
> management. In Ada one can implement many recursive data structures without
> access types or manual memory management. Maybe that's what you mean.
By "resource" I mean any resource -- like: database connections,
files, etc. -- that must be relinquished as soon as possible and that is
shared among different objects, in a way that makes it difficult for each object
to determine whether such resource is still needed by other objects or not. Of
course, this implies a dynamic environment that precludes the possibility of
creating all the needed resources in advance and then releasing them at the end
of computation.
> It's clear you come from a C/++ background, and I suspect you are thinking in
> C/++ terms.
I am not thinking in C++ terms. I am thinking in terms of patterns
that I know for managing resources. So far, I only know the "shared/weak
pointer" idiom. If Ada offers something else, besides manual reclamation, I am
eager to learn about it.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 20:53 ` EGarrulo
@ 2015-07-30 22:52 ` Jeffrey R. Carter
2015-07-31 7:29 ` Georg Bauhaus
` (3 subsequent siblings)
4 siblings, 0 replies; 175+ messages in thread
From: Jeffrey R. Carter @ 2015-07-30 22:52 UTC (permalink / raw)
On 07/30/2015 01:53 PM, EGarrulo wrote:
>
> By "resource" I mean any resource -- like: database connections,
> files, etc. -- that must be relinquished as soon as possible and that is
> shared among different objects, in a way that makes it difficult for each object
> to determine whether such resource is still needed by other objects or not. Of
> course, this implies a dynamic environment that precludes the possibility of
> creating all the needed resources in advance and then releasing them at the end
> of computation.
I still have no idea what you mean. Sharing a DB connection among objects seems
simple:
declare
DB : DB_Connection;
begin
O1.Op (DB => DB);
O2.Op (DB => DB);
O3.Op (DB => DB);
end;
and the sharing part remains just as simple if the operations pass the DB to
operations of other objects, and if the code is more complex with multiple paths
and orders of operation invocations. There doesn't seem to be any reason for the
objects to know whether another object will receive the DB after they're through
with it or not, or to be concerned with when it is "relinquished".
> I am not thinking in C++ terms. I am thinking in terms of patterns
> that I know for managing resources. So far, I only know the "shared/weak
> pointer" idiom. If Ada offers something else, besides manual reclamation, I am
> eager to learn about it.
If you only know one idiom, it's not surprising you have difficulty imagining
anything else. "Shared/weak pointer" certainly sounds fairly C/++ oriented to me.
I am perhaps constrained by my Ada experience since I can't image what kind of
problem you're talking about. I wish I could. It reminds me of someone who was
telling me about his experiments with overflowing buffers in C. I said I
preferred to use a language in which that wasn't possible, and he couldn't
conceive of the possibility. He showed me what he was doing, which was something
like
char b[100];
and using strcpy to copy argv[1] into b. He asked how I'd do that with Ada, so I
showed him
B : String := Ada.Command_Line.Argument (1);
He didn't seem to be able to wrap his mind around that. I may be having a
similar problem understanding you.
--
Jeff Carter
"Pray that there's intelligent life somewhere up in
space, 'cause there's bugger all down here on earth."
Monty Python's Meaning of Life
61
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 20:53 ` EGarrulo
2015-07-30 22:52 ` Jeffrey R. Carter
@ 2015-07-31 7:29 ` Georg Bauhaus
2015-07-31 7:53 ` gautier_niouzes
` (2 subsequent siblings)
4 siblings, 0 replies; 175+ messages in thread
From: Georg Bauhaus @ 2015-07-31 7:29 UTC (permalink / raw)
On 30.07.15 22:53, EGarrulo wrote:
> By "resource" I mean any resource -- like: database connections,
> files, etc. -- that must be relinquished as soon as possible and that is
> shared among different objects, in a way that makes it difficult for each object
> to determine whether such resource is still needed by other objects or not. Of
> course, this implies a dynamic environment that precludes the possibility of
> creating all the needed resources in advance and then releasing them at the end
> of computation.
This kind of automatic resource management cannot be real:
How could anything other than the entire collection of objects using
the resource determine whether any one of them still needs the resource?
Therefore, if you have several objects using the resource,
possibly in different tasks, handle the resource with the
help of a protected object.
The protected object implements a protocol. An object wishing
to use the resource will ask the PO for a handle, and will get one ASAP.
In simple cases, the resource can be released by the PO as soon
as all users have signaled to the protected object that they are
done with the resource.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 20:53 ` EGarrulo
2015-07-30 22:52 ` Jeffrey R. Carter
2015-07-31 7:29 ` Georg Bauhaus
@ 2015-07-31 7:53 ` gautier_niouzes
2015-07-31 8:26 ` Simon Wright
2015-07-31 11:26 ` Brian Drummond
4 siblings, 0 replies; 175+ messages in thread
From: gautier_niouzes @ 2015-07-31 7:53 UTC (permalink / raw)
Le jeudi 30 juillet 2015 22:53:28 UTC+2, EGarrulo a écrit :
> I am not thinking in C++ terms. I am thinking in terms of patterns
> that I know for managing resources. So far, I only know the "shared/weak
> pointer" idiom. If Ada offers something else, besides manual reclamation, I am
> eager to learn about it.
Fantastic, then the example below is for you!
Of course it is a trivial example. You can add a field of type Text to a window type for instance, and the memory will be automatically freed when the window itself is finalized. No pointer, no manual reclamation, no garbage waiting to be collected!... Magic, isn't it ?
-- This test program reads an entire text file into a variable
-- of type Text which is a vector of unbounded strings.
with Ada.Text_IO.Unbounded_IO; use Ada.Text_IO, Ada.Text_IO.Unbounded_IO;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Containers.Vectors;
procedure Text_Container is
package Text_Pkg is new Ada.Containers.Vectors(Positive, Unbounded_String);
---------------------
-- Text container --
---------------------
subtype Text is Text_Pkg.Vector;
--
name: constant String:= "text_container.adb";
t: Text;
f: File_Type;
begin
Open(f, In_File, name);
while not End_of_File(f) loop
t.Append(Get_Line(f));
end loop;
Close(f);
--
Create(f, Out_File, "copy_of_" & name);
for line of t loop
Put_Line(f, line);
end loop;
Close(f);
end;
_________________________
Gautier's Ada programming
http://gautiersblog.blogspot.com/search/label/Ada
NB: follow the above link for a valid e-mail address
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 20:53 ` EGarrulo
` (2 preceding siblings ...)
2015-07-31 7:53 ` gautier_niouzes
@ 2015-07-31 8:26 ` Simon Wright
2015-07-31 9:13 ` Dmitry A. Kazakov
2015-07-31 11:26 ` Brian Drummond
4 siblings, 1 reply; 175+ messages in thread
From: Simon Wright @ 2015-07-31 8:26 UTC (permalink / raw)
EGarrulo <egarrulo@gmail.com> writes:
> So far, I only know the "shared/weak pointer" idiom. If Ada offers
> something else, besides manual reclamation, I am eager to learn about
> it.
Would ref-counted smart pointers suit you? I'd address your problem by
having a smart pointer to a limited-controlled object representing the
resource, whose finalization would clean up the resource.
The smart pointer I wrote a while back (2003!) is at [1] (change to .adb
for the body). There are more modern ones, including AdaMagica's [2].
[1] http://sourceforge.net/p/booch95/code/ci/default/tree/src/bc-support-smart_pointers.ads
[2] http://www.christ-usch-grein.homepage.t-online.de/Ada/Smart_Pointers.html
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-31 8:26 ` Simon Wright
@ 2015-07-31 9:13 ` Dmitry A. Kazakov
2015-07-31 9:31 ` EGarrulo
0 siblings, 1 reply; 175+ messages in thread
From: Dmitry A. Kazakov @ 2015-07-31 9:13 UTC (permalink / raw)
On Fri, 31 Jul 2015 09:26:17 +0100, Simon Wright wrote:
> EGarrulo <egarrulo@gmail.com> writes:
>
>> So far, I only know the "shared/weak pointer" idiom. If Ada offers
>> something else, besides manual reclamation, I am eager to learn about
>> it.
>
> Would ref-counted smart pointers suit you? I'd address your problem by
> having a smart pointer to a limited-controlled object representing the
> resource, whose finalization would clean up the resource.
Your pointer is a "hard" (AKA strong) reference/pointer, i.e. the target is
not collected until at least pointer exists.
Soft/weak reference/pointer is a pointer that does not prevent collection,
but itself becomes invalid if collection occurs. [To access the target, a
strong pointer is obtained from the weak pointer, the object is accessed
through it, and then the strong pointer is disposed.]
If there is a complex mesh of references some references must be weak to
prevent circular references:
O1-->hard-->O2
<--soft--
Yes, there exist many implementations in Ada *and* there is no reason to
have it in the language, as it can be implemented at the library level.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-31 9:13 ` Dmitry A. Kazakov
@ 2015-07-31 9:31 ` EGarrulo
2015-07-31 11:01 ` Dmitry A. Kazakov
0 siblings, 1 reply; 175+ messages in thread
From: EGarrulo @ 2015-07-31 9:31 UTC (permalink / raw)
On Friday, July 31, 2015 at 11:13:21 AM UTC+2, Dmitry A. Kazakov wrote:
> Soft/weak reference/pointer is a pointer that does not prevent collection,
> but itself becomes invalid if collection occurs. [To access the target, a
> strong pointer is obtained from the weak pointer, the object is accessed
> through it, and then the strong pointer is disposed.]
> [...]
> Yes, there exist many implementations in Ada *and* there is no reason to
> have it in the language, as it can be implemented at the library level.
Many? Do you mean many libraries that implement "shared/weak pointer" semantics? Because I only know of GNATCOLL.Refcount, but this library requires
you "to create a new tagged type that extends GNATCOLL.Refcount.Refcounted, so
that it has a counter." This can be impractical. Apparently, the next version
of GNATCOLL will include an alternative implementation[1] that removes this
requirement. But this means that right now there is GNATCOLL.Refcount only.
--
[1] http://www.adacore.com/developers/development-log/NF-18-O422-013-gnatcoll/
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-31 9:31 ` EGarrulo
@ 2015-07-31 11:01 ` Dmitry A. Kazakov
2015-07-31 13:50 ` EGarrulo
0 siblings, 1 reply; 175+ messages in thread
From: Dmitry A. Kazakov @ 2015-07-31 11:01 UTC (permalink / raw)
On Fri, 31 Jul 2015 02:31:26 -0700 (PDT), EGarrulo wrote:
> On Friday, July 31, 2015 at 11:13:21 AM UTC+2, Dmitry A. Kazakov wrote:
>> Soft/weak reference/pointer is a pointer that does not prevent collection,
>> but itself becomes invalid if collection occurs. [To access the target, a
>> strong pointer is obtained from the weak pointer, the object is accessed
>> through it, and then the strong pointer is disposed.]
>> [...]
>> Yes, there exist many implementations in Ada *and* there is no reason to
>> have it in the language, as it can be implemented at the library level.
>
> Many? Do you mean many libraries that implement "shared/weak pointer"
> semantics? Because I only know of GNATCOLL.Refcount, but this library
> requires you "to create a new tagged type that extends
> GNATCOLL.Refcount.Refcounted, so
> that it has a counter." This can be impractical.
Can be, but isn't. My implementation also uses a base type:
http://www.dmitry-kazakov.de/ada/components.htm#Objects_etc
It has weak pointers as well:
http://www.dmitry-kazakov.de/ada/components.htm#persistent_objects
> Apparently, the next version
> of GNATCOLL will include an alternative implementation[1] that removes this
> requirement. But this means that right now there is GNATCOLL.Refcount only.
That will add a level of indirection as some other implementations do. I
don't see much merits doing this. There are no cases you might wish to have
another type as the base and furthermore it won't do any good anyway.
Because the only usable pattern of using strong pointers is this:
type Object_Interface is interface;
-- define operations here
procedure Foo (X : in out Object_Interface) is abstract;
in private
type Object_Implementation is
new Reference_Counted and Object_Interface with ...
-- implement operations here
overriding procedure Foo (X : in out Object_Implementation);
in public
type Object is new Object_Interface with private;
-- implement operations here
overriding procedure Foo (X : in out Object);
in private
type Object_Implementation_Ptr is access Object_Implementation'Class;
type Object is new Strong_Reference with record
Ptr : Object_Implementation_Ptr;
end record;
The implementation of Object's Foo delegates:
procedure Foo (X : in out Object) is
begin
X.Ptr.Foo;
end Foo;
If Object_Implementation must use some existing type, aggregate it. That
won't change anything, because public clients won't see
Object_Implementation anyway. Who cares what was the parent type of?
If you mean that this is too complex for your case, then you probably need
no smart pointers at all, which is, my estimate, 95% of cases when smart
pointers come into consideration. As others many times said pointers rarely
needed in Ada. Cases when in C++ you would use a pointer are handled by the
language itself.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-31 11:01 ` Dmitry A. Kazakov
@ 2015-07-31 13:50 ` EGarrulo
2015-07-31 16:29 ` Dmitry A. Kazakov
0 siblings, 1 reply; 175+ messages in thread
From: EGarrulo @ 2015-07-31 13:50 UTC (permalink / raw)
On Friday, July 31, 2015 at 1:02:03 PM UTC+2, Dmitry A. Kazakov wrote:
> > Apparently, the next version
> > of GNATCOLL will include an alternative implementation[1] that removes this
> > requirement. But this means that right now there is GNATCOLL.Refcount only.
>
> That will add a level of indirection as some other implementations do. I
> don't see much merits doing this. There are no cases you might wish to have
> another type as the base and furthermore it won't do any good anyway.
I don't understand what you mean. A common case is when you have an existing
class that wraps a resource and thus you can't change its base class.
Therefore the only general solution is to use composition, not inheritance, for
reference counting; like this, for example:
generic
type T is private;
package Shared_Accesses is
type Shared_Object is record
Reference_Count : Natural;
Object : T;
end record;
type Shared_Object_Access is access Shared_Object;
type Shared_Access is
-- Implementation of a controlled type that holds a Shared_Object_Access.
end;
end Shared_Accesses;
> Because the only usable pattern of using strong pointers is this:
>
> type Object_Interface is interface;
> -- define operations here
> procedure Foo (X : in out Object_Interface) is abstract;
>
> in private
> type Object_Implementation is
> new Reference_Counted and Object_Interface with ...
> -- implement operations here
> overriding procedure Foo (X : in out Object_Implementation);
>
> in public
> type Object is new Object_Interface with private;
> -- implement operations here
> overriding procedure Foo (X : in out Object);
>
> in private
> type Object_Implementation_Ptr is access Object_Implementation'Class;
>
> type Object is new Strong_Reference with record
> Ptr : Object_Implementation_Ptr;
> end record;
>
> The implementation of Object's Foo delegates:
>
> procedure Foo (X : in out Object) is
> begin
> X.Ptr.Foo;
> end Foo;
>
> If Object_Implementation must use some existing type, aggregate it. That
> won't change anything, because public clients won't see
> Object_Implementation anyway. Who cares what was the parent type of?
I can't follow what the code does, sorry. What would be the equivalent of this
C++ code:
std::shared_ptr<Object> shared_object (new Object);
in the above example? Thanks.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-31 13:50 ` EGarrulo
@ 2015-07-31 16:29 ` Dmitry A. Kazakov
0 siblings, 0 replies; 175+ messages in thread
From: Dmitry A. Kazakov @ 2015-07-31 16:29 UTC (permalink / raw)
On Fri, 31 Jul 2015 06:50:58 -0700 (PDT), EGarrulo wrote:
> On Friday, July 31, 2015 at 1:02:03 PM UTC+2, Dmitry A. Kazakov wrote:
>>> Apparently, the next version
>>> of GNATCOLL will include an alternative implementation[1] that removes this
>>> requirement. But this means that right now there is GNATCOLL.Refcount only.
>>
>> That will add a level of indirection as some other implementations do. I
>> don't see much merits doing this. There are no cases you might wish to have
>> another type as the base and furthermore it won't do any good anyway.
>
> I don't understand what you mean. A common case is when you have an existing
> class that wraps a resource and thus you can't change its base class.
> Therefore the only general solution is to use composition, not inheritance, for
> reference counting; like this, for example:
>
> generic
> type T is private;
> package Shared_Accesses is
> type Shared_Object is record
> Reference_Count : Natural;
> Object : T;
> end record;
1. Shared_Object here is not in T'Class [and T is not a limited type]. You
claimed that it would be of T.
2. This design need not to be generic. The implementation I posted is not.
3. Smart pointers are pretty much useless if T is not limited and definite.
Change it to
type T (<>) is limited private;
and see what happens.
>> Because the only usable pattern of using strong pointers is this:
>>
>> type Object_Interface is interface;
>> -- define operations here
>> procedure Foo (X : in out Object_Interface) is abstract;
>>
>> in private
>> type Object_Implementation is
>> new Reference_Counted and Object_Interface with ...
>> -- implement operations here
>> overriding procedure Foo (X : in out Object_Implementation);
>>
>> in public
>> type Object is new Object_Interface with private;
>> -- implement operations here
>> overriding procedure Foo (X : in out Object);
>>
>> in private
>> type Object_Implementation_Ptr is access Object_Implementation'Class;
Should have been
type Object_Implementation_Ptr is access Object_Interface'Class;
sorry.
>> type Object is new Strong_Reference with record
>> Ptr : Object_Implementation_Ptr;
>> end record;
>>
>> The implementation of Object's Foo delegates:
>>
>> procedure Foo (X : in out Object) is
>> begin
>> X.Ptr.Foo;
>> end Foo;
>>
>> If Object_Implementation must use some existing type, aggregate it. That
>> won't change anything, because public clients won't see
>> Object_Implementation anyway. Who cares what was the parent type of?
>
> I can't follow what the code does, sorry. What would be the equivalent of this
> C++ code:
>
> std::shared_ptr<Object> shared_object (new Object);
>
> in the above example?
Not even close. The design goals are:
1. Hiding the implementation type from the clients. Clients have no access
to the destination object except than through the "pointer".
2. Decoupling "pointer" from the target type. Thus target type can be
designed later, there can be more than one target type.
3. Ensuring that each target type implements the interface of the
"pointer".
The C++'s design is upside down and inside out.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 20:53 ` EGarrulo
` (3 preceding siblings ...)
2015-07-31 8:26 ` Simon Wright
@ 2015-07-31 11:26 ` Brian Drummond
2015-07-31 12:12 ` EGarrulo
` (2 more replies)
4 siblings, 3 replies; 175+ messages in thread
From: Brian Drummond @ 2015-07-31 11:26 UTC (permalink / raw)
On Thu, 30 Jul 2015 13:53:26 -0700, EGarrulo wrote:
> I am not thinking in C++ terms. I am thinking in terms of patterns that
> I know for managing resources. So far, I only know the "shared/weak
> pointer" idiom. If Ada offers something else, besides manual
> reclamation, I am eager to learn about it.
To help us all get on the same page, can you link to a good description
(presumably, not in C++ terms) of what you mean by the "shared/weak
pointer idiom"? Or name the appropriate Design Pattern(s)?
I have sometimes felt it would be useful to translate some of the
standard programming texts into Ada - some of the GoF "Design Patterns"
turn out to be utterly trivial in Ada; some others have been covered ad-
hoc in the "Gems" series, in other cases I'm not clear which of several
approaches would be most appropriate.
-- Brian
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-31 11:26 ` Brian Drummond
@ 2015-07-31 12:12 ` EGarrulo
2015-07-31 12:15 ` EGarrulo
2015-07-31 17:54 ` Jeffrey R. Carter
2 siblings, 0 replies; 175+ messages in thread
From: EGarrulo @ 2015-07-31 12:12 UTC (permalink / raw)
On Friday, July 31, 2015 at 1:28:11 PM UTC+2, Brian Drummond wrote:
> On Thu, 30 Jul 2015 13:53:26 -0700, EGarrulo wrote:
>
> > I am not thinking in C++ terms. I am thinking in terms of patterns that
> > I know for managing resources. So far, I only know the "shared/weak
> > pointer" idiom. If Ada offers something else, besides manual
> > reclamation, I am eager to learn about it.
>
> To help us all get on the same page, can you link to a good description
> (presumably, not in C++ terms) of what you mean by the "shared/weak
> pointer idiom"? Or name the appropriate Design Pattern(s)?
Unfortunately, since the "shared/weak pointer" idiom originated in C++, where
its usage is pervasive, most examples are implemented in C++. Anyway, here
are some articles that you may read (just skip the C++ parts):
https://en.wikipedia.org/wiki/Smart_pointer
https://en.wikipedia.org/wiki/Weak_reference
https://en.wikipedia.org/wiki/Reference_counting
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-31 11:26 ` Brian Drummond
2015-07-31 12:12 ` EGarrulo
@ 2015-07-31 12:15 ` EGarrulo
2015-07-31 17:54 ` Jeffrey R. Carter
2 siblings, 0 replies; 175+ messages in thread
From: EGarrulo @ 2015-07-31 12:15 UTC (permalink / raw)
On Friday, July 31, 2015 at 1:28:11 PM UTC+2, Brian Drummond wrote:
> I have sometimes felt it would be useful to translate some of the
> standard programming texts into Ada - some of the GoF "Design Patterns"
> turn out to be utterly trivial in Ada; some others have been covered ad-
> hoc in the "Gems" series, in other cases I'm not clear which of several
> approaches would be most appropriate.
Indeed, this has been done for dynamic languages:
http://norvig.com/design-patterns/
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-31 11:26 ` Brian Drummond
2015-07-31 12:12 ` EGarrulo
2015-07-31 12:15 ` EGarrulo
@ 2015-07-31 17:54 ` Jeffrey R. Carter
2015-07-31 18:20 ` EGarrulo
2 siblings, 1 reply; 175+ messages in thread
From: Jeffrey R. Carter @ 2015-07-31 17:54 UTC (permalink / raw)
On 07/31/2015 04:26 AM, Brian Drummond wrote:
>
> I have sometimes felt it would be useful to translate some of the
> standard programming texts into Ada - some of the GoF "Design Patterns"
> turn out to be utterly trivial in Ada; some others have been covered ad-
> hoc in the "Gems" series, in other cases I'm not clear which of several
> approaches would be most appropriate.
Many of the "design patterns" are actually implementation patterns to work
around deficiencies in the languages used in the book. An obvious example is the
"singleton pattern". In Ada, a singleton is simply a pkg. It's only a problem
that needs a pattern in languages that lack modules.
--
Jeff Carter
"I'm a kike, a yid, a heebie, a hook nose! I'm Kosher,
Mum! I'm a Red Sea pedestrian, and proud of it!"
Monty Python's Life of Brian
77
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-31 17:54 ` Jeffrey R. Carter
@ 2015-07-31 18:20 ` EGarrulo
2015-07-31 18:51 ` Jeffrey R. Carter
` (2 more replies)
0 siblings, 3 replies; 175+ messages in thread
From: EGarrulo @ 2015-07-31 18:20 UTC (permalink / raw)
On Friday, July 31, 2015 at 7:54:52 PM UTC+2, Jeffrey R. Carter wrote:
> Many of the "design patterns" are actually implementation patterns to work
> around deficiencies in the languages used in the book. An obvious example is the
> "singleton pattern". In Ada, a singleton is simply a pkg. It's only a problem
> that needs a pattern in languages that lack modules.
But a singleton would be instantiated when the "Get_Instance" function gets
called by client code, not when a module gets loaded. Or does Ada load a package
at the first call?
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-31 18:20 ` EGarrulo
@ 2015-07-31 18:51 ` Jeffrey R. Carter
2015-08-01 7:20 ` Simon Wright
2015-08-01 7:48 ` Dmitry A. Kazakov
2 siblings, 0 replies; 175+ messages in thread
From: Jeffrey R. Carter @ 2015-07-31 18:51 UTC (permalink / raw)
On 07/31/2015 11:20 AM, EGarrulo wrote:
>
> But a singleton would be instantiated when the "Get_Instance" function gets
> called by client code, not when a module gets loaded. Or does Ada load a package
> at the first call?
Only a generic is instantiated. A singleton need not be generic.
--
Jeff Carter
"I'm a kike, a yid, a heebie, a hook nose! I'm Kosher,
Mum! I'm a Red Sea pedestrian, and proud of it!"
Monty Python's Life of Brian
77
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-31 18:20 ` EGarrulo
2015-07-31 18:51 ` Jeffrey R. Carter
@ 2015-08-01 7:20 ` Simon Wright
2015-08-01 8:06 ` EGarrulo
2015-08-01 17:00 ` Jeffrey R. Carter
2015-08-01 7:48 ` Dmitry A. Kazakov
2 siblings, 2 replies; 175+ messages in thread
From: Simon Wright @ 2015-08-01 7:20 UTC (permalink / raw)
EGarrulo <egarrulo@gmail.com> writes:
> On Friday, July 31, 2015 at 7:54:52 PM UTC+2, Jeffrey R. Carter wrote:
>> Many of the "design patterns" are actually implementation patterns to
>> work around deficiencies in the languages used in the book. An
>> obvious example is the "singleton pattern". In Ada, a singleton is
>> simply a pkg. It's only a problem that needs a pattern in languages
>> that lack modules.
>
> But a singleton would be instantiated when the "Get_Instance" function
> gets called by client code, not when a module gets loaded. Or does
> Ada load a package at the first call?
According to Wikipedia, a singleton "is useful when exactly one object
is needed to coordinate actions across the system". And encapsulating
that object in a package meets that criterion.
Isn't a Get_Instance function a way of getting the desired effect in C++
etc, rather than a necessary detail of the pattern? I can see that it
allows you to postpone creating the singleton instance until a time of
your choosing, rather than the Ada way of doing it during package
elaboration in a sequence chosen by the compilation/build engine.
With regard to Carter's point about "instantiation", it's a term that
Ada has specialised to mean creating an instance of a generic. I don't
know if there's an Ada term that means creating an object that is an
instance of a type? I could suggest "reification" :-) but I doubt that
would fly.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-08-01 7:20 ` Simon Wright
@ 2015-08-01 8:06 ` EGarrulo
2015-08-01 8:33 ` Simon Wright
2015-08-01 16:53 ` Jeffrey R. Carter
2015-08-01 17:00 ` Jeffrey R. Carter
1 sibling, 2 replies; 175+ messages in thread
From: EGarrulo @ 2015-08-01 8:06 UTC (permalink / raw)
On Saturday, August 1, 2015 at 9:19:05 AM UTC+2, Simon Wright wrote:
> EGarrulo writes:
>
> > On Friday, July 31, 2015 at 7:54:52 PM UTC+2, Jeffrey R. Carter wrote:
> >> Many of the "design patterns" are actually implementation patterns to
> >> work around deficiencies in the languages used in the book. An
> >> obvious example is the "singleton pattern". In Ada, a singleton is
> >> simply a pkg. It's only a problem that needs a pattern in languages
> >> that lack modules.
> >
> > But a singleton would be instantiated when the "Get_Instance" function
> > gets called by client code, not when a module gets loaded. Or does
> > Ada load a package at the first call?
>
> According to Wikipedia, a singleton "is useful when exactly one object
> is needed to coordinate actions across the system". And encapsulating
> that object in a package meets that criterion.
But all languages that I know let you do that, including C. Their concept of
a package may be informal, but it is there.
> Isn't a Get_Instance function a way of getting the desired effect in C++
> etc, rather than a necessary detail of the pattern? I can see that it
> allows you to postpone creating the singleton instance until a time of
> your choosing, rather than the Ada way of doing it during package
> elaboration in a sequence chosen by the compilation/build engine.
I can't see how Ada lets you postpone the creation of a singleton until a time
of your choosing, without resorting to Get_Instance. What is the equivalent of
this code:
if Some_Condition then
Singleton := Singleton_Package.Get_Instance;
-- Use singleton.
end if;
without using Get_Instance? I have tried:
if Some_Condition then
declare
with Ada; use Ada;
begin
Singleton := Singleton_Package.Singleton_Instance; -- Read variable.
-- Use singleton.
end;
end if;
But the compiler complains that "aspect specifications not allowed here". Or
does "with Package" put a package in scope without elaborating it until "use
Package", and therefore I should have left only the "use" directive?
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-08-01 8:06 ` EGarrulo
@ 2015-08-01 8:33 ` Simon Wright
2015-08-01 10:47 ` EGarrulo
2015-08-01 16:53 ` Jeffrey R. Carter
1 sibling, 1 reply; 175+ messages in thread
From: Simon Wright @ 2015-08-01 8:33 UTC (permalink / raw)
EGarrulo <egarrulo@gmail.com> writes:
> if Some_Condition then
> declare
> with Ada; use Ada;
> begin
> Singleton := Singleton_Package.Singleton_Instance; -- Read variable.
> -- Use singleton.
> end;
> end if;
>
> But the compiler complains that "aspect specifications not allowed
> here". Or does "with Package" put a package in scope without
> elaborating it until "use Package", and therefore I should have left
> only the "use" directive?
"with Pkg" can only occur in a compilation unit's context clauses.
"use Pkg" can appear there, and also in a declarative region (e.g. your
"declare" section).
"use" has no effect on elaboration, only on visibility. See ARM 10.2,
Program Execution.
http://www.adaic.org/resources/add_content/standards/12rm/html/RM-10-2.html
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-08-01 8:33 ` Simon Wright
@ 2015-08-01 10:47 ` EGarrulo
2015-08-01 11:27 ` Simon Wright
2015-08-01 11:44 ` Niklas Holsti
0 siblings, 2 replies; 175+ messages in thread
From: EGarrulo @ 2015-08-01 10:47 UTC (permalink / raw)
On Saturday, August 1, 2015 at 10:32:47 AM UTC+2, Simon Wright wrote:
> EGarrulo writes:
>
> > if Some_Condition then
> > declare
> > with Ada; use Ada;
> > begin
> > Singleton := Singleton_Package.Singleton_Instance; -- Read variable.
> > -- Use singleton.
> > end;
> > end if;
> >
> > But the compiler complains that "aspect specifications not allowed
> > here". Or does "with Package" put a package in scope without
> > elaborating it until "use Package", and therefore I should have left
> > only the "use" directive?
>
> "with Pkg" can only occur in a compilation unit's context clauses.
>
> "use Pkg" can appear there, and also in a declarative region (e.g. your
> "declare" section).
>
> "use" has no effect on elaboration, only on visibility. See ARM 10.2,
> Program Execution.
>
> http://www.adaic.org/resources/add_content/standards/12rm/html/RM-10-2.html
Thanks. Therefore there is no way to postpone the creation of a singleton
until client code needs it, by relying on package elaboration alone, right?
Therefore Ada -- too -- needs the Singleton pattern.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-08-01 10:47 ` EGarrulo
@ 2015-08-01 11:27 ` Simon Wright
2015-08-01 11:44 ` Niklas Holsti
1 sibling, 0 replies; 175+ messages in thread
From: Simon Wright @ 2015-08-01 11:27 UTC (permalink / raw)
EGarrulo <egarrulo@gmail.com> writes:
> Therefore there is no way to postpone the creation of a singleton
> until client code needs it, by relying on package elaboration alone,
> right? Therefore Ada -- too -- needs the Singleton pattern.
Not quite sure of the use case for that! I'd have thought it more likely
that you'd need to control the order of initialization.
But you're right that sometimes you can't rely on elaboration order
alone.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-08-01 10:47 ` EGarrulo
2015-08-01 11:27 ` Simon Wright
@ 2015-08-01 11:44 ` Niklas Holsti
2015-08-01 12:19 ` EGarrulo
1 sibling, 1 reply; 175+ messages in thread
From: Niklas Holsti @ 2015-08-01 11:44 UTC (permalink / raw)
On 15-08-01 13:47 , EGarrulo wrote:
> On Saturday, August 1, 2015 at 10:32:47 AM UTC+2, Simon Wright wrote:
>> EGarrulo writes:
>>
>>> if Some_Condition then
>>> declare
>>> with Ada; use Ada;
>>> begin
>>> Singleton := Singleton_Package.Singleton_Instance; -- Read variable.
>>> -- Use singleton.
>>> end;
>>> end if;
>>>
>>> But the compiler complains that "aspect specifications not allowed
>>> here". Or does "with Package" put a package in scope without
>>> elaborating it until "use Package", and therefore I should have left
>>> only the "use" directive?
>>
>> "with Pkg" can only occur in a compilation unit's context clauses.
>>
>> "use Pkg" can appear there, and also in a declarative region (e.g. your
>> "declare" section).
>>
>> "use" has no effect on elaboration, only on visibility. See ARM 10.2,
>> Program Execution.
>>
>> http://www.adaic.org/resources/add_content/standards/12rm/html/RM-10-2.html
>
> Thanks. Therefore there is no way to postpone the creation of a singleton
> until client code needs it, by relying on package elaboration alone, right?
> Therefore Ada -- too -- needs the Singleton pattern.
Discussion of design patterns easily degenerates into a debate about
terminology.
To second Simon's post, an Ada (library-level) package, as a collection
of state and operations, with necessarily exactly once instance of the
state, matches the concept of a singleton object in all respects except
as regards the "lazy initialization" thing, which to me is a very
secondary aspect of singletons.
If an Ada "singleton" package is a significant consumer of memory and/or
initialization time, it is easy to arrange for most of the memory
allocation and initialization to occur lazily, when the package (or that
part of the package) is used for the first time. One way to do that is
to insert a check for initialization at the start of every operation;
another way is to have some kind of Get_Instance operation that
initializes the package (i.e. "creates the singleton") and returns a
handle that is a required parameter for all other operations.
While elaboration order is defined by the "need" relationship between
modules, this is the static relationship defined by the "with" clauses,
and is satisfied before the main subprogram starts. Whether this means
that Ada "needs" the singleton pattern is a moot point.
--
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
. @ .
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-08-01 11:44 ` Niklas Holsti
@ 2015-08-01 12:19 ` EGarrulo
2015-08-01 17:49 ` Jeffrey R. Carter
0 siblings, 1 reply; 175+ messages in thread
From: EGarrulo @ 2015-08-01 12:19 UTC (permalink / raw)
On Saturday, August 1, 2015 at 1:44:59 PM UTC+2, Niklas Holsti wrote:
> Discussion of design patterns easily degenerates into a debate about
> terminology.
>
> To second Simon's post, an Ada (library-level) package, as a collection
> of state and operations, with necessarily exactly once instance of the
> state, matches the concept of a singleton object in all respects except
> as regards the "lazy initialization" thing, which to me is a very
> secondary aspect of singletons.
But the original point was that the Singleton pattern was conceived to work
around deficiencies in the languages used in the "Design Patterns" book. I
don't see how those languages are deficient in that respect. It is just that
those languages implement the concept differently. What is a package in Ada,
is a class with static methods in C++ and Java, or even a ".c" file in C. The
goal of the "Design Patterns" book was not to describe how to work around
deficiencies in a language, or even to show how to solve some design problems, but to describe but how problems had already been solved and then to establish
a shared vocabulary to improve communication between designers. The "Design
Patterns" book is descriptive, not prescriptive.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-08-01 12:19 ` EGarrulo
@ 2015-08-01 17:49 ` Jeffrey R. Carter
2015-08-01 18:15 ` Paul Rubin
2015-08-01 20:44 ` EGarrulo
0 siblings, 2 replies; 175+ messages in thread
From: Jeffrey R. Carter @ 2015-08-01 17:49 UTC (permalink / raw)
On 08/01/2015 05:19 AM, EGarrulo wrote:
>
> But the original point was that the Singleton pattern was conceived to work
> around deficiencies in the languages used in the "Design Patterns" book. I
> don't see how those languages are deficient in that respect. It is just that
> those languages implement the concept differently. What is a package in Ada,
> is a class with static methods in C++ and Java, or even a ".c" file in C. The
> goal of the "Design Patterns" book was not to describe how to work around
> deficiencies in a language, or even to show how to solve some design problems, but to describe but how problems had already been solved and then to establish
> a shared vocabulary to improve communication between designers. The "Design
> Patterns" book is descriptive, not prescriptive.
I guess we have different definitions of "deficiency." Yours seems to be
something that it is impossible to achieve using the language; if there's a way
to do it, no matter how difficult, complex, and unintuitive, then it's not a
deficiency. By mine, a language that doesn't have a simple, obvious way to
implement common concepts has a deficiency.
In this case, a common idiom that is so simple and obvious in Ada that it
doesn't even have a name for it (I was creating them for over a decade before I
ever encountered the term "singleton" as used in DP) is so difficult, complex,
and unintuitive in these other languages that apparently many people can't
figure it out on their own, so the "trick" has to be written down for them.
The differences between true modules and the C++ "class" construct have been
hashed over so much that there's no point in me repeating it here. The upshot of
it is that they are not equivalent. If they were, a singleton in C++ would be as
simple and obvious as in Ada.
The pkg is a very important concept in Ada, and your insistence that there has
to be a Get_Instance function shows that you don't fully understand it yet.
Until you do, you won't really understand Ada.
--
Jeff Carter
"I don't know why I ever come in here. The
flies get the best of everything."
Never Give a Sucker an Even Break
102
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-08-01 17:49 ` Jeffrey R. Carter
@ 2015-08-01 18:15 ` Paul Rubin
2015-08-01 18:59 ` Jeffrey R. Carter
2015-08-01 20:30 ` Georg Bauhaus
2015-08-01 20:44 ` EGarrulo
1 sibling, 2 replies; 175+ messages in thread
From: Paul Rubin @ 2015-08-01 18:15 UTC (permalink / raw)
"Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> writes:
> The pkg is a very important concept in Ada, and your insistence that there has
> to be a Get_Instance function shows that you don't fully understand it yet.
> Until you do, you won't really understand Ada.
Is there a good place to read about this? I had the impression that
package initialization runs unconditionally. EGarrulo was asking how to
get it to run only in response to a runtime request that might never
happen.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-08-01 18:15 ` Paul Rubin
@ 2015-08-01 18:59 ` Jeffrey R. Carter
2015-08-01 20:30 ` Georg Bauhaus
1 sibling, 0 replies; 175+ messages in thread
From: Jeffrey R. Carter @ 2015-08-01 18:59 UTC (permalink / raw)
On 08/01/2015 11:15 AM, Paul Rubin wrote:
>
> Is there a good place to read about this? I had the impression that
> package initialization runs unconditionally. EGarrulo was asking how to
> get it to run only in response to a runtime request that might never
> happen.
It depends on what you mean by "initialize". Elaboration of a library pkg occurs
at start up unconditionally. There's no requirement that a pkg be a library pkg,
so that could be a way to get pkg elaboration to happen later, though it's not
common.
Initialization of an object happens when the object is created. For an object
created by an object declaration, that happens when the declaration is elaborated:
package body P is
State : Integer := Integer'First;
If the initialization is complex, it can be done in the executable part of the
pkg body when that is elaborated:
package body P is
State : Integer;
...
begin
-- complex code that assigns a value to State
end P;
If initializing State requires information that the pkg can't get by itself,
then initialization can be performed by an operation called by a client:
package P is
State : Integer;
Initialized : Boolean := False;
procedure Initialize (Value : in Integer) is
begin
if Initialized then
raise Already_Initialized;
end if;
State := Value;
Initialized := True;
end Initialize;
procedure Op is
begin
if not Initialized then
raise Not_Initialized;
end if;
...
end Op;
This latter case delays initialization to response to a run-time request that
might never happen. Allocation of storage for State still happens during
elaboration of P. Delaying allocation of storage as well is straightforward and
left as an exercise for the reader.
--
Jeff Carter
"I don't know why I ever come in here. The
flies get the best of everything."
Never Give a Sucker an Even Break
102
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-08-01 18:15 ` Paul Rubin
2015-08-01 18:59 ` Jeffrey R. Carter
@ 2015-08-01 20:30 ` Georg Bauhaus
1 sibling, 0 replies; 175+ messages in thread
From: Georg Bauhaus @ 2015-08-01 20:30 UTC (permalink / raw)
On 01.08.15 20:15, Paul Rubin wrote:
> "Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> writes:
>> The pkg is a very important concept in Ada, and your insistence that there has
>> to be a Get_Instance function shows that you don't fully understand it yet.
>> Until you do, you won't really understand Ada.
>
> Is there a good place to read about this? I had the impression that
> package initialization runs unconditionally. EGarrulo was asking how to
> get it to run only in response to a runtime request that might never
> happen.
I'm sneaking this in here. A generic instance has context, sometimes
non-static context, on which it depends:
with Ada.Text_IO;
with Ada.Calendar; use Ada.Calendar;
procedure Late is
Start : Time;
generic
Now : Time;
package Again is
-- tells the time
end Again;
package body Again is
begin
Ada.Text_IO.Put_Line (Duration'Image (Now - Start));
end Again;
begin
Start := Clock;
loop
delay 1.0;
declare
package Tick is new Again (Now => Clock);
begin
null;
end;
end loop;
end Late;
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-08-01 17:49 ` Jeffrey R. Carter
2015-08-01 18:15 ` Paul Rubin
@ 2015-08-01 20:44 ` EGarrulo
2015-08-01 22:44 ` Jeffrey R. Carter
1 sibling, 1 reply; 175+ messages in thread
From: EGarrulo @ 2015-08-01 20:44 UTC (permalink / raw)
On Saturday, August 1, 2015 at 7:49:17 PM UTC+2, Jeffrey R. Carter wrote:
> I guess we have different definitions of "deficiency." Yours seems to be
> something that it is impossible to achieve using the language; if there's a way
> to do it, no matter how difficult, complex, and unintuitive, then it's not a
> deficiency. By mine, a language that doesn't have a simple, obvious way to
> implement common concepts has a deficiency.
I would rather say that my definition of "deficiency" does not include
different idioms. Ada and C++ have different ways to accomplish encapsulation:
Ada encapsulation is accomplished using the Package.
C++ encapsulation is accomplished using the Class.
[source: http://www.adahome.com/articles/1997-03/ada_vs_cpp.html]
> The differences between true modules and the C++ "class" construct have been
> hashed over so much that there's no point in me repeating it here. The upshot of
> it is that they are not equivalent. If they were, a singleton in C++ would be as
> simple and obvious as in Ada.
And indeed it is. Your Ada example:
if Some_Condition then
-- Call operations of Singleton_Package
end if;
translates directly to C++:
if (some_condition) {
// Call static operations of Singleton_Class.
}
Where is the difference? I don't see any.
Maybe some C++ constructs are not well understood by Ada programmers. Take this
quote, for example:
12. What is the fundamental difference between a C++ class and an Ada
package?
Ada packages are more generalize [sic] encapsulations that can define any
number of types.
[see https://stevanussugianto.wordpress.com/2013/06/06/concept-of-programming-languages-chapter-11-abstract-data-types-and-encapsulation-constructs/]
But you can define any number of types in C++ classes, too! This is why you can
ask a container about the type of its elements; something that the STL exploits
heavily; and also something that you can't do in Ada, because the type of the
elements of a container are defined in the package that defines the
container.
> The pkg is a very important concept in Ada, and your insistence that there has
> to be a Get_Instance function shows that you don't fully understand it yet.
> Until you do, you won't really understand Ada.
Actually, I don't see anything esoteric about Ada packages. I have insisted on
a Get_Instance function because otherwise the Singleton pattern wouldn't be any
different from global variables (or static class members).
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-08-01 20:44 ` EGarrulo
@ 2015-08-01 22:44 ` Jeffrey R. Carter
2015-08-01 23:39 ` EGarrulo
2015-08-02 2:53 ` Paul Rubin
0 siblings, 2 replies; 175+ messages in thread
From: Jeffrey R. Carter @ 2015-08-01 22:44 UTC (permalink / raw)
On 08/01/2015 01:44 PM, EGarrulo wrote:
>
> if Some_Condition then
> -- Call operations of Singleton_Package
> end if;
>
> translates directly to C++:
>
> if (some_condition) {
> // Call static operations of Singleton_Class.
> }
>
> Where is the difference? I don't see any.
>
> Actually, I don't see anything esoteric about Ada packages. I have insisted on
> a Get_Instance function because otherwise the Singleton pattern wouldn't be any
> different from global variables (or static class members).
Here you've lost me again. A singleton is some hidden state and some operations
that use that state. If it can be as simple as calling static operations of a
class, then why do you and the DP book insist on all the complications? If the
complications are necessary, how can it be that simple?
--
Jeff Carter
"I don't know why I ever come in here. The
flies get the best of everything."
Never Give a Sucker an Even Break
102
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-08-01 22:44 ` Jeffrey R. Carter
@ 2015-08-01 23:39 ` EGarrulo
2015-08-02 0:02 ` Jeffrey R. Carter
2015-08-02 2:53 ` Paul Rubin
1 sibling, 1 reply; 175+ messages in thread
From: EGarrulo @ 2015-08-01 23:39 UTC (permalink / raw)
On Sunday, August 2, 2015 at 12:44:46 AM UTC+2, Jeffrey R. Carter wrote:
> On 08/01/2015 01:44 PM, EGarrulo wrote:
> >
> > if Some_Condition then
> > -- Call operations of Singleton_Package
> > end if;
> >
> > translates directly to C++:
> >
> > if (some_condition) {
> > // Call static operations of Singleton_Class.
> > }
> >
> > Where is the difference? I don't see any.
> >
> > Actually, I don't see anything esoteric about Ada packages. I have insisted on
> > a Get_Instance function because otherwise the Singleton pattern wouldn't be any
> > different from global variables (or static class members).
>
> Here you've lost me again. A singleton is some hidden state and some operations
> that use that state.
It is more than that. The "Applicability" for the Singleton patterns requires
that "the sole instance should be extensible by sub-classing, and clients should
be able to use an extended instance without modifying their code." In other
words: if you don't need sub-classing, then you don't need the complications of
the Singleton pattern.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-08-01 23:39 ` EGarrulo
@ 2015-08-02 0:02 ` Jeffrey R. Carter
2015-08-02 0:18 ` EGarrulo
2015-08-02 0:30 ` EGarrulo
0 siblings, 2 replies; 175+ messages in thread
From: Jeffrey R. Carter @ 2015-08-02 0:02 UTC (permalink / raw)
On 08/01/2015 04:39 PM, EGarrulo wrote:
>
> It is more than that. The "Applicability" for the Singleton patterns requires
> that "the sole instance should be extensible by sub-classing, and clients should
> be able to use an extended instance without modifying their code." In other
> words: if you don't need sub-classing, then you don't need the complications of
> the Singleton pattern.
You never need programming by extension.
--
Jeff Carter
"I don't know why I ever come in here. The
flies get the best of everything."
Never Give a Sucker an Even Break
102
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-08-02 0:02 ` Jeffrey R. Carter
@ 2015-08-02 0:18 ` EGarrulo
2015-08-02 0:30 ` EGarrulo
1 sibling, 0 replies; 175+ messages in thread
From: EGarrulo @ 2015-08-02 0:18 UTC (permalink / raw)
On Sunday, August 2, 2015 at 2:02:30 AM UTC+2, Jeffrey R. Carter wrote:
> You never need programming by extension.
"Never" is a big word :) Here is a use case: a GUI application that lets the
user use its preferred GUI widgets (GTK, Motif, etc.).
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-08-02 0:02 ` Jeffrey R. Carter
2015-08-02 0:18 ` EGarrulo
@ 2015-08-02 0:30 ` EGarrulo
2015-08-02 6:05 ` Jeffrey R. Carter
1 sibling, 1 reply; 175+ messages in thread
From: EGarrulo @ 2015-08-02 0:30 UTC (permalink / raw)
I meant: a GUI application that lets the user select its preferred GUI widget
toolkit (GTK, Motif, etc.) at startup.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-08-02 0:30 ` EGarrulo
@ 2015-08-02 6:05 ` Jeffrey R. Carter
2015-08-02 8:29 ` EGarrulo
0 siblings, 1 reply; 175+ messages in thread
From: Jeffrey R. Carter @ 2015-08-02 6:05 UTC (permalink / raw)
On 08/01/2015 05:30 PM, EGarrulo wrote:
> I meant: a GUI application that lets the user select its preferred GUI widget
> toolkit (GTK, Motif, etc.) at startup.
Programming by extension is not needed for this.
--
Jeff Carter
"I don't know why I ever come in here. The
flies get the best of everything."
Never Give a Sucker an Even Break
102
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-08-02 6:05 ` Jeffrey R. Carter
@ 2015-08-02 8:29 ` EGarrulo
2015-08-02 19:21 ` Jeffrey R. Carter
0 siblings, 1 reply; 175+ messages in thread
From: EGarrulo @ 2015-08-02 8:29 UTC (permalink / raw)
On Sunday, August 2, 2015 at 8:05:21 AM UTC+2, Jeffrey R. Carter wrote:
> On 08/01/2015 05:30 PM, EGarrulo wrote:
> > I meant: a GUI application that lets the user select its preferred GUI widget
> > toolkit (GTK, Motif, etc.) at startup.
>
> Programming by extension is not needed for this.
How would you solve the problem, then?
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-08-02 8:29 ` EGarrulo
@ 2015-08-02 19:21 ` Jeffrey R. Carter
2015-08-02 21:37 ` EGarrulo
0 siblings, 1 reply; 175+ messages in thread
From: Jeffrey R. Carter @ 2015-08-02 19:21 UTC (permalink / raw)
On 08/02/2015 01:29 AM, EGarrulo wrote:
> On Sunday, August 2, 2015 at 8:05:21 AM UTC+2, Jeffrey R. Carter wrote:
>> On 08/01/2015 05:30 PM, EGarrulo wrote:
>>> I meant: a GUI application that lets the user select its preferred GUI widget
>>> toolkit (GTK, Motif, etc.) at startup.
>>
>> Programming by extension is not needed for this.
>
> How would you solve the problem, then?
With programming by composition, of course.
--
Jeff Carter
"Hold your temper. Count ten.... Now let 'er go.
You got a good aim."
Never Give a Sucker an Even Break
105
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-08-02 19:21 ` Jeffrey R. Carter
@ 2015-08-02 21:37 ` EGarrulo
2015-08-03 2:35 ` Jeffrey R. Carter
0 siblings, 1 reply; 175+ messages in thread
From: EGarrulo @ 2015-08-02 21:37 UTC (permalink / raw)
On Sunday, August 2, 2015 at 9:21:12 PM UTC+2, Jeffrey R. Carter wrote:
> On 08/02/2015 01:29 AM, EGarrulo wrote:
> > On Sunday, August 2, 2015 at 8:05:21 AM UTC+2, Jeffrey R. Carter wrote:
> >> On 08/01/2015 05:30 PM, EGarrulo wrote:
> >>> I meant: a GUI application that lets the user select its preferred GUI widget
> >>> toolkit (GTK, Motif, etc.) at startup.
> >>
> >> Programming by extension is not needed for this.
> >
> > How would you solve the problem, then?
>
> With programming by composition, of course.
And would that decrease complexity, or just move it elsewhere? I am afraid
that it would increase complexity, and substantially. Indeed, the "Design
Patterns" book itself recommends "Favor 'object composition' over 'class
inheritance'". And yet the Singleton pattern uses inheritance. Had the
authors felt that composition were applicable for the Singleton, they would
have adopted it, don't you think? Anyway, if an alternative to Singleton that
uses composition has been documented somewhere, I would gladly peruse it.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-08-02 21:37 ` EGarrulo
@ 2015-08-03 2:35 ` Jeffrey R. Carter
0 siblings, 0 replies; 175+ messages in thread
From: Jeffrey R. Carter @ 2015-08-03 2:35 UTC (permalink / raw)
On 08/02/2015 02:37 PM, EGarrulo wrote:
>
> And would that decrease complexity, or just move it elsewhere? I am afraid
> that it would increase complexity, and substantially. Indeed, the "Design
> Patterns" book itself recommends "Favor 'object composition' over 'class
> inheritance'". And yet the Singleton pattern uses inheritance. Had the
> authors felt that composition were applicable for the Singleton, they would
> have adopted it, don't you think? Anyway, if an alternative to Singleton that
> uses composition has been documented somewhere, I would gladly peruse it.
Some years ago I published articles on the problems with programming by
extension. I'm hardly going to repeat them here. Using examples intended to show
the advantages of extension, I showed that programming by composition can do
anything extension can, leads to code that is clearer and easier to understand,
and that the examples violated basic S/W-engineering principles. The papers can
be be found at
http://pragmada.x10hosting.com/papers.html
--
Jeff Carter
"Hold your temper. Count ten.... Now let 'er go.
You got a good aim."
Never Give a Sucker an Even Break
105
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-08-01 22:44 ` Jeffrey R. Carter
2015-08-01 23:39 ` EGarrulo
@ 2015-08-02 2:53 ` Paul Rubin
2015-08-02 6:07 ` Jeffrey R. Carter
2015-08-02 8:36 ` EGarrulo
1 sibling, 2 replies; 175+ messages in thread
From: Paul Rubin @ 2015-08-02 2:53 UTC (permalink / raw)
"Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> writes:
> Here you've lost me again. A singleton is some hidden state and some operations
> that use that state. If it can be as simple as calling static operations of a
> class, then why do you and the DP book insist on all the complications? If the
> complications are necessary, how can it be that simple?
Singleton is sort of a misnomer. It sounds like there is always exactly
one instance, but it really means there is either one instance or zero
instances. There are zero when the program starts, but during the
program's execution it may decide to create one instance. The scheme
you're describing with packages sounds like the one instance is created
when the program starts. It doesn't explain how to start with zero
instances, and dynamically create one later.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-08-02 2:53 ` Paul Rubin
@ 2015-08-02 6:07 ` Jeffrey R. Carter
2015-08-02 8:36 ` EGarrulo
1 sibling, 0 replies; 175+ messages in thread
From: Jeffrey R. Carter @ 2015-08-02 6:07 UTC (permalink / raw)
On 08/01/2015 07:53 PM, Paul Rubin wrote:
>
> Singleton is sort of a misnomer. It sounds like there is always exactly
> one instance, but it really means there is either one instance or zero
> instances. There are zero when the program starts, but during the
> program's execution it may decide to create one instance. The scheme
> you're describing with packages sounds like the one instance is created
> when the program starts. It doesn't explain how to start with zero
> instances, and dynamically create one later.
Normally you don't care if you've allocated the pkg state and it's never used.
That's the normal Ada way. If there is some reason to avoid allocating the state
unless it's used, then you don't allocate the state until an operation is called.
--
Jeff Carter
"I don't know why I ever come in here. The
flies get the best of everything."
Never Give a Sucker an Even Break
102
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-08-02 2:53 ` Paul Rubin
2015-08-02 6:07 ` Jeffrey R. Carter
@ 2015-08-02 8:36 ` EGarrulo
1 sibling, 0 replies; 175+ messages in thread
From: EGarrulo @ 2015-08-02 8:36 UTC (permalink / raw)
On Sunday, August 2, 2015 at 4:53:49 AM UTC+2, Paul Rubin wrote:
> "Jeffrey R. Carter" writes:
> > Here you've lost me again. A singleton is some hidden state and some operations
> > that use that state. If it can be as simple as calling static operations of a
> > class, then why do you and the DP book insist on all the complications? If the
> > complications are necessary, how can it be that simple?
>
> Singleton is sort of a misnomer. It sounds like there is always exactly
> one instance, but it really means there is either one instance or zero
> instances. There are zero when the program starts, but during the
> program's execution it may decide to create one instance.
Actually, the Singleton pattern lets you add instances later, without the
clients noticing.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-08-01 8:06 ` EGarrulo
2015-08-01 8:33 ` Simon Wright
@ 2015-08-01 16:53 ` Jeffrey R. Carter
1 sibling, 0 replies; 175+ messages in thread
From: Jeffrey R. Carter @ 2015-08-01 16:53 UTC (permalink / raw)
On 08/01/2015 01:06 AM, EGarrulo wrote:
>
> I can't see how Ada lets you postpone the creation of a singleton until a time
> of your choosing, without resorting to Get_Instance. What is the equivalent of
> this code:
>
> if Some_Condition then
> Singleton := Singleton_Package.Get_Instance;
> -- Use singleton.
> end if;
The Ada equivalent is
if Some_Condition then
-- Call operations of Singleton_Package
end if;
You don't have a variable for a singleton; the pkg is the singleton. The need
for a variable in other languages is why this "pattern" is a workaround for the
lack of modules in those languages.
If for some reason your application has a requirement that the storage for the
state of the pkg not be allocated until the first use of the pkg, then the
implementation of the pkg can allocate that storage the 1st time the pkg is
used. The clients of the pkg use it the same way in both cases.
Such a requirement is rare in my experience. What is more common is that the
initialization of the pkg state requires information that is not available
during elaboration; in that case, the pkg has an Initialize operation that is
called when the information is available.
--
Jeff Carter
"I don't know why I ever come in here. The
flies get the best of everything."
Never Give a Sucker an Even Break
102
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-08-01 7:20 ` Simon Wright
2015-08-01 8:06 ` EGarrulo
@ 2015-08-01 17:00 ` Jeffrey R. Carter
1 sibling, 0 replies; 175+ messages in thread
From: Jeffrey R. Carter @ 2015-08-01 17:00 UTC (permalink / raw)
On 08/01/2015 12:20 AM, Simon Wright wrote:
>
> With regard to Carter's point about "instantiation", it's a term that
> Ada has specialised to mean creating an instance of a generic. I don't
> know if there's an Ada term that means creating an object that is an
> instance of a type? I could suggest "reification" :-) but I doubt that
> would fly.
Creating an object of a type can be done in 2 ways in Ada, and there are 2 terms
for it. One is an object declaration:
Object : [constant] Type_Name [:= Initial];
The other is an allocator:
type Type_Ptr is access [all] Type_Name;
Ptr : Type_Ptr;
Ptr := new Type_Name['(Initial)];
--
Jeff Carter
"I don't know why I ever come in here. The
flies get the best of everything."
Never Give a Sucker an Even Break
102
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-31 18:20 ` EGarrulo
2015-07-31 18:51 ` Jeffrey R. Carter
2015-08-01 7:20 ` Simon Wright
@ 2015-08-01 7:48 ` Dmitry A. Kazakov
2 siblings, 0 replies; 175+ messages in thread
From: Dmitry A. Kazakov @ 2015-08-01 7:48 UTC (permalink / raw)
On Fri, 31 Jul 2015 11:20:35 -0700 (PDT), EGarrulo wrote:
> On Friday, July 31, 2015 at 7:54:52 PM UTC+2, Jeffrey R. Carter wrote:
>> Many of the "design patterns" are actually implementation patterns to work
>> around deficiencies in the languages used in the book. An obvious example is the
>> "singleton pattern". In Ada, a singleton is simply a pkg. It's only a problem
>> that needs a pattern in languages that lack modules.
>
> But a singleton would be instantiated when the "Get_Instance" function gets
> called by client code, not when a module gets loaded. Or does Ada load a package
> at the first call?
Well, since other responses regarding singletons were IMO wrong. Here is an
answer from the OO POV.
In Ada singleton is achieved directly by the language means.
[ When Ada was designed there was no pattern stuff, which Jeffrey correctly
characterized as workarounds. Yet Ada designers understood the problem,
maybe unconsciously, and resolved it at the language level. ]
Ada's singleton is an object of anonymous type. Many types allow object
declarations of anonymous types, which guarantees single instance, because
the type has no name.
Array singleton:
Singleton : array (1..3) of Integer;
Task singleton:
task Singleton is
...
end task;
Protected object singleton:
protected Singleton is
...
end task;
Access type singleton (note access, not the target):
Singleton : [not null] access ...;
For other types the singleton pattern is a declaration of the type and the
instance in the package body. This is probably what Jeffrey meant talking
about packages:
package body P is
type Nobody_See_Me is ...;
Singleton : Nobody_See_Me;
P.S. Get_Instance is C++ gibberish because it cannot create/return
unconstrained instances. In Ada you declare an object, singleton or not,
and that creates it. End of story.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 8:03 ` EGarrulo
2015-07-30 8:08 ` Jacob Sparre Andersen
@ 2015-07-30 8:23 ` Georg Bauhaus
2015-07-30 8:45 ` EGarrulo
` (2 more replies)
2015-07-30 8:28 ` Pascal Obry
` (2 subsequent siblings)
4 siblings, 3 replies; 175+ messages in thread
From: Georg Bauhaus @ 2015-07-30 8:23 UTC (permalink / raw)
On 30.07.15 10:03, EGarrulo wrote:
> On Thursday, July 30, 2015 at 9:31:36 AM UTC+2, björn lundin wrote:
>> On 2015-07-30 08:01, Niklas Holsti wrote:
>>> On 15-07-30 03:10 , EGarrulo wrote:
>>>> Who knows? But since the realm of Ada is limited to embedded
>>>> development,
>>>
>>> It isn't.
>>
>> It is certainly not.
>> I've spent 18 years writing Ada in WMS/WCS systems -
>> Database intense system with 100+ concurrent users
>> Nothing embedded at all with them.
>
> That doesn't mean much. Ada doesn't offer any facility for
> automatic resource management, and that makes it unsuitable for
> applications that go beyond constrained embedded development. Who
> wants to chase resource leaks in this day and age?
Is this about GC only? Having had to fight GC in Java,
at a time when it was assumed that GC would magically have
no effect on the program, I'm not sure this isn't a bit
optimistic. But surely it is what one should say.
For completeness, management of resources other than
memory, if tied to GC, becomes uncontrolled happenstance.
There are others who think that the allocation management
of older Objective-C, say, was something they could well
live with (e.g. Hillegass, but maybe he is biased).
And now we got weak and strong properties and all kinds
of algorithmic shift around them. That seems to match what
Dmitry has been explaining about hard/soft references.
The next cry is certainly for automatic hardness management
of reference.
In Ada, use the stack, if possible!
In Ada 2005, use containers, if possible!
> Not to mention
> the crippled support for exceptions in Ada.
Do you mean that exceptions of Ada cannot be used for indirecting
non-local control flow with the help of exception objects? I'm still
not sure anything but messages should go with exceptions: it is
too tempting for consultants to apply techniques of obfuscation
via exception classes. Even involuntarily!
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 8:23 ` Georg Bauhaus
@ 2015-07-30 8:45 ` EGarrulo
2015-07-30 9:19 ` Dmitry A. Kazakov
` (3 more replies)
2015-07-30 9:18 ` EGarrulo
2015-07-30 11:35 ` Brian Drummond
2 siblings, 4 replies; 175+ messages in thread
From: EGarrulo @ 2015-07-30 8:45 UTC (permalink / raw)
On Thursday, July 30, 2015 at 10:23:23 AM UTC+2, Georg Bauhaus wrote:
> On 30.07.15 10:03, EGarrulo wrote:
> > On Thursday, July 30, 2015 at 9:31:36 AM UTC+2, björn lundin wrote:
> >> On 2015-07-30 08:01, Niklas Holsti wrote:
> >>> On 15-07-30 03:10 , EGarrulo wrote:
> >>>> Who knows? But since the realm of Ada is limited to embedded
> >>>> development,
> >>>
> >>> It isn't.
> >>
> >> It is certainly not.
> >> I've spent 18 years writing Ada in WMS/WCS systems -
> >> Database intense system with 100+ concurrent users
> >> Nothing embedded at all with them.
> >
> > That doesn't mean much. Ada doesn't offer any facility for
> > automatic resource management, and that makes it unsuitable for
> > applications that go beyond constrained embedded development. Who
> > wants to chase resource leaks in this day and age?
>
> Is this about GC only? Having had to fight GC in Java,
> at a time when it was assumed that GC would magically have
> no effect on the program, I'm not sure this isn't a bit
> optimistic. But surely it is what one should say.
>
> For completeness, management of resources other than
> memory, if tied to GC, becomes uncontrolled happenstance.
>
> There are others who think that the allocation management
> of older Objective-C, say, was something they could well
> live with (e.g. Hillegass, but maybe he is biased).
> And now we got weak and strong properties and all kinds
> of algorithmic shift around them. That seems to match what
> Dmitry has been explaining about hard/soft references.
> The next cry is certainly for automatic hardness management
> of reference.
>
> In Ada, use the stack, if possible!
> In Ada 2005, use containers, if possible!
>
> > Not to mention
> > the crippled support for exceptions in Ada.
>
> Do you mean that exceptions of Ada cannot be used for indirecting
> non-local control flow with the help of exception objects?
Exceptions in Ada cannot carry contextual information, nor they
can be chained (albeit you could hack them to do both). Where
is the usefulness of knowing that something has gone awry,
without any context? For example: "'File not found?' What file
was the program trying to open, and why?" In embedded software,
it makes sense to avoid memory allocations while raising an
exception, but elsewhere?
> I'm still
> not sure anything but messages should go with exceptions: it is
> too tempting for consultants to apply techniques of obfuscation
> via exception classes. Even involuntarily!
Could you explain further, please?
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 8:45 ` EGarrulo
@ 2015-07-30 9:19 ` Dmitry A. Kazakov
2015-07-30 11:22 ` Niklas Holsti
` (2 subsequent siblings)
3 siblings, 0 replies; 175+ messages in thread
From: Dmitry A. Kazakov @ 2015-07-30 9:19 UTC (permalink / raw)
On Thu, 30 Jul 2015 01:45:18 -0700 (PDT), EGarrulo wrote:
> Exceptions in Ada cannot carry contextual information,
Which is right and important, semantically. The context is dead, not
carrying corpses...
Ada's model (and of C++ as well) is leave first, handle later. An
alternative model in early languages, like in PL/1: handle, then return,
proved to be useless.
> Where
> is the usefulness of knowing that something has gone awry,
> without any context?
Of course there is a context, this is the context of the handler. See
above, it is an important semantic of the design. An exceptional state is
one that *cannot* be handled on the context it occurred. That is the whole
idea. If you could handle it, you would right at the point. Exception
propagation is looking for a context where you can handle the exception.
Note also decoupling, an important thing from the SW design POV. Neither
context need not to know anything about the other.
> For example: "'File not found?' What file
> was the program trying to open, and why?"
Yes, how the OS (the exception context) is supposed to know this? The
handler's context knows it fine, because it is where file was attempted to
open.
> In embedded software,
> it makes sense to avoid memory allocations while raising an
> exception, but elsewhere?
Everywhere. It is about limiting the side effects of an action. Exceptions,
since more than frequently, are misused for dealing with bugs, are first
candidates to limit side effects as much as possible.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 8:45 ` EGarrulo
2015-07-30 9:19 ` Dmitry A. Kazakov
@ 2015-07-30 11:22 ` Niklas Holsti
2015-07-30 13:00 ` EGarrulo
2015-07-30 14:31 ` G.B.
2015-07-30 18:46 ` Randy Brukardt
3 siblings, 1 reply; 175+ messages in thread
From: Niklas Holsti @ 2015-07-30 11:22 UTC (permalink / raw)
On 15-07-30 11:45 , EGarrulo wrote:
> On Thursday, July 30, 2015 at 10:23:23 AM UTC+2, Georg Bauhaus wrote:
>> On 30.07.15 10:03, EGarrulo wrote:
>>> Not to mention
>>> the crippled support for exceptions in Ada.
>>
>> Do you mean that exceptions of Ada cannot be used for indirecting
>> non-local control flow with the help of exception objects?
>
> Exceptions in Ada cannot carry contextual information, Where
> is the usefulness of knowing that something has gone awry,
> without any context? For example: "'File not found?' What file
> was the program trying to open, and why?"
I suspect that you are conflating two possible uses of exception-handling:
1. To let the program detect and possibly recover automatically from
run-time failures.
2. To inform the program's user about run-time failures so that the user
can understand what went wrong and how to correct it.
Ada's exception facility was designed for (1), and is only indirectly
useful for (2). The idea is that exceptions should be handled at a level
that knows enough about the context to perform the recovery, or to
describe the details of the failure to the user.
For example, the idiom for opening a file is:
File_Name : String := ...
begin
Open (File, Name => File_Name, ...);
-- Successful: do something with the File.
exception when ... =>
-- Here the handler knows which file we tried to open
-- and can act accordingly.
end;
This can be a bit cumbersome in case one needs to open several files in
sequence, but then one must also consider if the program should (a)
abort on the first missing file, or (b) attempt to open them all, so
that it can give the user a complete list of missing files. Associating
the name of the missing file with the exception occurrence would help
with (a), but not really with the more user-friendly (b).
> Exceptions in Ada cannot ... be chained
I'm not sure what you mean by "chained", but an Ada exception handler
can either raise another exception, or re-raise the same exception, for
handling at higher levels.
--
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
. @ .
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 11:22 ` Niklas Holsti
@ 2015-07-30 13:00 ` EGarrulo
2015-07-30 13:30 ` Dmitry A. Kazakov
0 siblings, 1 reply; 175+ messages in thread
From: EGarrulo @ 2015-07-30 13:00 UTC (permalink / raw)
On Thursday, July 30, 2015 at 1:22:36 PM UTC+2, Niklas Holsti wrote:
> On 15-07-30 11:45 , EGarrulo wrote:
> > Exceptions in Ada cannot ... be chained
>
> I'm not sure what you mean by "chained", but an Ada exception handler
> can either raise another exception, or re-raise the same exception, for
> handling at higher levels.
By "chained", I mean that a failure in an operation can
cause a failure in the calling operation, and so on. Let's
imagine that the initialization of an application relies
on reading a configuration file. If the syntax of the
configuration file is not correct, then the routine that
reads it will raise an exception, but this exception would
be too low-level to be meaningful for the user. Therefore,
it makes sense to chain this exception to another higher-
level exception that explains what the application was
trying to do. To the end user, this will appear as a chain
of exceptions:
- INITIALIZATION_ERROR: The application failed to initialize;
- CONFIGURATION_ERROR: The configuration failed;
- BAD_FORMAT: The configuration file isn't formatted correctly;
- SYNTAX_ERROR: The value of LEVEL is not of the expected type.
Basically, each exception in the chain answers the
question "why?" Now, if you report only one of those
exceptions, then you lose context. This is why you should
be able to chain exceptions. Of course, you could achieve
a similar result by concatenating messages, but this way
you would be performing manually what the language should
have performed automatically.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 13:00 ` EGarrulo
@ 2015-07-30 13:30 ` Dmitry A. Kazakov
2015-07-30 13:51 ` EGarrulo
0 siblings, 1 reply; 175+ messages in thread
From: Dmitry A. Kazakov @ 2015-07-30 13:30 UTC (permalink / raw)
On Thu, 30 Jul 2015 06:00:11 -0700 (PDT), EGarrulo wrote:
> On Thursday, July 30, 2015 at 1:22:36 PM UTC+2, Niklas Holsti wrote:
>> On 15-07-30 11:45 , EGarrulo wrote:
>> > Exceptions in Ada cannot ... be chained
>>
>> I'm not sure what you mean by "chained", but an Ada exception handler
>> can either raise another exception, or re-raise the same exception, for
>> handling at higher levels.
>
> By "chained", I mean that a failure in an operation can
> cause a failure in the calling operation, and so on. Let's
> imagine that the initialization of an application relies
> on reading a configuration file. If the syntax of the
> configuration file is not correct, then the routine that
> reads it will raise an exception, but this exception would
> be too low-level to be meaningful for the user. Therefore,
> it makes sense to chain this exception to another higher-
> level exception that explains what the application was
> trying to do. To the end user, this will appear as a chain
> of exceptions:
>
> - INITIALIZATION_ERROR: The application failed to initialize;
> - CONFIGURATION_ERROR: The configuration failed;
> - BAD_FORMAT: The configuration file isn't formatted correctly;
> - SYNTAX_ERROR: The value of LEVEL is not of the expected type.
>
> Basically, each exception in the chain answers the
> question "why?" Now, if you report only one of those
> exceptions, then you lose context. This is why you should
> be able to chain exceptions. Of course, you could achieve
> a similar result by concatenating messages, but this way
> you would be performing manually what the language should
> have performed automatically.
exception
when Error : Chain_Error =>
raise Chain_Error with "Worse than " & Exception_Message (Error);
end;
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 13:30 ` Dmitry A. Kazakov
@ 2015-07-30 13:51 ` EGarrulo
2015-07-30 14:13 ` Dmitry A. Kazakov
0 siblings, 1 reply; 175+ messages in thread
From: EGarrulo @ 2015-07-30 13:51 UTC (permalink / raw)
On Thursday, July 30, 2015 at 3:30:53 PM UTC+2, Dmitry A. Kazakov wrote:
> On Thu, 30 Jul 2015 06:00:11 -0700 (PDT), EGarrulo wrote:
> > Basically, each exception in the chain answers the
> > question "why?" Now, if you report only one of those
> > exceptions, then you lose context. This is why you should
> > be able to chain exceptions. Of course, you could achieve
> > a similar result by concatenating messages, but this way
> > you would be performing manually what the language should
> > have performed automatically.
>
> exception
> when Error : Chain_Error =>
> raise Chain_Error with "Worse than " & Exception_Message (Error);
> end;
Ehm... That is exactly what I had said. Thanks for your
confirmation. But I wonder whether chaining strings could
lead to an "Out of memory" error in Ada. Indeed, my
understanding was that Ada only lets you attach a message
to an exception because doing more could lead to an
"Out of memory" error, and that would hide the original
source of the error (and indeed the approach of Ada seemed
sensible).
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 13:51 ` EGarrulo
@ 2015-07-30 14:13 ` Dmitry A. Kazakov
2015-07-30 14:46 ` Simon Wright
0 siblings, 1 reply; 175+ messages in thread
From: Dmitry A. Kazakov @ 2015-07-30 14:13 UTC (permalink / raw)
On Thu, 30 Jul 2015 06:51:48 -0700 (PDT), EGarrulo wrote:
> On Thursday, July 30, 2015 at 3:30:53 PM UTC+2, Dmitry A. Kazakov wrote:
>> On Thu, 30 Jul 2015 06:00:11 -0700 (PDT), EGarrulo wrote:
>>> Basically, each exception in the chain answers the
>>> question "why?" Now, if you report only one of those
>>> exceptions, then you lose context. This is why you should
>>> be able to chain exceptions. Of course, you could achieve
>>> a similar result by concatenating messages, but this way
>>> you would be performing manually what the language should
>>> have performed automatically.
>>
>> exception
>> when Error : Chain_Error =>
>> raise Chain_Error with "Worse than " & Exception_Message (Error);
>> end;
>
> Ehm... That is exactly what I had said. Thanks for your
> confirmation. But I wonder whether chaining strings could
> lead to an "Out of memory" error in Ada.
It should not, at least not for this reason, because the exception message
length is bounded. You get the message truncated if it becomes too large.
But the idea of exception stack trace does not make much sense, except when
debugging.
-------------------
GNAT provides stack traces at run time. You can have a symbolic trace back
down to the individual source lines. [This does not work on some platforms,
though. Which is the reason why it is not a language feature. The
implementation burden would be too high for some small microcontroller]
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 14:13 ` Dmitry A. Kazakov
@ 2015-07-30 14:46 ` Simon Wright
0 siblings, 0 replies; 175+ messages in thread
From: Simon Wright @ 2015-07-30 14:46 UTC (permalink / raw)
"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> GNAT provides stack traces at run time. You can have a symbolic trace
> back down to the individual source lines. [This does not work on some
> platforms, though. Which is the reason why it is not a language
> feature. The implementation burden would be too high for some small
> microcontroller]
But it's fine in the debugger (since the debug info is on the host). Of
course this doesn't help if the exception happens in deployed
software.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 8:45 ` EGarrulo
2015-07-30 9:19 ` Dmitry A. Kazakov
2015-07-30 11:22 ` Niklas Holsti
@ 2015-07-30 14:31 ` G.B.
2015-07-30 18:46 ` Randy Brukardt
3 siblings, 0 replies; 175+ messages in thread
From: G.B. @ 2015-07-30 14:31 UTC (permalink / raw)
On 30.07.15 10:45, EGarrulo wrote:
>> I'm still
>> not sure anything but messages should go with exceptions: it is
>> too tempting for consultants to apply techniques of obfuscation
>> via exception classes. Even involuntarily!
>
> Could you explain further, please?
Dmitry has explained the context for a handler.
As you explained "chaining", exceptions can propagate
and be exchanged for different exceptions, perhaps after
intermediate handling.
But all the "programming" and "executing" going on when
exceptions are regular objects, or when exception messages
are concatenated, is dubious IMHO. Hack-ish. Instead, in
languages without pre-allocated environments such as Ada
or C++, I'd rather do bookkeeping of all information that
is needed for restarting, if possible, at any level of
handling.
Conceptually, maybe not always applicable:
declare
P : Protocol; -- representing known good state
begin
-- either pass P to Op, or maybe have
-- Op use P as a relatively global variable
Op (...);
exception
when Not_Program_Error_Etc =>
-- we now have a P ready for inspection
...
end;
In fact, sometimes this is the only way one can handle
exceptions across task borders; Google's App Engine is
one example. One process never knows what is going on in some
separate process unless the other process leaves information
in the datastore, at some location known to both processes.
Involuntary obfuscation happens when the programmer codes
any knowledge of various parts of a program into exception types:
If a programmer knows two different parts of the program,
defines the exception's type in one and uses the thrown
object in the other, there is no trace of this knowledge in
the program's source text. IOW, knowing the conditions
of non-local flow entirely depends on good will, discipline,
conventions, documentation, etc., but not on language.
That's unlike P above: both parts, the one that finally
raises, as well as the handling part will refer to it.
It doesn't look elegant, but it works in general.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 8:45 ` EGarrulo
` (2 preceding siblings ...)
2015-07-30 14:31 ` G.B.
@ 2015-07-30 18:46 ` Randy Brukardt
3 siblings, 0 replies; 175+ messages in thread
From: Randy Brukardt @ 2015-07-30 18:46 UTC (permalink / raw)
"EGarrulo" <egarrulo@gmail.com> wrote in message
news:b68e14e7-e304-4220-81f5-67a88cef5767@googlegroups.com...
...
>> Do you mean that exceptions of Ada cannot be used for indirecting
>> non-local control flow with the help of exception objects?
>
>Exceptions in Ada cannot carry contextual information, nor they
>can be chained (albeit you could hack them to do both).
Huh? Every Ada implementation has some sort of contextual information in the
Exception_Occurrence. The language doesn't try to specify what is available
there, because that would necessarily prevent better implementations. (For
instance, Janus/Ada includes a subprogram traceback in the
Exception_Occurrence.)
I'm not sure what you mean by "chained". Reraise works (and does not erase
the context in Janus/Ada, perhaps it does in other implementations).
> Where is the usefulness of knowing that something has gone awry,
> without any context? For example: "'File not found?' What file
> was the program trying to open, and why?"
Again, every real Ada implementation provides that information in the
Exception_Message. Trying to specify that in a language standard would have
been a never-ending task, so it's implementation-defined. But implementers
don't intentionally make their implementations useless...
Randy.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 8:23 ` Georg Bauhaus
2015-07-30 8:45 ` EGarrulo
@ 2015-07-30 9:18 ` EGarrulo
2015-07-30 18:55 ` Randy Brukardt
2015-07-30 11:35 ` Brian Drummond
2 siblings, 1 reply; 175+ messages in thread
From: EGarrulo @ 2015-07-30 9:18 UTC (permalink / raw)
On Thursday, July 30, 2015 at 10:23:23 AM UTC+2, Georg Bauhaus wrote:
> Is this about GC only? Having had to fight GC in Java,
> at a time when it was assumed that GC would magically have
> no effect on the program, I'm not sure this isn't a bit
> optimistic. But surely it is what one should say.
This is because you didn't use Java like it is meant to be used!
Hahaha! I am just (half) joking, after having replied to a
similar criticism just now.
> For completeness, management of resources other than
> memory, if tied to GC, becomes uncontrolled happenstance.
Of course. But manual resource management is too error-prone to
leave it completely in the hands of programmers, at least all
the time. It is too easy to push the complexity on the
programmer by providing "Unchecked" facilities and then forget
about it.
> In Ada, use the stack, if possible!
> In Ada 2005, use containers, if possible!
Otherwise use C++ and its "shared/weak pointer" support ;)
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 9:18 ` EGarrulo
@ 2015-07-30 18:55 ` Randy Brukardt
2015-07-30 19:32 ` EGarrulo
0 siblings, 1 reply; 175+ messages in thread
From: Randy Brukardt @ 2015-07-30 18:55 UTC (permalink / raw)
"EGarrulo" <egarrulo@gmail.com> wrote in message
news:a10c8bc6-d5de-4b36-a15b-dd830c92c75b@googlegroups.com...
...
>
>> In Ada, use the stack, if possible!
>> In Ada 2005, use containers, if possible!
>
> Otherwise use C++ and its "shared/weak pointer" support ;)
We had a proposal for adding that to Ada, and it just was a complete mess.
We simplified it to the basic subpool mechanism, which is a lot easier to
understand and use (if not quite as safe, since it relies on the programmer
to get the details right).
But seriously, if you can't use the stack and/or containers in Ada 2005 and
later, you're already into a fairly unlikely problem. And then you can use
one of the various "smart pointer" packages out there; those do reference
counting and hide that behind the various syntax sugar techniques of Ada
2012. (See Christophe Grein's package, for example.) There's an argument
that one of those packages should get added to the Ada.Containers hierarchy
(someone should propose that on Ada-Comment).
Anyway, unless you are implementing a container, the need to use access
types directly (and thus do the storage management directly) is pretty rare.
And if you are implementing a container, you can limit the management to
that container (thus taking the problem out of the hands of clients).
Randy.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 18:55 ` Randy Brukardt
@ 2015-07-30 19:32 ` EGarrulo
2015-07-31 0:10 ` Randy Brukardt
0 siblings, 1 reply; 175+ messages in thread
From: EGarrulo @ 2015-07-30 19:32 UTC (permalink / raw)
On Thursday, July 30, 2015 at 8:56:01 PM UTC+2, Randy Brukardt wrote:
> "EGarrulo" wrote in message
> ...
> >
> >> In Ada, use the stack, if possible!
> >> In Ada 2005, use containers, if possible!
> >
> > Otherwise use C++ and its "shared/weak pointer" support ;)
>
> We had a proposal for adding that to Ada, and it just was a complete mess.
I wonder why. Smart pointers are conceptually simple. Sure, Ada tries to
provide bullet-proof solutions, but that is difficult, for pointers.
> But seriously, if you can't use the stack and/or containers in Ada 2005 and
> later, you're already into a fairly unlikely problem. And then you can use
> one of the various "smart pointer" packages out there; those do reference
> counting and hide that behind the various syntax sugar techniques of Ada
> 2012. (See Christophe Grein's package, for example.) There's an argument
> that one of those packages should get added to the Ada.Containers hierarchy
> (someone should propose that on Ada-Comment).
>
> Anyway, unless you are implementing a container, the need to use access
> types directly (and thus do the storage management directly) is pretty rare.
> And if you are implementing a container, you can limit the management to
> that container (thus taking the problem out of the hands of clients).
Unfortunately, it is clear that I haven't been clear enough (the *curse of
knowledge* has hit me, too). This is because, as a former C++ programmer, I
tie memory and resources because -- in C++ -- the idiom is that you take care of
the memory, and the system will take care of the tied resources. Hence, my
problem is not memory alone. It seems that the package that you have suggested
addresses the problem, albeit it doesn't provide weak pointers.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 19:32 ` EGarrulo
@ 2015-07-31 0:10 ` Randy Brukardt
0 siblings, 0 replies; 175+ messages in thread
From: Randy Brukardt @ 2015-07-31 0:10 UTC (permalink / raw)
"EGarrulo" <egarrulo@gmail.com> wrote in message
news:2ac21830-619c-4145-ab99-d6036bd4ed30@googlegroups.com...
> On Thursday, July 30, 2015 at 8:56:01 PM UTC+2, Randy Brukardt wrote:
>> "EGarrulo" wrote in message
>> ...
>> >
>> >> In Ada, use the stack, if possible!
>> >> In Ada 2005, use containers, if possible!
>> >
>> > Otherwise use C++ and its "shared/weak pointer" support ;)
>>
>> We had a proposal for adding that to Ada, and it just was a complete
>> mess.
>
> I wonder why. Smart pointers are conceptually simple.
Sure, but thats not what the proposal was about. And "weak" pointers aren't
so simple; the proposal required converting them (via a function) to a
strong pointer before they could be used. And if you put that temporary
strong pointer into a handy global, you could end up locking the object for
a long time. Plus there was some sort of automated reference counting.
We decided instead to follow the Ada philosophy and provide the building
blocks so that people could roll their own useful smart pointers. Thus we
defined subpools (for arena management of memory), user-defined
dereferencing (so that the lifetime of references can be managed), and so
on.
Perhaps some package will get enough usage that it should be promoted to be
part of the Standard (that's what I meant by suggesting that someone propose
a package to be added to Ada.Containers), but we didn't think that we had
enough of an idea how these things would be used to Standardize it in 2012.
> Sure, Ada tries to provide bullet-proof solutions, but that is difficult,
> for pointers.
Exactly. But what is the point of another half-way safe solution? We already
have plenty of those (subpools, unchecked deallocation itself, etc.).
Randy.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 8:23 ` Georg Bauhaus
2015-07-30 8:45 ` EGarrulo
2015-07-30 9:18 ` EGarrulo
@ 2015-07-30 11:35 ` Brian Drummond
2015-07-30 13:30 ` EGarrulo
2 siblings, 1 reply; 175+ messages in thread
From: Brian Drummond @ 2015-07-30 11:35 UTC (permalink / raw)
On Thu, 30 Jul 2015 10:23:25 +0200, Georg Bauhaus wrote:
> On 30.07.15 10:03, EGarrulo wrote:
>>
>> Ada doesn't offer any facility for automatic
>> resource management, and that makes it unsuitable for applications that
>> go beyond constrained embedded development. Who wants to chase
>> resource leaks in this day and age?
>
> Is this about GC only?
No, since he widens the discussion beyond just memory as a resource, I
suspect he means controlled types.
-- Brian
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 11:35 ` Brian Drummond
@ 2015-07-30 13:30 ` EGarrulo
2015-07-31 11:07 ` Brian Drummond
0 siblings, 1 reply; 175+ messages in thread
From: EGarrulo @ 2015-07-30 13:30 UTC (permalink / raw)
On Thursday, July 30, 2015 at 1:36:56 PM UTC+2, Brian Drummond wrote:
> On Thu, 30 Jul 2015 10:23:25 +0200, Georg Bauhaus wrote:
>
> > On 30.07.15 10:03, EGarrulo wrote:
> >>
> >> Ada doesn't offer any facility for automatic
> >> resource management, and that makes it unsuitable for applications that
> >> go beyond constrained embedded development. Who wants to chase
> >> resource leaks in this day and age?
> >
> > Is this about GC only?
>
> No, since he widens the discussion beyond just memory as a resource, I
> suspect he means controlled types.
>
> -- Brian
Yes, I mean controlled types. As far as I can tell, right
now controlled types are useful for resources that are local
to a routine, but they don't scale well for shared resources
because of insufficient support from the language. I know
that non-intrusive shared pointers have been implemented in
Ada (just a couple of months ago, though, but late is better
than never), but they feel cumbersome and error-prone to use.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 13:30 ` EGarrulo
@ 2015-07-31 11:07 ` Brian Drummond
0 siblings, 0 replies; 175+ messages in thread
From: Brian Drummond @ 2015-07-31 11:07 UTC (permalink / raw)
On Thu, 30 Jul 2015 06:30:32 -0700, EGarrulo wrote:
> On Thursday, July 30, 2015 at 1:36:56 PM UTC+2, Brian Drummond wrote:
>> On Thu, 30 Jul 2015 10:23:25 +0200, Georg Bauhaus wrote:
>>
>> > On 30.07.15 10:03, EGarrulo wrote:
>> >>
>> >> Ada doesn't offer any facility for automatic resource management,
>> > Is this about GC only?
>> No, since he widens the discussion beyond just memory as a resource, I
>> suspect he means controlled types.
>
> Yes, I mean controlled types. As far as I can tell, right now
> controlled types are useful for resources that are local to a routine,
> but they don't scale well for shared resources because of insufficient
> support from the language. I know that non-intrusive shared pointers
> have been implemented in Ada (just a couple of months ago, though, but
> late is better than never), but they feel cumbersome and error-prone to
> use.
I suspect what's missing isn't so much anything in controlled types
themselves, but something like an Ada Gems worked example showing their
use in a non-trivial example. At least I can't point at a good example
offhand.
-- Brian
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 8:03 ` EGarrulo
2015-07-30 8:08 ` Jacob Sparre Andersen
2015-07-30 8:23 ` Georg Bauhaus
@ 2015-07-30 8:28 ` Pascal Obry
2015-07-30 12:00 ` EGarrulo
2015-07-30 10:01 ` Björn Lundin
2015-07-30 11:21 ` gautier_niouzes
4 siblings, 1 reply; 175+ messages in thread
From: Pascal Obry @ 2015-07-30 8:28 UTC (permalink / raw)
Le jeudi 30 juillet 2015 à 01:03 -0700, EGarrulo a écrit :
> That doesn't mean much. Ada doesn't offer any facility for
> automatic resource management,
Wrong! Please learn Ada first or we are going to have a very lengthly
discussion.
--
Pascal Obry / Magny Les Hameaux (78)
The best way to travel is by means of imagination
http://v2p.fr.eu.org
http://www.obry.net
gpg --keyserver keys.gnupg.net --recv-key F949BD3B
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 8:28 ` Pascal Obry
@ 2015-07-30 12:00 ` EGarrulo
0 siblings, 0 replies; 175+ messages in thread
From: EGarrulo @ 2015-07-30 12:00 UTC (permalink / raw)
On Thursday, July 30, 2015 at 10:28:40 AM UTC+2, Pascal Obry wrote:
> Le jeudi 30 juillet 2015 à 01:03 -0700, EGarrulo a écrit :
> > That doesn't mean much. Ada doesn't offer any facility for
> > automatic resource management,
>
> Wrong! Please learn Ada first or we are going to have a very lengthly
> discussion.
No lenghty discussion! I know that enough Ada to be dangerous ;) Ada has controlled types and
finalization. The problem is that the standard leaves the
implementation of resource management as an exercise for the
reader, when we know that there are many pitfalls in
implementing resource management reliably.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 8:03 ` EGarrulo
` (2 preceding siblings ...)
2015-07-30 8:28 ` Pascal Obry
@ 2015-07-30 10:01 ` Björn Lundin
2015-07-30 10:59 ` Pascal Obry
2015-07-30 11:21 ` gautier_niouzes
4 siblings, 1 reply; 175+ messages in thread
From: Björn Lundin @ 2015-07-30 10:01 UTC (permalink / raw)
On 2015-07-30 10:03, EGarrulo wrote:
> On Thursday, July 30, 2015 at 9:31:36 AM UTC+2, björn lundin wrote:
>> On 2015-07-30 08:01, Niklas Holsti wrote:
>>> On 15-07-30 03:10 , EGarrulo wrote:
>>>> Who knows? But since the realm of Ada is limited to embedded
>>>> development,
>>>
>>> It isn't.
>>
>> It is certainly not.
>> I've spent 18 years writing Ada in WMS/WCS systems -
>> Database intense system with 100+ concurrent users
>> Nothing embedded at all with them.
>
> That doesn't mean much. Ada doesn't offer any facility for
> automatic resource management, and that makes it unsuitable for
> applications that go beyond constrained embedded development.
if you use 'new'.
We hardly do. Why would we ?
You define a type, and use variables of that type.
Extremely seldom pointer to that type.
variables of that type is put in containers.
No pointers.
The only time we use pointers is when interfacing to c-routines,
which are encapsulated in procedures - and leak-free.
> Who
> wants to chase resource leaks in this day and age? Not to mention
> the crippled support for exceptions in Ada.
I guess what you don't know, you don't miss.
I have no real objections to todays exceptions,
so what do I miss ?
--
--
Björn
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 8:03 ` EGarrulo
` (3 preceding siblings ...)
2015-07-30 10:01 ` Björn Lundin
@ 2015-07-30 11:21 ` gautier_niouzes
4 siblings, 0 replies; 175+ messages in thread
From: gautier_niouzes @ 2015-07-30 11:21 UTC (permalink / raw)
Le jeudi 30 juillet 2015 10:03:15 UTC+2, EGarrulo a écrit :
> That doesn't mean much. Ada doesn't offer any facility for
> automatic resource management, and that makes it unsuitable for
> applications that go beyond constrained embedded development. Who
> wants to chase resource leaks in this day and age?
Ouch - troll alarm there ?...
In case it's not: you've missed the controlled types. It works like a charm and statistically much better than GC, that appears to work in a random way... and sometimes not at all!... Just put a microphone in a room with C# developers shouting at memory leaks ;-) ...
BTW: in Ada you have a type system that let you do almost everything without heap allocation, it is helpful as well :-)
_________________________
Gautier's Ada programming
http://gautiersblog.blogspot.com/search/label/Ada
NB: follow the above link for a valid e-mail address
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 6:01 ` Niklas Holsti
2015-07-30 7:33 ` Björn Lundin
@ 2015-07-30 18:35 ` Randy Brukardt
2015-07-31 15:21 ` Stefan.Lucks
1 sibling, 1 reply; 175+ messages in thread
From: Randy Brukardt @ 2015-07-30 18:35 UTC (permalink / raw)
"Niklas Holsti" <niklas.holsti@tidorum.invalid> wrote in message
news:d1tst3FoastU1@mid.individual.net...
...
> The only improvement in the basic Ada output facilities that I wish for is
> a standardisation of the GNAT 'Img attribute
That was done in the recently approved Corrigendum (other than that we
called it "'Image"; the only reason GNAT called it "'Img" is that
changing/extending language-defined attributes is not allowed).
> and extension of this attribute to cover record and array types.
We've tried that (and the topic is still open, AI12-0020-1), but it quickly
runs into a host of little problems (what do to with access components?
How/whether to make a matching 'Value? What about private components? Etc.)
I wouldn't count on seeing that ever happen.
Randy.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 18:35 ` Randy Brukardt
@ 2015-07-31 15:21 ` Stefan.Lucks
2015-07-31 17:28 ` Pascal Obry
` (2 more replies)
0 siblings, 3 replies; 175+ messages in thread
From: Stefan.Lucks @ 2015-07-31 15:21 UTC (permalink / raw)
[-- Attachment #1: Type: text/plain, Size: 958 bytes --]
On Thu, 30 Jul 2015, Randy Brukardt wrote:
>> and extension of this attribute to cover record and array types.
>
> We've tried that (and the topic is still open, AI12-0020-1), but it quickly
> runs into a host of little problems (what do to with access components?
> How/whether to make a matching 'Value? What about private components? Etc.)
> I wouldn't count on seeing that ever happen.
How about supporting
T'Image (or O'Image for objects of type T)
if and only if T'Image has explicitely been defined?
One could write
for T'Image use function The_Image_Of_T(Input: T) return String;
or in aspect syntax
type T is record
...
end record
with Image => ...;
-------- I love the taste of Cryptanalysis in the morning! --------
www.uni-weimar.de/de/medien/professuren/mediensicherheit/people/stefan-lucks
----Stefan.Lucks (at) uni-weimar.de, Bauhaus-Universität Weimar, Germany----
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-31 15:21 ` Stefan.Lucks
@ 2015-07-31 17:28 ` Pascal Obry
2015-08-01 11:38 ` Björn Lundin
2015-08-03 23:26 ` Randy Brukardt
2 siblings, 0 replies; 175+ messages in thread
From: Pascal Obry @ 2015-07-31 17:28 UTC (permalink / raw)
Le vendredi 31 juillet 2015 à 17:21 +0200, Stefan.Lucks@uni-weimar.de a
écrit :
> How about supporting
>
> T'Image (or O'Image for objects of type T)
>
> if and only if T'Image has explicitely been defined?
>
> One could write
>
> for T'Image use function The_Image_Of_T(Input: T) return String;
>
> or in aspect syntax
>
> type T is record
> ...
> end record
> with Image => ...;
Right, this would be really nice! And has been discussed many time
here.
--
Pascal Obry / Magny Les Hameaux (78)
The best way to travel is by means of imagination
http://v2p.fr.eu.org
http://www.obry.net
gpg --keyserver keys.gnupg.net --recv-key F949BD3B
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-31 15:21 ` Stefan.Lucks
2015-07-31 17:28 ` Pascal Obry
@ 2015-08-01 11:38 ` Björn Lundin
2015-08-01 20:07 ` Stefan.Lucks
2015-08-03 23:26 ` Randy Brukardt
2 siblings, 1 reply; 175+ messages in thread
From: Björn Lundin @ 2015-08-01 11:38 UTC (permalink / raw)
On 2015-07-31 17:21, Stefan.Lucks@uni-weimar.de wrote:
> On Thu, 30 Jul 2015, Randy Brukardt wrote:
>
>>> and extension of this attribute to cover record and array types.
>>
>> We've tried that (and the topic is still open, AI12-0020-1), but it
>> quickly
>> runs into a host of little problems (what do to with access components?
>> How/whether to make a matching 'Value? What about private components?
>> Etc.)
>> I wouldn't count on seeing that ever happen.
>
> How about supporting
>
> T'Image (or O'Image for objects of type T)
>
> if and only if T'Image has explicitely been defined?
>
> One could write
>
> for T'Image use function The_Image_Of_T(Input: T) return String;
>
> or in aspect syntax
>
> type T is record
> ...
> end record
> with Image => ...;
>
And if not explicitly defined, T'Image could perhaps
return an empty string, ""
--
Björn
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-08-01 11:38 ` Björn Lundin
@ 2015-08-01 20:07 ` Stefan.Lucks
0 siblings, 0 replies; 175+ messages in thread
From: Stefan.Lucks @ 2015-08-01 20:07 UTC (permalink / raw)
[-- Attachment #1: Type: text/plain, Size: 784 bytes --]
On Sat, 1 Aug 2015, Björn Lundin wrote:
>> How about supporting
>>
>> T'Image (or O'Image for objects of type T)
>>
>> if and only if T'Image has explicitely been defined?
>>
>> One could write
>>
>> for T'Image use function The_Image_Of_T(Input: T) return String;
>>
>> or in aspect syntax
>>
>> type T is record
>> ...
>> end record
>> with Image => ...;
>>
>
> And if not explicitly defined, T'Image could perhaps
> return an empty string, ""
I would prefer raising a "Program_Error" (or whatever).
-------- I love the taste of Cryptanalysis in the morning! --------
www.uni-weimar.de/de/medien/professuren/mediensicherheit/people/stefan-lucks
----Stefan.Lucks (at) uni-weimar.de, Bauhaus-Universität Weimar, Germany----
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-31 15:21 ` Stefan.Lucks
2015-07-31 17:28 ` Pascal Obry
2015-08-01 11:38 ` Björn Lundin
@ 2015-08-03 23:26 ` Randy Brukardt
2 siblings, 0 replies; 175+ messages in thread
From: Randy Brukardt @ 2015-08-03 23:26 UTC (permalink / raw)
<Stefan.Lucks@uni-weimar.de> wrote in message
news:alpine.DEB.2.20.1507311715090.24880@debian...
On Thu, 30 Jul 2015, Randy Brukardt wrote:
>>> and extension of this attribute to cover record and array types.
>>
>> We've tried that (and the topic is still open, AI12-0020-1), but it
>> quickly
>> runs into a host of little problems (what do to with access components?
>> How/whether to make a matching 'Value? What about private components?
>> Etc.)
>> I wouldn't count on seeing that ever happen.
>
>How about supporting
>
> T'Image (or O'Image for objects of type T)
>
>if and only if T'Image has explicitely been defined?
>
>...
There would be a contract model problem (in a generic, you couldn't know if
a formal private type had 'Image). That's solveable.
The real problem is that this doesn't buy much of anything. All it does is
changes the name slightly, as anyone can define a function Image for their
type. And the call is easier than the attribute reference since you don't
have to figure out the name of the subtype:
Image (Obj)
or
Obj.Image -- If Obj has a tagged type.
vs.
My_Type'Image (Obj)
The gain from having an attribute is when it is automatically created in
some cases (that's true for Streams, and it's true here). And that's where
the issues pop up.
Randy.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-29 22:32 ` EGarrulo
2015-07-29 23:51 ` Jeffrey R. Carter
@ 2015-07-30 6:08 ` Dmitry A. Kazakov
2015-07-30 6:37 ` Georg Bauhaus
` (3 subsequent siblings)
5 siblings, 0 replies; 175+ messages in thread
From: Dmitry A. Kazakov @ 2015-07-30 6:08 UTC (permalink / raw)
On Wed, 29 Jul 2015 15:32:20 -0700 (PDT), EGarrulo wrote:
> If Ada offered runtime typing by means of a type `Any`, then `Printf`
> could be trivially written as:
>
> type Printf_Arguments is array (Positive range <>) of Any;
>
> procedure Printf (Format : String; Arguments : Printf_Arguments);
This is pretty much useless because Any has no operations. It should be:
type Printable_Sequence is array (Positive range <>) of Printable'Class;
With Printable having the primitive operation Image.
In fact no run-time typing is required for dealing with that except three
things:
1. MI
2. Ad-hoc supertypes. Some existing types might have no Printable ancestor,
you will have to add it later.
3. Flattening arrays/record (that is if you wanted to drop brackets around
the array aggregate in the calls to Printf).
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-29 22:32 ` EGarrulo
2015-07-29 23:51 ` Jeffrey R. Carter
2015-07-30 6:08 ` Dmitry A. Kazakov
@ 2015-07-30 6:37 ` Georg Bauhaus
2015-07-30 8:27 ` Pascal Obry
` (2 subsequent siblings)
5 siblings, 0 replies; 175+ messages in thread
From: Georg Bauhaus @ 2015-07-30 6:37 UTC (permalink / raw)
On 30.07.15 00:32, EGarrulo wrote:
> If a programming
> language doesn't let programmers print formatted output easily, then it
> is deficient and it must be fixed, because printing formatted output is
> a basic task.
This seems a valid marketing argument, assuming that "easily" means
"conveniently quick and like with a format string".(*)
How useful would a language defined pragma be that does the job
of just dumping a text representation?
pragma Dump (On|Off, name {, name });
where »name« stands for any entity from the current unit?
__
(*) Writing
Put (Some_Float_Object);
is pretty easy to understand and write? Even if you write two Puts
on a line.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-29 22:32 ` EGarrulo
` (2 preceding siblings ...)
2015-07-30 6:37 ` Georg Bauhaus
@ 2015-07-30 8:27 ` Pascal Obry
2015-07-30 9:22 ` Dmitry A. Kazakov
` (2 more replies)
2015-07-30 15:23 ` Niklas Holsti
2015-07-30 19:32 ` Randy Brukardt
5 siblings, 3 replies; 175+ messages in thread
From: Pascal Obry @ 2015-07-30 8:27 UTC (permalink / raw)
Le mercredi 29 juillet 2015 à 15:32 -0700, EGarrulo a écrit :
> But is this a valid excuse? Aren't programming languages supposed to
> let programmers write useful programs?
You mean useful and unsafe. No thanks.
Nobody should care about programmers' fingers! Verbosity is one of the
strength as it makes the code far more *readable*. And remember that a
piece of code is written once and read many times during the
application lifetime.
> If Ada offered runtime typing by means of a type `Any`, then `Printf`
> could be trivially written as:
>
> type Printf_Arguments is array (Positive range <>) of Any;
>
> procedure Printf (Format : String; Arguments : Printf_Arguments);
This can be accomplished by libraries, an example is
GNAT.Formatted_String. But there is other implementations around.
--
Pascal Obry / Magny Les Hameaux (78)
The best way to travel is by means of imagination
http://v2p.fr.eu.org
http://www.obry.net
gpg --keyserver keys.gnupg.net --recv-key F949BD3B
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 8:27 ` Pascal Obry
@ 2015-07-30 9:22 ` Dmitry A. Kazakov
2015-07-30 11:51 ` EGarrulo
2015-07-30 11:54 ` EGarrulo
2 siblings, 0 replies; 175+ messages in thread
From: Dmitry A. Kazakov @ 2015-07-30 9:22 UTC (permalink / raw)
On Thu, 30 Jul 2015 10:27:09 +0200, Pascal Obry wrote:
> This can be accomplished by libraries, an example is
> GNAT.Formatted_String. But there is other implementations around.
Especially ones that use no formats. It is much more simpler to format
strings without formats, the approach I am using it for both Ada and C++.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 8:27 ` Pascal Obry
2015-07-30 9:22 ` Dmitry A. Kazakov
@ 2015-07-30 11:51 ` EGarrulo
2015-07-30 12:23 ` Dmitry A. Kazakov
2015-07-30 18:12 ` Jeffrey R. Carter
2015-07-30 11:54 ` EGarrulo
2 siblings, 2 replies; 175+ messages in thread
From: EGarrulo @ 2015-07-30 11:51 UTC (permalink / raw)
On Thursday, July 30, 2015 at 10:27:12 AM UTC+2, Pascal Obry wrote:
> Le mercredi 29 juillet 2015 à 15:32 -0700, EGarrulo a écrit :
> > But is this a valid excuse? Aren't programming languages supposed to
> > let programmers write useful programs?
>
> You mean useful and unsafe. No thanks.
No, I mean useful and safe. Yes, thanks ;)
> Nobody should care about programmers' fingers! Verbosity is one of the
> strength as it makes the code far more *readable*. And remember that a
> piece of code is written once and read many times during the
> application lifetime.
Exactly! And:
Printf ("Mr %Arg you have won %Arg dollars!\n", Surname, Amount);
is much more readable than:
Put ("Mr ");
Put (Surname);
Put (" you have won ");
Put (Amount);
Put (" dollars!");
New_Line;
Now, multiply this for all the times that your program needs
to print formatted text... Not to mention that the order of the
arguments is hard-coded in the valid Ada snippet, whilst you could
need a different order to support formatted output in different
languages.
>
> > If Ada offered runtime typing by means of a type `Any`, then `Printf`
> > could be trivially written as:
> >
> > type Printf_Arguments is array (Positive range <>) of Any;
> >
> > procedure Printf (Format : String; Arguments : Printf_Arguments);
>
> This can be accomplished by libraries, an example is
> GNAT.Formatted_String. But there is other implementations around.
Then why are we discussing this? The answer is that Ada does
support formatted output. It is strange that this doesn't come with the standard, but that is it.
the standard
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 11:51 ` EGarrulo
@ 2015-07-30 12:23 ` Dmitry A. Kazakov
2015-07-30 13:55 ` Niklas Holsti
2015-07-30 14:07 ` EGarrulo
2015-07-30 18:12 ` Jeffrey R. Carter
1 sibling, 2 replies; 175+ messages in thread
From: Dmitry A. Kazakov @ 2015-07-30 12:23 UTC (permalink / raw)
On Thu, 30 Jul 2015 04:51:48 -0700 (PDT), EGarrulo wrote:
> Exactly! And:
>
> Printf ("Mr %Arg you have won %Arg dollars!\n", Surname, Amount);
>
> is much more readable than:
It is not readable and it is not formatting, just string concatentation.
> Put ("Mr ");
> Put (Surname);
> Put (" you have won ");
> Put (Amount);
> Put (" dollars!");
> New_Line;
Much better, though in such cases, which are not formatting, I rather do
Put_Line ("Mr " & Surname & " you have won " & Image(Amount) & "dollars!");
> Now, multiply this for all the times that your program needs
> to print formatted text...
Yes and a lot more because formatting involves fields, justification,
fonts, encodings, localization etc.
[ In real-life C++ it quickly becomes printf ("%s\n", Text) with all
formatting stuff done elsewhere. ]
The point is that for debug messages and other adhockery no full-blown
formatting is ever needed and Put_Line + Image is all anybody could ever
want. For text formatting proper printf is utterly useless.
> Not to mention that the order of the
> arguments is hard-coded in the valid Ada snippet, whilst you could
> need a different order to support formatted output in different
> languages.
And how is it different from printf, except that printf has a hard-coded
order used twice rather than once (once in the format and once in the
arguments), adding a nice source of run-time errors...
My favorite was under 68k UNIX Sys V. The C run-time sometimes modified the
format string while processing printf. In the end the format string was
supposed to be restored to its original state. Alas, the linker put the
format string into a read-only section...
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 12:23 ` Dmitry A. Kazakov
@ 2015-07-30 13:55 ` Niklas Holsti
2015-08-30 7:03 ` David Thompson
2015-07-30 14:07 ` EGarrulo
1 sibling, 1 reply; 175+ messages in thread
From: Niklas Holsti @ 2015-07-30 13:55 UTC (permalink / raw)
On 15-07-30 15:23 , Dmitry A. Kazakov wrote:
> On Thu, 30 Jul 2015 04:51:48 -0700 (PDT), EGarrulo wrote:
>
>> Exactly! And:
>>
>> Printf ("Mr %Arg you have won %Arg dollars!\n", Surname, Amount);
>>
>> is much more readable than:
>
> It is not readable and it is not formatting, just string concatentation.
>
>> Put ("Mr ");
>> Put (Surname);
>> Put (" you have won ");
>> Put (Amount);
>> Put (" dollars!");
>> New_Line;
>
[snip]
>> Not to mention that the order of the
>> arguments is hard-coded in the valid Ada snippet, whilst you could
>> need a different order to support formatted output in different
>> languages.
>
> And how is it different from printf, except that printf has a hard-coded
> order used twice rather than once (once in the format and once in the
> arguments), adding a nice source of run-time errors...
Some printf's support, in the "%" conversion specifications, an initial
part of the form "%12$" to say that the argument to be converted is
argument number 12 in the argument list. So the format string can pick
the arguments in any order it wants -- even converting the same argument
several times.
(I did not find this feature in the C99 standard. I don't know how
widely it is supported.)
I don't have any experience of writing multilingual programs, but it
seems to me that just supplying a language-specific format-string to
printf is unlikely to be enough, even if this printf has this ability to
pick arguments in any order.
--
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
. @ .
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 13:55 ` Niklas Holsti
@ 2015-08-30 7:03 ` David Thompson
0 siblings, 0 replies; 175+ messages in thread
From: David Thompson @ 2015-08-30 7:03 UTC (permalink / raw)
On Thu, 30 Jul 2015 16:55:52 +0300, Niklas Holsti
<niklas.holsti@tidorum.invalid> wrote:
<snip>
> Some printf's support, in the "%" conversion specifications, an initial
> part of the form "%12$" to say that the argument to be converted is
> argument number 12 in the argument list. So the format string can pick
> the arguments in any order it wants -- even converting the same argument
> several times.
>
> (I did not find this feature in the C99 standard. I don't know how
> widely it is supported.)
>
It's not in any C standard to date. It is in POSIX, marked XSI meaning
"extension to the C standard", and has been as long as I remember.
POSIX is pretty widely supported.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 12:23 ` Dmitry A. Kazakov
2015-07-30 13:55 ` Niklas Holsti
@ 2015-07-30 14:07 ` EGarrulo
1 sibling, 0 replies; 175+ messages in thread
From: EGarrulo @ 2015-07-30 14:07 UTC (permalink / raw)
On Thursday, July 30, 2015 at 2:23:43 PM UTC+2, Dmitry A. Kazakov wrote:
> And how is it different from printf, except that printf has a hard-coded
> order used twice rather than once (once in the format and once in the
> arguments), adding a nice source of run-time errors...
There is a misunderstanding here: I am not saying that "printf"
is perfect. I am only saying that it provides a convenient
solution to a recurring problem (not in a type-safe way, but
then C *is* unsafe, and while adding some cryptic formatting
directives). Thanks to its format string, "printf" lets you see
at a glance what the output will look like. On the contrary,
solutions in Ada -- that involve more than simple string
concatenation -- tend to obscure what the final result will look
like, and are cumbersome both to write and to read.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 11:51 ` EGarrulo
2015-07-30 12:23 ` Dmitry A. Kazakov
@ 2015-07-30 18:12 ` Jeffrey R. Carter
2015-07-30 18:51 ` EGarrulo
1 sibling, 1 reply; 175+ messages in thread
From: Jeffrey R. Carter @ 2015-07-30 18:12 UTC (permalink / raw)
On 07/30/2015 04:51 AM, EGarrulo wrote:
>
> Exactly! And:
>
> Printf ("Mr %Arg you have won %Arg dollars!\n", Surname, Amount);
>
> is much more readable than:
>
> Put ("Mr ");
> Put (Surname);
> Put (" you have won ");
> Put (Amount);
> Put (" dollars!");
> New_Line;
A nice strawman argument. No one would ever write that. Depending on what Printf
does with Amount, one would either write
Ada.Text_IO.Put_Line (Item => "Mr " & Surname & " you have won" &
Money'Image (Amount) & " dollars!");
or
Ada.Text_IO.Put (Item => "Mr " & Surname & " you have won ");
Money_IO.Put (Item => Amount, ...);
Ada.Text_IO.Put_Line (Item => " dollars!");
both of which I find easier to read than the Printf call.
--
Jeff Carter
"Pray that there's intelligent life somewhere up in
space, 'cause there's bugger all down here on earth."
Monty Python's Meaning of Life
61
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 18:12 ` Jeffrey R. Carter
@ 2015-07-30 18:51 ` EGarrulo
2015-07-30 19:27 ` Jeffrey R. Carter
2015-07-30 23:58 ` Randy Brukardt
0 siblings, 2 replies; 175+ messages in thread
From: EGarrulo @ 2015-07-30 18:51 UTC (permalink / raw)
On Thursday, July 30, 2015 at 8:12:13 PM UTC+2, Jeffrey R. Carter wrote:
> On 07/30/2015 04:51 AM, EGarrulo wrote:
> >
> > Exactly! And:
> >
> > Printf ("Mr %Arg you have won %Arg dollars!\n", Surname, Amount);
> >
> > is much more readable than:
> >
> > Put ("Mr ");
> > Put (Surname);
> > Put (" you have won ");
> > Put (Amount);
> > Put (" dollars!");
> > New_Line;
>
> A nice strawman argument. No one would ever write that. Depending on what Printf
> does with Amount, one would either write
>
> Ada.Text_IO.Put_Line (Item => "Mr " & Surname & " you have won" &
> Money'Image (Amount) & " dollars!");
>
> or
>
> Ada.Text_IO.Put (Item => "Mr " & Surname & " you have won ");
> Money_IO.Put (Item => Amount, ...);
> Ada.Text_IO.Put_Line (Item => " dollars!");
>
> both of which I find easier to read than the Printf call.
OK. Now please write the code so that it could be easily adapted to a
different language by possibly swapping the arguments that are fed to the
output string (this may not cover all existing languages, but it could be good
enough). I would reimplement Printf to accept a format with positional
arguments, like "Mr %1 you have won %2 dollars!\n". Then I would define a new
format string for the alternative output and I would be done. This was
possible because a solution based on a formatting procedure recognizes that
output should easily adaptable, something that hard-coded concatenations of
strings are not.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 18:51 ` EGarrulo
@ 2015-07-30 19:27 ` Jeffrey R. Carter
2015-07-30 19:54 ` EGarrulo
2015-07-30 23:58 ` Randy Brukardt
1 sibling, 1 reply; 175+ messages in thread
From: Jeffrey R. Carter @ 2015-07-30 19:27 UTC (permalink / raw)
On 07/30/2015 11:51 AM, EGarrulo wrote:
>
> OK. Now please write the code so that it could be easily adapted to a
> different language by possibly swapping the arguments that are fed to the
> output string (this may not cover all existing languages, but it could be good
> enough). I would reimplement Printf to accept a format with positional
> arguments, like "Mr %1 you have won %2 dollars!\n". Then I would define a new
> format string for the alternative output and I would be done. This was
> possible because a solution based on a formatting procedure recognizes that
> output should easily adaptable, something that hard-coded concatenations of
> strings are not.
Why should I? That's not the problem you presented and I responded to. First a
strawman and now a non-sequitur. Clearly you have no argument.
--
Jeff Carter
"Pray that there's intelligent life somewhere up in
space, 'cause there's bugger all down here on earth."
Monty Python's Meaning of Life
61
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 19:27 ` Jeffrey R. Carter
@ 2015-07-30 19:54 ` EGarrulo
2015-07-30 22:53 ` Jeffrey R. Carter
0 siblings, 1 reply; 175+ messages in thread
From: EGarrulo @ 2015-07-30 19:54 UTC (permalink / raw)
On Thursday, July 30, 2015 at 9:27:56 PM UTC+2, Jeffrey R. Carter wrote:
> On 07/30/2015 11:51 AM, EGarrulo wrote:
> >
> > OK. Now please write the code so that it could be easily adapted to a
> > different language by possibly swapping the arguments that are fed to the
> > output string (this may not cover all existing languages, but it could be good
> > enough). I would reimplement Printf to accept a format with positional
> > arguments, like "Mr %1 you have won %2 dollars!\n". Then I would define a new
> > format string for the alternative output and I would be done. This was
> > possible because a solution based on a formatting procedure recognizes that
> > output should easily adaptable, something that hard-coded concatenations of
> > strings are not.
>
> Why should I? That's not the problem you presented and I responded to. First a
> strawman and now a non-sequitur. Clearly you have no argument.
I had already explained in this discussion why I think that the "Printf"
solution is preferable:
Thanks to its format string, "printf" lets you see
at a glance what the output will look like. On the contrary,
solutions in Ada -- that involve more than simple string
concatenation -- tend to obscure what the final result will look
like, and are cumbersome both to write and to read.
--
Now, multiply this for all the times that your program needs
to print formatted text... Not to mention that the order of the
arguments is hard-coded in the valid Ada snippet, whilst you could
need a different order to support formatted output in different
languages.
If I don't repeat my arguments, it is because doing so would be redundant, not
because I am playing fancy tricks to win an argument. So... have you got an
alternative to propose, or do you agree that "Printf" is a more flexible
approach? Before you reply, I am adding that I have already proposed a
specification of Printf that takes an array of strings as the arguments to its
format string, so that formatting can be done outside, and be customized for
new types. Actually, I think that such a function should become
standard, because it would integrate well with existing functions (like
To_Picture).
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 19:54 ` EGarrulo
@ 2015-07-30 22:53 ` Jeffrey R. Carter
0 siblings, 0 replies; 175+ messages in thread
From: Jeffrey R. Carter @ 2015-07-30 22:53 UTC (permalink / raw)
On 07/30/2015 12:54 PM, EGarrulo wrote:
>
> I had already explained in this discussion why I think that the "Printf"
> solution is preferable:
>
> Thanks to its format string, "printf" lets you see
> at a glance what the output will look like. On the contrary,
> solutions in Ada -- that involve more than simple string
> concatenation -- tend to obscure what the final result will look
> like, and are cumbersome both to write and to read.
>
> --
>
> Now, multiply this for all the times that your program needs
> to print formatted text... Not to mention that the order of the
> arguments is hard-coded in the valid Ada snippet, whilst you could
> need a different order to support formatted output in different
> languages.
Your Print as described at that point did not have any support for different
languages without changing the order of the arguments, either. So again you
changed the problem. I can do the same thing: take your Printf with its format
string of type String and numbered placeholders and show how it handles Hebrew.
> If I don't repeat my arguments, it is because doing so would be redundant, not
> because I am playing fancy tricks to win an argument. So... have you got an
> alternative to propose, or do you agree that "Printf" is a more flexible
> approach? Before you reply, I am adding that I have already proposed a
> specification of Printf that takes an array of strings as the arguments to its
> format string, so that formatting can be done outside, and be customized for
> new types. Actually, I think that such a function should become
> standard, because it would integrate well with existing functions (like
> To_Picture).
Printf is a bad idea since humans are bad at mentally parsing things like the
format string and bad at counting things such as the position of an argument in
the argument list, and doing both at once while also trying to match the
placeholders in the format string with the arguments tends to be error-prone.
If formatting can be done "outside", then it's reasonable for such formatting to
result in the entire text to be output:
Ada.Wide_Wide_Text_IO.Put_Line
(Item =>
Internationalized (Who_Won, Language, (Surname, Image (Amount) ) ) );
--
Jeff Carter
"Pray that there's intelligent life somewhere up in
space, 'cause there's bugger all down here on earth."
Monty Python's Meaning of Life
61
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 18:51 ` EGarrulo
2015-07-30 19:27 ` Jeffrey R. Carter
@ 2015-07-30 23:58 ` Randy Brukardt
1 sibling, 0 replies; 175+ messages in thread
From: Randy Brukardt @ 2015-07-30 23:58 UTC (permalink / raw)
"EGarrulo" <egarrulo@gmail.com> wrote in message
news:262cbf86-25a0-4802-b72e-ec6e650e1dc7@googlegroups.com...
...
> OK. Now please write the code so that it could be easily adapted to a
> different language by possibly swapping the arguments that are fed to the
> output string (this may not cover all existing languages, but it could be
> good
> enough).
Localization is a very difficult problem that defies simple solutions like
format strings (or resource files or any other such solution). These simple
solutions tend to provide enough of the solution to be seductive, but not
enough of the solution to actually save any effort.
Ultimately, one has to adopt an application-specific solution (which is why
the only localization Ada provides is a query to find out the country and
language). And that is no easier or harder in Ada than it is in any other
traditional language.
Randy.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 8:27 ` Pascal Obry
2015-07-30 9:22 ` Dmitry A. Kazakov
2015-07-30 11:51 ` EGarrulo
@ 2015-07-30 11:54 ` EGarrulo
2015-07-30 12:42 ` Pascal Obry
2 siblings, 1 reply; 175+ messages in thread
From: EGarrulo @ 2015-07-30 11:54 UTC (permalink / raw)
> This can be accomplished by libraries, an example is
> GNAT.Formatted_String. But there is other implementations around.
By the way, the implementation of GNAT.Formatted_String is cryptic.
Isn't Ada code supposed to be readable? I must be missing
something.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 11:54 ` EGarrulo
@ 2015-07-30 12:42 ` Pascal Obry
2015-07-30 13:21 ` EGarrulo
0 siblings, 1 reply; 175+ messages in thread
From: Pascal Obry @ 2015-07-30 12:42 UTC (permalink / raw)
Le jeudi 30 juillet 2015 à 04:54 -0700, EGarrulo a écrit :
> By the way, the implementation of GNAT.Formatted_String is cryptic.
> Isn't Ada code supposed to be readable?
> I must be missing something.
Yes, sure: Open Mind score below 0!
--
Pascal Obry / Magny Les Hameaux (78)
The best way to travel is by means of imagination
http://v2p.fr.eu.org
http://www.obry.net
gpg --keyserver keys.gnupg.net --recv-key F949BD3B
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 12:42 ` Pascal Obry
@ 2015-07-30 13:21 ` EGarrulo
2015-07-30 13:38 ` Dmitry A. Kazakov
0 siblings, 1 reply; 175+ messages in thread
From: EGarrulo @ 2015-07-30 13:21 UTC (permalink / raw)
On Thursday, July 30, 2015 at 2:42:36 PM UTC+2, Pascal Obry wrote:
> Le jeudi 30 juillet 2015 à 04:54 -0700, EGarrulo a écrit :
> > By the way, the implementation of GNAT.Formatted_String is cryptic.
> > Isn't Ada code supposed to be readable?
>
> > I must be missing something.
>
> Yes, sure: Open Mind score below 0!
Not really. Compare the arbitrary overloading of "+", "-" and
"&" (and the cryptic "#") in GNAT.Formatted_String here:
procedure Fout is
F : Formatted_String := +"%c %% %#08x";
Vc : Character := 'v';
Vi : Integer := 12;
begin
F := F & Vc & Vi;
Put_Line (-F); -- Prints: "v % 0x00000c"
end Fout;
with the explicit formatting directives here (I am not sure that
this is valid Ada, but you should get the idea):
procedure Fout is
F : Formatted_String;
Vc : Character := 'v';
Vi : Integer := 12;
begin
F := ("%A %% %A", (Format (Vc),
Format (Vi,
Prefix => "0x"
Base => 16,
Width => 8,
Filler => "0"));
Put_Line (F); -- Prints: "v % 0x00000c"
end Fout;
The only convention that you need to know is that "%A" inserts
an argument and that "%%" inserts a literal "%". Much simpler,
don't you think? And extensible! You can define "Format"
for your own types, independently from "Formatted_String".
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 13:21 ` EGarrulo
@ 2015-07-30 13:38 ` Dmitry A. Kazakov
2015-07-30 13:55 ` EGarrulo
0 siblings, 1 reply; 175+ messages in thread
From: Dmitry A. Kazakov @ 2015-07-30 13:38 UTC (permalink / raw)
On Thu, 30 Jul 2015 06:21:42 -0700 (PDT), EGarrulo wrote:
> On Thursday, July 30, 2015 at 2:42:36 PM UTC+2, Pascal Obry wrote:
>> Le jeudi 30 juillet 2015 à 04:54 -0700, EGarrulo a écrit :
>>> By the way, the implementation of GNAT.Formatted_String is cryptic.
>>> Isn't Ada code supposed to be readable?
>>
>>> I must be missing something.
>>
>> Yes, sure: Open Mind score below 0!
>
> Not really. Compare the arbitrary overloading of "+", "-" and
> "&" (and the cryptic "#") in GNAT.Formatted_String here:
>
> procedure Fout is
> F : Formatted_String := +"%c %% %#08x";
> Vc : Character := 'v';
> Vi : Integer := 12;
> begin
> F := F & Vc & Vi;
> Put_Line (-F); -- Prints: "v % 0x00000c"
> end Fout;
>
> with the explicit formatting directives here (I am not sure that
> this is valid Ada, but you should get the idea):
>
> procedure Fout is
> F : Formatted_String;
> Vc : Character := 'v';
> Vi : Integer := 12;
> begin
> F := ("%A %% %A", (Format (Vc),
> Format (Vi,
> Prefix => "0x"
> Base => 16,
> Width => 8,
> Filler => "0"));
> Put_Line (F); -- Prints: "v % 0x00000c"
> end Fout;
>
> The only convention that you need to know is that "%A" inserts
> an argument and that "%%" inserts a literal "%". Much simpler,
> don't you think? And extensible! You can define "Format"
> for your own types, independently from "Formatted_String".
declare
Text : String (1..40);
Pointer : Integer := Text'First;
begin
Put (Text, Pointer, Vc & " % 0x");
Put (Text, Pointer, Vi, Base=>16,Fill=>'0',Field=>6,Justify=>Right);
Put_Line (Text, 1..Pointer - 1);
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 13:38 ` Dmitry A. Kazakov
@ 2015-07-30 13:55 ` EGarrulo
0 siblings, 0 replies; 175+ messages in thread
From: EGarrulo @ 2015-07-30 13:55 UTC (permalink / raw)
On Thursday, July 30, 2015 at 3:38:25 PM UTC+2, Dmitry A. Kazakov wrote:
> On Thu, 30 Jul 2015 06:21:42 -0700 (PDT), EGarrulo wrote:
>
> > On Thursday, July 30, 2015 at 2:42:36 PM UTC+2, Pascal Obry wrote:
> >> Le jeudi 30 juillet 2015 à 04:54 -0700, EGarrulo a écrit :
> >>> By the way, the implementation of GNAT.Formatted_String is cryptic.
> >>> Isn't Ada code supposed to be readable?
> >>
> >>> I must be missing something.
> >>
> >> Yes, sure: Open Mind score below 0!
> >
> > Not really. Compare the arbitrary overloading of "+", "-" and
> > "&" (and the cryptic "#") in GNAT.Formatted_String here:
> >
> > procedure Fout is
> > F : Formatted_String := +"%c %% %#08x";
> > Vc : Character := 'v';
> > Vi : Integer := 12;
> > begin
> > F := F & Vc & Vi;
> > Put_Line (-F); -- Prints: "v % 0x00000c"
> > end Fout;
> >
> > with the explicit formatting directives here (I am not sure that
> > this is valid Ada, but you should get the idea):
> >
> > procedure Fout is
> > F : Formatted_String;
> > Vc : Character := 'v';
> > Vi : Integer := 12;
> > begin
> > F := ("%A %% %A", (Format (Vc),
> > Format (Vi,
> > Prefix => "0x"
> > Base => 16,
> > Width => 8,
> > Filler => "0"));
> > Put_Line (F); -- Prints: "v % 0x00000c"
> > end Fout;
> >
> > The only convention that you need to know is that "%A" inserts
> > an argument and that "%%" inserts a literal "%". Much simpler,
> > don't you think? And extensible! You can define "Format"
> > for your own types, independently from "Formatted_String".
>
> declare
> Text : String (1..40);
> Pointer : Integer := Text'First;
> begin
> Put (Text, Pointer, Vc & " % 0x");
> Put (Text, Pointer, Vi, Base=>16,Fill=>'0',Field=>6,Justify=>Right);
> Put_Line (Text, 1..Pointer - 1);
Thank you. Hence the functionality is already there. You only
need to wrap it in a more convenient interface.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-29 22:32 ` EGarrulo
` (3 preceding siblings ...)
2015-07-30 8:27 ` Pascal Obry
@ 2015-07-30 15:23 ` Niklas Holsti
2015-07-30 19:32 ` Randy Brukardt
5 siblings, 0 replies; 175+ messages in thread
From: Niklas Holsti @ 2015-07-30 15:23 UTC (permalink / raw)
On 15-07-30 01:32 , EGarrulo wrote:
> On Wednesday, July 29, 2015 at 10:32:16 PM UTC+2, Randy Brukardt wrote:
>> "EGarrulo" wrote in message
>>> Generics *are* glorified macros anyway, in a sense.
>>
>> This is an especial sore point with me!
>>
>> Formally in the Ada RM they are, which causes all manner of nonsense effects
>> which then get erased by special rules. Stupid.
>
> What do you mean? Conceptually, generics are macros.
Randy Brukardt's message already explained why Ada generics are
conceptually *not* macros, but perhaps his answer was too focused on how
his compiler (Janus/Ada) implements generics and not enough on the
conceptual point.
The aim of Ada generics is to make program components parametrizable by
types in a safe and predictable way. (In Ada 83, generics were also the
only way to parametrize program components by operations, but now there
are other ways to do that.)
The "generic contract" idea in Ada is that the generic declaration
alone, without looking at the body, gives enough information about the
generic's formal parameters to decide two things at compile-time:
1. Whether an implementation (body) of the generic is legal, that is,
uses only the declared properties of the generic formal parameters.
2. Whether an instantiation of the generic with particular actual
parameters (actual types, etc.) is legal, that is, whether the actual
parameters have all the properties declared for the generic formal
parameters.
Thus, compile-time error messages for an illegal generic instantiation
need only point out discrepancies between the declaration of the generic
and the actuals in the instantiation. These error messages do not need
to refer to the body of the generic.
Contrast this with C macros, which are pure text substitution which
means that the compiler's error messages refer to the definition of the
macro and can be quite obscure. Similarly, errors in C++ template
instances are usually detected when the body of the template is compiled
with the actual template parameters substituted for the formals, and
again the error messages refer to and must be interpreted by looking at
the body of the template ("body" is probably not the correct C++ term,
sorry, I hope my meaning is clear).
This conceptual difference is related to the fact that the theoretical
computational power of Ada generic instantiation is far below that of
C++ template instantiation, which is Turing-complete.
> If a compiler is clever enough to reuse a common implementation,
> then kudos to the writers of that compiler, but such behaviour
> shouldn't be a requirement, I think.
The generic contract concept is rather equivalent to a requirement that
it shall be *possible* to implement generics with shared code. However,
the generic contract concept is programmer-oriented, not
compiler-oriented. The choice between shared code or instance-specific
code is a pragmatic one -- for example, I suspect that the choice of
shared code in Janus/Ada was influenced by its original
memory-constrained target processors. Most of GNAT's targets are not so
memory-constrained.
--
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
. @ .
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-29 22:32 ` EGarrulo
` (4 preceding siblings ...)
2015-07-30 15:23 ` Niklas Holsti
@ 2015-07-30 19:32 ` Randy Brukardt
2015-07-30 20:10 ` EGarrulo
5 siblings, 1 reply; 175+ messages in thread
From: Randy Brukardt @ 2015-07-30 19:32 UTC (permalink / raw)
"EGarrulo" <egarrulo@gmail.com> wrote in message
news:d5a73210-a67f-4d21-8b16-536af10ab157@googlegroups.com...
> On Wednesday, July 29, 2015 at 10:32:16 PM UTC+2, Randy Brukardt wrote:
...
>> In Ada terms, typing is something done at compile-time. Ada does not have
>> runtime typing (one could imagine tag checks to be runtime typing, but
>> that's a check in Ada, not related to typing).
>
> But is this a valid excuse? Aren't programming languages supposed to
> let programmers write useful programs?
Within the language philosophy. If writing *your* useful programs is too
hard, then you are probably using the wrong language (or you need some
re-education, which I think applies more to the current case ;-).
...
> If Ada offered runtime typing by means of a type `Any`, then `Printf`
> could be trivially written as:
>
> type Printf_Arguments is array (Positive range <>) of Any;
>
> procedure Printf (Format : String; Arguments : Printf_Arguments);
Surely, at the cost of all compile-time checking (because there isn't any).
And there couldn't be any useful runtime checking, either (at least not
unless Ada added Multiple Inheritance, which is unlikely), so such a
construct would be unsafe. (Exactly how unsafe depends on the capabilities
of the format string.)
...
>> > Generics *are* glorified macros anyway, in a sense.
>>
>> This is an especial sore point with me!
>>
>> Formally in the Ada RM they are, which causes all manner of nonsense
>> effects
>> which then get erased by special rules. Stupid.
>
> What do you mean? Conceptually, generics are macros.
Definitely not; that's the problem that programmers with extensive C++
knowledge don't understand, because they *are* macros in C++. But in Ada,
the contents of the source text is not what gets duplicated (even though the
RM mistakenly describes it that way -- definitely a sore point with me).
Niklas explained the model in far more detail, so I won't repeat it here --
but the "generic contract" is considered critically important to the
language design (just like avoiding privacy violations is). It is very
unlikely that we would ever allow anything that would make an Ada generic
work like a macro.
Randy.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 19:32 ` Randy Brukardt
@ 2015-07-30 20:10 ` EGarrulo
2015-07-31 0:23 ` Randy Brukardt
0 siblings, 1 reply; 175+ messages in thread
From: EGarrulo @ 2015-07-30 20:10 UTC (permalink / raw)
On Thursday, July 30, 2015 at 9:32:17 PM UTC+2, Randy Brukardt wrote:
> "EGarrulo" wrote in message
> > But is this a valid excuse? Aren't programming languages supposed to
> > let programmers write useful programs?
>
> Within the language philosophy. If writing *your* useful programs is too
> hard, then you are probably using the wrong language (or you need some
> re-education, which I think applies more to the current case ;-).
>
> ...
> > If Ada offered runtime typing by means of a type `Any`, then `Printf`
> > could be trivially written as:
> >
> > type Printf_Arguments is array (Positive range <>) of Any;
> >
> > procedure Printf (Format : String; Arguments : Printf_Arguments);
>
> Surely, at the cost of all compile-time checking (because there isn't any).
But not all conversions can be checked during compilation, that is a fact
already.
> And there couldn't be any useful runtime checking, either
Why not? Please explain me why this is acceptable:
-- This conversion will fail if Some_Integer is bigger than what
-- Constrained_Integer_Type can hold.
Some_Constrained_Integer := Constrained_Integer_Type (Some_Integer);
whilst this is not:
-- This conversion will fail if Any doesn't contain an Integer.
Some_Integer := Integer (Any);
I don't see any difference. Both conversions can fail at runtime because types
don't match.
> unless Ada added Multiple Inheritance, which is unlikely), so such a
> construct would be unsafe. (Exactly how unsafe depends on the capabilities
> of the format string.)
If Printf took care of formatting, then the number of supported types would be
limited to standard types (incidentally, this is why I envisioned an alternative
where formatting happens before passing the arguments to Printf).
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-30 20:10 ` EGarrulo
@ 2015-07-31 0:23 ` Randy Brukardt
2015-07-31 6:29 ` Dmitry A. Kazakov
2015-08-02 10:08 ` EGarrulo
0 siblings, 2 replies; 175+ messages in thread
From: Randy Brukardt @ 2015-07-31 0:23 UTC (permalink / raw)
"EGarrulo" <egarrulo@gmail.com> wrote in message
news:d3142cab-776d-4daa-8475-1dd4d46d8556@googlegroups.com...
> On Thursday, July 30, 2015 at 9:32:17 PM UTC+2, Randy Brukardt wrote:
...
>> And there couldn't be any useful runtime checking, either
>
> Why not? Please explain me why this is acceptable:
>
> -- This conversion will fail if Some_Integer is bigger than what
> -- Constrained_Integer_Type can hold.
> Some_Constrained_Integer := Constrained_Integer_Type (Some_Integer);
>
> whilst this is not:
>
> -- This conversion will fail if Any doesn't contain an Integer.
> Some_Integer := Integer (Any);
>
> I don't see any difference. Both conversions can fail at runtime because
> types
> don't match.
This is the same nonsense that Dmitry has been spouting. In the first
instance, you have the *same* types with different constraints (ranges in
this case). Ranges *might* be checked at rumtime, although Ada compilers
spend an enormous amount of effort into checking them at compile-time (so
there is no overhead).
The second case is a mapping of actual different types. That would require
some sort of runtime type representation, which would imply a lot of
overhead for elementary types (as the runtime type representation would be
larger than the type itself in many cases). Additionally, elementary types
are by-copy; that would prevent the techniques used for tagged types from
working. Most likely, one would have to add a level of indirection into most
objects. That sort of distributed overhead is typically frowned on in Ada.
Indeed, if the second case was allowed in Ada, it definitely would NOT
represent different types. The check would be some sort of constraint check
(similar to the tag check of tagged types). "Any" would represent any type,
and thus would never fail type matching.
Randy.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-31 0:23 ` Randy Brukardt
@ 2015-07-31 6:29 ` Dmitry A. Kazakov
2015-08-02 10:08 ` EGarrulo
1 sibling, 0 replies; 175+ messages in thread
From: Dmitry A. Kazakov @ 2015-07-31 6:29 UTC (permalink / raw)
On Thu, 30 Jul 2015 19:23:18 -0500, Randy Brukardt wrote:
> "EGarrulo" <egarrulo@gmail.com> wrote in message
> news:d3142cab-776d-4daa-8475-1dd4d46d8556@googlegroups.com...
>> On Thursday, July 30, 2015 at 9:32:17 PM UTC+2, Randy Brukardt wrote:
> ...
>>> And there couldn't be any useful runtime checking, either
>>
>> Why not? Please explain me why this is acceptable:
>>
>> -- This conversion will fail if Some_Integer is bigger than what
>> -- Constrained_Integer_Type can hold.
>> Some_Constrained_Integer := Constrained_Integer_Type (Some_Integer);
>>
>> whilst this is not:
>>
>> -- This conversion will fail if Any doesn't contain an Integer.
>> Some_Integer := Integer (Any);
>>
>> I don't see any difference. Both conversions can fail at runtime because
>> types
>> don't match.
>
> This is the same nonsense that Dmitry has been spouting. In the first
> instance, you have the *same* types with different constraints (ranges in
> this case). Ranges *might* be checked at rumtime, although Ada compilers
> spend an enormous amount of effort into checking them at compile-time (so
> there is no overhead).
It is nowhere same what I am saying. [Leaving apart the point that subtype
is a type and it is not same, the semantics of operations is different.]
> The second case is a mapping of actual different types. That would require
> some sort of runtime type representation, which would imply a lot of
> overhead for elementary types (as the runtime type representation would be
> larger than the type itself in many cases).
No. The actual problem is that Any does not have the operation "Integer".
It is all about semantics. Type conversion is an operation as any other [I
don't care what RM says, when semantics is considered, you know]. There is
no such operation between any type and Integer. Period.
What you are talking about is some imaginary scenario when there existed
Root_Integer'Class and Any would be from that class. Then, indeed, Integer
would a primitive operation of. But in that scenario no conversion will be
ever necessary anyway, because Put (or Image) would be just another
operation of.
In short, you don't need to convert anything if you have a class. That is
the beauty of strong typing and Ada's OO model. It is safe and you don't
need type conversions. All cases where you do are suspicious.
> Additionally, elementary types
> are by-copy; that would prevent the techniques used for tagged types from
> working.
It would not, the class-wide of a scalar type will have a different
representation. Conversion to class-wide and back will be proper
conversion, not a view conversion.
Then for this case, the class is not Root_Integer'Class, but
Printable'Class. Yes, Integer should be a member of.
> Most likely, one would have to add a level of indirection into most
> objects. That sort of distributed overhead is typically frowned on in Ada.
No overhead in any existing code.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-07-31 0:23 ` Randy Brukardt
2015-07-31 6:29 ` Dmitry A. Kazakov
@ 2015-08-02 10:08 ` EGarrulo
2015-08-02 12:15 ` EGarrulo
1 sibling, 1 reply; 175+ messages in thread
From: EGarrulo @ 2015-08-02 10:08 UTC (permalink / raw)
On Friday, July 31, 2015 at 2:23:20 AM UTC+2, Randy Brukardt wrote:
> "EGarrulo" wrote in message
> > On Thursday, July 30, 2015 at 9:32:17 PM UTC+2, Randy Brukardt wrote:
> ...
> >> And there couldn't be any useful runtime checking, either
> >
> > Why not? Please explain me why this is acceptable:
> >
> > -- This conversion will fail if Some_Integer is bigger than what
> > -- Constrained_Integer_Type can hold.
> > Some_Constrained_Integer := Constrained_Integer_Type (Some_Integer);
> >
> > whilst this is not:
> >
> > -- This conversion will fail if Any doesn't contain an Integer.
> > Some_Integer := Integer (Any);
> >
> > I don't see any difference. Both conversions can fail at runtime because
> > types
> > don't match.
>
> This is the same nonsense that Dmitry has been spouting. In the first
> instance, you have the *same* types with different constraints (ranges in
> this case). Ranges *might* be checked at rumtime, although Ada compilers
> spend an enormous amount of effort into checking them at compile-time (so
> there is no overhead).
>
> The second case is a mapping of actual different types. That would require
> some sort of runtime type representation, which would imply a lot of
> overhead for elementary types (as the runtime type representation would be
> larger than the type itself in many cases). Additionally, elementary types
> are by-copy; that would prevent the techniques used for tagged types from
> working. Most likely, one would have to add a level of indirection into most
> objects. That sort of distributed overhead is typically frowned on in Ada.
>
> Indeed, if the second case was allowed in Ada, it definitely would NOT
> represent different types. The check would be some sort of constraint check
> (similar to the tag check of tagged types). "Any" would represent any type,
> and thus would never fail type matching.
Right. A proper type-safe and efficient solution would require the use of
generics but, right now, C++ is the only language whose generics are complete
enough to implement such a solution. In Ada, we are stuck with performing the
job of Printf by hand, or sacrifice performance.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: Running a preprocessor from GPS?
2015-08-02 10:08 ` EGarrulo
@ 2015-08-02 12:15 ` EGarrulo
0 siblings, 0 replies; 175+ messages in thread
From: EGarrulo @ 2015-08-02 12:15 UTC (permalink / raw)
On Sunday, August 2, 2015 at 12:08:52 PM UTC+2, EGarrulo wrote:
> On Friday, July 31, 2015 at 2:23:20 AM UTC+2, Randy Brukardt wrote:
> > "EGarrulo" wrote in message
> > > On Thursday, July 30, 2015 at 9:32:17 PM UTC+2, Randy Brukardt wrote:
> > ...
> > >> And there couldn't be any useful runtime checking, either
> > >
> > > Why not? Please explain me why this is acceptable:
> > >
> > > -- This conversion will fail if Some_Integer is bigger than what
> > > -- Constrained_Integer_Type can hold.
> > > Some_Constrained_Integer := Constrained_Integer_Type (Some_Integer);
> > >
> > > whilst this is not:
> > >
> > > -- This conversion will fail if Any doesn't contain an Integer.
> > > Some_Integer := Integer (Any);
> > >
> > > I don't see any difference. Both conversions can fail at runtime because
> > > types
> > > don't match.
> >
> > This is the same nonsense that Dmitry has been spouting. In the first
> > instance, you have the *same* types with different constraints (ranges in
> > this case). Ranges *might* be checked at rumtime, although Ada compilers
> > spend an enormous amount of effort into checking them at compile-time (so
> > there is no overhead).
> >
> > The second case is a mapping of actual different types. That would require
> > some sort of runtime type representation, which would imply a lot of
> > overhead for elementary types (as the runtime type representation would be
> > larger than the type itself in many cases). Additionally, elementary types
> > are by-copy; that would prevent the techniques used for tagged types from
> > working. Most likely, one would have to add a level of indirection into most
> > objects. That sort of distributed overhead is typically frowned on in Ada.
> >
> > Indeed, if the second case was allowed in Ada, it definitely would NOT
> > represent different types. The check would be some sort of constraint check
> > (similar to the tag check of tagged types). "Any" would represent any type,
> > and thus would never fail type matching.
>
> Right. A proper type-safe and efficient solution would require the use of
> generics but, right now, C++ is the only language whose generics are complete
> enough to implement such a solution. In Ada, we are stuck with performing the
> job of Printf by hand, or sacrifice performance.
If I recall correctly, Ada was the first standardized language that introduced
generics. Then other languages caught up and nowadays they lead the way.
Yet, I am sure that Ada will catch up in the future.
^ permalink raw reply [flat|nested] 175+ messages in thread