Path: utzoo!utgpu!attcan!uunet!lll-winken!lll-tis!helios.ee.lbl.gov!pasteur!ucbvax!PENNDRLS.BITNET!DAVID From: DAVID@PENNDRLS.BITNET Newsgroups: comp.lang.forth Subject: Re: Thinking FORTH Message-ID: <8808031609.AA26840@jade.berkeley.edu> Date: 3 Aug 88 15:33:56 GMT Sender: daemon@ucbvax.BERKELEY.EDU Reply-To: Forth Interest Group International List Organization: The Internet Lines: 177 Fraser Orr writes: >[I write:] >>Agreed. My programming in all languages has improved since I learned >>FORTH (specifically since I read `Thinking FORTH'). And no, I don't > >In what way? Do you mean that since reading the holy book you have been >able to design your programs better? If so, wonderful. But really, >programming language and program design are separate issues. If you want >to know about program design I can recomend several books that deal >with the topic in a lanugage independent way, thus you see how DESIGN >ideas fit (e.g., the concept of a named parameter, or a labeled >variable) and how these fit in with your language of choice (in Forth, Yes, please (if you have a minute), I *would* be interested in a good book on program design from a language independent point of view. I am curious to see how the tradeoff between program size and subroutine call overhead is presented. I also look forward to improving my programming some more; this is *not* a facetious request. Part of the motivation behind my remark was that Thinking FORTH taught me to decompose problems into subroutines in ways that I would not have thought of from my traditional language background. I am interested in finding out what the current theories of program design are, but I haven't found a good book yet. (Haven't looked too hard yet, either.) >no named parameters, and a rather tacky idea of labeled variables.) "?" he says, with a puzzled frown. :-) My definition of a 'named parameter' is: a constant referred to throughout a program or set of programs by a symbolic name. In which case a FORTH constant fits the bill very well. If what you are looking for is a way to assign a constant a name during compilation and have the compiler substitute the real value into the compiled program, then you are no longer being language independent. A litteral (a constant compiled directly into a FORTH word) executes more slowly than a FORTH constant. If it is referred to more than once, it also occupies more memory. (disregarding headers, which any good target compiler will have deleted.) Of course, if we are talking about different concepts my point is moot. What's a labeled variable? (I know, I know: 'read the book'. :-) O.K, which book?) >If I gave Kernighan and Richie's book on C, and you read it, you would >undoubtedly learn sopmething about program design (though in K&R's case >not a lot), but you would have to spend a lot of your time ignoring >all the guff about the language. If you want to learn about program >design, read a book about program design, not about Forth program >design! This is not really a valid comparison. Kernighan and Richie is a book about a language that happens to also talk about program design in that language. Thinking FORTH is a book about program design using FORTH as the vehicle for illuminating its points that happens to also talk about some specifically FORTH design issues. This is, of course, not the same as talking about program design independent of any language. Still, if you want to firmly ground a concept it helps to give examples, and FORTH is better for some examples than any other language. Just as LISP, or even C, is better for others. So I think I can have learned some things from Thinking FORTH that I would not have learned by reading a language independent design book. (Which won't stop me from doing both!) >>however. At some point the overhead of a subroutine call makes >>smallness impractical. C's macro facility goes a long way toward >>alleviating > >This is a totally spurious point. The only differences between a forth >subroutine call and a C call is that C has to make a stack frame (i.e., >*allocate* a small amount of memory on the top of the stack), the >parameters have to be put there in but languages, the return address has >to be put in by both langnuages, the PC has to be set in both languages, >in fact C calls are going to be at most 1usec slower than Forth ones, >not in my opinion worth worrying about. This of course assumes that the >forth program has been compiled onto a Forth microprocessor, if it's >interpreted, well ... Hmm. You're right; if you properly design a C program it can be *almost* as fast as a FORTH program compiled on an 'equivalent' FORTH microprocessor. Slower by more than you think, though. In most FORTH programs the arguments to a word are already on the stack fairly often, rather than needing to be moved into place. Ditto for removing them afterward. And on a FORTH micro, the FORTH return from subroutine is faster. Add up the number of subroutine calls in a fair sized program, and we are talking about a significant difference. Still, I would be willing to bet that, assuming 'equivalent' underlying chips, one could write a C program and a FORTH program that would do the same job equally efficiently, but the average subroutine size in the C program would have to be larger (though perhaps not much larger). So I don't think my point is completely spurious. Of course, I have no way of testing it, so you should feel free to not change your mind :-). (Hmm. It might be worth comparing a direct threaded FORTH to a C on the same micro . . . that I may be able to try some day. I suspect the results would be very similar.) >>that problem, though. Yet even when I write what I feel is an >>appropriately sized subroutine in C, it is still larger visually than >>the corresponding FORTH program and therefore harder to grasp and >>think about. At this level we are talking about a small difference, > >:fact dup 0 gt else 1 then dup 1 sub fact if ; > >vs >int Fact ( n ) >{ > if ( n > 0 ) > return n*fact(n-1) > else > return 1 ; >} > >If you find the former easier to understand, you've got a twisted >mind! (PS apologies for my forth, it has been a while since I wrote >any, and after all it is not the most memorable syntax:^) Let's try: int Fact ( n ) : Fact ( n -- n! ) { VS Dup if ( n > 0 ) -- 0= If return n*fact(n-1) Drop 1 Exit else Else return 1 ; Dup 1- Fact } * Then ; (Excuse me, but didn't you forget to declare n?) I find the two approximately equally understandable. I wrote the FORTH after almost a year of writing no FORTH code and looking at very little, but got it right on the first try. *I* find FORTH's syntax memorable. I learned C and then did not use it for a year, and when I tried to write a C program I got bit by the '=' vs. '==' distinction and had to look up the syntax of the for and while constructs. I think I remember them now, but I wouldn't bet on it. To see what I mean by visually larger, let's try: void CFormatOK(Count,Args) : CFormatOK ( a n -- ) int Count; 1 ?REXXArgs char **Args; 0 Arg UpperCase { ?Devid char *Devid,*OutType,*Format; ?OutputName REXXArgs(Count,1); VS ?FormatName UpperCase(Args[0]); -- ?EndArg Devid = DevidCheck(Args[0]); FormatOK OutType = OutTypeCheck(Args[0]); REXXReturn Format = FormatNameCheck(Args[0]); ; NoMore(Args[0]); REXXReturn(FormatOK(Devid,OutType,Format)); } I drew this example from a C program I threw together the other month; don't worry about what it does. The point is that the FORTH is smaller visually. True, this also means the FORTH version does not convey as much information about the arguments to the subroutines as the C version, but I find that information more distracting than helpful. As long, that is, as I am consistent in how my FORTH subroutines handle arguments. Given that I know what the subroutines do (which anyone studying the code would have to learn anyway) I can see at a glance what the FORTH version does, whereas my eyes and mind have to do more work to get the same information out of the C version. My conclusion, I think, is that FORTH encourages small subroutines (which you agree is good) and C does not, and that even when the subroutines are of the same size code wise, the FORTH subroutines are smaller mentally. Since a good programmer can program well in any language, I'll program (when I can) in FORTH, and you can program in whatever language *you* prefer. -- R. David Murray (DAVID@PENNDRLS.BITNET, DAVID@PENNDRLS.UPENN.EDU)