How to convert Infix notation to postfix notation

S

spinoza1111

Not into status at all, are we???

Nope, nope, nope.

Notes:
    1) Granted, if somebody attacks you, it is pretty hard to resist the
        temptation to start singing your virtues (listing your
        accomplishments)
    2) This point (#1 above) illustrates why it is a bad thing to claim
        to not be motivated by status.  Sooner or later (and in this
        case, it didn't take long), you're going to end up looking like
        a hypocrite (or worse...)

Kenny is right. May as well admit that you're motivated by status. Cf.
Alexandre Kojeve, An Introduction to the Phenomenology of Mind: life
is a struggle to the death for pure Recognition.
 
S

spinoza1111

Wow 5000 lines of code.

Wow three bug reports. Please note that in a nasty environment, a
manager like Heathfield can easily make those 3*10eN where N is any
number simply by spreading vicious rumors that multiply those bug
reports. If you by repetition get into the game of destroying a man's
reputation as opposed to discussing ideas in an enlightened fashion,
without shooting your smart mouth about people's qualifications, be
prepared to be hoist by your own reports.

The point is your job function is not a programmer, whereas I had that
function for thirty years. This means that your observations on coding
are worthless. Had you not prejudiced your own case by attacking the
real programmer Herb Schildt, with academic and professional
qualifications you lack, I'd of course be prepared to credit you.
Indeed, I am crediting your bug reports insofar as they are worthwhile
in the infix2Polish change record. However, my experience in this
discussion is that you have little to contribute apart from your
prejudices about style. Whereas Ben gets into the code and finds real
issues.
 
S

spinoza1111

Not just here, though.  Pretty much everywhere.


No, we have learned that you can't read for comprehension.

I wrote the filesystem interface code that we use for all our builds; it's
about 5k lines of code, written in three weeks, and we've had three bug
reports on it in a year of heavy use.  :)

I don't actually change the compiler internals, 'cuz we subcontract that
to specialists, but that doesn't change much.

I actually "changed the compiler internals" at Bell Northern Research
for five years. Since that time, programming and programming related
jobs have become overspecialized, and as a result people are shoe-
horned into jobs in which they can use only a small amount of their
brain capacity. I think that in your case, the capacity is there, but
you've not had a chance to see whether the folklore that you pass on
as wisdom actually works.
No, it doesn't.

For one thing, systems Hungarian is the wrong choice for that, because the
ranges of values aren't necessarily defined by those types; for instance,
"long" might not be the same size on different supported targets.  In many
cases, the correct range is not related to a specific type.

"Long" need only refer to common usage, because when you are coding
systems Hungarian, you are doing a form of documentation in a form of
common usage. Overprecision would defeat this goal. Today, long pretty
much means 64 bits (long long is a barbaric C idiom). On the most
common systems, which are of course twos-complement, this is a fixed
range which most intelligent technicians can be expected to know.
For a concrete example, if you are storing "an inode number", the correct
type is ino_t, not int or long, and you don't need to know the range --
because the range is "whatever values the system yields in the range covered
by the existing type".  When you're referring to a file, you don't need a
prefix to identify the inode; you just CALL it an inode and you're done.
Same thing goes for a whole lot of other standard types.

This is nonsense. Systems Hungarian expresses the truetype whereas
your prefix expresses only a pious hope that everything will work, and
the ino_t will stay within the expected values. The code reader needs
to know the actual range on the machine.
There are cases where it makes sense to indicate type information, but
usually systems Hungarian is the wrong way to do it.  Consider, for instance,
that both an array index and the size of a block of memory are presumably
size_t.  In systems Hungarian, used by idiots, they are described as being
the same type because they have the same range of values.  In apps Hungarian,
used by people who are not as stupid, thye are not described as having
the same type because, while they have the same range of possible values,
the values are not interchangeable.  Mistaking the range of values for the
data type is pretty much a newbie mistake.

People who are not stupid don't think this way at all. Again, pious
hopes are not documentation.

People who are not stupid code in a modern OO language in which the
array index and the block of memory would be different objects: the
array index would be intIndex1 or uintIndex1 if extra control is
needed: the block would be in my very not stupid scheme an obj, since
the scheme is NOT extended to a new SH prefix for each object.

The SH prefix is important documentation of what the object is and a
reminder that especially in languages like C, the actual range of a
value may diverge from the expected range.
 
B

bartc

Richard Heathfield said:
So did pencil and paper, for computation. So?

That's not the same thing. Those gadgets are not that physically different
from their predecessors, but happen to have digital electronics inside. The
user however doesn't care and it doesn't suddenly turn them into what is
generally perceived as a computer.

So the next generation has hardwired logic inside (or little elves), and now
they're not computers anymore? The microprocessor thing is an irrelevance.
(Of course some efforts are underway to converge all these different
products, including discrete computers, for reasons I don't quite
understand.)
 
S

spinoza1111

There were other problems.

Itemise them. NOW. Otherwise you're again making a small number of
errors into a full scale trashing as you did with Schildt.

Release 4 of the infix2Polish conversion program is attached to this
reply. All of your concerns, including the small H issue, have been
addressed, and you have been credited in the Change Record. From now
on, I want you to economically report problems as they arise or
contribute your own code to this discussion. When I want anything
more, I'll beat it out of you.
This really isn't a power/generality question.  It's a design tradeoff,
and different companies have made different choices.


Man, you just blew out another milspec irony meter.  That quote is awesome
coming from someone who uses "As I have said" as a way to introduce claims
for which he's never presented any kind of support other than his own
assertions.

If you by your own repetition force me to repeat then yes indeed, your
own reputation is being damaged by this online discussion. But please
note that you are the aggressor as you were with Herb. He chose not to
respond. I choose to, and in so doing I repeat what you've told me
about your learning disorder and the fact that you don't seem to have
either academic qualifications or real programming experience.

If you do not like this, then confine yourself in the future to actual
technical points.

Here is version 4 of infix2Polish.


// ***************************************************************
// * *
// * infix2PolishC Infix to Polish notation using a grammar *
// * *
// * *
// * This application converts infix to Polish notation using a *
// * simple grammar. *
// * *
// * *
// * C H A N G E R E C O R D --------------------------------- *
// * DATE PROGRAMMER DESCRIPTION OF CHANGE *
// * -------- --------- --------------------------------- *
// * 11 01 09 Nilges Version 1 *
// * *
// * 11 03 09 Nilges Version 2 *
// * ANON 1. Commenting added DONE *
// * 2. Routine index added with *
// * forward definitions DONE *
// * 3. Expected/actual cleanup DONE *
// * 4. Bug? Seems to convert Polish *
// * expression to value of first *
// * token without complaint *
// * FIXED *
// * 5. Minor bug: extra spaces in *
// * polish expression FIXED *
// * 6. Bugs as found by anon *
// * 8.1 1) FIXED *
// * 8.2 (((1)))) FIXED *
// * 7. Predetermine malloc using *
// * number of symbols other than *
// * parentheses and white space *
// * *
// * 11 04 09 Nilges Version 3 *
// * 1. Predetermine malloc using *
// * infix length times two *
// * 2. Detab code for posting *
// * 3. Free polish expression after *
// * displaying it in testcase() *
// * as noticed by Seebs and *
// * recommended by Schildt *
// * 4. Display purpose of code on *
// * entry *
// * 5. Option to specify malloc *
// * request on command line for *
// * Polish expression (primarily *
// * to test storage usage) *
// * *
// * 11 06 09 Nilges Version 4 *
// * Seebs 1. Fix upper case in #include *
// * 2. Comment corrections *
// * 3. Bug: intMaxPolishLength not *
// * assigned when malloc specified*
// * on command line *
// * 4. Renamed string2UnsignedInt to *
// * string2Int *
// * 5. Use macros to better format *
// * about info *
// * 6. Command line malloc is now a *
// * maximum request allowable *
// * 7. Bug: invalid malloc request *
// * caused zero to be used without*
// * error indication. *
// * 8. Changed str2Int to return err *
// * when nonnumeric characters *
// * appear *
// * *
// * I S S U E S ----------------------------------------------- *
// * DATE POSTER DESCRIPTION AND RESOLUTION *
// * -------- --------- --------------------------------- *
// * Nilges Version 5 plan *
// * Seebach 1. Random expressions *
// * Gene 2. Alternative versions from *
// * Anon Seebach, Gene, anon *
// * 3. Add timing facilities *
// * 4. String handling centralized *
// * 5. Display command line syntax *
// * 6. Command line options *
// * 6.1 /T terse output *
// * 6.2 /? display help info: *
// * exit *
// * 6.3 /S <seed> seed the random*
// * # generator *
// * 6.4 /M <max> define max *
// * malloc request *
// * 7. Prescan the infix expression *
// * *
// ***************************************************************

#include <stdio.h> // May help Heathfield
#include <stdlib.h>
// ***** Macros **************************************************

// --- Pass over white space
#define SKIP_WHITE_SPACE(s, i, e) \
{ for(; (i) <= (e) && (s)[(i)] == ' '; (i)++ ); }

// --- Return maximum value
#define MAX(x, y) ((x) > (y) ? (x) : (y))

// --- Return minimum value
#define MIN(x, y) ((x) < (y) ? (x) : (y))

#define SHOW_ABOUT_INFO \
{ \
printf("This application converts infix to Polish "); \
printf("notation using a simple grammar-based approach. "); \
printf("Its command line syntax is: infix2PolishC "); \
printf("[ mallocMax ]"); \
}

// ***** Function index ******************************************
#define ADDFACTOR \
int addFactor(char *strInfix, \
char *strPolish, \
int *intPtrIndex, \
int intEnd, \
int intMaxPolishLength)
ADDFACTOR;
#define ERRORHANDLER \
int errorHandler(char *strMessage)
ERRORHANDLER;
#define ERRORHANDLERSYNTAX \
int errorHandlerSyntax(int intIndex, \
char *strMessage, \
char *strInfix)
ERRORHANDLERSYNTAX;
#define EXPRESSION \
int expression(char *strInfix, \
char *strPolish, \
int *intPtrIndex, \
int intEnd, \
int intMaxPolishLength)
EXPRESSION;
#define FINDCHARS \
int findChars(char *strInstring, \
char *strFind, \
int intStartIndex)
FINDCHARS;
#define INFIX2POLISH \
int infix2Polish(char *strInfix, \
char *strPolish, \
int intMaxPolishLength)
INFIX2POLISH;
#define MAIN \
int main(int intArgCount, \
char *strArgs[])
MAIN;
#define MULFACTOR \
int mulFactor(char *strInfix, \
char *strPolish, \
int *intPtrIndex, \
int intEnd, \
int intMaxPolishLength)
MULFACTOR;
#define STRING2INT \
int string2Int(char *strInstring)
STRING2INT;
#define STRINGAPPENDCHAR \
int stringAppendChar(char *strString, \
char chrNew, \
int intMaxLength, \
int intSpaceBefore)
STRINGAPPENDCHAR;
#define STRINGLENGTH \
int stringLength(char *strInstring)
STRINGLENGTH;
#define TESTCASE \
void testCase(char *strInfix, \
char *strExpected, \
int intMallocMax)
TESTCASE;
#define TESTER \
void tester(int intMallocMax)
TESTER;

// ***** Functions ***********************************************

// ---------------------------------------------------------------
// Command line handler
//
// int main(int intArgCount, char **strArgs)
//
MAIN
{
int intMallocMax = -1;
SHOW_ABOUT_INFO;
if (intArgCount > 1)
if ((intMallocMax = string2Int(strArgs[1])) < 0)
{
printf("%sInvalid malloc request %s\n", intMallocMax);
return;
}
tester(intMallocMax);
printf("\n\nTesting complete: check output for correctness");
return;
}

// ---------------------------------------------------------------
// Parse add factor
//
// int addFactor(char *strInfix,
// char *strPolish,
// int *intPtrIndex,
// int intEnd,
// int intMaxPolishLength)
//
// addFactor = mulFactor [ *|/ mulFactor ]
//
ADDFACTOR
{
char chrMulOp = ' ';
int intStartIndex = 0;
if (!mulFactor(strInfix,
strPolish,
intPtrIndex,
intEnd,
intMaxPolishLength))
{
errorHandlerSyntax(*intPtrIndex,
"mulFactor not found",
strInfix);
return 0;
}
if (*intPtrIndex > intEnd) return -1;
intStartIndex = *intPtrIndex;
while (1)
{
SKIP_WHITE_SPACE(strInfix, (*intPtrIndex), intEnd)
if (*intPtrIndex > intEnd) break;
if ((chrMulOp = strInfix[*intPtrIndex]) != '*'
&&
chrMulOp != '/')
return -1;
(*intPtrIndex)++;
if (*intPtrIndex > intEnd
||
!mulFactor(strInfix,
strPolish,
intPtrIndex,
intEnd,
intMaxPolishLength))
return errorHandlerSyntax
(*intPtrIndex,
"Mul/div op not followed by mulFactor",
strInfix);
if (!stringAppendChar(strPolish,
chrMulOp,
intMaxPolishLength,
1)) return 0;
}
return -1;
}

// ---------------------------------------------------------------
// Error handler
//
// int errorHandler(char *strMessage)
//
ERRORHANDLER
{
printf("\n%s\n", strMessage); return 0;
}

// ---------------------------------------------------------------
// Syntax error handler
//
// int errorHandlerSyntax(int intIndex,
// char *strMessage,
// char *strInfix)
//
ERRORHANDLERSYNTAX
{
int intIndex1 = 0;
printf("\nError at character %d: %s\n",
intIndex,
strMessage);
printf("%s\n", strInfix);
for (intIndex1 = 0; intIndex1 < intIndex; intIndex1++)
printf(" ");
printf("$");
return 0;
}

// ---------------------------------------------------------------
// Parse expression
//
// int expression(char *strInfix,
// char *strPolish,
// int *intPtrIndex,
// int intEnd,
// int intMaxPolishLength)
//
EXPRESSION
{ /* expression = addFactor [ +|- addFactor ] */
char chrAddOp = ' ';
int intStartIndex = 0;
if (!addFactor(strInfix,
strPolish,
intPtrIndex,
intEnd,
intMaxPolishLength))
{
errorHandlerSyntax(*intPtrIndex,
"addFactor not found",
strInfix);
return 0;
}
intStartIndex = *intPtrIndex;
while (1)
{
SKIP_WHITE_SPACE(strInfix, (*intPtrIndex), intEnd)
if (*intPtrIndex > intEnd) break;
if ((chrAddOp = strInfix[*intPtrIndex]) != '+'
&&
chrAddOp != '-')
return
errorHandlerSyntax
(*intPtrIndex,
"Unrecognizable char found instead of add op",
strInfix);
(*intPtrIndex)++;
if (*intPtrIndex > intEnd
||
!addFactor(strInfix,
strPolish,
intPtrIndex,
intEnd,
intMaxPolishLength))
return errorHandlerSyntax
(*intPtrIndex,
"Add/sub op not followed by addFactor",
strInfix);
stringAppendChar(strPolish,
chrAddOp,
intMaxPolishLength,
1);
}
return -1;
}

// ---------------------------------------------------------------
// Find one of a set of alternative characters
//
// int findChars(char *strInstring,
// char *strFind,
// int intStartIndex)
//
FINDCHARS
{
int intIndex1 = intStartIndex;
int intIndex2 = 0;
for (; strInstring[intIndex1] != '\0'; intIndex1++)
for (intIndex2 = 0;
strFind[intIndex2] != '\0';
intIndex2++)
if (strInstring[intIndex1] == strFind[intIndex2])
return intIndex1;
return intIndex1;
}

// ---------------------------------------------------------------
// Convert infix to Polish
//
// int infix2Polish(char *strInfix,
// char *strPolish,
// int intMaxPolishLength)
//
INFIX2POLISH
{
int intIndex = 0;
int intLength = stringLength(strInfix);
strPolish[0] = '\0';
if (!expression(strInfix,
strPolish,
&intIndex,
intLength - 1,
intMaxPolishLength))
{
errorHandler("Error");
return 0;
}
return -1;
}

// ---------------------------------------------------------------
// Parse multiplication factor
//
// int mulFactor(char *strInfix,
// char *strPolish,
// int *intPtrIndex,
// int intEnd,
// int intMaxPolishLength)
//
// mulFactor = LETTER | NUMBER | '(' expression ')'
//
MULFACTOR
{ int intIndexStart = 0;
int intLevel = 0;
char chrNext = ' ';
int intInner = 0;
int intSpaceBefore = 0;
SKIP_WHITE_SPACE(strInfix, (*intPtrIndex), intEnd)
if (*intPtrIndex > intEnd)
return errorHandlerSyntax(*intPtrIndex,
"mulFactor unavailable",
strInfix);
chrNext = strInfix[*intPtrIndex];
if (chrNext >= 'a' && chrNext <= 'z')
{
(*intPtrIndex)++;
return stringAppendChar(strPolish,
chrNext,
intMaxPolishLength,
1);
}
intIndexStart = *intPtrIndex;
intSpaceBefore = -1;
while(*intPtrIndex <= intEnd
&&
(chrNext = strInfix[*intPtrIndex]) >= '0'
&&
chrNext <= '9')
{
if (!stringAppendChar(strPolish,
chrNext,
intMaxPolishLength,
intSpaceBefore))
return 0;
intSpaceBefore = 0;
(*intPtrIndex)++;
}
if (*intPtrIndex > intIndexStart)
return -1;
if (chrNext == '(')
{
intLevel = 1;
(*intPtrIndex)++;
intInner = *intPtrIndex;
while (intLevel > 0 && *intPtrIndex <= intEnd)
{
if ((chrNext = strInfix[(*intPtrIndex)++]) == '(')
{
intLevel++;
}
else
{
if (chrNext == ')')
{
intLevel--;
}
}
}
if (intLevel != 0)
return errorHandlerSyntax
(*intPtrIndex,
"Unbalanced left parenthesis",
strInfix);
if (!expression(strInfix,
strPolish,
&intInner,
*intPtrIndex - 2,
intMaxPolishLength))
return errorHandlerSyntax
(intInner,
"Expression doesn't appear in parentheses",
strInfix);
return -1;
}
return 0;
}

// ---------------------------------------------------------------
// Convert string to an unsigned integer
//
// int string2Int(char *strInstring)
//
//
STRING2INT
{
int intIndex1 = 0;
int intValue = 0;
for (; strInstring[intIndex1] != '\0'; intIndex1++)
{
if (strInstring[intIndex1] < '0'
||
strInstring[intIndex1] > '9') return -1;
intValue = intValue * 10
+
strInstring[intIndex1] - (int)'0';
}
return intValue;
}

// ---------------------------------------------------------------
// Append character to string
//
// int stringAppendChar(char *strInstring,
// char chrNew,
// int intMaxLength,
// int intSpaceBefore)
//
STRINGAPPENDCHAR
{
int intLength = stringLength(strString);
int intSpaceBeforeInEffect =
intSpaceBefore
&&
intLength > 0
&&
strString[intLength - 1] != ' ';
if (intLength
intMaxLength - (intSpaceBeforeInEffect ? 2 : 1))
{
errorHandler
("Cannot append character(s): insufficient storage");
return 0;
}
if (intSpaceBeforeInEffect)
{
strString[intLength++] = ' ';
}
strString[intLength] = chrNew;
strString[intLength + 1] = '\0';
return -1;
}

// ---------------------------------------------------------------
// Return string length
//
// int stringLength(char *strInstring)
//
STRINGLENGTH
{
int intIndex1;
for (intIndex1 = 0;
strInstring[intIndex1] != '\0';
intIndex1++) { }
return intIndex1;
}

// ---------------------------------------------------------------
// Test case
//
// void testCase(char *strInfix,
// char *strExpected,
// int intMallocMax)
//
TESTCASE
{
char *strPolish;
int intMaxPolishLength = stringLength(strInfix) << 1;
int intReq = MAX(intMaxPolishLength + 1, 10);
if (intMallocMax >= 0)
{
intReq = MIN(intMallocMax, intReq);
intMaxPolishLength = intReq - 1;
}
printf("\n\nConverting \"%s\": expect \"%s\"",
strInfix,
strExpected);
strPolish = (char *)malloc(intReq);
if (strPolish == 0)
errorHandler("Can't get storage");
printf("\n\"%s\"\n",
(infix2Polish(strInfix,
strPolish,
intMaxPolishLength)
?
strPolish
:
"Conversion failed"));
free(strPolish); // cf. Schildt, C: the Complete Reference
}

// ---------------------------------------------------------------
// Tester
//
// void tester()
//
TESTER
{
testCase("1", "1", intMallocMax);
testCase("1+1", "1 1 +", intMallocMax);
testCase("(10+613)*a", "10 613 + a *", intMallocMax);
testCase(")", "Error", intMallocMax);
testCase("1)", "Error", intMallocMax);
testCase("(((1))))", "Error", intMallocMax);
testCase("10 113 + a *", "Error", intMallocMax);
testCase("(10 + 113) * a", "10 113 + a *", intMallocMax);
testCase(" ( 10 + 113 ) * a ", "10 113 + a *", intMallocMax);
testCase("(", "Error", intMallocMax);
testCase("((((2", "Error", intMallocMax);
testCase("////2", "Error", intMallocMax);
testCase("", "Error", intMallocMax);
testCase("()", "Error", intMallocMax);
testCase("(((5))", "Error", intMallocMax);
testCase("(((5)))", "5", intMallocMax);
testCase("((5))", "5", intMallocMax);
testCase("5", "5", intMallocMax);
testCase("((10+(113-(2+((((((2/(4+3)))))))+2+2))))*a", "10 113 2 2
4 3 + / + 2 + 2 + - + a *", intMallocMax);
testCase("a", "a", intMallocMax);
testCase(" a + b ", "a b +", intMallocMax);
testCase(" a + b ", "Malloc bound failure", 5);
}
 
S

spinoza1111

Caveat: I've never had any inclination to investigate it, but ...

Based on my reading, when I first started looking at .NET, there is
nothing per se that ties .NET to MS Windows.  And, in fact, there are
implementations for other platforms, including Linux (and no, I don't
mean by running a Windows emulator).

Of course, MS isn't completely stupid.  I'm sure there are gotchas
involved in using a non-Windows implementation.  But, still, given that
this is a newsgroup obsessed with so-called "accuracy" (so labeled for
what should, by now, be obvious reasons), we should feel safe in
poo-poo'ing the notion that .NET is MS Windows only.

Incidentally, on the subject of things MS, let me re-iterate what I've
said all along about what really makes this NG tick.  That is, a common
hatred of things MS.  And believe me, I know of what I speak.  I used to
be one.  But at some point, to paraphrase St. Paul, you have to leave
childish things behind.  Basically, once you realize that they aren't
getting you anywhere.

My basic thesis is that the lunacy that is CLC, pretty much came about
when, in the early 90s, the Unix-heads (and being once myself, I use
that term with love) realized that the world was going MS.  And it
pissed them off (as it did me, for a long time).  And so, rather than
see their beloved newsgroup(s) descend into endless discussions of
"lpParam", "GetWindowTitleName()", etc, they concocted this "what's in
the standard and only what's in the standard" nonsense.  And that's
where we are today...- Hide quoted text -

- Show quoted text -

Five-star post from someone with real experience on both sides of the
fence.

To make the use of an upper-case H a big deal is one of St Paul's
childish things, as was the attack on Schildt.

Excellent point, too, about .Net. The mono project, an open-source
implementation of .Net, shows that .Net has not necessary link with
Windows.
 
N

Nick Keighley

Nick Keighley said:
spinoza1111 wrote:
Grow up. Most platforms are Microsoft.
Absolute rubbish. If you're going by installation count, there are
approximately 1,000,000,000 PCs out there, not all of which run MS
operating systems. [lots of examples]
I keep hearing all this. But since the 80's, most of the computers I've
been able to buy have come with a MS operating system. Most of the rest have
been Macs.

which aren't MS platforms
That's a good analogy, but it helps make my point not yours:

unsurprisingly, I disagree :)
They travelon the same road and use the same basic technology
when someone
takes driving lessons, do they also include sections on HGV and PSV driving?
[Ie. trucks and buses]

transits. So the PC is the car, linux is the van and mainframes/
servers are the lorries. I'm not saying my mum should be expected to
be able to drive a truck but that doesn't mean a truck isn't a useful
motor vehicle.
I'm not saying otherwise (although you will note that recorded music,
photography, and telephones used to work just fine without them...)>

