New as function
Frank Heckenbach
ih8mj at fjf.gnu.de
Mon Jul 25 05:06:19 CEST 2005
Peter N Lewis wrote:
> Clearly you can write code that has the same semantic behaviour as
> WriteLn by expanding it sufficiently into multiple calls to multiple
> different procedures for each possible type. But that is not "like"
> WriteLn in that it is not even close to syntactically the same.
In fact it's only syntactically different. WriteLn (with several
arguments) is just a syntactic shortcut, as defined in the
standards. Semantically it's the same as a series of simple
procedure calls.
> The philosophy I refer to is that things that look like functions or
> procedures in the language should be possible to be written in the
> language.
>
> I consider this a worthy goal and hence a weakness in the
> language. The problem can be solved in a number of ways:
>
> 1. Support types as first class objects and support variable numbers
> of parameters.
That's *not* what WriteLn is. It's a common misunderstanding which
Chuck tried to rectify. This may be the core of the disagreement
here.
The built-in WriteLn is not a magical procedure that takes any
number of arguments, plus type information ("types as first class
objects") and acts on these.
Though a compiler could implement it like this if it's equivalent to
the real semantics, which is not quite easy to achieve due to some
hairy details. Also, this approach is generally likely to be less
efficient than the standard way. (I should know as GPC tried to do
this until last year, and indeed, it failed on some of those hairy
details, and it had a little runtime overhead for dispatching, as
well as some rather hairy runtime code.)
Sure, a complete, type-safe, variadic routine implementation could
emulate WriteLn, but in a less efficient way and with much, much
more effort, both for the language designer, the implementor and the
end-user. So, when this is usually implied by asking for being able
to reimplement "something like WriteLn", this would be huge overkill
for lesser results.
To actually do something like WriteLn's standard semantics, one
would need a way to specify those in a program. I have seen no real
suggestion how this could even look like. These would be things
like:
: For n>=1, write(f,p 1 ,...,p n ) shall access the textfile and establish a
: reference to that textfile for the remaining execution of the statement.
: For n>=2, the execution of the statement shall be equivalent to
:
: begin write(ff,p 1 ); write(ff,p 2 ,...,p n ) end
:
: where ff denotes the referenced textfile.
: Writeln(f,p 1 ,...,p n ) shall access the textfile and establish a
: reference to that textfile for the remaining execution of the statement.
: The execution of the statement shall be equivalent to
:
: begin write(ff,p 1 ,...,p n ); writeln(ff) end
:
: where ff denotes the referenced textfile.
The closest thing to these I remember having seen would be variadic
macros in the GCC C preprocessor (maybe also in standard C
meanwhile). Though not quite the same, because of usual macro issues
such as quoting and multiple evaluation, something in this direction
might be a way to actually implement something *like* WriteLn in
user code.
Not that I have any intentions to add this in GPC.
BTW, IME, the very large majority of possible applications for
requested "varargs" are one of these groups:
- A finite number of cases, which can also be solved with
overloading, sometimes even with default parameter values.
- Any number of arguments of the same type (e.g., `Concat' for n
string values). Actually, rather rare; can't remember another
example right now.
- Yet another form of Write[Ln] or Read[Ln] (the latter much rarer).
Such routines are somewhat common in C code (often for error
reporting etc.). Usually, though, this boils down to passing the
arguments around, ultimately to a predefined routine such as
[f|s]printf.
In Pascal we can get a very similar effect by using the standard
Write[Ln] routine and (possibly) redefining the output of a
(pseudo-)file. (In this case I concur with this suggestion of
Chuck's.) Both GPC and BP, and probably other dialects, provide
some mechanisms (though slightly different) to do this, e.g.
called TFDD (text file device drivers -- not to be confused with
OS drivers). Another possibility in Extended Pascal is to use
WriteStr and then pass a simple string around.
In both cases, we simply use the special syntax of Write[Ln|Str],
also including the `: Width' specifiers which I'm leaving out of
the discussion otherwiese for now, and just redefine the target of
the text, which is actually the purpose. On the target side,
things are much simpler, since the text is already formatted, so
number and type of arguments don't matter anymore.
Therefore, I don't think it's reasonable to add a huge framework,
just to be able to define one's own WriteLn-(un)like procedure
which in the end just passes its arguments on to the real
WriteLn ...
> 2. Dont support procedures that cannot be written in the language.
That would be a purist approach (IMHO overly so). C did so with
varargs, leading to several weaknesses (again, IMHO) in turn:
Varargs functions, predefined as well as user-defined ones, are not
type-safe, and printf etc. are more clumsy and dangerous to use for
that reason and in principle somewhat less efficient because of
runtime parsing.
I've seen other overly purist approaches (such as OO languages where
everything, including simple numbers, are objects). IMHO, these may
be interesting concepts, but not so useful in practice. So I think
Wirth chose a good compromise here.
> That leaves Pascal, as it is, with its weaknesses intact. I still
> consider Pascal to be about the best programming language there is,
> but that does not mean I don't consider some of its design decisions
> to be less than optimal.
I agree with the general statement, but not WRT WriteLn (more to
things such as lack of `endif' and a few other issues) ...
Frank
--
Frank Heckenbach, frank at g-n-u.de, http://fjf.gnu.de/, 7977168E
GPC To-Do list, latest features, fixed bugs:
http://www.gnu-pascal.de/todo.html
GPC download signing key: ACB3 79B2 7EB2 B7A7 EFDE D101 CD02 4C9D 0FE0 E5E8
More information about the Gpc
mailing list