Compile Time Resolution

compile-time resolution is the process by which any compiler and/or linker collects values, functions, and objects and resolves a wide variety of dependencies and, most importantly, does so at most once per CompileTime - generally at CompileTime, though some forms of 'lazy' execution would still fit the spirit of the word as it is used here.

Most programming-languages in popular use today that have a CompileTime perform any CompileTimeResolution outside of the language-proper and do so instead via tools in the programming-language environment - most often the 'linker'. (That said, newer languages are often adding CompileTimeResolution as a feature; I have seen several examples of such code on this WikiWiki. And compiled Lisp, as usual, probably already had it in some obscure and difficult-to-reach location involving macro-applications.)

Explicit language support for CompileTimeResolution allows programmers to perform necessary communications to collect arbitrary remote values or objects for direct inclusion to the compiled unit. It works especially well in combination with FirstClassTypes and arbitrary degrees of PartialEvaluation, allowing a much wider variety of MetaProgramming than is possible if any one of these components is missing. If a language lacks explicit support for CompileTimeResolution, about the only possible approach to perform it is to use third-party CodeGeneration tools (and thereby reinvent it... badly). The common alternative to reinventing it badly is to simply give up on certain levels of optimization and security and always attempt to handle the most generic case and pay any communications costs at runtime (every time). Between these alternatives, CompileTimeResolution is among the KeyLanguageFeatures and programmers accustomed to working without it may be subject to the BlubParadox.

A few prototypical examples of CompileTimeResolution would be grabbing JPEG logos to embed directly into an array (to avoid need to open a file at runtime), asking the OperatingSystem for its list of filesystems or printers and compiling in dedicated code, grabbing a relational schema or XML schema in order to automatically construct the parser and interaction code, and reading SQL or other text code from external files not written in the programming language for compile-time parsing (via PartialEvaluation) and construction into useful procedures. CORBA, WSDL, the list goes on - just about anything CodeGeneration is used for can be done by a combination of CompileTimeResolution, FirstClassTypes, PartialEvaluation, and perhaps a little syntax extension (for which dedicated mechanisms are beyond the scope of this page).


Things to consider for Language Support of CompileTimeResolution

A language might be said to support FirstClass CompileTimeResolution if it essentially bootstraps - i.e. there is no need for a Makefile or external linker; all 'linking' is performed via CompileTimeResolution within the language. This, in the general case, requires cyclic dependency resolution to be handled intelligently. This is similar to having a MetaCircularEvaluator, and should be considered necessary for SymmetryOfLanguage (at least when dealing with languages that support CompileTimeResolution). It offers several very neat forms of language flexibility. Trivially, languages that don't support modules and do support CompileTimeResolution automatically possess this.

'Lazy' CompileTimeResolution is probably a useful feature worthy of pursuit. This would be similar to other lazy evaluations, except it would execute just once (even across many runs of the application) and would (to be useful) involve communications rather than strict value-transformations. One might consider CompileTimeResolution that actually happens at CompileTime to be 'strict'.

CompileTimeResolution blurs and makes somewhat less distinct the 'CompileTime' itself. This distinction can be further blurred by supporting the embedding of the parser and compiler into the RunTime environment (e.g. as a simple set of functions in the standard library). In either case, the advantages of a CompileTime (mostly those involving safety, security, and optimization) can still be acquired, while seamlessly mixing CompileTime and RunTime. This might be associated with AlternateHardAndSoftLayers, but with much greater elegance and SymmetryOfLanguage.

CompileTimeResolution also introduces potential for SideEffects? to the compilation, along with offering a vector for compilation failure (e.g. due to communications failure) that isn't entirely within control of the programmer. Admittedly, languages where we're forced to use 'Makefiles' already have these potential side-effects, as does the use of third-party CodeGeneration tools that we might have used to 'badly' implement the features CompileTimeResolution offers, so there is very little net loss here. However, designers should take note of the potential for SideEffects? and attempt to control and limit them and, more usefully, explicitly recognize and offer preference for those that are idempotent or side-effect free.

One might even say (explicitly assume) that all forms of CompileTimeResolution are intended to be side-effect-free and idempotent. This would limit CompileTimeResolution just enough that it no longer blurs the line between CompileTime and RunTime (though it would become a very thin line), and this would slightly diminish SymmetryOfLanguage. However, with this assumption, the language can be optimized to drop all CompileTimeResolutions for which there is no apparent requirement for the returned 'value' (since the 'result' value must be the goal after you assume side-effects are not). This allows programmers an easier time justifying the use of CompileTimeResolution - heck, they can go hog-wild with it because they know that nothing is happening unless the value is actually required. They can also take far more advantage of caches and get GracefulDegradation during network failure.

Security is also an issue, especially in cases of migratory code with a compiler available in the runtime, so a compiler needs to run with PrincipleOfLeastPrivilege. Of course, evil code can have any number of evil things, so this shouldn't be considered a greater concern than those other evil things.

CompileTimeResolution allows us the possibility to treat everything as though it were a global namespace (modulo security and secrecy). Explicit support for it becomes ever more desirable as we move further and further away from the standalone computer.


Languages with Formal Support for CompileTimeResolution:


Weaknesses of CompileTimeResolution:

CompileTimeResolution can hurt "continuity" of a program across versions, and clearly partitions the language's CompileTime from its edit-time and run-time. This partitioning doesn't hurt all programs, of course, but if one wishes to achieve a strongly interactive programming environment or allow for dynamic upgrades against a trusted repository of source-code (e.g. LiveProgramming) then it is better to avoid CompileTimeResolution as a feature.


See Also: CompileTime, KeyLanguageFeatures, ThirdFutamuraProjection, DoubleDipping

EditText of this page (last edited June 24, 2010) or FindPage with title or text search