the phone system has been running on digital technology since the 60s.
Look up PCM and System-X. AT&T were forbiden from selling computers
but they were still building things that looked mightily like
computers.
[PC programmers?]
would welcome that book that was mentioned and there's no real reason for
them to care whether their product runs on anything else.
personnally I'd prefer a book that clearly distinguised standard stuff
from non-standard stuff. Some of us like to write software that runs
on multiple platforms. [...]

OK, there's a huge amount of different kinds of computing that goes on in
academia, industry, business and so on.

For those of us outside that world, who only really have access to
consumer-level PCs, why should we concern ourselves with anything else? At
most we might worry about portability between Windows, MacOS and Linux.

If you write programs that are that portable you've gone quite a long
way.
And even someone who in their day job writes code for some jet fighter, who
in their spare time wants to exchange programs with a friend who writes
programs for a supermarket, what common platform do you think they might
use?

I was never against a book about PC programming just the claim that it
covered the entire universe of computing.
 
S

spinoza1111

I think "everyone" here is either a retiree or else holds down some
computer-related job of checker upper onner where they are prevented
from actually coding for real, and it's for this reason I discount
their wisdom. We have learned that Seebach merely sends problems on to
real programmers, for example, and only Bacarisse here gives evidence
of actual problem-solving capacity: he does not have to pad his emails
with dozens of idiot saws learned second-hand from the guys at the
office on break: instead, when he posts, it's usually a show stopper.

