See also ProgrammingConceptsNotFoundInLisp
Lisp is a remarkable language, having pioneered putting into practice many immensely useful concepts in programming. These concepts (effective use of lists, dynamic typing, etc.) are well-documented elsewhere. This page is for useful programming concepts whose deployment is not pioneered by Lisp.
It should be noted that the decade of the sixties was the golden age for CS invention (from lisp to unix, including internet, OO, GUI, SQL, functional programming, logic programming, etc). (Almost) everything that came later was only refinements, and integrating speed improvements provided by electronics. Therefore it's not surprising that most concepts come from Lisp or some other language invented during that decade. We could as well make a page ProgrammingConceptsNotInventedInTheSixties.
Useful to what end? SoftwareConceptEtymology?? -- BobBockholt
[Concepts that are useful in programming in general. This page is not an anti-Lisp one, but was an offshoot of discussions in AreLispersTakingOverThisWiki] The very page I came from. I'm not objecting to the page, just curious about the value of assigning the introduction of a concept to a particular language. [Why ask why? I didn't start this page, but I find it an interesting topic. History is worthwhile for its own sake. And it is also useful to understand the origin of things. And as Santayana said, those who do not learn from history are doomed to repeat it. But really, you could ask "why" about any page. Why is there a Pattern Wiki? :-) What's so puzzling about this topic?] Gotcha, agree, NuffSaid, I'm happy now. Thank you. (sincere smile)
RefactoringNote?: I took away all discussion that died without a conclusion. -- PanuKalliokoski
- iterators (CLU 1974-77) (took away talk about terminology; it seems the entry is good as is)
- "GetNext?" has been around a while in various forms.
- DesignByContract (tm) (CLU 1974-77)
- The trademarked phrase "design by contract" came significantly after CLU introduced preconditions and postconditions
- static scope (Algol-60)
- loops (Plankalkül; never implemented)
- arrays and records (Plankalkül; never implemented)
- everything is a dictionary (?) Given discussion below, give URL to support use of term 'dictionary', else choose better word...or is it "everything HAS a dictionary? Refactoring needed in any case
- EverythingIsAnXyz? is not a concept, it's just a different way of saying SingleParadigmLanguage?.
- Not sure what you're referring too; Dictionaries are powerful first class entities in Postscript, but they're not "everything"
- In Lua and Python, every first-class object supports "dismemberment" i.e. you can say (in Python) myfunction.__doc__ etc. Lisp first-class object do not share any common interface.
- In Lua or Python you can only treat dictionaries as dictionaries. Numbers and strings, for example, are not dictionaries.
- Not so. By dictionary I mean anything that supports "dismemberment"; both numbers and strings have (at least in Python) properties and methods, so they're dictionaries too. But maybe this should be called something other than dictionary.
- In LISP you have functions that take values as arguments rather than methods attached to values, but any value can be passed to any function. Many functions work with different, or even all, types of value. A function in LISP that can be applied to all types has the same effect as a methods supported by all Python values. Furthermore, in LISP everything is an s-expr, so LISP also has the idea of a common data structure underlying all data types. LISP takes it even further: in LISP even code is an s-expr and can be manipulated as such, while in Python you can only manipulate properties attached to functions and while the code itself cannot be manipulated.
- Yes, in Lisp there is a unified underlying data model. It is important, however, that that data model is not one of dictionaries, but lists. Dictionaries allow adding more metadata in places where the need of metadata was not anticipated; lists better bend themselves to (relatively) memory-efficient (but pre-designed) representation of miscellaneous structures. Moreover, different Lisp data types do not share a common interface (you first query their type, then decide what to do with the datum); different Python (for instance) data structures do, namely, a list of members.
- But then again, Lisp supports "property lists" (dictionaries) for atoms (at least for identifiers; not sure what the standard says), so that one can in fact attach metadata "in places where the need of metadata was not anticipated". I've often wondered to what extent this should be considered to have been the earliest introduction of OO (and if so, why I haven't heard it claimed). The property list explicitly could and did include what amounts to member functions, e.g. a print function appropriate for that particular thing, so that (loosely, for non-Lispers:) generic-print(item) would translate to call-function(get-property("print-function", item), item), and no matter what kind of thing item is, generic-print() would be able to print it (so long as item supported that protocol by having a "print-function" in its property list, of course).
- implicit parallelism (Fortran?)
- LazyEvaluation (?)
- PatternMatching of types and parameters (ML?)
- Pattern Matching of strings as a control mechanism (Comit and Snobol)
- Classes and Inheritance (Simula-67, then Smalltalk)
- Not true. Classes and inheritance developed out of "frames" which were (are?) ontological networks to model the world in GoodOldFashionedArtificialIntelligence?. These frames, which are really objects and classes, were handled with syntax extensions in - you guessed it, a LISP environment. Smalltalk grew out of developing the "frame" paradigm. (In fact, almost every ProgrammingParadigm except imperative grew out of some kind of research on ArtificialIntelligence.)
- "frame" was coined (in this jargon sense) after Simula-67, you know, so this seems far from clear.
- Operations on first class arrays (APL)
- E.g. (non-APL syntax): (1 2 3 4) * (3 5 7 9) ==> (3 10 21 36)
- Conditionals via boolean vectors (APL)
- What does this mean?
- vector A contains 1 in each index where an operation should be performed on the corresponding index of vector B
- This means that rather than doing a loop that conditionally performed (by checking some predicate) an operation on each item in a vector, instead one could generate an appropriate boolean vector using the predicate, then e.g. take the dot-product of the boolean vector with the value vector, and hand the result to a vector operation that ignored zero/false entries. This can be very elegant, particularly if the boolean vector is reused for multiple ensuing vector operations, and in many cases, can be very efficient by avoiding branches in the generated code, particularly on vector machines, but also even on non-vector CPUs (this is one of the reasons that APL was sometimes preferred over Fortran for raw speed of arithmetic on vectors).
- Algebraic notation for arithmetic (Laning/Zerler and Fortran)
- concurrently executing tasks (PL/I)
- Pointers in a high level language (PL/I)
- What exactly is a "pointer"? Is any reference a "pointer"? If not, what is the distinquishing factor?
- They are the appearance in a high level language of RAM addresses. The word "reference" can mean many things, including lookup of an identifier in a symbol table to find a value; the latter definitely is not a "pointer". References in C++ and in Java are a form of constrained pointer.
- array cross sections (PL/I)
- High Level Language Macros (DougMcIlroy 1950s and in SAP 1960, unconfirmed claims in COBOL-60 that I don't believe but cannot yet refute...anyone know where the COBOL-60 standard is available online?)
- It's unclear that even assembler text macros, as they are modernly understood, existed prior to DougMcIlroy's work, although there are plenty of unconfirmed rumors about such assemblers. A lot of what people call early 1950s "macros" appear to be unconstrained text rewriting rather than expansion of an identifier.
- Lisp probably pioneered "semantic" macros (as opposed to text macros), but they did not exist in the early 1960s Lisp 1.5
- Separate compilation units (Fortran IV, 1962)
- CoRoutines (M.E. Conway in in assembly in 1958, Simula I, Simula67, etc)
- case ("switch") statement (invented by CarHoare, appeared in Algol-W 1965, later in Pascal)
- Um, (cond)
- That's an interesting point. But the Pascal invention was for the kind of case/switch where overlapping/duplicated ranges are caught by the compiler, and the ordering of clauses doesn't make a difference, and also that can be implemented as a jump table, which has been historically important compared with syntactic forms that must be implemented in machine code equivalent to if/else if/else if/else if.
- passing parameters by value-result (1965 Algol-W, later in Pascal)
- Programming as operations on relations (SQL)
- include files (BCPL)
- AugmentedAssignment?: += -= *= /= etc. (Algol-68)
- high level language as an effective systems programming language (Bliss and C)
- See HighLevelLanguage
- This seems odd today, but in general people used to be firmly convinced that only assembler was really appropriate for systems programming, even in principle.
- ListComprehensions (Haskell i believe?) (even if they are just syntactic sugar over filter/map/etc, they're damn nice syntactic sugar...)
- AbstractDataTypes as such, in pure form (CLU)
Please add others if you know what you're talking about. You can also
add discussion of where these actually are pioneered (if anywhere at all),
and whether these are
useful programming concepts.
How about ProgrammingConceptsNotFoundInLisp and ProgrammingConceptsPioneeredByLisp
CategoryLisp