Stylistic note on loops

M

Martin Gregorie

Fair enough, if you add the entire size of a COBOL compiler implemented
in COBOL onto every COBOL program. ;)
They exist: at least one of the ICL COBOL compilers (the VME/B one) was
written in COBOL. However, it was a semi-cheat because it ran in COIL, a
sort of JVM optimised to execute COBOL. I assume the code it generated
also ran in COIL but who knows: we only knew COIL existed because the
only time I saw the compiler crash the dump said it was a COIL-machine
dump. I never saw that from compiled COBOL, which always produced a very
nicely formatted COBOL-specific dump.
 
T

Tom Anderson

Of course I am.

Ah, I see. Looking at the crossposts it looks like you may be a Java
programmer. I hear they like their code verbose. I also hear that Java
is the COBOL of the 21st century. ;)

Statements which i cannot honestly deny.

The context i was reading your statement about readability in was
readability to a programmer who doesn't know the language - we'd been
having that discussion about languages which look like pseudocode. I have
never worked with COBOL, and although i wouldn't want to read very much of
it, i understand what the chunk above is doing. I don't know any kind of
LISP, although i did read a LISP book about fifteen years ago, and i find
your chunk of LISP rather impenetrable - the latter three lines are fine,
but i don't know what vec does, nor take, nor iterate and inc, although i
guess 'iterate inc 1' is something to do with a loop counter. Which atom
is the name of the array?

I'm going to guess that vec is the array, and that an array can be a
function, and that it calls its argument with each of its elements (how
would this happen, though?), and that the argument is essentially the
array dereferencing operator, itself bound to (curried with?) an argument
which is a closure that supplies an incrementing count.

Which, i have to say, is not how i think about totalling lists.

tom
 
M

Martin Gregorie

Actually that code produces an array of the values 1 ... n. I'm not sure
why I posted it. I think the COBOL code is supposed to sum the array.
Thats right. The WRITE statement is somewhat more complex too. If TOTAL
line was defined like this:

01 TOTAL-LINE
05 FILLER PIC X(13) VALUE "Array total: ".
05 TL-VALUE PIC Z(6)9.99.

and ARRAY-TOTAL was, say, 12.5, the WRITE would send the character string
"\nArray total: 12.50" to the printer, assuming TOTAL-LINE is
defined as a FILE SECTION record in a printer file definition.

What does the Lisp look like if it totals the array and outputs a similar
line to that shown above?
 
T

Tom Anderson

Eh, not quite.

Actually that code produces an array of the values 1 ... n. I'm not sure
why I posted it. I think the COBOL code is supposed to sum the array.

I believe so. Perhaps your proofreading would be aided by writing in a
more readable language? :)
(def array-total (reduce + the-array))

Short'n'sweet. :)

As long as you know what reduce does, that is indeed pretty obvious.

tom
 
R

Robert Klemme

Yes, but Ruby seems to delight in these kinds of off-kilter syntaxes.

For the purposes of pseudo-code, which of the following is clearer:

a.each {|line| ... } # or:

for each line in a { ... } # ?

In Ruby that would be

for line in a
...
end

:) Frankly, I don't see a big difference but then again: I'm biased.
Or which of the following:

99.times do |i| ... end # (and what's the first i value, 0 or 1?) or:

99.times iterates from 0 to 98 (including).
for i =1 to 99 do ... end # (or any of countless variations)?

Again, in Ruby

for i in 0..98
...
end

or with a half open interval

for i in 0...99
...
end

0.upto 98 do |i|
...
end

but I'm digressing. Still, I find all those pretty readable - at least
for someone who knows English.
It seems that once this way of using an iterator (or generator or whatever
it is) became available, then every program must make use of it at every
opportunity ...

Well, it's just the standard idiom in the same way as java.util.Iterator
dictates the standard iteration idiom in Java. But nobody forces you to
use it. Conversely I have seen numerous times people iterate through
java.util.List with get(int) (let's not debate efficiency in case of
LinkedList - that's a different story).

Kind regards

robert
 
M

Martin Gregorie

Eww. COBOL so stupid it needs to be told how long string literal is. :)
COBOL is designed around fixed length fields. Don't forget, its name is
an acronym: Common Business Oriented Language. This style of print
formatting is somewhat OTT for simple print lines like this one, but
works rather well for complex multi-column reports on plain paper and
statements or invoices that are output on pre-printed paper.
What does the Lisp look like if it totals the array and outputs a
similar line to that shown above?

For a function that does this, using the Lisp in question:

