[LONG] Re: Why code completion and early error checking are needed

From: Mark A. Gibbs (x_gibbsmark_at_rogers.com_x)
Date: 06/05/04


Date: Sat, 05 Jun 2004 19:36:11 GMT


Steven T. Hatton wrote:
> Some people have suggested the desire for code completion and refined
> edit-time error detection are an indication of incompetence on the part of
> the programmer who wants such features. Unfortunately these ad hominem
> rhetorts are frequently introduced into purely technical discussions on the
> feasibility of supporting such functionality in C++. That usually serves
> to divert the discussion from the technical subject to a discussion of the
> character of the proponent of the new technology. This recently happened in
> this newsgroup, and I have to confess, I took the bait and defended my
> character instead of ignoring the irrelevant comments.

your case starts on shaky ground. you throw ad hominem around, but what
about ad ignorantiam (among others fallacies)? it is you who proposes
that these features are required considerations in the evolution of c++.
if you want them to be taken seriously, you should back them up with
more than a "i just feel it should be so".

frankly what you feel, what i feel, and what anyone else feels is
irrelevant. if you have a case to present, please present that case on
its own merits. am i correct in assuming that your thesis is that one of
the guiding principles in the evolution of the c++ language should be
the ease with which machines can deduce code given partial samples?

> Will the IDE add the required headers and using declarations to your source
> automatically?

the problem with this is that ide must first be able to assume
intention. even in more simplified cases, such as java, a lot of
information is needed to make safe assumptions. for example, on first
appearance of a type name, the compiler has to search all known
libraries to find the type declaration. this is a tedious but trivial
process if there is only one matching type, but what if there are
duplicated type names?

for example, i type "Vector". does that mean the standard vector
container, int namespace java.util? or my own 3d vector class in indi.math?

in java's simplified world the solution to such a problem is simply to
offer a choice of all candidates. but c++ has special challenges. in
java, the required header to import is well-defined and can be easily
extrapolated from the type name, or even better, from the
fully-qualified typename. you want "Vector" in "java.util"? it doesn't
take a complicated algorithm to generate "import java.util.Vector".

but in c++ the header to import is not well-known, not only because no
part of it can be deduced from the type name, but because the possiblity
of nesting includes within other includes. for example, consider
std::string. obviously the correct include in this case is <string>, but
indulge me momentarily. imagine you have thousands of headers for
classes that use strings internally. how is the compiler to know that
you specifically want <string> and do not wish to come by string by some
other means?

it cannot be argued that programmers will only want to include the
actual base declaration header for a type. it may be by design that
<string> is not included directly, for several reasons, including
precompiled headers and the potential to transparently replace usage of
std::string in the library with something_else::string at some future date.

furthermore it may be that while "some_type" is actually declared in
"some_type.h", the intention was that "some_type.h" should never be
included in client code directly. take the classic case of <windows.h>.
the definition of type LPTSTR is given a default value in <windows.h>
that can be overidden by the use of precompiler macros. across the scope
of a project it would be expected that the definition is consistent, but
this may not be the case if <windows.h> is included directly instead of
"windows_includer.h".

you could argue that programmer oversight would properly direct the
ide's assumptions, but if the programmer has to read the documentation
and determine the proper include files themself, what gain is there in
having the ide attempt a guess? the cost is the time spent parsing what
may be a massive source pool (or the disk-space cost if it is
pre-parsed), the pros are.... what? forcing the programmer to read
documention he should be reading anyway?

so the ide will have a job of it. well then, maybe changes are needed
elsewhere, right?

even if it were possible to correct this problem by a reasonable
revision to the language standard (which i doubt), i do not believe that
it should be applied. it would be limiting to the power and flexibility
of the language to have certain naming and declaration standards
imposed. unlike a language such as java, c++ is multi-platform capable -
the task of writing portable code demands the ability to be flexible
with type declarations.

within a given coding team you could enforce standards that facilitate
easy machine analysis, and project leaders are welcome to do so.
personally, i am opposed to tying programmers hands with more rules than
are absolutely necessary - it limits efficiency to have to conform to
potentially unnatural rules, stifles creativity, and may preclude some
powerful problem solutions.

so the onus is back on the ide to somehow handle this. i don't pretend
it will be easy - c++ is a two-pass parsed language with a one
definition rule, but no one declaration rule. can it be done? oh most
probably. but it should be done by the ide, not by limiting the power
and flexibility of the language, or by hampering the programmers trying
to use it.

> Will it give an indication of the exceptions thrown by a function call?

the c++ exception specification mechanism is sadly broken. it is also
difficult to fix, even if one was inclined to rewrite the standard.

