Re: Pointers to "why C behaves like that ?"

"Stefan Ljungstrand" <>
20 Nov 2002 15:36:06 -0500

          From comp.compilers

Related articles
[11 earlier articles]
Re: Pointers to "why C behaves like that ?" (2002-11-20)
Re: Pointers to "why C behaves like that ?" (Marco van de Voort) (2002-11-20)
Re: Pointers to "why C behaves like that ?" (Charles Bryant) (2002-11-20)
Re: Pointers to "why C behaves like that ?" (Peter Flass) (2002-11-20)
Re: Pointers to "why C behaves like that ?" (Peter Flass) (2002-11-20)
Re: Pointers to "why C behaves like that ?" (Manos Renieris) (2002-11-20)
Re: Pointers to "why C behaves like that ?" (Stefan Ljungstrand) (2002-11-20)
Re: Pointers to "why C behaves like that ?" (Torben Ęgidius Mogensen) (2002-11-24)
Re: Pointers to "why C behaves like that ?" (Torben Ęgidius Mogensen) (2002-11-24)
Re: Pointers to "why C behaves like that ?" (Nick Maclaren) (2002-11-24)
Re: Pointers to "why C behaves like that ?" (2002-11-24)
Re: Pointers to "why C behaves like that ?" (jacob navia) (2002-11-24)
Re: Pointers to "why C behaves like that ?" (Nicola Musatti) (2002-11-24)
[49 later articles]
| List of all articles for this month |

From: "Stefan Ljungstrand" <>
Newsgroups: comp.compilers
Date: 20 Nov 2002 15:36:06 -0500
Organization: Chalmers University of Technology
References: 02-11-059 02-11-071 02-11-083 02-11-091
Keywords: C, design, rant
Posted-Date: 20 Nov 2002 15:36:06 EST

On 17 Nov 2002 Gayev.D.G.=?iso-8859-1?Q?=3Cdg=E0ev=40mail=2Eru=3E? wrote:

> WONG SAI-KEE wrote:
> > Gayev.D.G.=?koi8-r?Q?=3Cdg=C1ev=40mail=2Eru=3E? wrote:
> > : WONG SAI-KEE wrote:
> >
> > : Most modern languages require variables (as well as other objects) to
> >
> > But, languages like HyperCard, VisualBasic (I was told) do not.
> >
> > : compiler must know types of all program objects during
> > : compilation. Without explicit declarations, the type assigned to
> > : variable can only be determined by its usage -

> > : unreliable and
> > : sometimes rather hard to do.

(I'm not so sure about that.)

> > I am not against the necessary of declaration. In some programming
> > books, they don't explain why we need it (or they tell a reason which
> > does not explain). So I'm thinking about it may be due to the
> > compiler construction and historical reason.

(Somewhat, perhaps.)

> > The question is: ``rather hard to do'' is not a good reason in modern
> > computing (in the old days, OK, due to lack of resources). Because
> > the compiler is written once, and all the end user benefits from it.


> > That should always be one of the principle of writing a computer
> > program: we want the computer to do the tedious labor intensive work
> > (of course, we need to justify the cost and benefit in some cases, but
> > I think the user pool is huge for a language like C to be justifiable
> > to provide convenience to the user).
> >
> > I mean we should not sacrifice the easy of using the language due
> > to the compiler construction. I can understand when the author
> > first evolve the C lang, there are much uncertainty, so DECLARATION
> > is a good choice to start with. Then, this becomes the historical
> > reason. Other reason like unreliable is a good support, but I then
> > want to collect solid examples to show it in the book.
> >
> > : "Technical" reasons are not less important, that the "ideological" ones.
> > Can you clarify this more ? Thanks.
> Well, my original statement probably was too strong. Definitely not
> all of the modern languages require declarations. Basically and
> roughly, all languages may be subdivided into two categories: the
> "traditional" ones (like C/C++, Java, descendants of Pascal) and
> "typeless" (for the lack of better term) languages, like Vis Basic,
> PERL, Python, TCL... most scripting languages of any kind.
(Add Prolog, CommonLisp, Scheme, Smalltalk(?), Erlang, Oz(/Mozart)
  (Python ?, Ruby ?) etc ..)
