Index
Home
About
From: mash@mash.engr.sgi.com (John R. Mashey)
Newsgroups: comp.lang.c++,comp.sys.unisys,comp.arch
Subject: Re: call by name
Date: 26 Jun 1995 21:52:44 GMT
Organization: Silicon Graphics, Inc.
In article <9517616.19875@mulga.cs.mu.OZ.AU>, conway@munta.cs.mu.OZ.AU
(Thomas Charles CONWAY) writes:
|> #define foo(x, y) do { \
|> some stuff using x and y
|> } while (0)
|>
|> You're telling me that C macros are not call by name? Sure, they're
|> limited in their application (they cannot be properly recursive for
|> instance), but they still use call by name.
C macros are *not* call-by-name, but just (relatively simple) textual
substitutions with none of the effects of the (various) Algol
call-by-names in potentially importing into a procedure references to
names declared outside. [See for example: "Programming Languages and
Systems, Saul Rosen, ed., McGraw-Hill, 1967, p.73-77.]
I.e., call-by-name:
a) Can require some very different semantic effects.
b) Can strongly induce thunks (or equivalents) in implementation.
While call-by-name can sometimes allow some elegant expressions of
algorithms, I think it fits into a certain category of features:
a) The feature is the default [i.e., call-by-name, unless you explicitly
said call-by-value].
b) The feature is very general, with unanticipated complexities in
interpretation (recall that changes occurred betweeen the 1960 and 1963
ALGOL reports, for example).
c) The feature's generality is actually not often used, but implementations
may get very complicated to deal with the weirder cases.
Such features show up in many places:
1) Consider the difference between FORTRAN and C with regard to aliasing
of pointers to arguments: FORTRAN says they don't, C says they can;
the former choice is easier to optimize code for; one would prefer a
default that says "no parameters aliased unless so declared".
2) In computer architectures, offering the very general concatenations
of addressing modes (a la VAX or MC68020) that can require the handling
of very long instructions ... despite the statistically low rate of such
usage.
|> Do the particular set of tradeoffs used by
|> the current generation of processors imply particular
|> implementation strategies? (For instance, thunks have been
|> implemented by having the application construct a short
|> code sequence at runtime, and then at some later time
|> execute it. With a split cache this could have bad consequences)
CPU designers *really* do not want to be required to implicitly
synchronize I-cache with D-cache on a near-instantaneous basis.
Sometimes you may get away with it, but if you *ever* allow the
following code to be legal:
ST reg,label
label: ???
you are going to add gates to many potential implementations ... even those
with no caches [because there may well be pre-fetch buffers...]
For this reason, most archiecture+software combinations started in recent
years require *some* explicit notification by the program that it thinks
it is modifying code dynamically, and that doing so without notifying
the hardware/OS is undefined.
--
-john mashey DISCLAIMER: <generic disclaimer, I speak for me only, etc>
UUCP: mash@sgi.com
DDD: 415-390-3090 FAX: 415-967-8496
USPS: Silicon Graphics 6L-005, 2011 N. Shoreline Blvd, Mountain View, CA 94039-7311
From: mash@mash.engr.sgi.com (John R. Mashey)
Newsgroups: comp.lang.c++,comp.sys.unisys,comp.arch
Subject: Re: C++: CDC6600 vs B5500, RISC vs CISC (attn Peter Juhl)
Date: 19 May 1995 21:13:29 GMT
Organization: Silicon Graphics, Inc.
In article <D8syEH.Dx4@cwi.nl>, dik@cwi.nl (Dik T. Winter) writes:
(me:)
|> > The B5xxx (in my opinion) was a brilliant and elegant design, with many
|> > fine ideas; it actually had practical hardware for running Algol-like
|> > languages, which was non-trivial, and getting good performance from them
|> > without current optimization technology.
(Dik):
|> I doubt it. The design was indeed brilliant and elegant, but not
|> unprecedented (see for instance the KDF-9). But I doubt whether stack
|> architectures are indeed particulary suited for Algol-like languages.
I don't think we disagree on some of that [I didn't say unprecedented :-)],
but let me explain more. People may recall that Algol60 used "call by
name" ... which was "non-trivial" to execute efficiently on most
machines (which is why many commonly-used languages use call-by-reference
or call-by-value or value-result). The "practical hardware" above had
little to do with being a stack machine, but with the hardware
implementation of decriptors that otherwise required many instructions on
other systems [I once looked at IBM S/360 ALGOL-generated code, and once
was enough - it was hard.] To put it simply, bringing a value to the
top of a stack wasn't just a "LOAD" or "MOV" instruction, it was
OPDC (Operand Call), whose description required half a dozen pages.
But specifically, if you did:
OPDC simple-value => load simple value
OPDC subroutine-descriptor => invoke the subroutine, which
would leave value on top of stack,
just like it had been a simple value
That is, when compiling code for a function, you could generate a
simple OPDC aimed at an incoming parameter, and it would work without
a bunch of checking to see if it was a simple value or a thunk of
code implementing an expression that should be re-evaluated each time it
was referenced. Of course, call-by-name seems to have mostly
disappeared from common use, by now.
-john mashey DISCLAIMER: <generic disclaimer, I speak for me only, etc>
UUCP: mash@sgi.com
DDD: 415-390-3090 FAX: 415-967-8496
USPS: Silicon Graphics 6L-005, 2011 N. Shoreline Blvd, Mountain View, CA 94039-7311
Index
Home
About