(defn print-total! [arr]
(println (format "Array total: %9.2f" (reduce + arr))))
Neat.
I'm assuming your Z(6)9.99 means it should pad for six digits left of
the decimal point and round to the nearest hundredth:
Correct.
The code was short and sweet though wasn't it? The only thing slightly
mysterious, really, is the format specifier, and a) it's similar to what
a C programmer would use in a printf for the same job and b) COBOLs is a
damn sight uglier. :)
Sure, though the more complex number formats may be easier in COBOL, e.g.

PIC $,$$$,$$9.99BDB BLANK WHEN ZERO

which would output a debit of 5 cents as " $0.05 DB", leave a zero
amount as entirely blank and output a price of fifteen hundred dollars
and 23 cents as " 1,500.23 " as the result of MOVEing a value to the
field.

IMO most of COBOL's misfeatures are the result of the original language
design committee's assumption that:
- there exist a bunch of programmers who can understand all the
implications of a MOVE statement while being incapable of
understanding an assignment statement. The implications of MOVE are
non-trivial: MOVE will convert the content almost any source field to
match almost any destination field and this includes moving group
fields whose components may be of mixed types and different lengths
from the source.

- that these programmers can deal with complex logic expressed in almost
English but are mathematical illiterates.
 
L

Lew Pitcher

On November 14, 2010 07:50, in comp.lang.c, (e-mail address removed)
wrote:
IMO most of COBOL's misfeatures are the result of the original language
design committee's assumption that:
- there exist a bunch of programmers who can understand all the
implications of a MOVE statement while being incapable of
understanding an assignment statement. The implications of MOVE are
non-trivial: MOVE will convert the content almost any source field to
match almost any destination field and this includes moving group
fields whose components may be of mixed types and different lengths
from the source.

- that these programmers can deal with complex logic expressed in almost
English but are mathematical illiterates.

You forget that, at the time that COBOL was first proposed and
standardized, "programmers" were either "Computer Scientists", or they were
code monkeys.

COBOL was not designed for the /programmer's/ understanding; it was designed
so that /accountants/ could specify and follow the business logic.

Analyst: So, tell me how you calculate the final price of an item, given
it's price and the local sales tax expressed as a percentage of
price.

Accountant: I multiply the price by the percentage, which gives me the tax
amount. I then add the tax amount to the price, which gives me
the final price.

Analyst: Programmer, input this...
MULTIPLY PRICE BY PERCENTAGE GIVING TAX-AMOUNT.
ADD PRICE, TAX-AMOUNT GIVING FINAL-PRICE.
ad nauseum
 
M

Martin Gregorie

You forget that, at the time that COBOL was first proposed and
standardized, "programmers" were either "Computer Scientists", or they
were code monkeys.

COBOL was not designed for the /programmer's/ understanding; it was
designed so that /accountants/ could specify and follow the business
logic.
At the time COBOL was designed the majority of commercial programmers
were writing assembler - a task that required rather more in-depth
understanding of the target machine that a code monkey has. I'd also
dispute that there many computer scientists around at the time:
University computers mainly belonged to the departments of mathematics,
sciences and engineering - and most of them wrote Fortran or Algol 60.

As I said - designing a language for those who supposedly could
understand English but not logic or basic maths was a mistake since
nobody but the programmers are going to look at the code. Accountants
certainly won't and a high proportion of systems analysts back in the day
wouldn't look at code either: I worked with enough who wouldn't even
visit the programming office.
 
B

BartC

It also sounds like COBOL's sole significant advantages are convenient
currency datatypes and a bunch of fancy string-formatting capabilities --
the sort of thing easily added to any decent HLL as a library. ;)

I don't know why I'm sticking up for for Cobol, but: when you see a proper,
full, program (with Identification and Environment Divisions and all that),
it looks 'the business'.

Compare with the geeky-looking Lisp that might have been around at the same
time; who on earth could figure out what any of that did?. In fact the only
serious competitor might have been Fortran, but that was clearly for
Scientific work not Commercial.
the sort of thing easily added to any decent HLL as a library. ;)

That's easier said than done. And either this exists as standard (and
usually it doesn't), or every programmer does his own thing. It's not the
same as being built-in to the language.
 
S

Stefan Ram

Ken Wesson said:
*raises hand*

So what does this piece of code do?
(The purpose can be given in English using five words.)

