Re: ASCII text file I/O module

Elan Paznesh (icimjs@loop.com)
Thu, 29 Aug 1996 23:55:18 -0700

Dear Vinicius,

let me contribute a few thoughts to this discussion.

First I would like to deal with your arguments:

1. You write:
> I am a civil engineer and my concerns are far away from having to (...)
Furthermore you write
> If, as you say this discussion keeps appearing again and again, it
>is because there is something wrong with the way Oberon/F handles
>ASCII text file I/O.

May I point to you out that exactly that argument you use to emphatically
proclaim your disdain over being forced to deal with what you consider to
be an undue complexity of ASCII I/O in Oberon/F ("I am a civil engineer")
makes one wonder, why you would choose to assume a tone of authority in
explaining that "there is something wrong with the way Oberon/F
handles...". Maybe there isn't something wrong. Maybe you find it
inconvenient. And perhaps convenience is not the only criteria by which a
"right" or "wrong" implementation is to be decided. Perhaps there are
other, and maybe even more important criteria that you are neglecting?

2. In response to Bruno Essmann you write:
>You should have written that the
>idea was to use the following seven modules: TextModels, TextMappers,
>TextViews, Files, Converters, Stores, DevLog. Is this simple? Is this
>as efficient as it could be without all these modules? Are you sure
>about what these modules are really doing?

Do you prefer "print a b c", which is what we used for ASCII i/o in a
Basic-derived scripting language? How about: file << a << b << c, which -
if I recall correctly - is one of several ways you can do file i/o under
C++? Yes?

>Is this as efficient... Are you sure about what these modules are really
doing?
Dear Vinicius, in all fairness, are you sure you know what print is doing?
Do you know what is happening behind the scenes of Basic or C++? If by the
word efficient you really mean efficient, how do you know that "print ..."
or "<<" really is efficient? Just because all that is exposed to you as a
script writer - or "programer" if you wish - is one simple command that
does not at all mean that you know anything about how efficient it us
implemented. Or do you as a civil engineer understood the (in)efficiency of
operator overloading in C++?

A related concept in C++ is function overloading. Have you ever watched the
exciting display of C++ error messages when the compiler can't make up its
mind which of different overridden functions you are trying to call,
complaining that it can find no match for this function in combination with
the parameters you are using?

Which leads us to an important issue, one of those criteria that I propose
are more significant in determining whether or not there is something
"wrong" with Oberon/F than - what at first sight appears to be -
"convenience of use" taken absolutely and indiscriminantly. This criteria
is _level_of_control_. By having the option to choose TextModels,
TextMappers ... I as the programer (civil engineer) am in control of the
raw material or the tools used to craft the solution. A higher level of
control always demands a higher level of responsibility or involvement.

Many solutions have been proposed to simplify programing languages. (Check
out Scheme or Forth for instance) People who want to occassionally program
something simple don't want to deal with the involvement required by a
higher level of of control. That's why Basic is called Basic and why it
continues to by popular, even though it's evolvement (elements of
structured programming having been added over time) shows that the
"basicness" of Basic had to be overcome in order to maintain its
usefulness. A few years ago the same people who used to tell me that
structured programing is an unnecessary complication started bragging about
how Basic now supports structured programing. Whatever...

Personally, I will gladly give up a degree of apparanet simplicity in
exchange for a higher level of control. Have you ever invested a
significant amount of time in learning a "simple" scripting language only
to find that its simplicity makes it useless for the fifth or sixth program
you have to write, because it simply doesn't give you enough control?

Having given away one criteria, let me point out two more criteria that I
believe are critical. They are uniformity and simplicity (yes,
simplicity... just wait and see!). Print a b c may appear nice and simple,
but only as long you are attempting to do no more than ASCII file i/o. If
you want to output formatted text you have to use the function
PrintFormattedText a $b $c. For a bit map you have to use PrintBitmap, for
a file with mixed text and arithmetic values you have to use
PrintMixedString and for eight bit ASCII (in contrast to seven bit ASCII)
you have to use the command Print8 a b c. Do you notice something? As long
as you are only considering one special case of i/o it all looks quite
simple. But as soon as you begin to want to re-use what you have learned
about this scripting language and apply it to other programming projects,
you have to start extending your programming vocabulary.