(Not sure if the dynamic OOPLs can be said to be "typeless")

You forget the (mostly) "type-inferred" languages like Haskell,
the ML descendants (SML, Caml, O'Caml, etc), Mercury (hmm), Clean etc ...

These have static, compile-time typechecking ("types are associated with
variables"). But you generally don't have to explicitely supply type
declaration of variables (at least at the expression level, though there
are some differences on declarations on the module/package level), because
of the good type inferring algorithms (mostly Hindley-Milner based) can
determine a variable's type from its use.

> The
> traditional languages are mostly fully-compiled ones; the typeless
> ones are mostly interpreted or semi-compiled (e.g. producing some type
> of intermediate code to be executed later).

(Last-minute note : even compiler-produced machine code is usually stored
  somewhere (e.g. a file) and executed later :) by the processor (a kind of
  interpreter) :) There are some exception though, i believe, e.g. run-
  time code-generation (RTCG).

The type-inferred languages tend to be well suited to full-compilation
(probably because they have static typechecking like "traditional") or
at the very least byte-compiled ( = ypur semi-compiled, i assume). Though
this doesn't of course hinder interpreters to implemented.

> The problem of declarations is someway related to this distinction.
> Traditional languages require variables to be declared, because memory
> allocation and mapping is performed at compile time,

(I take you mean (or should mean) that memory allocation and mapping code
  is *prepared* and optimised at compile-time. I.e. programs written in
  "traditional" languages can, and often do, allocate and map memory
  dynamically. Even Fortran supports this now (which I have heard wasn't
  the case for X years ago).

> and, in order to
> expressions and statements to be compiled correctly, the exact types
> assigned to them must be known.

Many "type-inferred" languages (ML,Haskell,..) though have a notion which
might be called "variable declaration" (i.e. declaring what variables you
are going to use (but their type need not be given)) but this is often
integrated into "variable binding" and "pattern matching", so it's not
very much overhead (i.e. the "variable declaration" is just a such, but
have other useful purposes as well).
Some "type-inferred" languages (Erlang,Mercury,..) can't even be said to
have a "variable declaration" notion. (Erlang can perhaps be argued ...)

(Though "variable declaration" seem to be a notion more or less
  independent of static vs dynamic typing issues. E.g. Oz(/Mozart ?)
  has it even though it is dynamically typed (~= your "typeless"),
  and i think Mercury hasn't even though it is type-inferred (not totally
  sure about this).
  (Some would perhaps say type-checked / type-inferred ??)

> In typeless languages both allocation
> and ultimate "typisation" of the language objects are done dynamically
> at runtime, so variable predeclarations are not much needed. Of cause,
> the flexibility of "typeless" languages has some drawbacks: they are
> commonly less efficient, than the fully-compiled ones.

Of course, many/some type-inferred languages (and perhaps type-checked as
well ?) try to provide some "dynamic" types, e.g. Clean (Dyn), Mercury
(univ), Haskell (Dynamic), etc ..
(This is perhaps not as much needed because of parametric (and inclusion)
  polymorphism, type classes, etc ...)

> Of cause, the historical reasons also must be taken into
> account. Since the first "traditional" language (it was Algol-58,
> IMHO), the language designers decided what the forward declarations of
> variables is a good thing to have. IMHO, they are right :-) Technical
> matters for this decision are briefly discussed above, but there are
> matters of language design ideology as well. Explicit declarations of
> variables provide some additional program discipline and logic

(and documentation)

> , which is worthy.

In principle I agree with you here, at least on a higher (module, perhaps/
probably(?) also function/predicate) level, but IMHO often it clutter
things up more to have to type declare every variable and temporary,
especially when there exist good type-systems+inferencers which always
(or almost always, in some cases, hmm) can determine/infer its type.

It can even be a good thing to do, to first write one/some functions/
predicates(/objects+methods ?) without any type declarations and ask the
type-inferencer what typings it think your code has, even if one are going
to put (some) type-declarations in the (for the time) finished version.
Because the type-inferencer can sometimes find a more general typing
(see polymorphism) than the one you had in mind (if you indeed had one in
mind :). Then, if you don't like the general typing (perhaps too general),
you can always restrict it to the level you want.

There will probably still be things that "dynamically typed" languages
can do easier, or do at all, compared to "statically typed" (even type-
inferred) languages can do, but the gap seems to be closing somewhat.

Thinking more concretely about types also has some implications and cons
regarding how one structure the program code and regarding how one get
started coding (i'm thinking of using the type to write a probable
recursion/whatever pattern almost automatically (saving time (?)), and
then concentrating on how to solve the problem by filling in what is
missing, possibly refactoring the pattern to e.g. an accumulator on the

> The compiler easily can catch various errors - simple (as
> mistyped variable names)

Some (many ?) of those can be catched by some form of "variable
declaration" (see above). Some can perhaps be handled by dead-code
analysis. Also linear/uniqueness type-systems can catch some more
of these errors (if it knows, by inference or explicit declaration,
that such a variable should/must only be used exactly once (modulo
branching structores like if,switch,case/match, etc)).

> or more complex ones (as usage of variable
> inconsistent with its type).

(Both "type-checking" and "type-inferencing" languages
  catch all (almost all ?) of these.)

> And yes, in most languages there is not
> always possible to deduce type of variable (not declared previously)
> by context.

That depends if the language was designed to deduce/infer type of
variables and/or on what the common ideoms/paradigm/style of writing
programs in the language are.
IMHO, this is not so much a problem as you seem to think.
I think that if it isn't possible in many current languages, that
only (well, mostly) because of some small design choices that could
easily (at least in retrospect :-) have been avoided/circumvented/
different had the designers only investigated this a little more
(*and* had access to more-or-less recently developed type-systems ;-)

> There are many cases of possible ambiguity - if the variable is first
> mentioned in the argument list for the overloaded function, accepting
> parameters of various types, for example.

Admittedly there are some problems with combining type-inferencing
and (permeating use) ("ad-hoc") overloading (especially with regards
to "curried" functions). (Default arguments also, AFAICT.)

> And for the variables of
> derived types the situation will be even worse - so the explicit
> declaration is the best way to avoid such problems.

Not sure what you mean here by "derived" types. Do you mean "sub-types"/
"super-types" or something somewhat similar with "classes".
Perhaps you mean that a type-inferencer might infer a too general type,
in this case one probably has to explicitely provide a type declaration
(if the too general type is indeed a real problem here (?)), just as one
can do with a too general parameterically polymorphism function/predicate/
procedure(/method(/message ?)/class)/variable.

> Of cause, I may
> be not 100% right (and even completely wrong :), so additions and
> comments welcome.

Same disclamier goes for me ;)
(I'm but a student at university how has studied (both course and
  freetime :) some programming languages, thereof mostly functional ones.
  Also some type-systems, etc.
  Perhaps much of my post is old hat in this newsgroups (or just plain
  worng). I actually hasn't lurked enough here yet to tell.

I also agree (mostly) with the parent siblings and relatives of this post
(Robert A Duff, , Christian Bau,James Powell,etc).

> [Fortran and, debatably, Cobol preceded Algol-58. In Fortran, declarations
> are optional, in Cobol they're required. Fortran 77 added IMPLICIT NONE to
> let you turn off the automatic declarations. -John]

Hope to have added at least some value in this post to the group.

(Please reply if you want to refute, correct, comment or just write
  something related to above post.

Stefan Lj

Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.