As to you, you appear to edited a book for an unethical publisher with

Error: this should refer to "as to Heathfield, he appears to have
edited, etc"
 
N

Nick

spinoza1111 said:
printf("%sInvalid malloc request %s\n", intMallocMax);

There's something a tad iffy about this line.

Apart from the number of parameters, isn't that just the sort of thing
that the Hungarian notation is meant to help you spot?

As a more minor point, I'd tend to use "isspace" rather than ' ' in the
skip spaces macro - it's not that likely to matter but does help when
some editor manages to sneak a tab into your input stream.

NB, this is not a thorough review, the second is something I just
noticed and the first leaped out at me so I stopped looking at that
point.

Don't you have your compiler warnings set high enough for it to catch
this sort of thing? Or does it not support looking at format parameters
(GCC does).
 
M

Moi

On Thu, 05 Nov 2009 20:52:43 -0800, spinoza1111 wrote:

[snipped]
#define ADDFACTOR \
int addFactor(char *strInfix, \
char *strPolish, \
int *intPtrIndex, \
int intEnd, \
int intMaxPolishLength)
ADDFACTOR;
[snipped]

// --------------------------------------------------------------- //
Parse add factor
//
// int addFactor(char *strInfix,
// char *strPolish,
// int *intPtrIndex,
// int intEnd,
// int intMaxPolishLength) //
// addFactor = mulFactor [ *|/ mulFactor ] //
ADDFACTOR
{
char chrMulOp = ' ';
int intStartIndex = 0;
if (!mulFactor(strInfix,
strPolish,
intPtrIndex,
intEnd,
intMaxPolishLength))

[snipped]

The strange thing about this coding style is that it
will save you *no* keystrokes.
Since you actually duplicate the function prototype in the comment block
just above the function definition.
Whenever you have to change the function's arguments
you will have to change the (redundant) comment as well.

Plus, the preprocessor #define introduces yet another name
for something that already has a name.

So it is not only "bad style" but useless as well.


Adorno probably did not know this.

HTH,
AvK
 
N

Nick Keighley

That's not the same thing. Those gadgets are not that physically different
from their predecessors, but happen to have digital electronics inside. The
user however doesn't care and it doesn't suddenly turn them into what is
generally perceived as a computer.

So the next generation has hardwired logic inside (or little elves), and now
they're not computers anymore?

probably not the next generation
The microprocessor thing is an irrelevance.
(Of course some efforts are underway to converge all these different
products, including discrete computers, for reasons I don't quite
understand.)

because they can. Once you've got something digitised (voice,
photography, type setting) then they reduce (in some sense) to the
manipulation of bits and the same type of hardware can do that
manipulation. Don't you like the fact that your PC can manipulate
photograps, process words, make a phone call and show a "film" (film
of course being an anacronysm!).
 
