Re: COBOL's Influence on C
- From: "Pete Dashwood" <dashwood@xxxxxxxxxxxxxxxxxxxxxxxxx>
- Date: Fri, 16 Nov 2007 11:20:25 +1300
"Robert" <no@xxxxxx> wrote in message
news:ao5nj3htd2qp1g6p1r7r2c8pvmp8556ul5@xxxxxxxxxx
On Wed, 14 Nov 2007 00:55:56 -0800, Richard <riplin@xxxxxxxxxxxx> wrote:
On Nov 14, 1:18 pm, Robert <n...@xxxxxx> wrote:
On Tue, 13 Nov 2007 12:47:57 -0600, "tlmfru" <la...@xxxxxxx> wrote:
Robert <n...@xxxxxx> wrote in message
news:dsmhj317b7236kep9l7j2i53jp39dcvlo6@xxxxxxxxxx
On Mon, 12 Nov 2007 10:19:38 -0500, "Rick Smith" <ricksm...@xxxxxxx>wrote:
Modern BASICs also use conditions in the SELECT CASE
statement and may have been influenced by COBOL. <g>
Speaking of modern BASICs ...
GOSUB, which is the same as Cobol's out of line PERFORM, has beendepreciated by many/most
compilers and dropped from VB.NET. It was replaced by SUB, which islocal function
a
call. In my opinion, Cobol should have done the same.
In my opinion and usage, the word SUB, short for SUBroutine, refers to
a
stand-alone piece of code not included with the source program under
consideration. (It can certainly be in the same compilation unit, of
course). A function in this context is some common routine which isn't
compiled (I say this to keep OO vocabulary out of the discussion),
usually
supplied by the compiler writers: e.g., calls on the OS. There should
be a
completely different verb to execute sections of code within the source
program as opposed to that used to execute wholly external sections.
COBOL's PERFORM does the first perfectly well - unambiguous,
understandable - and CALL (or INVOKE, etc.) does the second: and
neither can
be mistaken for the other. Why change?
The target of a Cobol CALL can be in the same source or it can be
external.
In PROGRESS, a language I have little love for but have had to use
quite a
bit, the in-line perform is WHILE, and the out-of-line perform is RUN:
but
RUN is also used as the CALL. If the label isn't defined within the
current
source, it's assumed to be an external routine: no precautionary
diagnostic.
So it's very common to have a clean compile which then blows up with
unresolved linkages when attempting to execute. Not the same situation
as
what Robert's suggesting but a cautionary tale.
Cobol, along with most compiled languages, is the same. Depending on
linker options, you
learn of missing external names either at link or execution time.
Unlike most compiled languages, Cobol lets you CALL a name stored in a
variable. That kind
can only be bound at execution time. The calling program can handle
missing names with an
ON condition, but it's usually too late to do anything but abort. I've
never really needed
that feature. It is a bad idea for two reasons. First, it usually slows
every call, not
just the first. Second, the linker/loader nor tools like ldd cannot
check those references
because they don't know what value will be in the variable at execution
time. It's usually
a constant, but there's no way to declare that.
On Unix, you can check for missing externals by running "ldd -r
(program)', both after
compilation and before execution. Do z/OS or CA-7 have that ability?
It is certainly _not_ a bad idea. It is also not true that abort is
the only option. Simply because you have never discovered how to
exploit it to build dynamic systems does not make it bad.
This issue requires a rant on the inadequacies of programming language
designers. They
cause UNINTENDED CONSEQUENCES because they think like programmers rather
administrators.
Two examples are fresh in my mind because I'm fighting with them right
now.
I would have severe resevations about using a programming language designed
by Administrators.... :-)
Picture a very large shop that runs hundreds of thousands of batch jobs
that execute
millions of programs every month. Imagine an administrator writing
automated
'verification' of those jobs BEFORE they run, so errors can be fixed
BEFORE the jobs blow
up in production. The existance of data files is the easiest thing to
check. What about
the existance of program files (verifying they are the correct version is
the next step)?
This should be a "write once" exercise by a team of people who know
something about JCL... It doesn't matter how many millions of programs are
being used, they get invoked by a Job Control language of some kind, and
that's where the problem should be addressed.
Your bitch is that with dynamic calling they can't know what will be loaded.
How is that the fault of the language designers?
Leaving that aside for a moment, there must be approaches that can provide a
"skeleton" JCL procedure, or set of JCL (or equivalent) for ANY program
that is doing dynamic calling. If you can't know what is being called, then
you can't pre-check individual load module names/versions, but, you CAN make
sure that the libraries containing ANYTHING that might be called are on line
to the job. Shop Programming Standards can ensure that every program logs
itself and its version when loaded, if that is a concern, so there is an
audit trail if required. There are always solutions, and they don't
necessarily involve analysing load modules to obtain symbols...
Unix's ELF standard and the aforementioned ldd (LoaDer Diagnostics) tool
makes it easy to
verify the existance of called programs, recursively checking for ALL of
them. It works
for every language EXCEPT Cobol (and other programs calling dlopen()
directly, which is
rare). Why do Cobol programmers need the flexibility to determine the
names of child
programs at execution time? In the vast majority of cases, they don't.
Who are you to decide what COBOL programmers need or want? :-)
The people who designed the language needed to cater for every possible use
they could reasonably envision. Your site has exceptional needs.
Nevertheless, the facilites exist to meet even those needs. It is just a
question of looking at various approaches, and taking a wholistic view; not
just a language based one.
A few creative
programmers will write 'dynamic systems' driven by decision tables (or
similar) stored in
databases, from which they get the names of child programs. That allows
them to add child
programs without having to recompile the parents .. provided someone
installs the child
program BEFORE putting its name into the database. That's fine for small
systems with a
small number of users. The programmer will personally install the child
program. It
doesn't work when there are dozens to hundreds of machines. Worse, the
list of child
programs is in a NON-STANDARD location unknown to a general verification
tool. Each
creative programmer will design a DIFFERENT location. One might put the
list in a load
module, one in a database, one on his laptop's floppy mounted via NFS.
And that is one reason why installations have Local Standards... To ensure a
consistent approach.
(Actually, most of the dynamic systems I have worked with or designed, DON'T
use a list of possible candidates for calling. Instead they CALCULATE the
name of the needed module. This is possible because the standards require a
certain naming convention, and program names are carefully controlled and
allocated in accordance with that convention. A given module name will
indicate what it does, and which sub-system it applies to...)
This is anarcy.
It is anarchic only if you expect conformance with ONE specific approach...
Flexibility CAN become anarchic if it isn't controlled, that is why it is,
for the most part, controlled.
In order to verify programs, I need ALL externals stored in ELF headers.
That is a requirement that is extremely specific and nothing to do with
COBOL.
For Cobol programs calling via variables (data-names), I have to extract
the VALUE from
the data-name definition, look for MOVE 'prognm' TO DATA-NAME, use the
values to build a
dummy object that gets linked into the executable so the program's child
names are in its
symbol table. THIS SHOULD NOT BE NECESSARY.
It isn't. You find it necessary because of a specific approach you have
CHOSEN. A guy as bright and imaginative as you, Robert, could certainly find
alternative approaches. I reckon you're just not trying... :-)
If someone on the Cobol Standards Committee
had known the requirements of LARGE systems, the language would make a
distinction between
dynamic binding (a good thing) and dynamic determination of called program
name (a bad
thing).
Nothing is Good or Bad, but thinking makes it so.
------
My second gripe is over nested COPYs. The '85 Cobol Standard says they are
not allowed.
The unintended consequence of that stupid restriction is that our builds
take 18 hours
rather than 2 hours.
Very short sighted for a committee to not foresee (over twenty years ago)
that there would be this "unintended consequence" from what they decided...
:-)
Here's why. We don't write copybooks manually, we generate them from
data dictionaries, for several languages -- .h files for C, .cpy for
Cobol. We produce
separate copybooks for 88 levels and for types. A Cobol type looks like
"pic x(10)". The
top level copybook for a structure looks like:
05 customer-number copy custno.typ..
05 customer-status copy status.typ..
copy status.val. *> contains 88 levels
Because the '85 Cobol Standard says nested COPYs are a no-no, we run a
pre-pre-processor
that combines the nested COPYs into a single one, which looks like this:
custrow.cpy:
05 customer-number pic x(10).
05 customer-status pic x(01).
88 active value 'A'.
88 cancelled value 'C'.
Our compilations are driven by make files, which are driven by generated
dependency (make
rule) files, which are created from source code. The problem is, we cannot
determine the
dependencies from reading Cobol source programs. All we see is "copy
custrow.cpy". We
cannot tell that status.val is a dependent. (Make decides what to compile
by comparing
timestamps of dependents to the timestamp of the executable.) One way to
make it work
would be to generate custrow.cpy into a temp area, compare it to the
previous custrow.cpy,
replacing custrow.cpy only if there is a difference. THIS SHOULD NOT BE
NECESSARY,
especially since Micro Focus and the '02 Cobol Standard both support
nested COPYs. A
better way to make it work would be to simply eliminate the
pre-pre-processor. Instead we
run 18 hour full builds because somebody back in the early '80s thought
nested COPYs were
too much trouble or unnecessary. They WERE unnecessary for small systems.
If someone on
the '85 Standards Committee had known the requirements of LARGE systems
(10,000s of
programs), our builds would already be running in 2 hours.
If you are that bothered by this, you could certainly write your own COPY
processor. (I just finished doing that for a code generator I delivered a
few days ago. It's not rocket science... :-))
If you did a hardware upgrade, it wouldn't take 18 hours to build.... :-)
There are always options.
Hmmmmm..... :-)
It's hardly fair to expect a Standards Committee to predict HOW people are
going to use the provided facilities, before the applications have ever been
written... :-)
I was interested to see your post, Robert, and I recognise the problems you
are encountering, but this is not the fault of the people who designed
COBOL, or even those who later took responsibility for it.
Installations CHOOSE how they are going to do stuff.
It isn't the fault of the language.
Pete.
--
"I used to write COBOL...now I can do anything."
.
- Follow-Ups:
- Re: COBOL's Influence on C
- From: Howard Brazee
- Re: COBOL's Influence on C
- From: Robert
- Re: COBOL's Influence on C
- References:
- COBOL's Influence on C
- From: Rick Smith
- Re: COBOL's Influence on C
- From: Robert Jones
- Re: COBOL's Influence on C
- From: Rick Smith
- Re: COBOL's Influence on C
- From: Charles Hottel
- Re: COBOL's Influence on C
- From: Judson McClendon
- Re: COBOL's Influence on C
- From: Rick Smith
- Re: COBOL's Influence on C
- From: Robert
- Re: COBOL's Influence on C
- From: tlmfru
- Re: COBOL's Influence on C
- From: Robert
- Re: COBOL's Influence on C
- From: Richard
- Re: COBOL's Influence on C
- From: Robert
- COBOL's Influence on C
- Prev by Date: Re: COBOL's Influence on C
- Next by Date: Re: occurs
- Previous by thread: Re: COBOL's Influence on C
- Next by thread: Re: COBOL's Influence on C
- Index(es):
Relevant Pages
|