Defining a better QUIT - r3n/rebol-wiki GitHub Wiki
The purpose of this document is to define the general parameters of Rebol's run-time environment, and develop a better method of handling QUIT (and related functions).
There are four general environments for running Rebol programs. It is best to clearly label them, so we can refer to them later:
- Application - run by user, not for debugging purposes, but to achieve an end result
- Server - run by a server, not for debugging purposes, but to achieve an end result
- Shell - run by a user, using Rebol as a shell to run a variety of tasks that achieve an end result
- Development - run by developer, for debugging, education, or experimentation by using the console.
In addition, we will define Console to mean the Rebol interactive session (prompt, evaluate, and show result).
The importance of the console varies quite a lot, depending on the above environments:
- For an application: the console should be irrelevant. It should never open. Programmers should catch and handle all errors in their code. (And we may want to add an automatic dialog window for scripts that do not.)
- For a server: the console may have a different use: the standard input and output channel (e.g CGI scripts). Again, programmers should catch errors and write them to a log file.
- For shell: the console provides I/O for user interaction.
- For development: the console provides I/O as an interactive method for designing and testing code.
The third and fourth cases are different, because the console "belongs to the user" and not the script. It should be possible for the user to keep the console open, regardless of what scripts and code is being evaluated.
There are a few special cases in addition to the above. These are hybrid cases that mix two of the above environments.
- Special Shell - starts out like an APP (e.g. by clicking a script icon), preloads various utilities and functions, then enters the console Shell mode.
- Launchers - user's script launches other scripts that may call QUIT. In effect, the user's script behaves somewhat like the console.
Currently, when you start a script, it evaluates and eventually it returns. In other words, it falls off-the-end of its script, with the default that it returns to whatever script called it. Typically, that is it returns to:
- An application or server that started (DO) it.
- The console itself
- A script run from the console
(It may also be possible to bind special RETURN and EXIT words to allow it as well.)
The console handles three exceptional conditions for the termination of a script:
- QUIT - forces an immediate termination of the script and the Rebol system environment itself.
- HALT - forces the script to terminate, and returns to the console prompt (except in server environments, where it also will force a quit).
- THROW - an error has occurred, and if not handled by the script, will force the script similar to a HALT, but with an error message.
The problem case in the above list is QUIT.
Many programmers use QUIT to mean: The program is done, stop now.
Unfortunately, QUIT also terminates the Rebol system itself, and for Shell and Development work, that can be a problem.
So, it appears that an important case is missing from the above exceptions. We need something similar to QUIT: the script wants to terminate, but it does not terminate the Rebol system.
There are a few solutions to this problem, but we can narrow them down to the best two choices:
- Define a new function (or refinement) for the desired "script wants to quit" action.
- Modify the behavior of the QUIT function itself - making it "modal" - that is, what it does depends on a special mode of operation.
The second seems like it is a better solution. We can make QUIT modal (its mode depends on where it is used).
A modal QUIT is one that depends on its context (including how it was called). Before we examine how to implement such a QUIT, let's first determine if this would be an adequate solution to our needs:
- When running as an Application or Server, QUIT would terminate the program and the Rebol system
- When running as a Shell or for Development, QUIT would stop the script, but will not terminate the Rebol system.
- When evaluated directly from the console (not in a script), QUIT would terminate the Rebol system (as it does today).
There is another requirement implied by the above definitions: Should QUIT do some cleanup on the environment?
At this time, we can only do a small degree of cleanup... such as close all open windows. However, until we have the full R3 module system online, other resources will remain allocated and in use.
Once R3 modules are working, those parts of the script that do not modify the Rebol system itself can easily be purged from memory. In addition, we can allow a finalization method to close ports, files, and other resources.
If you have comments to this page, you can post them in the discussion area here (see tab at top) or send me (Carl) a note in the R3-Alpha world.