generic
type Element_Type is private;
with function "="( Left, Right: Element_Type ) return Boolean;
please help
It's a generic subprogram parameter. In the instantiation of the generic,
an actual subprogram is specified for "=" (in this case), and then every
occurence of the generic "=" in the generic is replaced by the actual "=" in
the program unit created by the instantiation.
The generic is letting the instantiator determine how to do "=".
-- mark
A rule of thumb for generics is that even for nonlimited types, it's still a
good idea to import the equality operator explicitly.
Also, in general, you should use default notation for generic formal
subprograms, like this:
generic
type Element_Type is private;
with function "=" (L, R : Elemenet_Type) return Boolean is <>; --say "is
box"
package GP is
This simplifies the instantiation, because you don't have to specify the
operation(s) explicitly.
Another thing to think about is that if the equality operator is used only
to implement a single operation (say, this is a container object, with its
own equality operator), then you could defer implementation of the
operation, by moving it to a child:
generic
type Element_Type is private;
package GP is ...
generic
with function "=" (L, R : Element_Type) return Boolean is <>;
function GP.Generic_Equality (L, R : Container_Type) return Boolean;
Another question to ask is whether you need assignment of elements. If not,
then you could declare the generic formal type as limited:
generic
type Element_Type is limited private;
package GP is ...
This would have the effect of also removing default equality (limited types
don't have predefined equality).
The idea is that for generic formals, you want to require as little from
your client as possible. I call this (after Deitel) the "principle of least
committment."
Regards,
Matt
"Matt Raikes" <mra...@vt.edu> wrote in message
news:ab21b49a.01072...@posting.google.com...
Right, this is a good idiom. Import "=" explicitly, but use the "box" :-)
>
> Another thing to think about is that if the equality operator is used only
> to implement a single operation (say, this is a container object, with its
> own equality operator), then you could defer implementation of the
> operation, by moving it to a child:
>
> generic
> type Element_Type is private;
> package GP is ...
>
> generic
> with function "=" (L, R : Element_Type) return Boolean is <>;
> function GP.Generic_Equality (L, R : Container_Type) return Boolean;
I don't see that this buys you anything... *unless* you make the formal type
limited (see below)...
But I could be wrong...(?)
>
> Another question to ask is whether you need assignment of elements. If
not,
> then you could declare the generic formal type as limited:
>
> generic
> type Element_Type is limited private;
> package GP is ...
>
> This would have the effect of also removing default equality (limited
types
> don't have predefined equality).
Now you can combine this with the child package idea above, right? So you
have a parent package that can be instantiated on any type, without
requiring the instantiator to supply "=" in the case of a limited type, and
then the child package provides functionality that can be had for a limited
type only if "=" is supplied. The style question is whether the
functionality requiring equality is sort of "core", fundamental stuff that
the user will almost always want -- in which case doing this just makes the
user have to instantiate one more thing -- or whether it's sort of
ancillary, add-on kind of functionality or whatever ("optimize for the
expected case").
>
> The idea is that for generic formals, you want to require as little from
> your client as possible. I call this (after Deitel) the "principle of
least
> committment."
I don't know who Deitel is (who is Deitel, BTW?), but it is an excellent
principle and now I have a name for it too... thanks :-)
This is one of the things about Ada generics that might be a little
counterintuitive until one gets the hang of it, don't you think? A generic
formal type is like a type declaration to the generic body, so words like
"limited" and "abstract" have their normal meaning to the body (and
technically, to the rest of the spec), which is that there are certain
things you're not allowed to do there -- e.g. assigning to objects of a
limited type, creating an object of an abstract type, etc. But for the
instantiator, it's the flip side, and these words mean that the actual type
is not required to have the corresponding properties. So the user of a
generic should read "limited" as "allowed to be limited" (but can be
limited); and while "tagged" indeed means "must be tagged", "abstract" means
"is allowed to be abstract" (but can be non-abstract).
The same goes for unknown discriminants in the generic formal type.
For maximum flexibility, the rules of thumb for formal private types are:
1) Declare as limited, if possible.
2) Declare with unknown discriminants, if possible
3) For tagged formals, declare as abstract if possible
-- mark
Actually, it means *in all cases* that the actual type MUST have the
corresponding type properties, and it MAY have additional properties.
A non-abstract type has all the properties of an abstract type and then
some. The reverse is not true, so an abstract type may *not* be an actual
for a non-abstract formal.
A non-limited type has all the properties of a limited type and then some.
The reverse is not true, so a limited type may *not* be an actual for a
non-limited formal.
A non-tagged type does *not* have all the properties of a tagged type. The
reverse it true, so a tagged type may be used as the actual for a non-tagged
formal.
A formal states what properties of a type the generic code may use and
therefore, must be supplied in an instantiation. It makes sense to use the
minimal set of type properties (and so state in the formal declaration), so
the widest set of types may be used to instantiate the generic.
> So the user of a
> generic should read "limited" as "allowed to be limited" (but can be
> limited); and while "tagged" indeed means "must be tagged",
> "abstract" means
> "is allowed to be abstract" (but can be non-abstract).
... "limited" as "must include properties of a limited type"
... "tagged" as "must include properties of a tagged type"
... "abstract" as "must include properties of an abstract type"
> The same goes for unknown discriminants in the generic formal type.
>
> For maximum flexibility, the rules of thumb for formal
> private types are:
>
> 1) Declare as limited, if possible.
> 2) Declare with unknown discriminants, if possible
> 3) For tagged formals, declare as abstract if possible
The rule of thumb is use a formal with the least amount of properties
possible. Use "private" if possible. Use "limited" if possible. Leave out
"tagged" if possible. Leave out discriminants if possible. Use "abstract"
if possible.
With discriminants there is one quirk -- to allow an indefinite
discriminated type to be used in an instantiation, the formal must have a
discriminant part. That is necessary so within the generic, use of the type
is able to "see" what the current discriminant is (to work with the type).
This is really just a corollary to the principle that an actual must have
the properties of the formal -- an indefinite discriminated type does not
have all the "properties" of a non-discriminated type.
Regards,
Steve
"Then, after a second or so, nothing continued to happen."
Steven Deller Smooth Sailing LLC
410 757 6924 del...@smsail.com
> Also, in general, you should use default notation for generic formal
> subprograms, like this:
>
> generic
> type Element_Type is private;
> with function "=" (L, R : Element_Type) return Boolean is <>; --say "is
> box"
> package GP is
It is nice to hear from Matthew Heaney. He has been absent for far too
long from this forum, and we always enjoy his comments.
I am going to respectfully disagree with Matthew on this. While using the
"box" makes it easier to instantiate the "with function" it also carries with
it some danger. Both Booch and Ed Berard made the case many years
ago for avoiding the use of operators directly in generic formal function
parameters. In the GRACE components it was common to see somethin
like this:
generic
type Element_Type is private;
with function Is_Equal(L, R : Element_Type) return Boolean;
package GP ...
This has the effect of demanding that the instantiating unit supply a
generic actual parameter.
I recall a PhD thesis from Ohio State (apologize for forgetting the
author's name) in which the case was made for making all generic
formal parameters limited private and requiring the instantiation
to provide all kinds of operations, including a copy procedure
since assignment cannot be overloaded.
Of course, now that we can create generic signature packages in
Ada 95, that is packages that contain only generic formal parameters
for further instantiation of generic formal package parameters, the
Ohio State thesis gains a bit more credibility.
Richard Riehle
Good to be back. Hope you're looking forward to some arguments!
> I am going to respectfully disagree with Matthew on this. While using
the
> "box" makes it easier to instantiate the "with function" it also carries
with
> it some danger. Both Booch and Ed Berard made the case many years
> ago for avoiding the use of operators directly in generic formal function
> parameters.
Do you mean operatORS specifically, or any generic formal subprogram?
Also, can you be more specific about what their objection is? Do you have
any references?
> In the GRACE components it was common to see somethin
> like this:
>
> generic
> type Element_Type is private;
> with function Is_Equal(L, R : Element_Type) return Boolean;
> package GP ...
>
> This has the effect of demanding that the instantiating unit supply a
> generic actual parameter.
But isn't this required only because Ada83 wouldn't let you pass the
operator form for equality? In Ada83 you *had* to do it this way, or resort
to loopholes like the Goodenough Trick.
> I recall a PhD thesis from Ohio State (apologize for forgetting the
> author's name) in which the case was made for making all generic
> formal parameters limited private and requiring the instantiation
> to provide all kinds of operations, including a copy procedure
> since assignment cannot be overloaded.
Do you have a more specific reference? If you can narrow down the year then
maybe we can do a UMI search.
> Of course, now that we can create generic signature packages in
> Ada 95, that is packages that contain only generic formal parameters
> for further instantiation of generic formal package parameters, the
> Ohio State thesis gains a bit more credibility.
Generic formal package parameters are very helpful.
Mmmm... I meant "property" in the sense of the property of limitidness, or
of abstractness...
-- mark
http://www.bagley.org/~doug/shootout/
__________________________________________________
Do You Yahoo!?
Find a job, post your resume.
http://careers.yahoo.com
But Ada surely ought to do very well. I know there are some places
where O'Caml (does well in the shootout) is likely faster. Maybe a few
places where C/C++ might beat Ada. But Ada (ie GNAT) is very good for
performance, and the shootout is for people who care about that. It's
an opportunity. Ada (GNAT) should be miles ahead of all of the
interpreted and bytecode languages, and will be in the group at the
front of the pack (I'd bet).
Al
Irrespective of where the benchmarks are any actual use or not (they
aren't...)
this could be a pretty good advert for Ada. I did write a program for the
first
benchmark (simple array allocations) and it was as fast as the 'C'
equivilant.
It seems a shame that just now the language isn't even represented...
How did it compare on their SLOC measurement?
The last time I read over that, its goals, methods, and conclusions seemed so
bogus that I didn't think it was worth participating. The ideal language for
them would be some compiled form of APL. Anything that proports to compare
languages in a general way and is stilted towards APL isn't worth my time.
---
T.E.D. homepage - http://www.telepath.com/dennison/Ted/TED.html
No trees were killed in the sending of this message.
However a large number of electrons were terribly inconvenienced.
no idea - I just wanted to prove, to myself as much as anything, that Ada95
could
hack it with the fastest of them... and it could.
> The last time I read over that, its goals, methods, and conclusions seemed
so
> bogus that I didn't think it was worth participating. The ideal language
for
> them would be some compiled form of APL. Anything that proports to compare
> languages in a general way and is stilted towards APL isn't worth my time.
I'm sure there are hundred of reasons why this sort of benchmarking is
'bogus' but
not actually entering a suite of Ada programs for (potentially favourable)
comparisons
just means that even more people think the language is dead. :-(
> The last time I read over that, its goals, methods, and conclusions
> seemed so bogus that I didn't think it was worth participating. The
> ideal language for them would be some compiled form of APL. Anything
> that proports to compare languages in a general way and is stilted
> towards APL isn't worth my time.
Hey, at least they are at the proper end of the alphabet :-)
Seriously, anything that gets the Ada name out there as being current
is worthwhile. If Ada comes out dead last in the terseness competition
it will attract favorable notice from those who have ever had to read
obfuscated code.
For the 'echo server' shootout, I coded up a solution, and Ada 95 was
going to be last since 251 lines long. This is the page on the "echo
server" shootout: the programs are expected to fork (or multitask) and
both send and receive bytes:
http://www.bagley.org/~doug/shootout/bench/echo/
Adasockets could be replaced with the newly available GNAT Sockets
code. But that maybe would not make the code smaller.
The lengthiest entry, the (forking) g++ code was about 129 lines long.
Maybe the G++ entry could produce zombies or core-dumps at run time:
int sigchld = 0;
void reaper (int sig) { sigchld = 1; }
...
signal(SIGCHLD, reaper);
if ((pid = fork()) == -1)
sysabort("server/fork");
The Ruby solution is about 29 lines long. Ruby might even be
initialising Winsockets (which could add maybe another 97
non-comment lines to any Ada 'echo' entry (bringing the total to
just over 300 lines).
I can e-mail out my echo server code to anybody else interested in
having Ada compete (i.e. lose) under a clean adjective-free
["stilted .. APL"] test where pairs of integers are compared.
The shootout could be altered (a committee investigates; hack his
site?), and these can be the new requirements
* code must be fast with 0 run time error problems, when running on
a slow CPU (this can eliminate Java easily: run time socket I/O
errors creep in and make it maybe 5 times slower than Ada)
* multitasking, requeue statements of each language demonstrated.
* portability to Windows operating systems and no forking.
* assembly inlining tests
I see that there is a TCP Stack coded in Java now:
http://www.websprocket.com/
When I had a discussion with him some months ago his attitude on
new languages seemed to be a matter of waiting until he personally
had time to deal with them.
Did you suppress run-time tests etc in Ada ?
Preben Randhol
--
Please, stop bombing civilians in Afghanistan. One cannot write off
killing innocent children and other civilians as "collateral damage".
A civilian is a civilian whether he or she is American or from another
country in the world. http://web.amnesty.org/11september.htm
Yes as the problem was simply writing various values to the array
and doing a few loops, a 'Range did the trick. I didn't see any need
for them to be there. If I had thought about it more, I would now have
checked to see if the compiler actually put any in, or if it was smart
enough to work out that none were required...
Personally, I think the effort is in good intention. Remember the
disclaimers he wrote, "I'm just a beginner in many of these languages,
so if you can help me improve any of the solutions, please drop me an
email. Thanks." This could help providing some useful insight. I have
not see erlang, OCAMl, and most of the other languages, like mlton,
stalin, mercury, smlnj and all other funny names. When I take a look
at those codes, clearly readbility is low, perhaps near to zero, and
it took me sometime to vaguely understand those code.
The shootout, of course, is not well designed and managed but
certainly has a lot to improve:
1. with plentyful of experienced software engineers in CLA, can
provide a proven methodology for the purpose.
2. Provide clearly written Ada code for comparison and I am confident
Ada will win the war in this area.
What do you think?
> When I had a discussion with him some months ago his attitude on
> new languages seemed to be a matter of waiting until he personally
> had time to deal with them.
He also seems to suggest that Ada didn't seem very interesting to him.
Perhaps he needs some "convincing".
Dave Brown
Isn't it true though that, given a long enough SLOC support from the
compiler,
any Ada program can be written on a single line? Or, at least, use as long
lines
as are supported by the compiler. That'll show them for sure ... :) So, what
was
that metric about?
What you describe is indeed an Ada capability.
More frequent is more important than more accurate when it comes to broad
publicity for Ada. This is public relations, not software engineering.
> Isn't it true though that, given a long enough SLOC support from the
> compiler,
> any Ada program can be written on a single line? Or, at least, use as long
> lines
> as are supported by the compiler. That'll show them for sure ... :) So, what
> was
> that metric about?
In modern programming, there are a lot of problems with the SLOC metric.
For example, do we count the SLOC of any libraries we might use? If we
count only the code of the program in question, does it matter if we put
several statements on one line? Wouldn't it be more useful to count the
number of statements instead of the number of lines?
Another problem. Some languages are better at writing short programs than
others. Ada is excellent for larger programs developed by a team of
engineers. It is terrible for "hello world" programs. One could write a
great "hello world" program in a few lines of assembler. In any other
language, there are supporting libraries for I/O that must be considered
as part of the solution space.
Let's see what happens in this "shootout" as the size of the programs increases
to, say, 100K non-comment source code statements. Now double that size.
Then double that. How is Visual Basic faring? How is C faring? Indeed,
compared to Ada, how is C++ holding up? Under the criteria of selecting
the right tool for the right job, Ada holds its own.
Unfortunately, this "shootout" is being conducted by someone without the
slightest idea, by his own admission, what it takes to build software in
a wide range of domains, especially large-scale software. It is an odd
revisiting of Zeno's Paradox all over.
Richard Riehle
That's the spirit - was the whole point of my post (Sorry I didn't make
the irony even clearer but I did put a smiley in there, didn't I?)