diff options
-rw-r--r-- | basic.lsp | 2 | ||||
-rw-r--r-- | cbasic.lisp | 4 | ||||
-rw-r--r-- | doc/breaking_rules.md | 88 | ||||
-rw-r--r-- | loot.lsp | 2 | ||||
-rw-r--r-- | xdr.lsp | 1 |
5 files changed, 51 insertions, 46 deletions
diff --git a/basic.lsp b/basic.lsp index a63ab27..09efc5c 100644 --- a/basic.lsp +++ b/basic.lsp @@ -67,7 +67,7 @@ (defgeneric ppl (pr expr)) (defmethod ppl (pr (expr <exp-int>)) - (convert (num expr) <string>)) + (convert (int expr) <string>)) (defmethod ppl (pr (expr <exp-var>)) (var expr)) (defmethod ppl (pr (expr <exp-str>)) diff --git a/cbasic.lisp b/cbasic.lisp index 0f2d63c..2ddc5b4 100644 --- a/cbasic.lisp +++ b/cbasic.lisp @@ -5,6 +5,10 @@ ;;; https://github.com/Henry/BuddKaminInterpreters and *maybe* ;;; https://oleksandrmanzyuk.wordpress.com/2014/06/18/from-object-algebras-to-finally-tagless-interpreters-2/ ;;; +;;; It might be worth reading the example in "Beautiful Racket" for +;;; the extensions suggested on the OCaml page, +;;; or more likely switch to COMAL. +;;; ;;; A BASIC interpreter already exists at ;;; https://gitlab.com/com-informatimago/com-informatimago/-/tree/master/small-cl-pgms/basic ;;; but it is idiomatic CL, diff --git a/doc/breaking_rules.md b/doc/breaking_rules.md index 694261b..947ca80 100644 --- a/doc/breaking_rules.md +++ b/doc/breaking_rules.md @@ -23,16 +23,17 @@ systems. I would personally recommend [2] and [3]. -*NB*: I am almost certainly re-inventing a SmallTalk wheel. However I +The SmallTalk community probably pioneered this development process. +However I argue that Lisp's combination of imperative & OO is an easier sell to industry whereas pure OO as in SmallTalk (or logic programming as in -Prolog) is still niche. +Prolog) is, perhaps undeservedly, more niche. -A closely related are is that of "specification animation", +A closely related area is that of "specification animation", quickly writing an implementation of some subset of a formal specification in for example Z or VDM. -Prolog is a common choice for this, but I choose Lisp instead. +Prolog is a common choice for this. However, as stated in the introduction, I differ in arguing that it is possible to *refine* a prototype into a product. @@ -57,6 +58,9 @@ Reasons for this decision include: * The imperative and object-oriented paradigms are commonly taught, used in industry, and have a small "impedence mismatch" to current hardware. +* The possible migration path of running under + [core-lisp](https://github.com/ruricolist/core-lisp) + and using the quicklisp libraries. Detailed implementations, libraries, etc. are as follows: @@ -73,40 +77,43 @@ it could be difficult to satisfy expectations. ### Dependencies -For the prototyping phase, -you should *really* limit yourself to ISLisp. -If absolutely necessary you can choose some of the libraries mentioned in the "Productisation" section below. +Counterintuitively, I chose ISLisp partly *because* it imposes limits in the prototyping phase. +Standard UNIX libraries like curses, catgets, xdr and dbm can still be used from compiled code using the FFI. ## Coding standards Even though this is a prototype, attention should be paid to basic craftsmanship. -* Divide the system into "packages". +* Divide the system conceptually into packages. This can start from just "section headers" with lots of semicolons. * Write comments for at least each public fun, class and package. - There are good guidelines in the Elisp manual, but for now one sentence will suffice. -* Use `assure` or `the` - to check the types of parameters in public interfaces (see below). + There are guidelines in the Elisp manual, but for now one sentence will suffice. +* Dynamically + check the types of parameters in public interfaces (see below). * Indent all the source code using Emacs. * Some minimal documentation, at least an overview like in [README driven development](https://tom.preston-werner.com/2010/08/23/readme-driven-development.html) and man (actually, [mdoc](https://manpages.bsd.lv/toc.html)) pages[7]. * Certain parts of a system justify greater detail for a *complete* specification. These are (newly-designed) network protocols and complex persistent data models. - For new protocols, use JSON-RPC as a base and follow the documentation style of LSP. + For new protocols, use XDR with or without RPC but generated from rpcgen .x files. Data models should be documented as commented SQL DDL. ### Run-time type-checking As stated above, -`declare` should be used for simple run-time type-checking of public functions. +`the` should be used for simple run-time type-checking of public functions. For example, the following: ```lisp (defun f (x) - (declare (fixnum x)) - (the fixnum (+ x 1))) + (the <fixnum> x) + (the <fixnum> (+ x 1))) ``` +`assure` might be better according to the standard, +but for now only `the` is used for inference +by the eisl compiler. + # Refinement to Production-Quality Software at the level of the previous section is quite usable. @@ -124,9 +131,10 @@ obviously at a maintenance cost. Ensure that the surrounding infrastructure is in place: * Configuration management. The prototype should already have been checked into git. -* Build. Write an ASDF description, and install as a local quicklisp package. +* Build. Split sections into different files, write simple Makefile. + *TODO*: copy elisp public/private convention? * Test. - Write FiveAM + Write *library/test.lsp* test cases. Extend the simple run-time type-checking to contracts where possible. * Track. Start using a defect tracking system. @@ -134,8 +142,9 @@ Ensure that the surrounding infrastructure is in place: Then, the following code & documentation improvements should be made: * Document the system more exhaustively -* Can use any of the "starred" libraries in quicklisp. -* Maybe "lparallel" to take advantage of all cores +* Can re-implement interfaces from the OpenLisp manual using UNIX libraries. +* Can port any of the `trivial-*` libraries from quicklisp. +* Maybe multi-process to take advantage of all cores Since we have a working prototype, it may make sense to write the documentation (and contracts, and tests) "bottom-up": @@ -158,7 +167,7 @@ PlantUML *should* be used where it can replace ad-hoc text. Documents should be stored under git in a "doc" subdirectory of the project. It is recommended to keep the separation between library and UI code, -e.g. for using ltk. +e.g. for using a GUI like Tk. The following can be added as sections to the README: @@ -183,52 +192,43 @@ However, some of this documentation is better in the source code: ```lisp (defun f (x) - (declare (fixnum x)) + (the <fixnum> x) (assert (precondition x)) (let ((res (+ x 1))) (assert (postcondition res)) - (the fixnum res))) + (the <fixnum> res))) ``` -`lisp-critic` can be used to perform static analysis of the codebase. -But it's not worth writing custom rules. +I'm not aware of any static analysis tool. ## Dependencies For productisation you may want to add more features. -Although the official ANSI standard is moribund, -"community standard" (i.e. starred) libraries are recommended on the -[Awesome-CL list](https://github.com/CodyReichert/awesome-cl), -or [CL portability layers](http://portability.cl/). +OpenLisp has idiomatic interfaces for several UNIX features in its manual, which could be re-implemented. +Also quicklisp (and as a second choice non-quicklisp) `trivial-*` libraries should be easy enough to port. Dependencies should be limited to these two initially. -Ltk can implement a GUI to replace the +Tk can implement a GUI to replace the prototype command-line or terminal-based UI, if it makes sense. -A second round of productisation, -which again may never actually be required, -could include: - -* Any of the `trivial-` libraries from the Awesome-CL list. The `trivial-` libraries may be *forked* and maintained locally. -* Any other `trivial-` libraries available in Quicklisp. -* Other libraries available in Quicklisp. +The order of preference is: +1. Any UNIX interface documented in the OpenLisp manual. +2. A port of any of the `trivial-` libraries from the Awesome-CL list. +3. A port of any other `trivial-` libraries available in Quicklisp. -Now it may also be worth taking on the complexity of a Web UI, -using HTMX and the platform.sh stack. -HTMX & ReST (following Fielding) seem simpler than single-page applications -(outside the very specific case of drawing on a canvas using ParenScript). +The complexity of a Web UI should be avoided in favour of simpler protocols like IRC, Gemini and maybe XMPP. ## Testing -Unit (FiveAM) tests grow in parallel with the module interface specs. +Unit tests grow in parallel with the module interface specs. Property-based testing would be nice here, but there doesn't seem to be a readily-available library. System tests grow in parallel with the requirements spec. -It's ok for system tests to use the same interfaces as the ltk code. +It's ok for system tests to use the same interfaces as the GUI code. All tests should be automated, except possibly for the UI/view layer. -Q: These scripts could be generated from a literate test plan? A: yes, probably one of the few places to use nw2md. +These scripts could be generated from a literate test plan, one of the places where it makes sense to use nw2md. As much of the testing work should be pushed "back" in the V model to contracts for the functions, following the pattern above. @@ -236,7 +236,7 @@ following the pattern above. # Conclusion A method for developing software from an incomplete understanding of the requirements is given. -It is hoped that this is more effective than most of what is currently-used. +It is hoped that this is more effective than a lot of what is currently-used. # References diff --git a/loot.lsp b/loot.lsp index 4dfb2c8..74378fc 100644 --- a/loot.lsp +++ b/loot.lsp @@ -38,4 +38,4 @@ (for ((n 0 (+ n 1))) ((> n 99)) (format (standard-output) "~A~%" (as-string (choose loot)))))) -(main) +;; (main) diff --git a/xdr.lsp b/xdr.lsp index b3cf1ad..ffae67f 100644 --- a/xdr.lsp +++ b/xdr.lsp @@ -1,4 +1,5 @@ ;;; Use (a subset of) CL and the xpc part of the "frpc" package from QuickLisp instead? +;;; No, use eisl and ../build/xdr-tests-1.0. (require "olunit") (defpackage #:xdr |