orr@cs.glasgow.ac.uk (Fraser Orr) (09/12/88)
In article <8809092121.AA09902@jade.berkeley.edu> Forth Interest Group International List <FIGI-L%SCFVM.bitnet@jade.berkeley.edu> writes: >Fraser Orr writes: [Stuff that I believe justifies the following assertion deleted] >>Forth bears absolutely no resemblance to any functional programming >>language I know, (appartfrom the fact that the both run on a computer of >>course :^>). > >First of all, I don't think the original poster was claiming that the >paper backed up FORTH as a wonderful programming language, but rather >that it singled out modularization as the greatest good; the fact that >FORTH makes it easy to completely modularize code then implies that >FORTH is a ``good'' language *in this regard*. > >Obviously, however, you do not agree that FORTH allows easy and >complete modularization. I think we need a definition of modularization. >I suspect you are in fact referring to language facilities directly >aimed at building modules. If so, you are correct, plain FORTH has >none. But even the computer scientists agree that modularization is >something that happens in the programmer's head, not in the language. >So to say that modularization is not available in FORTH is a misstatement. Yes, you've got me there. I'm sorry, but that wasn't really the intent of what I was saying. Clearly modularisation is possible in all languages (even down to the ubiquitous 68000 assembler), the question I was adressing was the support the progrmming language provided for modularisation. Now let me restate my point, Forth has very little support for the programmer's concept of modulariation (with the above proviso) >Further, I remember reading of at least one example of adding MODULA >style modules to FORTH ``in a few simple screens of definitions.'' >(Before you object that this is not part of the standard, keep in mind >that most functional programming languages start out with a very simple >(but powerful) core to which quite a bit of code must be added before >you have an adequate *programming* environment. Sound familiar?) I'm no expert on all the functional languages in extant. Those that I do know of though do need this package of extra stuff. The point though is that this packet of extra stuff is STANDARDISED. It comes with all releases of the language, so everybody has them avaliable, they are not added and rebuilt by every miranda programmer. Moreover many of the things we have been discussing in this group come as part of the language itself (as it should be), things like modularisation and glue, they are not bits stuck on as an afterthought, but are fully integrated into the language. >But even (or especially) *without* MODULA style modules FORTH provides >a good environment for modularization because it allows the problem >to be decomposed in a way that fits the *problem*, not the programming >language. (Of course, some traditional languages are better at allowing >this same kind of decomposition than others.) A program design book >I was reading recently (yes, Fraser, I found a generic one) maintains >that the proper way to decompose a program is to design data structures >in terms of the operations that may be performed on them (including >transformations between data structures). FORTH is excellent for this >kind of decomposition, better than any traditional language I know. >(C++ and SmallTalk may be as good; I don't know them.) Come on David. If you're going to make statments like this it would be helpful if you could give your reasons for believing so. I cannot even imagine why you believe this because I see no way in which forth is better at this sort of this that just about any other language I know (in fact I can see no way in which forth is not worse at this sort of thing than just about any language I know, my justification? Hidden parameter lists - thus it is dificult to see the data flowing, lack of type checking thus loosing all the benifits of having the compiler check out you are using data properly.) You reminded me that I had promised someone to post the name of a good generic program design book, I forgot who it was so I'll post it here, I would recomend - "Software Enginerring - A Practitioner's Approach" by Roger PressMan (McGraw-Hill 2nd Ed) You go on to discuss some of the things I said were avaliable in Functional languages but not in Forth. I've missed out the things we agree on to a large extent. > Higher order functions: are functions that operate on other > functions as data. FORTH can do this in several ways, since a > function can be represented by its address. Agreed, this is not > as elegant in practice as true functional programming, As I said above, you can also do this with 68000 assembler, the improtant thing is the notational convenience. In functional languages (the ones I know that is) the higher ordered-ness is not stated explicitly, but implied from the context. I'm not convinced this is good because there are a lot of errors that could result from this (most of which will be picked up by the type system), I don't know if I would prefer a seperate notation for partially applied functions The big win in functional languages (fl from now on) is that they provide this sort of facility with type checking. > FORTH glue bad because it is untyped: Since when have functional > program glues been typed? I didn't think that type checking was > part of the fundamental design. All the fl that I know have type checking as one of their central features. I've only seen Bakus' FP from afar, and what I saw, I don;t want to see any more. I'm interested in the new functional languages that are being designed now, and have been in the near past. And in answer to your implied question, yes this type checking is done at compile time (or pre-run time in the Miranda we have, which is interp) > Complex data structures: FORTH can pass data structures of > arbitrary complexity; this is one of its strengths. Any data > structure is represented by the address of its root. Again you can do this in assembler, notation is the important thing. There is no standard forth notation for records (that I know of anyway). > Explicitness: Functional programs may be explicit about what > functions are getting what arguments, but you still have to > visualize the actual data being handed around to *really* see what > is going on. If I see f(g(h(z))) I have to visualize the result As I've said earlier I would be in favour of a pipeline notation as an alternative to function composition. That is ... h (h-list) | g (g-list) | f(f-list) is equivilent to f(g(h(h-list),g-list)f-list) > Type security: Again, how does functional programming provide > type security? (That's not a challenge, that's an honest > question.) See above. FLs are the most type secure langusges I've ever used. > FORTH as a functional programming language: As I understand it, > the basic characteristic of a functional programming language > is that a function always has the same result when given the > same input values, regardless of the state of its environment. > Many many FORTH words have this characteristic. A number do not, > and many of these are critical to the functioning of the FORTH > system. It is this latter that makes FORTH appear so un-functional. > Good FORTH programs minimize and restrict these state-changing words. > Consider how few variables good FORTH programs have relative to > traditional programs and FORTH may start to seem more functional. If your saying that people should write in a functional style then great, I agree. All I'm saying is that your programming language should to as large an extent as is possible back up your programming style. FLs back up a functional style, forth in my opinion backs up a very low level style (by the falure of the language to abstract away from implementation details) I can't justify this without a few years of research, so I'll have to leave it as a gut reaction, that I'm sure you'll all agree with :^) >FORTH programs can be made more functional by reducing non-local variable >use. Higher order functions and lazy evaluation of some functions can >be introduced if sufficiently desirable. (I'll have to think about >that some.) FORTH runs efficiently on current hardware. Until >functional programming languages come of age, I'll stick to FORTH. >(But I'll try to investigate Miranda.) Yes, this is all true. You can make any program more functional by applying these rules, regardless of their programming language. Functional programming is educational in that it challenges you to program in other languages in a better manner. I agree with you that FLs are too slow for all practical intents just now (and I don't and wouldn't use one for my work). It is possible to put many functional features into languages that can be used practically. Now if forth had a pre-processor ... (Yawn, YAWN, Yawwwww zzzZZZZZ ! :^) >-- R. David Murray (DAVID@PENNDRLS.BITNET, DAVID@PENNDRLS.UPENN.EDU) You other forthers might think this is an inappropriate discussion for this group, but for the reasons outlines above I think it is benificial since by looking at the strengths and weaknesses of other langauges (and I freely accept that Miranda has both strengths and weaknesses) we all might learn something that we can take back and apply to our own style of programming. I would recomend that everybody learned at least simple functional programming, and I certify that you will be a much better programmer for it. Regards, ===Fraser
oster@dewey.soe.berkeley.edu (David Phillip Oster) (09/15/88)
We've been talking about "very high level languages", and "functional programming languages" and "languages with linguistic support for modularity". I prefer to lump them all together as "languages inspiring superior programming." Many forth programmers have never seen a "language inspiring superior programming" better than Pascal, C, or Fortran. I'm going to be using the phrase "language inspiring superior programming" a lot in this article, so I'm just going to abbreviate it LISP from here on out. In LISP, every data object (the equivalent of a Forth address) is tagged with a type. Operations such as "+" check the tag type of their operands and do the appropriate thing without any human intervention. In Pascal, You get error messages if you apply an operator to inappropriate types. In Forth you just get garbage results. In LISP the language will do the operation if it can. If it can't you'll get an error. (An error is a special kind of object, with special flow control properties, similar to resetting the return stack, except in LISP you can specify that certain clean-up operations, such as closing open files, will happen automatically if anybody, even the operating system, generates an error during the program.) In LISP you can add new data types and have them automatically take advantage of all the existing capabilities. For example, suppose you define a new kind of number, say complex number, and you want to use the convenient notation of (a + b) * c where "a" might be a floating point number, "b" an integer, and "c" a complex. In Pascal you can't use "+" to add complex numbers. You can write your own function to add complex numbers, but you loose access to the outer interpreter of Pascal's knowledge that most human beings mean "a b + c *" when they write "(a + b) * c". In Forth, you can, but you have to use a special version of "+" that lives in a different vocabulary from the integer "+" and you must explictly tell Forth to switch vocabularies. Since forth does not automatically keep track of the types of operands and automatically insert type coercion operators, you'd have to write something like: A @ FLOATVOC B @ INT->FLOAT + FLOAT->COMPLEX COMPLEXVOC C @ * much more cumbersome and error prone. (Note that I have to explicitly switch vocabularies to get floating "@", and again to get complex "@". If you don't have special hardware to do the tag analysis, doing the tag will slow the system down. Therefore many very high level languages have a compiler (the equivalent of the Forth outer interpreter) that, tries to determine the types of the operand. If it can it produces threaded code that directly performs the reuired operation, so it does the tag analysis in zero time. For example, if you multiply "65536 * 65536 * 65536" you'll get the wrong answer in Forth or Pascal, because that expression requires a 48 bit integer, and neither language supports the automatic overflow of integer arithmetic into variable sized big numbers, each as big as it needs to be. Better LISP systems do this. On the otherhand, if you are using the "i" of a "FOR" loop, and you write "i * i", the compiler can deduce, based on the upper bound of the for loop, that that expression will never overflow a 16-bit integer, and generate simple, fast code to evaluate it. Pascal is type strict: the compiler must be able to tell, strictly from by your inclusion of extra type declarations, the type assignment of every object in every expression. You can't extend the domain of the built in operators like "+" to handle new types. LISP is type safe: if the compiler doesn't know the types, they'll have to be checked at run time. You can extend the domain of the built in operators like "+" to handle new types. You can set up the system to detect and do something reasonable on overflow. Often type checks can be made at compile time, so the run time cost is zero. Forh is chaotic: if the programmer accidently applies an operator to inappropriate arguments, he is screwed. He has to find it himself, the compiler and the run-time system aren't going to tell him. --- David Phillip Oster --When you asked me to live in sin with you Arpa: oster@dewey.soe.berkeley.edu --I didn't know you meant sloth. Uucp: {uwvax,decvax,ihnp4}!ucbvax!oster%dewey.soe.berkeley.edu
jax@well.UUCP (Jack J. Woehr) (09/16/88)
in article 2,347,968 orr@cowdor writes: >blah blah blah, etc. No, really, Fraser, your postings are very interesting, but not enough so that I am going to burden the net by quoting them too often! :-) Type checking? Forth does it. It is type STACK or it doesn't exist! Really, what ever happened to the concept of MLL's? Why does everyone try to prove that Forth is a lousy HLL? C is a lousy delcarative language for that matter. Prolog is a lousy procedural language. Forth is MLL for them what need an environment that allows them to roll their own, to Go Where No Man Has Gone Before. ************* jax@well Orr, Orr ... where have I heard that before? jax@chariot Warnier Orr diagrams? Any relation? JAX on GEnie
ritchie@hpldola.HP.COM (Dave Ritchie) (09/18/88)
> >For example, if you multiply "65536 * 65536 * 65536" you'll get the wrong >answer in Forth or Pascal, because that expression requires a 48 bit integer, >and neither language supports the automatic overflow of integer arithmetic > I don't think so. try 51 bits + sign if in signed representation. Dave
ritchie@hpldola.HP.COM (Dave Ritchie) (09/19/88)
>/ hpldola:comp.lang.forth / ritchie@hpldola.HP.COM (Dave Ritchie) / 11:30 pm Sep 17, 1988 / >> >>For example, if you multiply "65536 * 65536 * 65536" you'll get the wrong >>answer in Forth or Pascal, because that expression requires a 48 bit integer, >>and neither language supports the automatic overflow of integer arithmetic >> > > I don't think so. try 51 bits + sign if in signed representation. > Dave Jeez, I shouldn't respond to notes late at night.... 49 bits (an 1 bit followed by 48 zero bits) + sign. Dave
orr@cs.glasgow.ac.uk (Fraser Orr) (09/21/88)
In article <7122@well.UUCP> jax@well.UUCP (Jack J. Woehr) writes: > Really, what ever happened to the concept of MLL's? Why does >everyone try to prove that Forth is a lousy HLL? C is a lousy delcarative >language for that matter. Prolog is a lousy procedural language. > There are two possibilities for what MLL stands for: Medium level language; Machine level language. The latter I agree is a fair catagorisation of forth. In fact that is what I've been saying all along. To say though that this is a great thing is not very sensible. It is clear that the purpose of a programming language is to make the machine easier to use without loosing any machine function (which can most certainly be done in practice) I agree that forth is a more powerful assembler than most, but it is still an assembler. I don't want to use this assembler any more than any other, (although I might like to use a compiler that had the advantage of producing this more powerful machine model.) Regards, ===Fraser
scowl@psu-cs.UUCP (Scott W. Larson) (09/24/88)
In article <1643@crete.cs.glasgow.ac.uk> orr@cs.glasgow.ac.uk (Fraser Orr) writes: >I agree that forth is a more powerful assembler than most, but it is still >an assembler. I don't want to use this assembler any more than any other, >(although I might like to use a compiler that had the advantage of producing >this more powerful machine model.) I'd like to see some justification for this comment! Why do you consider Forth to be just an assembler? Do you consider it to be an assembler because it is flexible, extensible, and easy to understand while compilers are rigid, complex, powerful monsters that produce highly complex code from complex high-level code? While Forth might be on the very lowest end of high-level lan- guages, writing Forth is far closer to writing in Pascal than writing 68000 assembler code! I suspect you're confusing the two because people who write in Forth, like those who write assembly code, don't view the compiler (or assembler) nor the compiled (assembled) code as hopelessly complex and mysterious.
olorin@juniper.uucp (David Weinstein) (09/25/88)
In article <1643@crete.cs.glasgow.ac.uk> orr@cs.glasgow.ac.uk (Fraser Orr) writes: >There are two possibilities for what MLL stands for: Medium level language; >Machine level language. The latter I agree is a fair catagorisation of forth. >In fact that is what I've been saying all along. To say though that this is >a great thing is not very sensible. It is clear that the purpose of a >programming language is to make the machine easier to use without loosing >any machine function (which can most certainly be done in practice) No. Or I'll make it a challenge. Pick a high-level language, and a common CPU for which there are programmers working in assembly regularly. Now, chose a problem. While the HLL programmer may finish first, a good assembly language programmer will produce *much* more efficient code. Furthermore, conventional languages can't work in many areas (do you want to explain why you need 4 more inches of space on the board to hold all the libraries your compiler linked in along the way... :-) The attitude, "If the program written in an HLL isn't fast enough then my compiler isn't good enough, and if my compiler is good enough but it's still too slow I'll buy a new machine", (which is a paraphrasing of a comment I found on comp.lang.misc a week or so ago) is one of the things that disturbs me most about CS departments (or at least the ones I've been in a position to observe). Quite simply...you can't really do that in the real world, with finite resources. Upper management in many cases will find your programming time a more reasonable expense then replacing the computer you just got with a faster one (and compiler revisions are infrequent at best...and remove old bugs simply to replace them with a host of new bugs). I shudder when I think the CS students who *don't* work in the real world while pursuing a degree, and face a dreadful shock when they get out of the ivory tower. -- Dave Weinstein Internet: olorin@walt.cc.utexas.edu UUCP: {ames,utah-cs,uunet}!ut-sally!ut-emx!{walt.cc.utexas.edu,juniper}!olorin GEnie: DHWEINSTEIN
orr@cs.glasgow.ac.uk (Fraser Orr) (09/29/88)
In article <4889@juniper.uucp> olorin@juniper.UUCP (David Weinstein) writes: > >In article <1643@crete.cs.glasgow.ac.uk> orr@cs.glasgow.ac.uk (Fraser Orr) writes: >No. Or I'll make it a challenge. Pick a high-level language, and a common CPU >for which there are programmers working in assembly regularly. Now, chose a >problem. While the HLL programmer may finish first, a good assembly language >programmer will produce *much* more efficient code. Furthermore, conventional >languages can't work in many areas (do you want to explain why you need 4 more >inches of space on the board to hold all the libraries your compiler linked in >along the way... :-) *Much* more efficient? This seems rather a strong statment. Although when programming in MLLs you can problably produce *somewhat* more efficient to say only this is to present a very narrow perspective. Firstly in HLLs you program closer to the problem area, so more thought can go into things like algorithims and program layout. This can in some cases even lead to *much* more efficient HLL programs (because you chose a better algorithim - I seem to remember mentioning this a while ago though). Yes I know that anything you can do in an HLL you can do in an MLL, but in MLL programming (in my experience of it anyway) you usually can't see the wood for the trees. Of course a far more important argument is that generally you can produce HLLs with far fewer bugs (again because your program is closer to the problem domain), and in my humble opinion a program that gives the right answer after an hour, is much better than one that crashes after five minutes. Furthermore a good optimising compiler can produce very good code indeed. Although it can't make some of the problem oriented optimisations that can be made in an MLL (and often also in an HLL) they can make other ones that would be tedious in the extreme for a human to do (an example that immediately springs to mind is efficient register usage.) As to board space, don't blame me if you've got a rotten linker! :^> I guess the problem with the linker is that it was written in an MLL and although it is faster than lightening, it was too dificult to put in features like selective loading... :^> >The attitude, "If the program written in an HLL isn't fast enough then my >compiler isn't good enough, and if my compiler is good enough but it's still >too slow I'll buy a new machine", (which is a paraphrasing of a comment I >found on comp.lang.misc a week or so ago) is one of the things that disturbs >me most about CS departments (or at least the ones I've been in a position to >observe). Quite simply...you can't really do that in the real world, with Hmmh, you've got a point. I take the acedemic view you outline above (surprise, surprise!) and I think that this is a reasonable veiw for an academic to take, since academic's job is to look to the future (when there most certainly will be bigger faster and better computers about.) But I accept that this cannot be the veiw taken in the "real" world. If you remember earlier I was saying that my favorite language was Miranda, but that I didn't use it in my job, because it was too slow. (That of course doesn't mean that Miranda is no good, because there will come a time when the computers are big and powerful enough to run Miranda) >observe). Quite simply...you can't really do that in the real world, with >finite resources. Upper management in many cases will find your programming >time a more reasonable expense then replacing the computer you just got with >a faster one (and compiler revisions are infrequent at best...and remove old >bugs simply to replace them with a host of new bugs). I shudder when I think I think that you have a cheek to talk about bugs!:^) You are advocating a style of programmning that produces far more bugs than I have problems with compilers. Compiler bugs I agree are a real pain, but they can be documented and got round. Anyway, what are you suggesting, write your compiler in MLL, and put in even more bugs?:^> >bugs simply to replace them with a host of new bugs). I shudder when I think >the CS students who *don't* work in the real world while pursuing a degree, >and face a dreadful shock when they get out of the ivory tower. Again you have a point, I think that a lot more practical stuff in CS courses would be of great benefit. But also of great benefit is to expose students to "pure" programming techniques so that they know whereabouts they are making compromises for the sake of efficiency. >Dave Weinstein Regards, ===Fraser