K

Kenny McCormack

Nick said:
I'm not convinced that saying "I'm capable of X, and I've done Y" in
response to "you cann't do anything and have never done anything" is
about status. Opening a conversation like that, sure. But giving it as
factual information in response to a challenge is pretty much all you
can do other than accept the original claim.

It *is* about status. It is perfectly understandable to react this way,
as I noted in the post to which you responded. But it is not consistent
with someone claiming to be totally unmotivated by "status" (or, in the
vernacular, "what other people think [of me]")

As EGN notes in his next post, every human being (with exceptions so few
as to be statistically invisible) is motivated by status. It is the
human condition.
 
S

spinoza1111

On Thu, 05 Nov 2009 20:52:43 -0800,spinoza1111wrote:

[snipped]
#define ADDFACTOR \
        int addFactor(char *strInfix, \
                      char *strPolish, \
                      int *intPtrIndex, \
                      int intEnd, \
                      int intMaxPolishLength)
ADDFACTOR;
[snipped]





// --------------------------------------------------------------- //
Parse add factor
//
// int addFactor(char *strInfix,
//               char *strPolish,
//               int *intPtrIndex,
//               int intEnd,
//               int intMaxPolishLength) //
// addFactor = mulFactor [ *|/ mulFactor ] //
ADDFACTOR
{
    char chrMulOp = ' ';
    int intStartIndex = 0;
    if (!mulFactor(strInfix,
                   strPolish,
                   intPtrIndex,
                   intEnd,
                   intMaxPolishLength))

[snipped]

The strange thing about this coding style is that it
will save you *no* keystrokes.
Since you actually duplicate the function prototype in the comment block
just above the function definition.
Whenever you have to change the function's arguments
you will have to change the (redundant) comment as well.

Yes. This, however, gives the best result for the program reader.
Programs should be laid out mostly for the convenience of the program
READER, not the WRITER. Indeed, the reinterpretation of the points
made first by Brian Kernighan in 1976 in The Elements of Programming
Style by many programmers is that "if I find it convenient to code and
maintain, the user will like it too".

This reinterpretation is nonsense. Readability takes work: as Baruch
Spinoza wrote in Of Human Freedom, everything excellent is as
difficult as it is rare.

It's just obscene in fact that many little paraprogrammers, as soon as
they see the evidence of work or thought, jump to the conclusion that
some mythical User, imaged in their media-sodden brains as Donald
Trump saying "you're fired", would be "offended".

Indeed: the first time I encountered, in a discussion of internals
that real computer day to day users never see, this bizarre reference
to a "user" was at Princeton in 1987. It came from a fellow employee
with deep rage against his father who had a very bad habit of using
the network to spread lies about other people's competence.

In this use of the word, the "user" actually means the Self who's
offended by the evidence of someone else's hard work. People today are
so unwilling to acknowledge the real conditions of their lives that
they identify on the job with a mythical Donald Trump.

Plus, the preprocessor #define introduces yet another name
 for something that already has a name.

So it is not only "bad style" but useless as well.

Adorno probably did not know this.

Actually, his whole theory of "reification" (treating a word as a
thing) is a precise critique of your reasoning, which is based on the
profound mistake of counting words.

The basic idea is that C is fucked up and preserves the need to define
and/or declare before use from the thrilling days of yesteryear when
compilers were referred to as "single pass". In Adorno, technology
becomes to the subaltern a second form of nature...which is where we
get, in fact, the idiotic claims that Herb is "wrong" in the way a
scientist is "wrong".

The abstract power of conditional at-will employment, under terms that
every year grow more and more absurdly harsh, is unbearable: therefore
techies prefer to naturalize, fetishize and reify the demands made on
them by the apparatus as anything but what they must do to survive in
a world divided between a vanishingly small number of absurdly wealthy
people and the rest of us.

In the case of C, it's just convenient to the wealthy (the venture
capitalists and majority stockholders) that software tools never be
completely usable, and that there's (systematically: universally) not
enough time to do it right, or rectify the mistakes of the past. In a
decent world there would be no division between theory and practice
and at the same time, separation of concerns in such a way that time
could be spent on rectification of names, as Confucius called it.

