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
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
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.