Wednesday, December 31, 2014

A Break for When Lisp Does or Does Not Make Error - Notes

I was working on some of the documentation for AFFTA, this morning, when I arrived at a concern concerning non-local exit of control within Common Lisp software programs.

The following Common Lisp software code does not result in the warn form being evaluated:
(handler-case (break) (condition (e) (warn "Got ~S" e)))
As would be indicated within the interactive debugger, the evaluation of break creates a condition object, but that cannot be retrieved by way of handler-case. Neither can it be retrieved with handler-bind

(labels ((condition-warn (e) (warn "Got ~s" e)))
  (handler-bind ((condition #'condition-warn))
    (break)))
In either instance, the break form results in a non-local exit of control. Moreover, a condition object is created during evaluation of the break form, and that condition object cannot be accessed via either of handler-case or handler-bind.

Reviewing the CLHS entry for break, it's apparent that the continue restart can be bound, such that may allow for a program to define an arbitrary "Break  handler" -- but more broadly, that may be applied in instance of break or cerror, if the restart would be "Reached" in either instance, from within the call-tree of the executing program.

Presently, I'll take note here at my DSP42 blog that a concept of a call tree may permit for some further explanation, to a level of detail concerning any specific operating system. While developing documentation for the illustriously named dobelle-app source tree, I had discovered some documentation about process and thread implementation specifically in the Linux kernel. I would summarize the same documentation, briefly: That in a sense like established of the Linux kernel: A single thread allows for exactly one flow of execution; a process serves effectively as a container for one or more threads, and would have at least one thread representative of the process. In LinuxThreads, one thread would be the controlling thread of the process. The concept, thread groups, would be orthogonal to the differentiation of such definitions of process and thread. I'd made a more formal reference to that documentation, in the README file for the dobelle-app source tree.

Returning to the item of documentation that I was developing, this morning, for the AFFTA source tree: In that matter, the concept of a call tree occurs if simply in addressing a design goal, that the AFFTA test executor should be  able to capture a condition object for representing any non-local exit of control from within an object of test, within a Common Lisp software program. The function, break, would present a specific concern towards that goal, as that it then requires a definition of a specific continue restart, to appropriately handle the non-local exit of control from break. In that sense, an "Appropriate handling" would entail: That the test executor for a test object, in testing a specific object of test via a specific function, would denote that the continue restart was reached from within the same function.

With regards to restarts in Common Lisp, a subset of items denoted in the CLHS Conditions Dictionary:
  • restart-bind
    • Allows for definition of a primary restart function, as well as optional, separate interactive function, report function, and test function
    • Concerning the primary restart function
      • See also: invoke-restart
    • Concerning the report function
      • Function must accept a single argument, namely a stream
      • This function will be applied by the Lisp printer, when a restart is reported and the value of *print-escape* is nil 
      • May seem semantically similar to the :report feature of a condition class. 
      • An application for controlled interaction with a Lisp environment may provide a single class of object such that an interface for condition handling may inherit -- as may be applied in systems development -- as well as an interface for restart handling, such as may be applied by a desktop environment, for managed interaction within the debugger -- viz a viz *debugger-hook*.
    • Concerning the interactive function
      • Function must accept zero arguments
      • Concerning how this function may be applied, refer to invoke-restart-interactively
    • Concerning the test function
      • Function must accept a single argument, namely a condition object
      • This function allows for an application to determine whether a restart is visible
      • Concerning how this function will be applied, refer to restart-bind and implementation-specific source code.
      • Possible applications may include, hypothetically:
        • Within an application within a graphical desktop environment, the test function may be applied as to to determine whether a specific restart is visible, as per whether a device is active for interaction with/via the graphical desktop environment.
        • For application within a remote server environment: Similar, albeit with some small complication in regards to interaction
  • restart-case
    • See also: invoke-restart and invoke-restart-interactively
  • find-restart
    • Caveat: find-restart must be provided with either a restart or a non-nil symbol.
      • Consequently: find-restart cannot be applied as to locate a restart that is not a named restart. 
      • See also: compute-restarts 
  • invoke-restart and invoke-restart-interactively
    • Essential concepts: 
      • A function is assigned to a restart
      • A function may be assigned to a restart, with either restart-bind -- in which a function is implicitly assigned to a restart, prior to the evaluation of a form -- or with restart-case, in which a lambda form is provided, though not explicitly to a definition of a function, in assignment to a named restart or a restart not a named restart. With either form, compute-restarts should compute the list of restarts specified in the form, including those restarts effectively shadowing any restarts otherwise established within the active lexical environment.
    • Related concept: Not all restarts are named restarts
      • For a restart that is not a named restart, the function restart-name returns nil
  • with-simple-restart
    • Allows for definition of a single, named restart, within the lexical environment of a form to be evaluated
    • The Examples section for this macro,  in the CLHS, provides a further demonstration of how multiple restarts may be defined with the same name, within differing lexical environments, essentially for differing applications of a single restart. In the first example in the CLHS Examples section for this macro: A restart function is bound for the abort restart, first and immediately within the lexical environment of a simple, example REPL function, then secondly within the loop form defined within the REPL function. The two bindings for the abort restart are different, then, as to where control will exit to, when the restart is invoked. 
    • Also in the Examples section in the CLHS, for this macro's reference page, there is a further example as to the relevance of the debugger as an interface for selecting a single restart, interactively
  • with-condition-restarts
  • compute-restarts
  • Conventional restarts
    • continue
      • may be used in break and cerror
      • Corresponds to the function: continue
    • abort
      • CLHS: "The intent of the abort restart is to allow return to the innermost ``command level.'' Implementors are encouraged to make sure that there is always a restart named abort around any user code so that user code can call abort at any time and expect something reasonable to happen; exactly what the reasonable thing is may vary somewhat."
      • Corresponds to the function: abort
    • store-value
      • CLHS: "generally used by handlers trying to recover from errors of types such as cell-error or type-error, which may wish to supply a replacement datum to be stored permanently"
      • Corresponds to the function: store-value
      • Concerning application for handling errors of types cell-error and type-error, see also: handler-bind and handler-case
    • use-value
      • CLHS: "generally used by handlers trying to recover from errors of types such as cell-error, where the handler may wish to supply a replacement datum for one-time use."
      • Corresponds to the function: use-value
      • Concerning application for handling errors of types cell-error and type-error, see also: handler-bind and handler-case
  • Implementation specific concept: Restart as object, moreover an instance of the system class cl:restart
    • As per CLHS [CLtL2], the system class cl:restart has an effective accessor, restart-name. Other accessors may be defined, extensionally, per each implementation, though such extensions -- if venturing beyond the design of any single implementation -- may appear to exceed the limitations for portable software exclusively under the CLHS
    • SBCL: cl:restart is implemented as a structure class
    • Other implementations: Likewise, an implementation-specific feature

Of course, this simple study would bear some relevance towards the development of the dobelle-app source tree, as well as its initial relevance with regards to the AFFTA source tree. Certainly, CLtL restarts would be among the features that a Dobelle application may provide an additional interface for, ostensibly towards more of convenience for application development in the Common Lisp programming environment.

A few of initial ideas, towards debugger support in Dobelle:

  • The extent to which the debugger may provide any useful information to a developer will be affected by the extent to which the software -- specifically, as in the lexical environment of each function call in the backtrace of function calls leading to entry to the debugger -- was compiled with any support for debugging
    • The debug optimization in Common Lisp allows for at least three specific levels of debugging
    • The amount of debugging information retained within compiled software may also be affected by other optimization settings, such as for speed, safety and space
  • Concerning applications of Common Lisp on interactive mobile platforms: It may be assumed that an average mobile phone user may not typically be equipped or willing to make sense of a debugger interface. 
  • The debugger interface is represented primarily in any single implementations of ANSI Common Lisp. Extensionally, a debubber interface may also be defined in some applications of Common Lisp, such as the McCLIM debugger application of the SLIME deubger interface for Emacs
  • A Common Lisp debugger interface -- as defined in any single Common Lisp programming environment -- would represent something of a unique, distinguishing feature, contrasted to other application programming platforms -- such as of a platform defined, effectively, of a C toolchain, or a platform -- cf. Intel XDK  -- available for web-based mobile application development, primarily for developing applications as typically implementing all of HTML5, Cascading Stylesheets, JavaScript and more specifically, jQuery  
  • If a mobile phone platform and/or a desktop platform may be defined for developers, certainly it may behoove a scientific interest, if that platform would be supportive not exclusively of any single programming environment. Insofar as that a computer architecture may be defined of a discrete set of known components,  in software and in hardware, generically: Whatever language an operating system's kernel may be implemented in, at any practical level of abstraction, but if a Common Lisp programming environment would be providing a significant number of features to such a platform, it may behoove the platform developer to ensure that some consideration will be made about how the debugger will be presented, when the debugger would be presented to a user. As denoted in the previous, such consideration may be limited not only to the interface toolkit, but may be applied about the entire software toolchain as well.
  • The Common Lisp debugger is for debugging Common Lisp software
  • GDB can be applied to debug software not developed in Common Lisp
    • One may observe that GDB can be applied onto a core file.
  • A concept similar to a core file may be developed, as of Common Lisp implementation and application toolchain such that would allow for a Lisp image to be written to permanent storage, if on event of entry to the debugger.
    • Such an implementation may be developed as either to fork before writing the image in a background process, or alternately to write the image in the foreground process -- and if in the foreground, then likely to terminate after the image is written to disk.
    • Such process -- of writing the image file to disk, whether in foreground or as a background process -- it may affect the arrangement of objects in memory space, however, and may therefore affect the debugging of the initial backtrace.
    • The initial backtrace should be stored separate to any subsequent data files as may be written consequent to the entry to the debugger -- i.e. program diagnostic files, etc.
      • A machine-readable format should be developed for a portable serialization of backtrade information within the debugger
      • See also: Details of SLIME/SWANK implementation 
    • An exact selection o diagnostic files may be made by a developer or by an end user, as far as entry to the debugger and subsequent diagnostic procedures. 
  • If the reader may be of any question as to whether this would describe a free/open source system, the reader might be kindly advised that this is being written within a Chromium browser, within a Linux distribution.
    • That the same Linux distribution is installed as a virtual machine appliance:
      • In one part, that may be mostly a matter of convenience.
      • In another part, it may seem  to describe an architecture for an open source meta-IDE. 
      • "First things first... &REST arbitrary"
  • Concerning the dignostic file set denoted previously in this single outline:
    • Existing work, in free/open source software platforms - See also KDE and GNOME desktop environments
    • Primary concern: User data security
      • A developer may or may not be excessively concerned about "Own data", when the developer is to be the only person viewing or reviwing any "Own data" contained in a backtrace or other diagnostic data produced by a software application, in any known procedure of the same.
        • Insofar as ethics and legal responsibilities: A developer may be aware, furthermore, that the set of "Own data" may  include "Third party" data.
      • If an application is configured to store and/or send its diagnostic file set in any manner as that it may be encountered by anyone not the single, individual developer
        1. Question: What information will be allowed to be stored in the diagnostic file set? The application itself should have full control as per the data security requirements of the respective application user.
        2. Question: How will that information be stored? Need it be encrypted, in storage? If so, that may require an application of such as PGP
        3. Question: How will that information be transmitted? It should be transmitted only via encrypted channel
        4. Question: Where will that information be transmitted to? There should be a public key infrastructure provided of the respective development office, to ensure safe transmittal of the diagnostic file set and any private user data contained within the diagnostic file set.
        5. Question: What liabilities are then presented to the recipient of the diagnostic file set? There might seem to be not a broad body of legal discourse, in regards to such a question, but it must be derived of legal precedent -- in all of regional and ethical regards, and for each region in which an application would be made available.
        6. Question: Concerning applications of existing issue tracking systems -- such as YouTrack, Bugzilla, etc -- and tools and frameworks such as the bug reporting infrastructure developed of the K Desktop Environment (KDE) namely: How would the application environment be developed as to integrate with an upstream issue tracking system? The matters of secure storage and transmittal of the diagnostic file set should be taken to consideration, in addressing this question. Furthermore, there may be a question as with regards to upgrade channels, insofar as addressing this of question.
      • Sidebar - Existing Work: One may observe the architecture of the Debian reportbug system, in all of its free and open source design.
    • Also a primary concern: Developers' legal rights and legal and ethical responsibilities