home *** CD-ROM | disk | FTP | other *** search
- Xref: sparky comp.lang.pop:216 comp.compilers:2243
- Newsgroups: comp.lang.pop,comp.compilers
- Path: sparky!uunet!think.com!spdcc!iecc!compilers-sender
- From: axs@cs.bham.ac.uk (Aaron Sloman)
- Subject: Compile-time vs Run-time
- Reply-To: axs@cs.bham.ac.uk (Aaron Sloman)
- Organization: School of Computer Science, University of Birmingham, UK
- Date: Sun, 24 Jan 1993 03:59:05 GMT
- Approved: compilers@iecc.cambridge.ma.us
- Message-ID: <93-01-170@comp.compilers>
- Keywords: pop-11
- Sender: compilers-sender@iecc.cambridge.ma.us
- Lines: 266
-
- -- Introduction
- -- A minimal concept of compilation
- -- Forms of interaction at run time
- -- -- Case a: compile then execute.
- -- -- Case b: alternating compilation and execution:
- -- -- Case c: nested as well as alternated compilations and executions:
- -- -- Case d: Merging compilation streams
- -- -- Case e: allowing multiple interleaved compilation streams.
- -- -- Case f: Time-shared concurrent streams:
- -- To summarise:
- -- Notes and qualifications
-
- -- Introduction
-
- There has been considerable discussion recently about dynamic vs lexical
- binding of variables in comp.lang.pop
-
- My impression is that there are more distinctions between different
- variable binding schemes than have so far been clearly defined in the
- discussion, and I thought it might be useful to list them, if only because
- Pop-11 offers more choices to the programmer than any other language I
- know of. (Maybe this should be a chapter in the Pop-11 primer.)
-
- Before I present the options regarding variable bindings I need to clarify
- some distinctions concerning compile time, run time, and compilation
- streams, as there are some issues concerning variable binding that concern
- only compile time, some concern only run time, and some involve relations
- between the two. These distinctions get complicated when there are
- different compilation streams in the same process.
-
- This article merely goes into the compile-time/run-time distinction and
- the notion of a compilation stream. In a later article, when I have time,
- I'll return to variable binding.
-
- I've cross-posted to comp.compilers in case someone who knows about other
- languages than Pop wishes to comment on the generality of my remarks.
-
- -- A minimal concept of compilation
-
- In what follows I shall talk about source code being "compiled",
- independently of whether it is compiled all the way to machine code, or to
- some intermediate interpreted form (e.g. lisp-like parse trees, or some
- interpreted intermediate machine language), or whether the source code is
- stored directly in the machine as strings of text and interpreted, or
- whether it is compiled into an object file which has to be linked and
- loaded before it can be run.
-
- In this sense, compiling is just the process of taking source code from a
- file or from the terminal and storing it in the machine in some form in
- which it can then be run. This process can include compiling whole
- procedure definitions, or compiling individual commands or declarations
- such as "let X = 99", in Basic or "vars X = 99" in Pop-11.
-
- -- Forms of interaction at run time
-
- Before I go on to distinguish various questions about access to variables,
- I need to clarify an important notion, namely that the language allows the
- programmer to interact with programs at run time using the original
- programming language. Unfortunately this is not a simple concept, as there
- are several slightly different cases to be considered.
-
- The question is whether there is a clearly separate phase in which
- source-code programs are read in ("compile time"), after which programs
- can only be executed ("run time"), or whether new source code can be added
- to the running system at any time, including "top level" source code
- instructions such as "print the value of X" or instructions to alter the
- contents of datastructures. Different cases will be distinguished.
-
- -- -- Case a: compile then execute.
-
- In most programming language systems (e.g. C, Pascal, Fortran) there is a
- sharp distinction between compile time and run time and they cannot be
- alternated or interleaved: for any program there is first a process of
- compilation, and then later on the program is run, perhaps on many
- occasions in different contexts. Within this paradigm, no program
- execution is possible till the whole program has been compiled (whether to
- machine code or an interpreted intermediate form), and once program
- execution has begun no more code can be added.
-
- In such a system, it is not possible for the user to interact with the
- running system unless the program contains a procedure that reads in text
- typed by the user (or responds to mouse actions, or whatever), and
- performs appropriate actions. I.e. a special "command interpreter" may be
- part of the program, and it will generally allow a command language that
- is different from the programming language used to create the program.
-
- -- -- Case b: alternating compilation and execution:
-
- By contrast, in BASIC, and many AI languages (Lisp, Prolog, Pop-11) and
- functional languages (Scheme, ML, Miranda) a procedure to support
- interaction is provided by the language system itself in the form of a
- built in command interpreter or an incremental compiler that remains
- available at run time.
-
- In its simplest form the compiler accepts, either from the user or from a
- specified file, commands which can either add declarations or procedure
- definitions or give commands to run system or user procedures. Such a
- compiler simply reads in definitions, declarations and commands and obeys
- them, always returning to the top level read loop whenever something has
- been completed. Sometimes this is referred to in connection with Lisp as a
- "read-eval-print" loop. In this case, compilation and execution are
- alternated.
-
- -- -- Case c: nested as well as alternated compilations and executions:
-
- In more sophisticated systems, compiling and running can be nested as well
- as alternated. For instance many AI systems allow the compiler to be
- invoked as a subroutine by user procedures. Then besides the top-level
- invocation, there is a new invocation of the compiler. That in turn can
- read in new commands which cause procedures to run which invoke the
- compiler. In that case there can be several coexisting "compilation
- streams", a point I'll return to later. By contrast if the compiler is
- always a top-level process, which continues running after each command is
- completed, then there is always only one compilation stream.
-
- Nesting is useful in several different contexts, e.g.
- o The decision to compile some additional files can be taken
- by a user procedure at run time, depending on task requirements.
- o The process of compiling one file can cause the compiler to be
- invoked to compile another file. The latter process will then have
- its own compilation stream, in most languages.
- o A learning program can create and compile new procedures on the
- basis of what it has learnt.
- o When testing programs it is sometimes useful to enter a "break" in
- which the compiler is invoked to give the user a chance to type in
- commands to interrogate values of variables, contents of
- datastructures, the current call stack, etc. Alternatively this may
- be required for the application, e.g. if the user is allowed to
- tailor the application by typing in procedures to be invoked in
- certain circumstances.
-
- When compilation streams are nested, compilation process C1 may cause
- procedure P1 to be invoked which then invokes compilation process C2,
- which may run P2, etc. P1 will not resume execution until C2 is complete.
- Similarly C1 will not continue until procedure P1 is complete.
-
- -- -- Case d: Merging compilation streams
-
- Note that Poplog Pop-11 allows different compilation streams to be merged
- into a single stream using #_INCLUDE (or the macro "include" which copes
- with search lists for directories of files to be "included").
-
- The advantage of allowing merged compilation streams as well as nested
- streams is that declarations that are normally local to a compilation
- stream, but which need to be shared between different libraries, need not
- be copied into all those libraries. Instead a single file contains the
- declarations, and it can be invoked by several different files. This is
- analogous to the use of #include in C, and the use of "source" in the Unix
- Cshell.
-
- Note that the reason why this facility is required in Pop-11 is that there
- are certain types of variables that cannot be shared across different
- compilation streams, namely file-local, or stream-local lexical variables.
- Thus if such declarations are encountered in a in a file whose compilation
- is nested they will not be inherited by the calling environment.
-
- Similarly if a unix shell script is run, the calling environment will not
- pick up any environment variables declared in the shell script, nor any
- directory changes, whereas using "source" to merge the script with the
- current shell overcomes this.
-
- It is interesting that the need for the merging facility became apparent
- only after the introduction of lexical scoping at the level of whole
- files. The need would have been apparent earlier had there been other
- things local to the current compilation stream, such as the current
- directory.
-
-
- -- -- Case e: allowing multiple interleaved compilation streams.
-
- A yet more sophisticated system can support multi-threading, or
- lightweight processes, which can resume or suspend one another. In that
- case procedure P1, instead of invoking C2 as a sub-routine may start it up
- as an independent compilation process. Then at some point C2 may be
- suspended, and P1 resumed. If P1 exits, then compilation process C1 is
- resumed. After a while it may be suspended and C2 resumed. For example, C1
- and C2 may run in different windows, and a mouse or keyboard event could
- be used to determine which compilation stream to use next to read in
- commands. So the processes C1 and C2 are then interleaved. (This is used,
- for example, by "immediate mode" in the Poplog editor, VED, where
- interleaving allows you to suspend a procedure definition or command,
- switch to another command stream to give commands to gain information
- about the language or the current state of the system, then return and
- complete the previous command.) Having different concurrent compilation
- streams in different windows for different purposes, can be helpful to the
- user, even if, in principle, it could all be done in one window using
- nested commands. Another case is where the system (like Poplog) actually
- supports different high level languages, in which case different
- concurrent compilation streams can be used for the different languages.
-
-
- -- -- Case f: Time-shared concurrent streams:
-
- A yet more sophisticated system will allow "backgrounding" - i.e. while
- one process continues running "in the background", e.g. compiling large
- files, another process reacts to user commands. This requires some kind of
- scheduler which allocates time-slices between the different compilation
- streams and the processes they generate. In Pop-11 a scheduler is not
- built in, but the combination of timed interrupts and the process
- mechanism makes it fairly easy to implement. (See HELP ACTOR)
-
- -- To summarise:
-
- a. Simple systems allow only compilation then execution
- b. Interactive language systems allow alternating compilation and
- execution processes.
- c. Systems in which the compiler is itself a procedure allow nested
- compilations as well as alternating compilation and execution.
- d. Systems that allow compilation streams involving different files
- to be merged.
- e. Systems that support multi-processing, permit interleaved compilation
- streams, as well as nested and alternating compilation and execution
- processes.
- f. A multi-processing system with a scheduler allows process switching
- on a time-sliced basis instead of waiting for an active stream to
- complete a sub-task and pause before another one can be resumed.
-
-
- -- Notes and qualifications
-
- [Note 1: A non-interactive system that allows object files to be
- dynamically linked in while a program is running blurs the distinction
- between programs that allow interaction at run time and those that don't.
- If, for example, a running program checks every now and again whether you
- have created a new object file called "commands.o" and if so takes steps
- to link it in (possibly after giving it a unique name), and then runs its
- top level procedure you have a sort of run time command interpreter,
- though it may feel clumsy to use.]
-
- [Note 2: The availability of a debugger, especially if it can be invoked
- after a program has started running, can also blur the distinction, if it
- provides commands for interrogating variables and data-structures, or
- calling procedures. If the debugger allows commands to be given in the
- same language as the original program, then it fits one of the previous
- categories. Conversely, languages that are fully interactive and allow
- nested compilation streams provide their own debugging facilities.]
-
- [Note 3: There are operating system command languages like the Unix shell
- languages that support all the above facilities. For instance, a shell
- command file can spawn a new shell. Two windows on the same machine can
- run two shells concurrently.]
-
- [Note 4: I have so far written as if variable binding environments, or
- identifier scopes, are tied entirely to compilation streams. But that is
- not the case, since when variables are local to a procedure the scope may
- be restricted to the portion of the compilation stream during which the
- procedure is being compiled, and in addition, if the same procedure is
- concurrently active more than once in a procedure calling hierarchy
- different bindings for those variables can be associated with each
- activation. Thus if the variable n is local to a recursive definition of
- factorial, then calling factorial(5) may create 5 different activations,
- in which the value of n is respectively 5, 4, 3, 2 and 1. This point is
- common to both lexical and dynamic binding, though shallow dynamic binding
- allows temporary sharing of activation values.]
-
- Later, I hope to turn back to the discussion of different variable binding
- regimes. Meanwhile I'd welcome comments on all this. Have I missed
- anything important?
- --
- Aaron Sloman,
- School of Computer Science, The University of Birmingham, B15 2TT, England
- EMAIL A.Sloman@cs.bham.ac.uk OR A.Sloman@bham.ac.uk
- Phone: +44-(0)21-414-3711 Fax: +44-(0)21-414-4281
- --
- Send compilers articles to compilers@iecc.cambridge.ma.us or
- {ima | spdcc | world}!iecc!compilers. Meta-mail to compilers-request.
-