Every special case has its own instruction with a unique parameter
sequence. Looking at the special case of ASCII i/o it all looks nice and
simple. However, having to learn a new instruction (and its very own,
special parameter sequence) for each and every output format becomes very
complicated. You see, how misleading first impressions can be? The
"special-case" languages, who have a special case for each and every
process (printThis, printThat, printSomethingElse, printYetAnotherthing
..., readThis, readThat ..., displayThis, displayThat...,
iterateThroughThis, iterateThroughThat, iter..., PrintASCIIToPrinter,
PrintBitmapToPrinter, PrintSomethingElseToPrinter ...) are really extremely
complicated. The alphabetically organized dictionary of available commands
shows you just how complicated they become, the more you use them, for
different applications. Shouldn't the exact opposite be true? Shouldn't
they become easier the more you use them?

"Special case languages" only appear simple initially because you can do
something simple real fast without knowing anything beyond that. However,
once you find out that you have to re-learn each time you want to do
something else, it becomse clumsy and cumbersome. In contrast, once you
have learned how to do ASCII i/o in Oberon/F, you can do any i/o for which
there is a converter, simply by changing the line WHILE (c # NIL) & (c.imp
# AsciiImporter) & (c.exp # AsciiExporter) DO to whichever importer and
exporter combination you wish to use. You can leave the rest of Bruno's
example as is _and_you_don't_ have to change those modules that import it.
By changing this one line in this one file you have enabled all modules
that depend on it to make use of your modified file-structure.

What we are talking about here is simplicity through uniformity. You see,
in a "special case language" once you have to change the file structure you
are writing to (and reading from) but want to continue maintaining the
availability of your existing functions, you have to invent a new output
function, search and replace the print function, replacing print a b c by
PrintFormattedText a $b $c in all relevant files that are using in- and
output, for instance. Maintenance of existing code becomes more complicated
and more error prone. Let's assume you want to only specialize certain
input-output and leave the rest as is. Consider how simple code maintenance
becomes once all you have to do is to change no more than one line in every
file that uses i/o, namely the import line. (If you use the notation cv :=
Converters ... in your import list, you will not have to make a single
other change to those files!) Now, that's true simplicity through
uniformity.

In summary, let me point out that someone who wishes to build a house is
not well-advised to buy a bunch of bricks and begin stacking them up on top
of each other. (print a b c, printBitmap ...) (S)He is better advised to
speak with an architect who might suggest doing some other things first.
The same here. Before you begin saving stuff to files it is better to first
deal with some other issues. These issues are on the same level of
simplicity as writing print a b c, for instance creating a record or using
a pointer. Oh yes, they don't print anything. And you don't intend to sleep
in the foundation. But you do want the house to last for a good time, don't
you? So, please let's first build a foundation, before we start printing.
We have more important things to do with our time than to learn by heart
and extend "special-case language" dictionaries on ongoing basis.

Finally, and please don't be mad at me for pointing this out to you,
Oberon/F does provide the mechanism to enable you to do what you want. This
has to do with the seperation in Oberon/F between Commands and Procedures.
Commands are meant exactly for extending the system with "special case"
components that allow you to easily do your ASCII file i/o. Copy Bruno
Essman's code to a file, add a command that you can call anytime you need
to use ASCII file i/o and you have this kind of print a b c solution.
Please don't be upset that Oberon/F does permit you to do some other things
besides ASCII file i/o, and allows you to these things in a very well
organized, uniform and minimalistic fashion.

So, what about your little teaser to our friends from OMI, threatening them
with bankruptcy if they ignore your demand for a simplified "special case"
ASCII file i/o? In all fairness (again) let's compare Oberon/F to other
languages that are doing much better marketing-wise than Oberon/F. As far
as market-presence is concerned, would you agree that C++ would be an
example for such an envied market hit? From 1985 to 1989 I programmed in C.
simplicity were to determine the success of a programming language, I can
assure you that the roles between C++ and Oberon/F would be reversed.

Oh, the portability issue. The most portable language known to man since
biblical times is C. (No? Which language do you propose?) We don't live
exclusively in programming languages. We live in programming languages
supporting frameworks for OS and GUIs. There is a lucrative market of
portability librairies between Macintosh, different flavors of Unix, MS
DOS, MS Windows ... for C! Let's no confuse issues.

Putting all this down on paper certainly helped me air some feelings about
your ongoing complaint. Did it did do anything useful for you? Please let
me know.

Elan