the problem really surfaces in the definition of template functions.
even given such a simplistic function as:

template <typename T>
T max(T const& a, T const& b)
{
    return (a > b) ? a : b;
}

when a T is substituted, it is possible that this function may throw an
exception in two places. on operator<(T const&, T const&) or on the T
copy constructor.

how now, do you stipulate this when you do not know a) what T will be
used and b) what the exception specifications on T will be.

in my mind, this and complications due to inheritance preclude changes
to the language directly, so the task for implementing this feature will
fall at the feet of the ide writer.

> Will it display all the overloaded function signture with an indication of
> the type of parameter it takes?

well now, you've opened up a whole new kettle of fish here. i
deliberately avoided mentioning functions when i was discussing
including the correct headers for types because the problem is even
worse there. even within the bounds of the standard library, there can
be several answers to the question of which file to include given a
specific function signature.

now that you're talking about considering not only multiple declarations
of a single function, but also potentially multiple signature for
multiple overloads, the complexity is increasing by leaps and bounds.

and of course, what about function templates and function-like macros?

i have already argued that neither the language nor the compiler should
be responsible for making code-completion easier, so i will not repeat
myself. this is a problem for ide writers to overcome.

> Does it filter according to context? That is, does it only show the
> identifiers visible in the current scope when it provides code completion
> (unless you ask for more)?

those are the kinds of design questions you would expect to see in the
development of an ide, not a language.

> When it shows error indicators in the edit buffer, is that a result of
> compiler output, or is the code evaluated as you input it?

the c++ language does not define error indicators or edit buffers. those
too, are ide writers' concerns.

> Can you add virtually any SDK such as the Xerces C++ to the available
> resources and have the code completion and checking work at the same level
> as it does for the Standard Libraray and the implementation's API(s)?

that also, is an ide concern. remember, as far as the c++ standard is
concerned, there is no need even for a file structure (and some cases
where there is none). each hosting platform should and does have its own
way of specifying where libraries are. given that, it is now the
responsibility of the ide to understand those library location
specifications, and parse accordingly.

> Since there is some question as to whether such functionality would be
> advantageous to C++, I will briefly address the matter. I have been
> working with a project that has grown from something I could download and
> build in a matter of minutes on 1997 computing technology (sparc 5, and P2
> intel platforms), to a world class desktop user interface environment with
> more than 40,000 lines of code. The collective libraries for all the
> components of the KDE is huge. It is unreasonable to expect a programmer
> to be aware of every feature of every class and function in these
> libraries. And that fails to take into account the number of different
> supporting libraries employed, or potentially employed by the developer.

i feel your pain. i am a lone wolf developer and hobbyist c++ coder. i
do not have the luxury of being a programmer that can choose to
specialize in one library, or even one aspect of program development. i
agree that the size of many libraries is daunting, and expecting anyone
to know all the capabilities and gotchas associated with any particular
api is ludicrous.

but these are not problems with the standard, they are concerns of the
library writer. even if the language were to make it laughably simple to
maniuplate huge libraries, the question remains as to whether making a
huge library is a good thing. a good library would be simple and
modular, so that for any given problem you would know where to look for
the solution set, and the size of that solution set is manageable.

the argument that c++ should have built-in facilities to support huge,
cumbersome libraries because they exist and must be used is no more or
less valid than the argument that built-in facilities to support huge,
monolithic should not be added to the c++ language because the c++
language is the way it is and must be used as is.

> The feature I have listed above have proven useful to developers working on
> large-scale projects using a different programming language. The provide a
> way for the programmer to leaverage the available resources more
> efficiently and effectively.

and there is no rational argument that i can imagine for why they should
not be developed and used - or at least available. the only question
here is where the burden for the development of these feature should be
placed.

> It has been suggested that an effort to support such functionality by
> ensuring the C++ implementation provides the necessary interface to the
> development environment would somehow encumber C++ and make it
> significantly less useful. Since, so far as I know, the requirements for
> providing this interface have not been established, I find it difficult to
> believe the impact on the language has been evaluated. Can anybody provide
> a reasoned, objective rationale for why the proposed support would
> significantly and negatively impact C++?

you make a good point. my argument exists only of glaring generalities.
but then, no-one has provided a valid proposal for how these
requirements could be met on any given c++ implementation, let alone all
of them. i will provide a reasoned, objective rationale for why the
proposed support would significantly impact c++ - positively, negatively
or both - when you provide a reasonable proposal of what this support
will be.

that being said, this is hardly the forum to do that. comp.lang.c++
discusses *using* the c++ language, not designing, changing or improving it.

mark



Relevant Pages