steven@boring.UUCP (02/25/86)
(I am speaking as someone who has taught introductory programming with several different languages, including Pascal, and who is now involved in a project designing a new programming language for 'non-professional' programmers (which includes students)). In my view, an introductory programming course should teach as much as possible about algorithms and programming, and as little as possible about the nuts and bolts of programming languages. The programming language used should therefore support this as much as possible by allowing algorithms to be expressed as closely as possible to their formulation, without the language imposing itself too much. Furthermore, the language should help the student and teacher as much as possible, by reducing the need for the student to ask about trivial matters (a better syntax for Pascal or C for instance would reduce problems with semi-colons). Strong typing for example is a boon to teachers (I believe) because many problems are picked out far earlier and can be solved by the student without reference to the teacher. So, an introductory language should have several basic properties: - It should be simple So that as little time as possible is spent teaching the language, and as much as possible on teaching programming. - It should have a simple syntax For the same reasons. An editor that flags syntax errors as you type them in would be a great time saver and educational tool too. - It should be high level To take the emphasis away from the machine, and put it on the algorithms - It should be structured For expressing algorithms - It should have strong typing and other static checks, to detect errors earlier, and speed up development time. An interactive system is also far more helpful than a batch one. A language that satisfies these requirements is B (the new one, NOT the predecessor to C): it is simple (only 2 basic types, and 3 structured ones), has a simple syntax (without semicolons) with an editor that does a lot of the syntax work for you (no missing brackets for instance), it is high level and structured, has strong typing (without declarations: it checks that all uses are consistent), and it is interactive. As an example of what I mean, consider what would be necessary to teach in Pascal or C in order to be able to teach about garbage collection, and how long a program simulating it would be, and how long it would take a student to write. Here is a program in B to do it. B has numbers and texts (=strings) and (sorted) lists. So {1; 4; 9; 16; 25} is a list of numbers, and {"cow"; "goat"; "dog"} a list of texts. Tables are a generalisation of arrays: the indexes and elements may be of *any* type, so: PUT {} IN graph initialises the variable 'graph' with an empty table PUT {1; 45; 61} IN graph[2] PUT {8; 27; 96; 125} IN graph[61] adds two elements to the table. Lists can be updated: INSERT 42 IN graph[2] REMOVE 61 FROM graph[2] WRITE graph[2] {1; 42; 45} The keys (=indexes) of a table can be got as a list: WRITE keys graph {2; 61} So here is the garbage collection program. The store is a graph, represented by a table where each index represents the 'address' of a data-object, and the element associate with that index is a list of addresses that that data-object references. The program is a function that takes such a graph, and a root node, and returns the graph with all nodes not reachable from the root deleted. It works by first collecting the addresses of all nodes reachable, and then deleting those not in that list. YIELD graph accessible'from root: MARK SWEEP RETURN graph MARK: PUT {root}, {root} IN accessible, to'do WHILE to'do > {}: SELECT'NODE TREAT'NODE SELECT'NODE: PUT min to'do IN node REMOVE node FROM to'do TREAT'NODE: FOR sub'node IN graph[node] IF sub'node not'in accessible: INSERT sub'node IN accessible INSERT sub'node IN to'do SWEEP: FOR node in keys graph: IF node not'in accessible: DELETE graph[node] B is actually in use in a couple of schools in the Netherlands, with some others planning it. The major problems are that the implementations are not really fast enough for large groups of students on one machine (though the Dutch schools are doing this; on personal computers it is fast enough for education), and there are not (yet) any introductory text-books. Steven Pemberton, CWI, Amsterdam; steven@mcvax
mangoe@umcp-cs.UUCP (Charley Wingate) (02/26/86)
A number of years ago we had a nice little language here at MAryland called SIMPL-T, which was used in the second programming course. The first course was in Fortran because it was thought that people needed to know it and nobody wanted to teach it in an upper-level course. This first course was very basic. The second course, however, taught this SIMPL-T language. Now this language was much like Algol-60 except radically streamlined; there were integer and string types, there were arrays, there was a single character type (which was rarely used), there was recursion, and there were simple files. Parameters could be passed by value or reference, and there was a Fortran interface when one needed. THere were no semicolons, and no "Begin-end" blocks (the conditionals and loops were like those in FTN-77); there was also no goto construct. The language was sufficiently advanced so that one could write a working compiler in it. This language sufficed to teach structured programming and basic techniques (e.g., linked lists and recursion). Most of us who used the language basicaly enjoyed it. The primary argument against its use was that nobody used it but Maryland. I've never really been convinced by this argument, because it has always seemed to me that language syntax shouldn't be that big a thing as far as educational goals are concerned. Eventually, Pascal was brought in. This had the effect of making programs more difficult to debug, because under the old system, people were introduced to BNF and Algol-60 before they had to deal with the likes of Pascal and PL/1. It also encouraged much more complicated programs, a situation which was exacerbated by the massive increase in students within the department. Eventually, Harlan Mills and the "Gang of seven" struck with a totally new system. This had the following features: * Essentially no Fortran (actually, 2 weeks at the end of the second course) * Use of CF-Pascal (to be described) * Program verification through Mills's "Program Calculus" * Spreading both the teaching of pascal and the verification over two courses * splitting techniques off into a third course The language CF-pascal is important to note. It consists of Pascal stripped of everything but characters, text files, and function calls. Needless to say, it is very difficult to do almost anything in this language. Does this new system work? Well, it's not really clear to me. I was a teaching assistant for these courses a few years back, and certainly all but the very brightest students had a lot of trouble-- not that we didn't want to weed people out very aggresively. The course has changed quite a bit since then though; in particular, the text has been revised massively. I would not want to attempt to give an opinion on it as it currently exists. I do have some comments about the efficacy of Pascal as a teaching language (which, we should all remember, was its orginal intent). My experience is that for people who haven't programmed, the syntax is too troublesome. Without BNF it is difficult to account for where semicolons go. The bug in relational-boolean precedence is also a problem. THe handling of text files is problematic. An ideal procedural teaching language would avoid: * Begin-end blocks * statement delimiters * complicated output formatting It would have: * a string type * recursion * parameter passing by value and reference * strong typing * lots of run-time (and even development-time) support SIMPL-T (and, judging from Mr. Pemberton's presentation, B) has these. No subset of any Algol-like language does. Oddly enough, the next generation Fortran will have most of these. These of course are my own opinions, and do not represent the opinions of the U. of Md. Computer Science Department or any of its personnel other than myself. C. Wingate
hsu@eneevax.UUCP (Dave Hsu) (02/26/86)
In article <3362@umcp-cs.UUCP> mangoe@umcp-cs.UUCP (Charley Wingate) writes: >... >I do have some comments about the efficacy of Pascal as a teaching language >(which, we should all remember, was its orginal intent). My experience is >that for people who haven't programmed, the syntax is too troublesome. >Without BNF it is difficult to account for where semicolons go. The bug in >relational-boolean precedence is also a problem. THe handling of text files >is problematic. > >An ideal procedural teaching language would avoid: > >* Begin-end blocks >* statement delimiters >* complicated output formatting > >It would have: > >* a string type >* recursion >* parameter passing by value and reference >* strong typing >* lots of run-time (and even development-time) support > To Charley's list I would add: It should avoid: * `FORWARD'-type statements to allow forward referencing * Variable length statements; i.e. CASE and IF statement default clauses should be mandatory (re semicolon problem) * Complicated EOF and EOLN mechanisms; I still don't see why EOLN should not be valid at EOF It should include: * Completely generic assignment; record A = record B without the subfield stuff * Some sort of improved pointer debugging > >These of course are my own opinions, and do not represent the opinions of >the U. of Md. Computer Science Department or any of its personnel other than >myself. > >C. Wingate ditto disclaimer, -dave -- David Hsu Communication & Signal Processing Lab, EE Department <disclaimer> University of Maryland, College Park, MD 20742 hsu@eneevax.umd.edu {seismo,allegra}!umcp-cs!eneevax!hsu "Godzilla has been spotted in Sector 5!"
jimc@ucla-cs.UUCP (02/28/86)
In article <6796@boring.UUCP> steven@mcvax.UUCP (Steven Pemberton) writes: >In my view, an introductory programming course should teach as much as >possible about algorithms and programming, and as little as possible about >the nuts and bolts of programming languages. The programming language used >should therefore support this as much as possible by allowing algorithms to >be expressed as closely as possible to their formulation, without the >language imposing itself too much. > I certainly agree. A family member learning programming started out going through chapter 1 of Kernighan and Ritchie, and learned a lot, but started getting bogged down when algorithm design started to dominate the programming task. She started an intro to DP class, in which was assigned "Karel the Robot" by (sorry, book not at hand). It turned out to be a VERY effective introduction to structured programming and algorithm design, with all the messes of math, data types, etc.etc. stripped away. The idea is, there's this programmable robot which can move, pick up objects, iterate... An emulator for the robot is available, sort of as shareware i.e. not free (see the book for address). But it's quite practical to emulate the robot by hand. -- James F. Carter (213) 206-1306 UCLA-SEASnet; 2567 Boelter Hall; 405 Hilgard Ave.; Los Angeles, CA 90024 UUCP:...!{ihnp4,ucbvax,{hao!cepu}}!ucla-cs!jimc ARPA:jimc@locus.UCLA.EDU
mendell@utai.UUCP (Mark Mendell) (03/01/86)
If you are looking for a teaching language to replace Pascal, I recommmend that you look at the Turing language that was developed here at the University of Toronto. Turing currently runs on VAXen and SUNs under UNIX, IBM 370s under CMS, and 808[68] under MS-DOS. "TURING is a super Pascal (it provides the features of Pascal plus modules, dynamic arrays, varying length strings, etc) with a no frills syntax (no semicolons, no program header, etc) and with an airtight formal definition (program execution is completely determined by the TURING language specification)." There is a book "An Introduction to Computer Programming Using the TURING Programming Language" by R.C. Holt and J.N.P. Hume (available from Reston Publishing, a Prentice-Hall company). A Turing program is completely checked. Uninitialized variables, subrange variables out of range, dangling pointers, etc are all detected. The "Turing Language Report" is a technical report that is available through CSRI, that describes the full languge. For more detail, contact: Distribution Manager Computer Systems Research Institute University of Toronto Sanford Fleming Bldg. Rm 2102 10 King's College Road Toronto, Ontario M5S 1A4 {ihnp4, utzoo, decvax, uw-beaver}!utcsri!distrib -- Mark Mendell Computer Systems Research Institute University of Toronto Usenet: {linus, ihnp4, allegra, decvax, floyd}!utcsri!mendell CSNET: mendell@Toronto ARPA: mendell%Toronto@CSNet-Relay
rfm@frog.UUCP (Bob Mabee, Software) (03/07/86)
In article <6796@boring.UUCP> steven@mcvax.UUCP (Steven Pemberton) writes: >In my view, an introductory programming course should teach as much as >possible about algorithms and programming, and as little as possible about >the nuts and bolts of programming languages. The programming language used >should therefore support this as much as possible by allowing algorithms to >be expressed as closely as possible to their formulation, without the >language imposing itself too much. For several years starting around 1966, MIT's second programming course (FORTRAN was the first, as elsewhere) used a language called PAL, designed by Jack Wozencraft and Art Evans. Some of its syntax resembled BCPL, because its compiler was the first application program written after Martin Richards brought up the first BCPL compiler. An earlier version (ancestor?) of PAL was implemented in LISP, and that influenced its model of data. PAL had no distinction between statements and expressions, or between functions and subroutines. Everything resulted in a value. ';' was used only to cause the result of one expression to be discarded before evaluating the next, and parentheses did the job of BEGIN-END. The resulting simple syntax made learning PAL much easier. PAL used a LISP-like garbage collector, so all data types could be freely passed around. Types applied to values rather than to names, so declarations did not exist (eliminating another batch of arbitrary syntax). Operators were not heavily overloaded so wrong-type errors didn't propagate too far. There were strings of characters with a limited set of operators, and n-tuples (arrays of arbitrary objects). n-tuples were not quite like LISP lists because they carried the implication of easy access to every element but difficult creation of all-but-the-first. On the other hand, they were much easier to grasp for people who had just mastered (?) FORTRAN. There were assignment and goto expressions, but they were not brought up until later in the course. PAL was very useful in a completely applicative subset, and that helped to teach us to think of the recursive solutions to a problem before automatically reaching for the iterative version. Assignment exposed the problem of sharing: two names (or tuple elements) might or might not share, such that an assignment to one alters the value of the other. Function parameters shared with the actual argument, so you got call-by-reference effects. I think this is desirable but is also a hump that stops some students. PAL had a wealth of name-defining syntactic forms, so that scope/extent could model all the other languages' rules. (One of the stated goals of the course was to give the student a basis for quickly grasping the ideas behind other languages, so PAL generally had to be a superset.) It also exposed the LAMBDA operator directly, so you could create a function with no name (and correct lexical binding, unlike most LISPs). In fact, every part of PAL was just a syntactic sugaring on top of Church's LAMBDA calculus. The early part of the course concentrated on that calculus and a blackboard evaluation scheme. This groundwork proved invaluable when we were taught that goto could jump to a label in a function that had already returned -- instead of feeling lost, we felt we completely understood how a label object could keep a copy of the CSED state from the time it (the label) was evaluated. The main idea I would add to PAL before using it for teaching is information hiding. PAL had no model for packages, object-oriented programming, or operator overloading. Any object that one function can create any other function can look inside of. Here is Steve's garbage collection example rewritten in iterative PAL. I kept his order of definition although it seems harder to follow that way. def // Define accessible_from with global scope. accessible_from (graph, root) = ( MARK nil; // Function call needs arg, doesn't need (). SWEEP nil; graph ) where // Define MARK only within accessible_from. MARK nil = ( let accessible, to_do = make_set (root), make_set (root) in ( while to_do ^= nil // Maybe ^= should be ne ? TREAT_NODE (SELECT_NODE nil); ) // This ) defines where where defines. (!) where SELECT_NODE nil = ( let nodename = head_set to_do; to_do := tail_set to_do; // Assumes tail is efficient. nodename ) and // Define TREAT with same scope as SELECT. TREAT_NODE nodename = ( let node = lookup (graph, nodename) // Find named object. in for i = 1 to Order node do if node i %not_in accessible // % makes infixed. ( add_set (accessible, node i); add_set (to_do, node i) ) ) ) and // Define SWEEP with same scope as MARK. SWEEP nil = ( let ktuple = keys graph in for i = 1 to Order ktuple do if ktuple i %not_in accessible // a %b c means b (a, c). then DELETE (graph, ktuple i) ) B provides an extremely powerful facility for 'keyed' sets, which simplifies this example by pruning away many details of implementation. Otherwise, is it an advantage in a teaching language? Or a liability, since it may befuddle? This is my recursive implementation of those set operations needed above (using n-tuples linked through first element): def make_set name = (nil, name) and add_set (set, name) = (set := $set, name) // $ unshares, avoids circular list and head_set set = set 2 and tail_set set = set 1 and not_in (name, set) = Null set ? TRUE | name = head_set set ? FALSE | not_in (name, tail_set set) def lookup (graph, name) = name = graph 2 ? graph 3 | lookup (graph 1, name) and DELETE (graph, name) = name = graph 2 ? (graph := graph 1) | DELETE (graph 1, name) and keys graph = Null graph ? nil | keys (graph 1) aug graph 2
fgtbell@kcl-cs.UUCP (ZNAC450) (03/08/86)
In article <9490@ucla-cs.ARPA> jimc@ucla-cs.UUCP (Jim Carter) writes: >getting bogged down when algorithm design started to dominate the programming >task. She started an intro to DP class, in which was assigned "Karel the >Robot" by (sorry, book not at hand). It turned out to be a VERY effective >introduction to structured programming and algorithm design, with all the >messes of math, data types, etc.etc. stripped away. The idea is, there's this >programmable robot which can move, pick up objects, iterate... An emulator >for the robot is available, sort of as shareware i.e. not free (see the book >for address). But it's quite practical to emulate the robot by hand. Something like that is done here in a specially-invented design language called Engol. Programs control the movement of a turtle which knows about iteration as well as primitive functions like pen-up , move(),turn(). The outputs produced are rewarding as they are graphical,not masses of figures,and the language also encourages top-down structured programming; at any point,one can push detail down to a lower level to be defined later. This is done by an everyday English sentence,eg draw a side-- The language is converted into Algol 68 by a preprocessor,but that's not the point.The point is that THIS is how you teach students about programming, not by confusing them with real,char and int,though I admit these have to be taught at some stage.