(funcall (funcall (funcall (lambda (m) (funcall (funcall
(funcall (funcall m (lambda (x) (lambda (x) (lambda (y) y))))
(lambda (x) (lambda (y) x))) (lambda (s) (lambda (z) (funcall
s z)))) (lambda (f) (lambda (x) (funcall (funcall m (funcall
(funcall (funcall (lambda (x) (lambda (n) (funcall (funcall
(funcall (funcall n (lambda (x) (lambda (x) (lambda (y) y))))
(lambda (x) (lambda (y) x))) (lambda (s) (lambda (z) (funcall
s z)))) (lambda (f1) (lambda (x1) (funcall (funcall n (funcall
(funcall (funcall x x) (funcall (funcall (funcall n (lambda
(x) (lambda (z) (funcall (funcall z (funcall (funcall (funcall
x (lambda (x) (lambda (y) x))) (lambda (n) (lambda (s) (lambda
(z) (funcall s (funcall (funcall n s) z)))))) (lambda (s)
(lambda (z) (funcall s z))))) (funcall x (lambda (x) (lambda
(y) x))))))) (lambda (z) (funcall (funcall z (lambda (s)
(lambda (z) z))) (lambda (s) (lambda (z) z))))) (lambda (x)
(lambda (y) y)))) f1)) x1)))))) (lambda (x) (lambda (n)
(funcall (funcall (funcall (funcall n (lambda (x) (lambda (x)
(lambda (y) y)))) (lambda (x) (lambda (y) x))) (lambda (s)
(lambda (z) (funcall s z)))) (lambda (f1) (lambda (x1)
(funcall (funcall n (funcall (funcall (funcall x x) (funcall
(funcall (funcall n (lambda (x) (lambda (z) (funcall (funcall
z (funcall (funcall (funcall x (lambda (x) (lambda (y) x)))
(lambda (n) (lambda (s) (lambda (z) (funcall s (funcall
(funcall n s) z)))))) (lambda (s) (lambda (z) (funcall s
z))))) (funcall x (lambda (x) (lambda (y) x))))))) (lambda (z)
(funcall (funcall z (lambda (s) (lambda (z) z))) (lambda (s)
(lambda (z) z))))) (lambda (x) (lambda (y) y)))) f1))
x1))))))) (funcall (funcall (funcall m (lambda (x) (lambda (z)
(funcall (funcall z (funcall (funcall (funcall x (lambda (x)
(lambda (y) x))) (lambda (n) (lambda (s) (lambda (z) (funcall
s (funcall (funcall n s) z)))))) (lambda (s) (lambda (z)
(funcall s z))))) (funcall x (lambda (x) (lambda (y) x)))))))
(lambda (z) (funcall (funcall z (lambda (s) (lambda (z) z)))
(lambda (s) (lambda (z) z))))) (lambda (x) (lambda (y) y))))
f)) x)))))(lambda (s) (lambda (z) (funcall s (funcall s
(funcall s (funcall s (funcall s z)))))))) (lambda (x) (+ x
1))) 0)
 
I

Ian Collins

So what does this piece of code do?
(The purpose can be given in English using five words.)

