Re: How come Ada isn't more popular?
- From: Maciej Sobczak <no.spam@xxxxxxxxxxx>
- Date: Tue, 06 Feb 2007 15:16:08 +0100
Markus E Leypold wrote:
And I stress again - GC is not the only solution for
manual memory management.
OK. I accept that for the moment. I'm just not convinced you can do
everything you need with scope bound memory
Sure. But for the sake of discussion completeness, you might wish to throw an example of a situation where scoped lifetime will not make it.
Determinism in both timing and resource consumption?
Which brings me back to what I said repeatedly to other people:
(1) That this determinism is very often not a requirement (outside of
embdedded programming)
Java programmer wrote a loop where he opened database cursors, released in the cursor finalizer. All was working like a charm, unless put into production, when in one case the loop had to spin many more times than he ever cared to test. GC did not clean up the abandoned cursor objects fast enough and the number of unnecessarily opened cursors hit the server limit. That was the end of this application.
The fix was easy: write explicit close/dispose/dismiss/whatever at the end of the loop, so that effectively there was never more than one open cursor. In fact, this was *manual* resource management.
The above would be avoided altogether with scoped lifetime.
You are right that determinism is very often not a requirement. It is just the life that very often shows that the initial requirements were not complete.
(2) The determinism is shot anyway by using a heap, not by using
GC. Even better: GC can introduce detereminism in space
consumption by compacting the heap, which naive heaps with manual
MM don't do because of fragementation.
There is nothing particular in scoped lifetime that would prohibit compacting heaps and there is nothing particular in GC that guarantees it. It's just the statistics based on popular implementations, not a rule.
I can perfectly imagine compacting heaps managed by scoped lifetime.
(3) What is often needed are upper limits not determinism and thos
upper limits can be guaranteed with GC or with an appropriate
collector.
This refers to memory consumption only, whereas I clearly stated deterministic *time* as a second (first, actually) goal.
My impression was that Ada Controlled storage is actually quite a
clean concept compared to C++ storage duration.
Clean? It adds tag to the type, which then becomes a controlling type
in every primitive operation.
I got bitten by this recently. Adding a destructor to C++ class
never has any side effects like this.
I understand. But the Ada OO way is peculiar, but not unmanagable.
OK, I accept the word "peculiar". I only oppose "quite a clean concept" in your previous post. :-)
Apart from this, the bare existence of *two* base types Controlled and
Limited_Controlled means that the concepts of controlled and limited
are not really orthogonal in the sense that adding one of these
meta-properties affects the interface that is "shared" by the other
aspect.
Still. Being able to add a Finalize means you need to have a tagged
type. I see no alternative.
You might want to take a look at C++.
But both tie allocation to program scope, synchronous with a stack. IWhat architecture?
insist that is not always desirable: It rules out some architecture,
especially those where OO abounds.
I already say in another post: That is difficult to show with a toy
system. It only shows in larger systems where you really can't / don't
want to say in any give subsystem module how long a certain peice of
data lives. So none of those can be burdened with deallocating it.
OK. What about refcounting with smart pointers?
The problem with Controlled, BTW, is that it seems to interact with
the rest of the language in such a way that GNAT didn't get it right
even after ~10 years of development. Perhaps difficult w/o a formal
semantics.
You see.
Yes, I see. But GNAT is also a political problem (see the role of
AdaCore, formerly ACT), so (public) GNAT not getting things right
might well not indicate a problem with reading the Ada standard, but
in the release politics for public version. My hint: There is no
incentive to release a high quality public version GNAT.
I get the message. Clear enough.
In other words, it's very nice that GC doesn't preclude me from doing
some stuff manually, but that's not enough.
I'm appalled: You don't want GC, but no, it doesn't do enough for you?
Exactly. It's not enough, because it doesn't solve the problem of resource management in a general way.
Of yourse YMMV. but when I have it, it works really well for me.
I acknowledge that there might be some applications which are strictly memory-oriented. They are just not the ones I usually write.
Apart from that languagesThese "nice tricks" are not so nice. Most of all, they provide no
with GC often provide nice tricks to tie external ressources to their
memory proxy and ditch them when the memory proxy is unreachable
guarantee whatsoever, even that they will be invoked at all.
That's not quite true. Those tricks are building blocks to implement
ressources that are automatically finalized when becoming
unreachable. But it's up to the library author to write a complete
implementation.
I don't understand. If the is no guarantee that the finalizer will be *ever* called, then what kind of building block it is?
A friend of mine spent long evenings recently hunting for database
connection leaks in a big Java application. That's telling something.
Well -- so he was naive and should have handled / understood that part
of the system better.
Sure. In other words, be prepared that with GC you have to handle/understand some parts of the sytem better.
A friend of mine spent half a month with finding
problems with manual allocation/deallocation and sneaking heap
corruption. Does that prove anything? I don't think so.
It does prove that your friend did not benefit from the language that provides scoped lifetime.
And BTW - in
fcuntional langauges you can do more against ressource leaks, sicne
you can "wrap" functions:
(with_file "output" (with_file "out_put" copy_data))
It's not always done, but a useful micro pattern.
Yes, it basically emulates something that is just natural in those
languages that provide scope-based lifetime out of the box.
This is no emulation, but how FP does "scope based". Without the
necessity to add exception handling at the client side or without
having to introduce tagged types / classes. Isn't THAT nice? :-)
Same thing with scoped lifetime, as implemented in C++. No need for exception handling (unless handling is actually meaninful), nor for changes in the interface. That's nice, I agree.
The difference is that in languages with scoped lifetime the lifetime management is a property of the type (and so applies to all instances), whereas the "FP-trick" above is a property of the use-side. Which one is more robust and less prone to bugs?
BTW - please show me an example involving 10 objects of different kinds. :-)
But I notice, thatExcept that it's not the point I'm making.
"Languages like C provide a more general solution (with regard to
accessing memory), which is conceptually not related to any kind of
fixed type system and can therefore implement any type and data model"
would become a valid argument if I agreed with you.
No, but the structure of the argument is basically the same. The
analogy should help to show why it is (IMHO) invalid.
Ok, but please elaborate on the above first, so I'm sure that it relates to my point.
Tons of exception handling (and not only - every way to leave a scope
needs to be guarded, not only by exception) are necessary in those
languages that rely on GC without providing the above possibility at
the same time.
No. I've done the same in Ada w/o controlled objects, but using a
generic procedure.
procedure mark_data_records is new process_cache_with_lock( Operation => mark_record, ... );
begin
mark_data_records(...);
end;
The client side has no burden with exceaption handling.
Could you explain this example a bit?
I agree for references/pointers in polymorphic
collections. That's not even close to "almost everywhere" for me, but
your application domain may differ.
Yes. it does, abviously. You might not be aware, but code destined for
mere consumers (as opposed to embedded code and code destined as tools
for other developers) has a large amount of GUI code in it.
Yes.
(b) AFAIR there are restrictions on _where_ I can define controlledThat's a mess. I'm sorry to repeat that.
types. AFAIR that was a PITA.
Yes. But does C++ do it better? The Ada restrictions AFAIK come from
the necessity of separate linking and compilation (you must be able to
relink w/o looking at the body) and C++ treats that against the
ability to add finalizers everyhwere.
I don't understand. Adding a finalizer/destructor to the type that didn't have it before means changes in both specs and the body. Relinking is not enough.
--
Maciej Sobczak : http://www.msobczak.com/
Programming : http://www.msobczak.com/prog/
.
- Follow-Ups:
- Re: How come Ada isn't more popular?
- From: Ray Blaak
- Re: How come Ada isn't more popular?
- From: Markus E Leypold
- Re: How come Ada isn't more popular?
- References:
- Re: How come Ada isn't more popular?
- From: Markus E Leypold
- Re: How come Ada isn't more popular?
- From: Maciej Sobczak
- Re: How come Ada isn't more popular?
- From: Markus E Leypold
- Re: How come Ada isn't more popular?
- From: Maciej Sobczak
- Re: How come Ada isn't more popular?
- From: Markus E Leypold
- Re: How come Ada isn't more popular?
- From: Maciej Sobczak
- Re: How come Ada isn't more popular?
- From: Markus E Leypold
- Re: How come Ada isn't more popular?
- Prev by Date: Re: in defense of GC
- Next by Date: Ada.Containers.Doubly_Linked_Lists
- Previous by thread: Re: How come Ada isn't more popular?
- Next by thread: Re: How come Ada isn't more popular?
- Index(es):