Some years ago, when CP/M-86 was talked about in the comp.os.cpm
Newsgroup, many persons searched a C compiler for it. I answered that
it was obvious: BDS C was the best C compiler running under CP/M 2.2,
had a huge software library, so, the logical conclusion was to port
BDS C under CP/M-86. Many persons countered that it was not ANSI
compatible... I could not believe my eyes: I was believing that the
mantra of C programmers was K&R-compatibility, as defined in the 2nd
Edition of the Propagandastaffel book?
Of course, in the end, nobody was able to port a C compiler under CP/
M-86, despite Leor Zolman releasing the source code of BDS C... (and
some full source codes, in C, of some C compilers for CP/M being
found!)
I will never understand C fans.
While searching for something else, I found a little C program
published in 1994 in France.
int a=10000,b=0,c=8400,d,e=0,f[8401],g;
main(){for(;b-c;){f[b++]=a/5;}for(;d=0,g=c*2;c-=14,printf("%.4d",e+d/
a),e=d%a)
{for(b=c;d+=f[b]*a,f[b]=d%--g,d/=g--,--b;d*=b);}}
So, since C is, obviously, superior to BASIC (the famous "power of
C"), I am asking C fans out there to tell us what this obviously
simple C program does... (I have no idea if it is K&R or ANSI
compatible.)
It should be obvious, no?
Yours Sincerely,
Mr. Emmanuel Roche, France
Looks like an entry from The Ofuscated C Programming Contest.
It appears to be an attempt to calculate pi to 2400 places except
the decimal point is missing. Not being a mathematician, I can't
tell you if it does this acurately.
As for the "elegance" of the program, don't blame the language
for the actions of the programmer. I once did the same kind
of thing in COBOL in order to demonstrate why we were teaching
"Structured COBOL". One can write crap in any language, including
BASIC and PL/1.
bill
--
Bill Gunshannon | de-moc-ra-cy (di mok' ra see) n. Three wolves
bill...@cs.scranton.edu | and a sheep voting on what's for dinner.
University of Scranton |
Scranton, Pennsylvania | #include <std.disclaimer.h>
> It appears to be an attempt to calculate Pi
Hum... I wrote:
> > So, (...), I am asking C fans out there to tell us
> > what this obviously simple C program does...
So, yes, you gave the purpose of the program, but, no, you did not
explain what it does (or how it achieves its result, or even how to
prove that it reaches its goal).
As for it being a little bit "obfuscated", Ok, I am too kind. Here is
a nicely tabulated one:
main()
{
double B=4095.1;
double A=B+1;
double x=1;
int n;
printf("initialisation x=%.16f\n",x);
for (n=1 ; n <= 9 ; n++)
{
x = (A*x) - B;
printf("iteration %01d x=%+.16f\n",n,x);
}
}
To help you (I am really too kind), I even give you what it outputs
(gcc without optimization under PC running Linux):
initialisation x= +1.0000000000000000
iteration 1 x= +1.0000000000004547
iteration 2 x= +1.0000000018631452
iteration 3 x= +1.0000076316294826
iteration 4 x= +1.0312599175240718
iteration 5 x= +129.0437481703507956
iteration 6 x= +524480.9968805739190429
iteration 7 x= +2148322516.2225189208984375
iteration 8 x= +8799743854603.9609375000000000
iteration 9 x=+36044630802839192.0000000000000000
This time, I will ask 2 questions:
1) What does this program?
2) Is its output correct? (If no: what should it output?)
(If you are a Philosopher: Why?)
> As for it being a little bit "obfuscated", Ok, I am too kind. Here is
> a nicely tabulated one:
> main()
> {
> double B=4095.1;
> double A=B+1;
> double x=1;
> int n;
> printf("initialisation x=%.16f\n",x);
> for (n=1 ; n <= 9 ; n++)
> {
> x = (A*x) - B;
> printf("iteration %01d x=%+.16f\n",n,x);
> }
> }
Interesting. It should of course print 1.000000000000000 for each
iteration. However once you get rounding errors e.g. converting the deimal
to its internal binary representation then the iterative process amplifies
it.
Make all the doubles into long doubles and adjust the printf format to
%+.16Lf and the output is as analysis suggests it should.
All this shows is that converting decimal fractions to binary floating
point representions is not always precise (in any programming language).
Sure. Just as obvious as an equivalent in BASIC.
' QuickBASIC 4.5 version of example C Pi program posted by Mr. Roche
' NOTE needed to use LONG rather than INTEGER
' Original code used 32 bit (or larger) integers (see notes)
DIM a AS LONG: a = 10000: DIM b AS LONG: b = 0:
DIM c AS LONG: c = 8400: DIM d AS LONG:
DIM e AS LONG: e = 0: DIM f(8401) AS LONG: DIM g AS LONG
WHILE b - c: f(b) = a \ 5: b = b + 1: WEND
WHILE c * 2: d = 0: g = c * 2
b = c
again:
d = d + f(b) * a: g = g - 1: f(b) = d MOD g
d = d \ g: g = g - 1: b = b - 1
IF b = 0 GOTO notagain
d = d * b
GOTO again
notagain:
c = c - 14: PRINT USING "####"; e + d \ a; : e = d MOD a
WEND
- Bill
NOTES:
The output of the two programs is not exactly identical.
The first 40 digits of the C program produces:
3141592653589793238462643383279502884197
But the first 40 digits of the BASIC program are:
31415926535897932384626433832795 2884197
Note the space rather than a zero near the right side. This is because the
program computes in groups of four digits. The C program prints leading
zeros for each group as necessary. The BASIC program does not. If there's
a way to get QB4.5 to do leading zeros, I'm unaware of it. Whenever I've
needed it I've always had to write a subroutine to do them.
And, of course, the BASIC program should really be compressed into a minimum
number of lines. But after getting it going, I wasn't motivated to fix
either the leading zero or the number of lines.
The original C program was unlikely to have been targeted for CP/M since it
assumes 32 bit, or larger, integers. The CP/M compilers of the era almost
always used 16 bits for "int" and 32 bits for "long". Of course, Mr. Roche
didn't claim it was a CP/M program, though one might have thought so since
we're on comp.os.cpm.
I checked the digits and this program *does* print 3 and the next
2399 decimal places of pi accurately.
> As for the "elegance" of the program, don't blame the language
> for the actions of the programmer. I once did the same kind
> of thing in COBOL in order to demonstrate why we were teaching
> "Structured COBOL". One can write crap in any language, including
> BASIC and PL/1.
>
Bill, one should *not* interrupt the French Luser while he is
pontificating! ;-)
--
+----------------------------------------+
| Charles and Francis Richmond |
| |
| plano dot net at aquaporin4 dot com |
+----------------------------------------+
> Interesting. It should of course print 1.000000000000000
> for each iteration.
Yes. On my IBM Mainframe, I used BCD for commercial programming in
COBOL. When I started using MBASIC under CP/M, I discovered Floating-
Point and its countless rounding errors (thing that, apparently, many
people do not understand). That's why I spent so much time on the
subject, retyping/disassembling several 8080 FP packages.
In this particular case, here is what says its author:
"The preceding experiments were about non linear systems. But what is
about linear models? Let us study the following program:
main()
{
double B=4095.1;
double A=B+1;
double x=1;
int n;
printf("initialisation x=%.16f\n",x);
for (n=1 ; n <= 9 ; n++)
{
x = (A*x) - B;
printf("iteration %01d x=%+.16f\n",n,x);
}
}
The computed values (after a 'gcc' compilation without optimization on
a Linux PC) are as follows:
initialisation x= +1.0000000000000000
iteration 1 x= +1.0000000000004547
iteration 2 x= +1.0000000018631452
iteration 3 x= +1.0000076316294826
iteration 4 x= +1.0312599175240718
iteration 5 x= +129.0437481703507956
iteration 6 x= +524480.9968805739190429
iteration 7 x= +2148322516.2225189208984375
iteration 8 x= +8799743854603.9609375000000000
iteration 9 x=+36044630802839192.0000000000000000
Initially:
x = 1
and the following relation holds:
A-B = 1 (mathematically speaking...)
(it is noteworthy that 'A' equals a power of 4 plus 0.1; when using
another decimal part, things are more complicated...) then, the
variable 'x' should be equal to its initial value (1) all along the
iterations. Or it is not true... By the way, this program gives the
right answer (1) when substituting double with float (that means that,
"by chance", A-B equals 1 exactly) or again compiling with
optimization!
Then, it is very important not to confuse mathematical linearity and
numerical linearity; the preceding example is non linear at the
numerical level for there is one multiplication using a constant value
(in a computer memory, the difference between a constant value and a
variable one is very light...)!
By the way, these very simple decimal numbers cannot be precisely
defined:
B = 4095.1 =
{0x40affe33,33333333}
A = B+1 = 4096.1 =
{0x40b00019,9999999a}
A-B = 1.0000000000004547 =
{0x3ff00000,00000800}
1.0 =
{0x3ff00000,00000000}
the preceding values being obtained with a PC. A similar phenomenon is
in fact very common: see for example 1/3 that is a finite sum of
powers of 1/3 (0.1 using base 3) and in the same time an infinite sum
of powers of 1/10 (0.33333...)."
- "ARE FLOATING POINT COMPUTATIONS RELIABLE?"
Jean-François Colonna
http://www.lactamme.polytechnique.fr/Mosaic/descripteurs/FloatingPointNumbers.01.Ang.html
Yes, but C is the one really famous for its error proneness. The Atari
TOS was written in C and all of its many bugs and errors are down to
the typical and well known C traps and snares.
I'll grant you that one course and one simple finished project are not
really a lot of base upon which to judge any language, but I found all
my prejudices about C confirmed. Sources in related languages like
Javascript are very hard to follow, while BASIC, Pascal and FORTRAN
tend to be eminently legible and easy to understand.
"Mr Emmanuel Roche, France" <roch...@laposte.net> schreef in bericht
news:3022d041-4fdc-4c00...@f12g2000yqn.googlegroups.com...
I found FORTH to be much more error prone. I always suspected that was
because didn't really "get" FORTH. I couldn't think in it.
> The Atari
> TOS was written in C and all of its many bugs and errors are down to
> the typical and well known C traps and snares.
C, like assembler, requires self discipline. Especially resisting the urge
to do things it'll let you do, but you really shouldn't do.
>
> I'll grant you that one course and one simple finished project are not
> really a lot of base upon which to judge any language, but I found all
> my prejudices about C confirmed. Sources in related languages like
> Javascript are very hard to follow, while BASIC, Pascal and FORTRAN
> tend to be eminently legible and easy to understand.
Once you understand it, it's easy to understand it.
I've been programming in C for almost 30 years now. The times I find C
(nearly) incomprehensible is when someone has abused it's flexibility and/or
one of it's features. The example Mr. Roche posted is typical of these
abuses, specifically the comma operator and the flexibility of the "for"
statement. What sort of lunatic puts a print statement inside the section
of a "for" statement where you're supposed to prepare for the next
iteration? Or uses the comma operator in the test section? Most of that
code belongs in the body of the loop.
I couldn't find this on the Obfusticated C contest site. Perhaps if I'd
looked longer it's there. The only possible justification for this sort of
thing might be that this particular coding approach produced faster code
and, given the hardware available, that was actually a consideration. For
example, perhaps it's from a "fastest computation of PI to N places"
contest. This could be optimized for the particular machine and compiler
used. I've occasionally seen C done by competent programmers in very
special circumstances that seemed rather like this. I've even written some.
But at least in my cases, the readable version and explanation of what and
why was contained in comments along with the unreadable one.
- Bill
Yes, I'll grant you that and it is why I pointed out my extremely
limited experience here.
On the other hand I'm not a programmer but programming things I need
for my tasks, often in macro languages or databases, is something I
need to do frequently. I do maintain that for part-time and small tool
programmers like me the BASIC and FORTRAN like languages have a lot
going for them.
For application and OS programmers things may well look quite
differently.
The feeling is likely mutual. Here is an interesting C program written
in Aztec C that will run either in CP/M 86 or MS-DOS (This runs fine
on my PC in Jim Lopushinsky's CP/M 86 emulator or in a Windows XP cmd
window, and a working copy of all is distributed through my Aztec C
Website)... the fact that this was not made in France and the lack of
usefulness of the program are likely not relevent factors since the
rest of this thread seems to be somewhat pointless anyway...
/* bpic.c (C) Copyright 2008 Bill Buckels. All rights reserved. */
/* A BASIC BSaved graphics image loader for
DOS 2.0 or CP/M-86
Written in Aztec C86 v3X
Handles CGA 320 x 200 x 4-Color or 640 x 200 x 2 Color screens.
For more info on these See my Wikipedia Article at:
http://en.wikipedia.org/wiki/BSAVE_(graphics_image_format)
For a program to create these in Windows XP from a variety of
sources download a copy of my ClipShop program at:
*/
#include <fcntl.h>
/* one of my headers */
#include <regs.h>
/* no need to load the entire image
just load the 192 bytes between the interleaves
to simplify for a contiguous load */
#define SCREENSIZE 16192
#define SCREENSEG 0xb800
/* a read buffer */
char databuf[SCREENSIZE];
/* a microsoft compatible bsaved image format descriptor */
char bsave_header[7]=
{'\xfd','\x00','\xb8','\x00','\x00','\x00','\x40'};
/* for verification... check the first 5 bytes only!
the marker byte 0xfd is followed by 3 intel 16 bit integers
giving originating segment, offset, and filelength of the image.
The filelength can vary here but the first 5 bytes are
pretty mich invariant. As far as length most of these were 0x4000
(16384) bytes not including the 7 byte header and BASIC's
ubiquituous
[CTRL]-Z (0x1a) footer (which was reminiscent of the early x86 file
systems
but wasn't always present at the end of these either depending on
who and how).
The reason that most of us saved them that way was probably because
of the example in the GWBASIC manual... and IBM PC StoryBoard's
PictureMaker (PM.EXE) v1 saved them that way as well... perhaps
they read the
same manual.
But John Bridges saved these in PicEM the same way I am loading
them here... without the padding on the end. (John didn't code in
BASIC
even in those days), and Eugene Ying who did saved them as 16512
bytes
in PCPG which doesn't make much sense to me.
That was a long time ago anyway.
*/
/* K & R style function body */
main(argc, argv)
int argc;
char **argv;
{
int fh, idx, status, vmode = 'M';
union REGS inregs, outregs;
struct SREGS sregs;
if (argc < 2) {
printf("Usage: bpic [my.bas] [options 'H' for hires or 'M' for
medres]\n");
exit(1);
}
/* check for video mode */
if (argc > 2) {
if (argv[2][0] == '-')idx =1;
else idx = 0;
if (argv[2][idx] == 'h' || argv[2][idx] == 'H')vmode = 'H';
}
sysint(0x11,&inregs,&outregs); /* get equipment list from the bios */
/* get display type (bits 4 and 5 of ax) */
if (!((outregs.x.ax & 0x30) < 0x30)) {
printf("CGA compatible displays only! Exiting.\n");
exit(1);
}
fh = open(argv[1],O_RDONLY);
if (fh == -1) {
printf("Unable to open %s!\n",argv[1]);
exit(1);
}
read(fh,databuf,7);
for (idx = 0; idx < 5; idx++) {
if(databuf[idx]!= bsave_header[idx]) {
close(fh);
printf("Unsupported Format!\n");
exit(1);
}
}
/* we are in small memory model so need to get the segment
that we are running-in to move image data direct
to the CGA screen address... */
segread(&sregs);
read(fh,&databuf[0],SCREENSIZE);
close(fh);
mode(vmode);
/* note that I am using the ds register value with
the datasegment address of my near pointer
for my image data buffer as the base address for
the source of my memory block move... */
movblock(&databuf[0],sregs.ds,0,SCREENSEG,SCREENSIZE);
/* wait for a key press */
/* use sysint to generate int 16h */
inregs.x.ax = 0x0000;
inregs.x.dx = 0x0000;
sysint(0x16,&inregs,&outregs);
/* return the low order char */
status = outregs.x.ax&0x00ff;
mode('L');
exit(status);
}
I have programmed in C for many years, but have 10 *solid* years
programming in C on a Unix system. C is *not* hard to understand,
but just different in some ways from Pascal and FORTRAN.
ISTM that many of the bugs in C programs are caused by the pointer
arithmetic and that pointers can be altered to point every which way.
Putting things in the "for" statement itself should only be done
when it makes the code clearer. The test is the *only* think that
really *has* to be there.
> I couldn't find this on the Obfusticated C contest site. Perhaps if I'd
> looked longer it's there. The only possible justification for this sort
> of thing might be that this particular coding approach produced faster
> code and, given the hardware available, that was actually a
> consideration. For example, perhaps it's from a "fastest computation of
> PI to N places" contest. This could be optimized for the particular
> machine and compiler used. I've occasionally seen C done by competent
> programmers in very special circumstances that seemed rather like this.
> I've even written some. But at least in my cases, the readable version
> and explanation of what and why was contained in comments along with the
> unreadable one.
>
What I have seen is the opposite: I have seen code that seems
long and unwieldy, but that executed quickly... because the
"execution path" through the code tended to be short. Like a
"switch" with 15 cases, but each execution of the function would
only pick one case.
Yes, FORTRAN and BASIC can be good for "part time and small tool
programmers". But as someone who usually programs in C, I find
myself using C for the small tasks too. I'm sure it's just because
I am more comfortable with it.
Well, the test is optional, and I have written for loops
without one. Sometimes similar to the PL/I DO I=1 BY 1;
But yes, the goal should be clearer code.
Initializing other variables used in the loop I sometimes
find clearer and other times not.
-- glen
Yes, I understood that.
> On the other hand I'm not a programmer but programming things I need
> for my tasks, often in macro languages or databases, is something I
> need to do frequently. I do maintain that for part-time and small tool
> programmers like me the BASIC and FORTRAN like languages have a lot
> going for them.
I agree.
If I'm trying to debug some new bit of hardware I pretty much always use
BASIC rather than C. Though more a log of my reason for that is that it's
interactive.
> For application and OS programmers things may well look quite
> differently.
- Bill
I was specifically thinking of the time period Mr. Roche mentioned. In 1984
with both much slower hardware and much less robust code generation, there
was sometimes and excuse. In rare cases (I do a lot of embedded work on
limited processors) there may still be an excuse. But in general, I agree
and my more recent experience (say, since the '90's) has been the same as
yours. The performance increase, if there even is any, is rarely worth the
unreadable code.
- Bill
I started with assembler (PDP-8 PAL-III) then went to BASIC and was
frustrated that I could not deal with strings for IO. Later I would
do PDP10 assembler, Algol and move on to 8080 asm and BASIC.
BASIC had two problems for most fo the work I wanted to do first it
was slow and the wight of the interpreter was high, the compiler
still ahd a large runtime package so it was overweight. But for
non speed critical projects it was acceptable. I would move on
to Pascal (first exposure was UCSD P-system) and that proved much
better for modular programming and database work I was starting
to get into. However getting into C and understanding it was a step
up as to me that was far closer to assembler than a HLL. I still use
it despite the many varients and drift away from K&R. It is a good
tool for systems level work that would be much mroe time intensive
to debug if done in asm and far less portable.
Every programing language I've seen including Python, Lua and
the "visual" languages have buckets of pitfalls and traps.
If you write well thought out and structured code it's at least
debugable. I've seen cryptic stuff in most every language.
the worst and most inscrutable example of code I've worked
(as in had to add a feature to) was QB45 and I consider that
an excellent BASIC. It was written deliberately to be unreadable
and also meet a size limit on media. Comments would really
have helped as they cost nothing (compiled code).
The contest to write obscure C was Byte in the late 70s if the
memory wasn't totally blown. The winning example took
advantage of replacement operators such that the result
was barely human readable. The contest required the code
to be functional and produce correct results.
Allison
Ho, my... 10 messages!
Why are you talking so much, when I mention C, and not when I talk
about CP/M?
I cannot, and don't want, to comment each comment, but I feel that I
should precise a few things:
1) *NOBODY* explained the 3-lines C program.
2) Bill Leary: MBASIC puts spaces in front of zero: each of my
published program had to use the PRINT RIGHT$ statement to display the
leading zeros (for example: the address of a dump). So, it is a well-
known thing.
3) Charles Richmond: Could you send me the 2400 decimals? Would like
to see if I can produce them with 8-bit BASIC.
4) Charles Richmond: I hope that you were joking when you wrote: "one
should *not* interrupt the French Luser while he is
pontificating! ;-)"
English is not my native language, but how could I pontify when it is
me who is asking for explanation of a foreign language (that nobody
explained)?
5) Henk Siewert: Why should it be me, who don't known C, who should
recreate the manual? Are you a fan of C, or not? If so, do the logical
thing...
I will never understand C fans.
6) Bill Leary: I have a fascination for Forth because only 2KB of code
needs to be written in assembly language. After that, everything is
written in "high-level" Forth... The only slight problem being that I
never had the "Haha!" experience in Forth. When I recreated the Dr.
Logo manual, I found amazing similarities between Logo and Forth: one
uses a list, the other a stack. But, again, thinking in "functional
programming" does not come automatically to me. Too bad: I am not
ashame to say publicly that I think that Dr. Logo is the most powerful
PL running under CP/M-86.
7) Bill Buckels: Finally, a C programmer explaining how his program
works!
It was interesting to read how you explain "the first 5 bytes".
Apparently, this is the fundamental "data structure" of this file
format. Some people simply use:
The previous message was sent by error when I hit a key!
So, some people use
+-----+-------------+---------+----------------+
| FD | Segment | Offset | FileLength |
+-----+-------------+---------+----------------+
to describe the data structure used.
This is an idea.
To finish: to all: instead of *REACTING* to what I write, why not
*ACT* yourself, and write something?
Bill, even in 2010 there is a need for fast code, think about driver,
conversion programs or similar.
And if you like, you can easily write readable and well commented C
programs, too.
Regards
Peter
Why should anyone? It was clearly a "loaded" question - designed to provoke
replies. It was also clear that the C program was transformed into that
mess from understandable C code, i.e., obfuscated.
> I will never understand C fans.
FORTH "fans" don't understand C "fans" either. Every noise they make just
blows past each other... (pun intended).
> Why are you talking so much, when I mention C, and not when I talk
> about CP/M?
Why are you talking about C in a CP/M forum?
I don't mind. I love C. It's the best of the 14 or so languages I've
experienced. A PL/1 variant (more like Pascal than PL/1...) was just as
powerful too, but far more wordy. I find it difficult to keep track of
variables in languages without named variables. These include assembly and
stack oriented languages like FORTH or Postscript. A variable in assembly
can be moved between registers, stack, and memory - each of which is named
or accessed differently. In a stack oriented language like FORTH or
Postscript, when a variable or data is put on the stack, it loses it's
naming - if it ever had any. FORTH and Postscript are also devoid of syntax
which makes following the program's flow difficult. BASIC was good for
string processing: LEFT$, RIGHT$, MID$, and + for string concatentation.
Simple. Clean. Easy. Otherwise, the only good use I've seen for BASIC is in
machine control - where it's line-orientedness is useful for commands to
control devices. Fortunately, C has the same string functionality, although
it's not as concise or as easy to use as BASIC. Pascal was far too
restrictive. It was impossible to do any interaction with the operating
system using Pascal. FORTRAN was just a nightmare to program. Something
must be in this column, or that column, undocumented language features and
undocumented syntax, difficulties of implementation everywhere, odd side
effects both numerical and not, etc.
> 6) Bill Leary: I have a fascination for Forth because only 2KB of code
> needs to be written in assembly language. After that, everything is
> written in "high-level" Forth...
Many languages and libraries are built up from a subset of functionality.
You might find this post of mine interesting:
http://groups.google.com/group/comp.lang.forth/msg/10872cb68edcb526
Also, there's comp.lang.forth for FORTH discussion. It's quite active.
Lot's of people with decades of FORTH experience. Even a few of the
original (e.g., 1970's) FORTH programmers are there.
Rod Pemberton
Roche has performed the classic "troll" tactic of posting something
both marginally on-topic, and sure to provoke response. Even one of
the respondents was aware of this. Roche all but admits his
intentions. Before responding further, I suggest you review his other
posts, and my document linked below, and draw your own conclusions
about the consequences of responding.
http://www.retrotechnology.com/herbs_stuff/offtopic.html
Herb Johnson
retrotechnology.com
(I tried to write you privately, but found a strange-looking e-mail
address, so decided to reply publicly. Anyway, I have nothing to hide.
Especially to Herb Johnson.)
> > 1) *NOBODY* explained the 3-lines C program.
>
> Why should anyone? It was clearly a "loaded" question - designed
> to provoke replies.
Hahaha! Who knows? Personally, I published it since I know nothing
about C, and this 3-lines program seemed interesting. But I am
obviously too much of a Newbie to have judged its difficulty (or lack
of) correctly.
(Since I have an interest for FP, I liked finding the second one. Very
educative.)
> I don't mind. I love C. It's the best of the 14 or so languages I've experienced.
Haaaaa! Finally! An interesting discussion about PLs!
> I find it difficult to keep track of variables in languages without named variables.
I precisely mentioned, a few days ago, that languages without needing
to declare variables at the start eliminated, by essence, half of the
bugs, since statistics have found (or had found, when there was
statistics and books about programming) that half of the errors where
in LET A=B+3-like lines.
> These include assembly and stack-oriented languages like FORTH or Postscript.
Ho! I see: you mean: when the intermediate variable is on the stack,
or in a register. Under SID (DDT?), there is a command to see the
"levels" of the stack of the CPU. The problem being, of course, that
the stack is variable, so its contents is variable, too. Isn't there
Forth commands to display the variables on stack? (Else, you could
give a byte/word/etc a name, and store the value of the variable
there. Once debugged, you could remove the "data section", and run the
program only with the Stack.)
> BASIC was good for string processing:
Hahaha! It is the first time that I see this advantage mentioned! In
the academic papers that I used to read, the standard string language
was SNOBOL. Since it is written totally in macros, I tried to
implement it under CP/M, but could not find all the books, at the
time.
> Otherwise, the only good use I've seen for BASIC is in machine control
??? Even more surprising! I was thinking that Forth was the ultimate
to control something?
> Pascal was far too restrictive.
Hum... I never liked Pascal, but I won't say too harsh things about
it. I think that it suffered from a lack of definition of its I/O.
Computer Science profs loved to use it to explain algorithms: it was a
kind of standard for Maths teachers.
> FORTRAN was just a nightmare to program.
Hahaha! If my engineer friend was reading this!
> Many languages and libraries are built up from a subset of functionality.
> You might find this post of mine interesting:
??? A "3-Instructions Forth"? Incredible!
> Also, there's comp.lang.forth for FORTH discussion. It's quite active.
> Lot's of people with decades of FORTH experience. Even a few of the
> original (e.g., 1970's) FORTH programmers are there.
(I note that you still write "FORTH", so you must be an Old Timer.)
Yes, many thanks, but this does not answer the question: How do you
have the "Haha!" experience with Forth? Me, I tried several times --
without success.
Hope that you will contribute more to the comp.os.cpm Newsgroup. Most
of the regulars seem to be hardware types. And speaking of 30-years
old systems.
Think about "real time" applications like flying a cruise missile.
There *is* a requirement that things get done within a specific
time frame. And *lots* of things are going on.
And think about computers used in automobiles. Engine controllers
have *lots* to do and have to get it done in "real time".
So yes, many computer applications have constraints which require
fast code.
Here is pi to 2400 decimal places:
3.
141592 653589 793238 462643 383279 502884 197169 399375
105820 974944
592307 816406 286208 998628 034825 342117 067982 148086
513282 306647
093844 609550 582231 725359 408128 481117 450284 102701
938521 105559
644622 948954 930381 964428 810975 665933 446128 475648
233786 783165
271201 909145 648566 923460 348610 454326 648213 393607
260249 141273
724587 006606 315588 174881 520920 962829 254091 715364
367892 590360
011330 530548 820466 521384 146951 941511 609433 057270
365759 591953
092186 117381 932611 793105 118548 074462 379962 749567
351885 752724
891227 938183 011949 129833 673362 440656 643086 021394
946395 224737
190702 179860 943702 770539 217176 293176 752384 674818
467669 405132
000568 127145 263560 827785 771342 757789 609173 637178
721468 440901
224953 430146 549585 371050 792279 689258 923542 019956
112129 021960
864034 418159 813629 774771 309960 518707 211349 999998
372978 049951
059731 732816 096318 595024 459455 346908 302642 522308
253344 685035
261931 188171 010003 137838 752886 587533 208381 420617
177669 147303
598253 490428 755468 731159 562863 882353 787593 751957
781857 780532
171226 806613 001927 876611 195909 216420 198938 095257
201065 485863
278865 936153 381827 968230 301952 035301 852968 995773
622599 413891
249721 775283 479131 515574 857242 454150 695950 829533
116861 727855
889075 098381 754637 464939 319255 060400 927701 671139
009848 824012
858361 603563 707660 104710 181942 955596 198946 767837
449448 255379
774726 847104 047534 646208 046684 259069 491293 313677
028989 152104
752162 056966 024058 038150 193511 253382 430035 587640
247496 473263
914199 272604 269922 796782 354781 636009 341721 641219
924586 315030
286182 974555 706749 838505 494588 586926 995690 927210
797509 302955
321165 344987 202755 960236 480665 499119 881834 797753
566369 807426
542527 862551 818417 574672 890977 772793 800081 647060
016145 249192
173217 214772 350141 441973 568548 161361 157352 552133
475741 849468
438523 323907 394143 334547 762416 862518 983569 485562
099219 222184
272550 254256 887671 790494 601653 466804 988627 232791
786085 784383
827967 976681 454100 953883 786360 950680 064225 125205
117392 984896
084128 488626 945604 241965 285022 210661 186306 744278
622039 194945
047123 713786 960956 364371 917287 467764 657573 962413
890865 832645
995813 390478 027590 099465 764078 951269 468398 352595
709825 822620
522489 407726 719478 268482 601476 990902 640136 39443
> 4) Charles Richmond: I hope that you were joking when you wrote: "one
> should *not* interrupt the French Luser while he is
> pontificating! ;-)"
>
> English is not my native language, but how could I pontify when it is
> me who is asking for explanation of a foreign language (that nobody
> explained)?
>
You do *not* want an explanation of C. You barely *pretend* to be
objective, but your real purpose is to criticize the structure of
the C language. (The above digits of pi were produced using a C
program.)
You can find an Apple ][ BASIC program for calculating pi at:
http://bob-bishop.awardspace.com/ApplePi/index.html
> Here is Pi to 2400 decimal places:
>
> 3.
> 141592 653589 793238 462643 383279 502884 197169 399375
> 105820 974944
(snip)
Hum... Let's see. 6 digits per block. 10 blocks per line. So, 60
digits per line. 34 lines.
> 522489 407726 719478 268482 601476 990902 640136 39443
Last line = 8 times 6 (if we take into account the starting "3").
Total:
34 * 60 = 2040 (computed in my head)
8 * 6 = 48
--------------
2088 digits
> You do *not* want an explanation of C.
Really? How do you know?
> You barely *pretend* to be objective,
Objective? Me? Then why would I still use a 30-years old OS and its
PLs?
> but your real purpose is to criticize the structure of the C language.
I openly challenge you to find one sentence written by me where I
"criticize the structure of the C language". Contrary to you, I have
used several PLs, and I know (by experience, me) that each one has
advantages and drawbacks in some domains.
> (The above digits of Pi were produced using a C program.)
So what?
Of course. I gave an example, embedded systems (often with limited memory
and cycles), where the performance gain might be worth it. But even in
those cases, it's rarely actually necessary to sacrifice readability for
performance. I have encountered a few cases where certain code sequences
worked much faster. In those cases, if it actually mattered to the
application, I'd code the less readable form, but with associated comments
to make both the purpose of the odd code, and the justification for it being
odd, clear.
You gave two other examples where I've occasionally found it worth the hit
in readability. But, usually, it's not.
- Bill
It is not always necessary to explain much about a program even in
C... this depends on the audience of course...
For writing things like filters and command line utilities I don't
favour descending into the depths of assembly language much... but
each to their own...
So here's an example of another interesting C for CP/M program which
isn't very commented but reads conversationally so doesn't need to be,
as long as one remembers how simple terminal characters work and their
ascii values...
Again this is available in glorius working format from the Aztec C
Website complete with compiler and disk images and so forth...
/* -------------------------------------------------------------------
System : Apple II CP/M 80
Environment : Aztec C
Program : more.c
Description : paged or line oriented text file viewer
This program is a filter that displays a text file
either page by page if the spacebar is pressed
or line by line if enter is pressed.
If the [ESCAPE] key or the letter 'Q' is pressed
the program ends.
It will optionally accept a filename to read input
from. All output is to the standard output device
unless redirected.
It is oriented to the 80 column x 24 row display.
Example:
more abc.txt
read input from abc.txt,
output goes to screen.
more <abc.txt
same as previous example
Written by : Bill Buckels
Date Written : Nov 2008
Revision : 1.0 First Release
------------------------------------------------------------------ */
#include <stdio.h>
main(argc, argv)
int argc;
char **argv;
{
int c, d = 0, ctr = 0;
FILE *fp = NULL;
if (argc > 1)
fp = fopen(argv[1], "r");
for (;;) {
if (NULL == fp)
c = getchar();
else
c = fgetc(fp);
if (c==EOF)break;
putchar(c);
if(c=='\n') {
ctr++;
if (ctr > 22) {
d = getch();
if (d == 27 || d=='q' || d == 'Q')break;
else if (d == 32)ctr = 0;
else if (d == 13)ctr = 22;
}
}
}
if (d != 27 && d !='q' && d != 'Q') {
if (ctr > 0 && ctr < 22)getch();
}
if (NULL != fp) {
fclose(fp);
exit(0);
}
}
getch()
{
/* return the last key press */
int ch;
while((ch=bdos(6,0xff))==0);
return ch;
}
Regards,
Bill Buckels
http://en.wikipedia.org/wiki/User:Bill_Buckels
http://www.appleoldies.ca/
http://www.c64classics.ca/
http://www.cpm8680.com/
http://www.clipshop.ca/c86/
http://www.clipshop.ca/
http://www.teacherschoice.ca/
I once wrote what might be the simplest C filter, which
went something like:
#include <stdio.h>
main() {
while(getchar()!=EOF) putchar(getchar());
}
We had binary files written by the Sun PASCAL compiler that
were supposed to be written as bytes, but the system decided that
eight bits needed a sign bit, and rounded up to 16. Every byte
came out with a preceeding null character.
-- glen
Thanks for posting this, thru it I found Frank Sergeant's pygmy forth,
which is very accessible for pcdos. http://pygmy.utoh.org/forth.html
and very reminicient of the cp/m-86 forth: http://z80cpu.eu/mirrors/klaw/forth86.zip
Steve
Yes, sorry, I no longer communicate via email.
> > I don't mind. I love C. It's the best of the 14 or so languages I've
experienced.
>
> Haaaaa! Finally! An interesting discussion about PLs!
comp.lang.misc seems to be the place for conversations regarding language
design, implementation, limitations. At least, that's where I've receive
the best response to similar replies. Although, they seem to prefer ideas
for new languages, instead of discussing old languages. You might also try
comp.compilers. IIRC, it's moderated and requires a valid email.
> Yes, many thanks, but this does not answer the question: How do you
> have the "Haha!" experience with Forth? Me, I tried several times --
> without success.
According to those on c.l.f., you either understand Forth or you don't. I'm
mostly in the don't. I understand much of the language as individual
commands or operations, but I don't do so well programming Forth. I've been
learning more now that I'm coding an interpreter for it in C. It may be
that I just need to work through all the hidden details to fully understand
it. Although, I'll never like it's lack of syntax or variable naming
issues.
> Hope that you will contribute more to the comp.os.cpm Newsgroup.
Well, I'm unfamiliar with CP/M. I know it existed. I know it is a basic
and simple operating system. It's era was slighly before my first use of a
computer. Steve Dubrovich and I have discussed other operating systems and
related issues elsewhere. So, I added c.o.c. for a while for operating
system ideas and maybe some historical info.
Rod Pemberton
Oops, yes, I misspelled his name...
> which is very accessible for pcdos. http://pygmy.utoh.org/forth.html
> and very reminicient of the cp/m-86 forth:
http://z80cpu.eu/mirrors/klaw/forth86.zip
There are *many* Forth's. This c.l.f. post of mine has just a handful of
links at the bottom:
http://groups.google.com/group/comp.lang.forth/msg/cc23cc71fa62ede8
My personal collection of publicly available Forth's has 59 directories and
numerous others I haven't sorted.
Rod Pemberton
> comp.lang.misc seems to be the place for conversations regarding language design, implementation, limitations.
Not exactly, since I am only interested in PLs that ran under CP/M
2.2, CP/M-86, and MS-DOS (I now use a "DOS Box" on my Internet/Windows
computer).
Fortunately, Digital Research put a lot of work so that their PLs were
running exactly the same under the above 3 OSes. Hence, my programs
are portable thanks to the work of Digital Research.
> According to those on c.l.f., you either understand Forth or you don't.
Ouch! At my age, it will be difficult to learn "new tricks".
> I've been learning more now that I'm coding an interpreter for it in C.
One that I wondered if I could port it in Tiny-C, so as to use it
under CP/M-86, is "UNTIL", by Norman Smith. It is on Taygeta. He was a
Forth programmer on a DEC VAX. When he discovered the IBM Clown, he
was horrified by its segments, so rewrote the kernel in C. He claims
that his code is portable.
> Well, I'm unfamiliar with CP/M.
Argh! Too bad. Here, there is too much hardware types, and not enough
programmers.
I was reluctant to mention that because a lot of people think it's an urban
legend. It's not. I've seen the code, it's in the task switching routines.
The comments that precede the one you quote explain what's going on, but
unless you know how the hardware works and how UNIX uses the stack, there
isn't much chance you'll understand the comment or the code.
- Bill
Ah, excellent. Please give me an opinion, if you would.
To make sense of that bit, I found knowing the hardware was necessary.
Did/do you know the machine? I forget, at this point, what it was. PDP-8
comes to mind, but I by no means sure that's right. I wondered at the time
if someone not knowing the machine would be able to figure it out.
What's your thought?
- Bill
>"Jonathan Graham Harston" <j...@arcade.demon.co.uk> wrote in message
>news:100129...@arcade.demon.co.uk...
>> Bill_...@msn.com wrote:
>>> Jonathan Graham Harston wrote:
>>> > The UNIX source contains at least one comment: "you are not meant
>>> > to understand this".
>>>
>>> The comments that precede the one you quote explain what's going on, but
>>> unless you know how the hardware works and how UNIX uses the stack, there
>>> isn't much chance you'll understand the comment or the code.
>>
>> I've got the source here in front of me. It took me several careful reads
>> to understand that particular bit of code ;)
>
>Ah, excellent. Please give me an opinion, if you would.
>
>To make sense of that bit, I found knowing the hardware was necessary.
>Did/do you know the machine? I forget, at this point, what it was. PDP-8
>comes to mind, but I by no means sure that's right. I wondered at the time
>if someone not knowing the machine would be able to figure it out.
>
>What's your thought?
>
> - Bill
There isn't a C compiler for the pdp-8 its way to sparse a machine to
implement C on (no stack in hardware). Unix was initialy built on a
18bit PDP7 then ported tothe 16bit PDP-11. However the contest was
at a time when unix was the likely host or an 8080/z80 system running
smallc or BDS c.
Allison
ISTM that the *first* Unix did *not* employ C as the
implementation language. IIRC C was invented to code Unix in a
more portable way, and probably was first used on the PDP-11.
Affirmitive. I have a old bell labs white paper on that.
C reflects directly the addressing capabilities (pointers and stacks)
that are native to the PDP11.
Allison