GreenSpunning is the ''ad hoc'' implementation of domain-independent language features in a language which lacks the feature; it can range from a simple one-line function or macro to the canonical description of GreenSpunning: a "half-assed implementation of half of CommonLisp''. There are several levels of GreenSpunning to consider; some may object to calling these GreenSpunning. Note: It is assumed that the emulated feature may come from any language; not just Lisp. Greenspunning typically does not refer to third-party libraries which are not part of the definition of a particular language, but which are widely available, of high quality, and generally considered part of the programmer's toolkit. Instead, the term should be reserved for instances of ReinventingTheWheel. '''Level 0: The Features Are Already There''' No work needs to be done apart from using them. '''Level 1: By Convention''' A feature is "implemented" by some convention on how to use another feature; for example, imitating Java interfaces in C++ by use of classes which contain nothing but PureVirtual methods. Many DesignPatterns are actually instances of Level 1 GreenSpunning. See AreDesignPatternsMissingLanguageFeatures. '''Level 2: One-liners''' A language feature is trivially implemented on top of another language feature, by use of a simple class, function, or macro, often containing just one or a few lines of code. '''Level 3: As a Library''' The language feature is implemented as non-trivial library of functions, classes, macros, etc., with the restriction that the implementation is portable. Often times, such libraries get added to the language definition, in which case claims of GreenSpunning may then vanish, if done well. The majority of such libraries are, however, ''ad hoc'' and half-assed. Many home-brew collection class libraries are of this sort. (See IhadToWriteMyOwnLinkedList.) '''Level 4: Dirty tricks''' Similar to the above case, but UndefinedBehavior is invoked in order to implement the feature. All GarbageCollection libraries for C/C++ are in this category -- for them to function properly they need incestuous knowledge of the compiled code and the target platform. Porting such a library to a new target often involves more effort than a recompile. Use of PointerCastPolymorphism to implement OO in CeeLanguage is another popular example, although the dirtiness is from the need for programmer discipline rather than from UndefinedBehavior in that case. '''Level 5: MetaProgramming''' Some external tool is used to generate code in the target language from a specification in some augmented form, or a higher-level language. This is ''not'' GreenSpunning when done as a clean DomainSpecificLanguage; GreenSpunning refers to the domain-independent case done in an ''ad hoc'' manner. A classic example would be a homebrew system for RemoteProcedureCall that worked in the same manner -- taking an interface definition file and spitting out stubs/skeletons in the target language. (Again, use of industry-standard tools like CORBA or "real" RPC is not Greenspunning). Another example: implementing LispLanguage in CeePlusPlus TemplateMetaprogramming. ''The TestCollector pattern in C++ sometimes has this problem. To automatically collect all cases into suites, some test rigs use an external script to harvest them and write a C++ suite.'' '''Level 6: The Intepreter / Framework''' The limiting case of Greenspunning: an interpreter for the high-level language (or an extended language containing the desired feature) is written in the low-level language, which then executes code in the high-level language at runtime. Again, when done as a clean coherent design, not really GreenSpunning; otherwise it's just AlternateHardAndSoftLayers -- but most developed as mission-critical private tools are unfortunately ''ad hoc''. Numerous scripting languages such as ToolCommandLanguage and LuaLanguage are often used in this manner. ---------------------- I like these levels, but I object to all those special exceptions. AlternateHardAndSoftLayers is something you do because at least one of your languages is insufficient (not secure enough, not flexible enough) for both. Using an external tool rather than a library for the DomainSpecificLanguage elements suggests your language isn't as flexible as it could be. ---------------------- See: PhilipGreenspun, GreenspunsTenthRuleOfProgramming, FourLevelsOfFeature