For example, I believe that in an ideal world (in other words, the
only sort of world worth living in), any programmer would be both at
liberty to, and qualified to, **write his own compiler** where this
makes sense given a problem...and it does in many surprising
situations.

In the real world, of course, this is a termination offense.

For this reason, I am willing to write the declaration more than once
using the preprocessor. I am willing to make the effort, because the
final result (when error free or even with minor typos in comments) is
far more readable: the higher level functions appear before the lower
level functions.

Don't tell me this was too much work for me to do. I'll be the judge
of that. Restrict your comments to one question only: is the code
readable as a result of the technique?
 
S

spinoza1111

There's something a tad iffy about this line.  

Apart from the number of parameters, isn't that just the sort of thing
that the Hungarian notation is meant to help you spot?

Thanks for the bug report. This will be fixed in the next release.
Would you rather be Nick or Anon2?
As a more minor point, I'd tend to use "isspace" rather than ' ' in the
skip spaces macro - it's not that likely to matter but does help when
some editor manages to sneak a tab into your input stream.

Ewwwwww nasty problem. Sounds like for portability I should follow
this advice. But on the other hand, if in your environment this is a
possibility, it sounds like you have too many editors.
 
K

Kenny McCormack

My basic thesis is that the lunacy that is CLC, pretty much came about
when, in the early 90s, the Unix-heads (and being once myself, I use
[/QUOTE]
^^^^
This was a typo. I meant to write "one", not "once".
I still consider myself a Unix-head.
Five-star post from someone with real experience on both sides of the
fence.

Indeed. Thank you.
To make the use of an upper-case H a big deal is one of St Paul's
childish things, as was the attack on Schildt.

Yes. The .H thing is a lot like the endless preening about the "DS9000".
Totally irrelevant to the "newbies" who are the supposed audience of all
the preening.
Excellent point, too, about .Net. The mono project, an open-source
implementation of .Net, shows that .Net has not necessary link with
Windows.

Have you ever tried it? (I have not). As I said, MS is not completely
stupid. I'm sure they built in some gotchas so that even though they
can claim not to be a monopoly, it is still the case that it (.NET)
works best on their own OSs.
 
M

Moi

Yes. This, however, gives the best result for the program reader.
Programs should be laid out mostly for the convenience of the program
READER, not the WRITER. Indeed, the reinterpretation of the points made

[snipped]

Well, not for *me* as a reader. And not for a lot of others, too.
The physical distance between the silly #define and the actual comment
will make the program more error-prone.
For both READER and WRITER.

AvK
 
S

spinoza1111

Yes. This, however, gives the best result for the program reader.
Programs should be laid out mostly for the convenience of the program
READER, not the WRITER. Indeed, the reinterpretation of the points made

[snipped]

Well, not for *me* as a reader. And not for a lot of others, too.
The physical distance between the silly #define and the actual comment
will make the program more error-prone.

Literally untrue, for the comment being wrong won't make the actual
program error-prone. Putting actual declarations in two different
places will, and this is what you have to do, short of REVERSING the
order of functions and placing the trivial functions first, if you
don't use the preprocessor.

The comments were inserted as a convenience for the program READER. I
went the extra mile to do this because unlike a lot of the big mouths
here I am actually interested, not in pleasing some internalized
Donald Trump asshole of an end-user, or a bunch of dweebs, but an
actual person with an actual job to do.

To add a new routine, all you have to do is:

1. Copy a pre-existing decl and its first use in the function index
in the front of the program.

2. Change it for your new routine.

3. Go to the appropriate place for the new function, and insert its
comment header (using my nice and friendly visual prototype), recoding
its decl as a comment.

For both READER and WRITER.

Sloppy English won't make your case. How can a program be "error
prone" for the "reader"? Do you mean "conducive to misreading?" That's
precisely what my style is not.
 
N

Nick

Nick said:
I'm not convinced that saying "I'm capable of X, and I've done Y" in
response to "you cann't do anything and have never done anything" is
about status. Opening a conversation like that, sure. But giving it as
factual information in response to a challenge is pretty much all you
can do other than accept the original claim.

It *is* about status. It is perfectly understandable to react this way,
as I noted in the post to which you responded. But it is not consistent
with someone claiming to be totally unmotivated by "status" (or, in the
vernacular, "what other people think [of me]")

I disagree. You are a purple banana. If you deny that is it about
status? Well, to the extent that status means "the state that you are",
of course it is. But to somehow claim that because someone provides an
explanation of what experience they have in response to someone else
claiming they haven't means that they are "motivated by status" seems
pretty damn silly to me.
As EGN notes in his next post, every human being (with exceptions so few
as to be statistically invisible) is motivated by status. It is the
human condition.

Well people are motivated by hundreds of things to a greater or lesser
extent. To a very small degree indeed I'm motivated by people not
wanting to think I'm an invisible pink unicorn - but to go around
claiming that I've reported a bug in his code because I'm motivated by
people not wanting to think I'm an invisible pink unicorn is - frankly -
barking. And that seems to be what this bizarre squabble seems to be
about.

Most of comp.lang.c seems to be about you two claiming people are
motivated by status. Could we return to talking about C please?
 
N

Nick

spinoza1111 said:
Yes. This, however, gives the best result for the program reader.
Programs should be laid out mostly for the convenience of the program
READER, not the WRITER. Indeed, the reinterpretation of the points
made first by Brian Kernighan in 1976 in The Elements of Programming
Style by many programmers is that "if I find it convenient to code and
maintain, the user will like it too".

But as lots of other people have pointed out, doing it twice means that
sooner or later (usually sooner) one of them will be wrong.

I quite like the idea of avoiding having to keep the prototype and the
definition in synch if you change them (not enough to want to adopt it,
but I do quite like it). But what you need to do is make the macro
definition act as the documentation as well. Without this, you are - as
they pointed out - defining it twice anyway.
 
B

bartc

Flash Gordon said:
Mobile phones (even analogue ones) have never worked without processors,
and GM phones are mobile phones, not land line phones.

I could pick up radio telephone calls on airband radio in the 70's. I doubt
microprocessors were involved.

And while the sophistication of GSM would be difficult without them,
wireless telephony has been around for a long time.
For those of us outside that world [industry etc], who only really have
access to consumer-level PCs, why should we concern ourselves with
anything else? At most we might worry about portability between Windows,
MacOS and Linux.

So? A lot of people don't know either English or Chinese. If someone who
only spoke Swahili said that because he does not know any English or
Chinese speakers that Swahili is the most common language in the world,
and English and Chinese speakers are not people, would you think he was
correct?

No. But that's nothing to do with the undeniable ubiquity of PCs.
 

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

Members online

Forum statistics

Threads
474,077
Messages
2,570,567
Members
47,203
Latest member
EmmaSwank1

Latest Threads

Top