(funcall (funcall (funcall (lambda (m) (funcall (funcall

To demonstrate a sick mind.
 
S

Stefan Ram

Ken Wesson said:
So what does this piece of code do?
(The purpose can be given in English using five words.)
(funcall (funcall (funcall (lambda (m) (funcall (funcall (funcall
[snip]
It computes the number 120.

Yes. This is the extension. The intension is to compute the
factorial of 5, where - if I understand it correctly - 5 is
expressed using lambda expressions itself. I believe that
one might possibly arrive at such code, when one is using
combinators (

http://en.wikipedia.org/wiki/Combinatory_logic

) and then is substituting combinators by their lambda
representation.

(I have not mentioned the original author in the body of my
post to make it less obvious that the explanation can be
found via a search engine. However, the original author is
given at the end of the »X-Copyright« header line of my
previous post.)
 
A

Arne Vajhøj

Indeed, but its yet another reason I don't write code in that environment.

BTW, what do you make of this situation: at the start of a major project
in which there was a project manager, a technical manager and I was the
design authority and C was the programming language, and my design and
project-specific infrastructure specifications (e.g. a set of common
supporting libraries to handle intra-process connections and an active
data dictionary used to transform a set on incoming data formats to
common internal formats) had been signed off, the TM wrote a spec.
mandating K&R naming and coding standards and went off on leave for two
weeks.

Meanwhile two of us got stuck in and wrote and tested the supporting
libraries to the standards that he'd released.

At this point the TM returned, tore up his original coding standards and
re-issued them mandating 'Hungarian notation'. His next action was to
tell me that the support libraries must be rewritten in hungarian
notation.

By now the rest of the programmers were on board and we had a challenging
deadline to meet, so I told him to get stuffed and was able to make this
stick due to looming deadlines. All the code I wrote both then and
subsequently (under even tighter deadlines) adhered to the original
standards.

I maintain he was right out order changing his issued standards so
radically. What do you guys think?

Obviously convention should not be changed after initial phase
of project.

Arne
 
A

Arne Vajhøj

yes, but it is not the exact same convention from the link elsewhere in the
thread, which sort of invalidates the whole "one true convention" argument,
in favor of a "code in this project should use 'this' particular
convention"...

They either use that link or define their standard as delta
from that.

It can almost not do more to recognize that link as THE standard.

Arne
 
D

David Thompson

Sadly, there's still useful stuff that COBOL can do more concisely than
other more recent languages.

Apart from its ability to fill an array or data structure with a literal
value without using an explicit loop

Fortran>=1990 does arrays, with any expression not just a literal, and
I believe so does APL (forever?). For a heterogenous structure (not
like complex . X,Y or pixel . R,G,B) I've rarely found this useful.

Java has j.u.Arrays.fill() in the standard library. Although there is
presumably source for that in Sunnyvale, it's not source you or I need
to write, or even should. Somewhat similarly, C++ std::fill,fill_n do
the loop for you, although it isn't very well hidden.
there's its edited fields. A field defined like this:

PIC $,$$$,$$$,$$9.99DB BLANK WHEN ZERO <snip>
I don't know how to do this is any other language in a single statement
with or without the use of conditional formatting, yet its a very common
requirement in a financial program.
PL/I copied most of COBOL PIC, and also most of FORTRAN FORMAT.
IIRCWIMN it includes everything in your example except BWZ, which
needs only one simple additional IF. (Some) BASIC also had PRINT USING
with some but AIR more limited editing (and output-only).

But I don't think anything else does MOVE CORRESPONDING. The handful
of times I found a use for that it was wonderful.
 
N

Niklas Holsti

David said:
Fortran>=1990 does arrays, with any expression not just a literal, and
I believe so does APL (forever?). For a heterogenous structure (not
like complex . X,Y or pixel . R,G,B) I've rarely found this useful.

Java has j.u.Arrays.fill() in the standard library. Although there is
presumably source for that in Sunnyvale, it's not source you or I need
to write, or even should. Somewhat similarly, C++ std::fill,fill_n do
the loop for you, although it isn't very well hidden.

To continue this language list: Ada has array expressions ("aggregates")
of the form

(others => expr)

where the keyword "others" stands for all the indices in the result, and
expr can be any expression of the array's element type. For example:

int_array := (others => 42);

This can be combined with explicit index ranges, for example:

float_array := (1 .. 51 => 1.0, 52 .. 91 => 2.0, others => 0.0);

with "others" covering any index values in float_array outside 1 .. 91.
But I don't think anything else does MOVE CORRESPONDING. The handful
of times I found a use for that it was wonderful.

Ada has something a bit like MOVE CORRESPONDING. You can declare a
record (struct) type R with some components (fields), then derive from
this type a new record type S with the same components, but with a
different memory layout, for example a packed layout with the components
in a different order. If x is a variable of type R, and y is a variable
of type S, the assignment statement y := S(x); will move the values of
all components of x to the corresponding components of y, transforming
the order and layout from that of type R to that of type S.

However, this is less flexible than MOVE CORRESPONDING because the
source and destination structures must have exactly the same set of
components. Type S cannot have more components than type R, or vice versa.
 
M

Martin Gregorie

Fortran>=1990 does arrays, with any expression not just a literal, and I
believe so does APL (forever?). For a heterogenous structure (not like
complex . X,Y or pixel . R,G,B) I've rarely found this useful.
IME Its mainly useful for zero filling or space-filling arrays, often
constructed from non-elementary data items
PL/I copied most of COBOL PIC, and also most of FORTRAN FORMAT. IIRCWIMN
it includes everything in your example except BWZ, which needs only one
simple additional IF. (Some) BASIC also had PRINT USING with some but
AIR more limited editing (and output-only).
Indeed - together with a block structure it swiped from Algol 60. I've
used PL/1 subset G for non-trivial jobs on Stratus and AS/400 kit, have
always found it somewhat of a mongrel language and strongly dislike the
way it uses exception handlers for everything from genuine exceptions to
EOF handling. Its not so much the use of exceptions that annoys me, more
the way the syntax imposes a total separation between the exception-
generating code and the trap. I much prefer the Java try/catch structure.
But I don't think anything else does MOVE CORRESPONDING. The handful of
times I found a use for that it was wonderful.
Its been discouraged in a lot of places I've worked, mainly because it
requires data names with the "ELEMENT OF RECORD" form to be used, while
many projects prefer unique names data names, usually with prefixes that
show where a data item belongs:

01 CUSTOMER-ACCOUNT.
05 CA-NUMBER PIC 9(6).
05 CA-NAME PIC X(32).
......
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top