about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorDarren Bane <darren.bane@gmail.com>2020-08-21 23:57:52 +0100
committerDarren Bane <darren.bane@gmail.com>2020-08-21 23:57:52 +0100
commitd737f1ab887c1d3e7b97cfaa443e6037d5f53c5b (patch)
tree779782540833971a982888c1662c0519d1838dd3
parente6931993d7193b60881d0303110974b6af6af852 (diff)
downloadlsp-d737f1ab887c1d3e7b97cfaa443e6037d5f53c5b.tar.gz
Chose a project
-rw-r--r--cbasic.lisp34
-rw-r--r--doc/bane.20.cdr15.md1
-rw-r--r--doc/breaking_rules.md88
-rw-r--r--doc/refs5
4 files changed, 89 insertions, 39 deletions
diff --git a/cbasic.lisp b/cbasic.lisp
index ddbd900..1974c24 100644
--- a/cbasic.lisp
+++ b/cbasic.lisp
@@ -1,24 +1,28 @@
+;;; I'm trying to write an interpreter for a BBC BASIC subset
+;;; using a Frankenstein design following
+;;; https://caml.inria.fr/pub/docs/oreilly-book/html/book-ora058.html and
+;;; https://github.com/Henry/BuddKaminInterpreters
+
 ;;; Not sure yet if it's a good idea or not,
 ;;; but I'm trying to keep the number of top-level functions the same as in OCaml.
 
 (defun one-command (st)
-   (with-handler #'error-handler
-      (let ((l parse (read-line)))
-           (case (car l)
-                 ((line) (insert (cadr c)))
-                 ((p-end) (throw 'end nil)))))) ; throw and conditions are orthogonal
+  (format (standard-output) "> ")
+  (with-handler #'error-handler
+    (let ((l (parse (read-line))))
+      (case (car l)
+        ((line) (insert (cadr c)))
+        ((p-end) (throw 'end nil)))))) ; throw and conditions are orthogonal
 
-(defclass <state> () ((program :accessor prog)
+(defclass <state> () ((program :accessor program)
                       (env :accessor env)))
 (defmethod initialize-object :after ((self <state>) initargs)
-   (setf (program self) nil)
-   (setf (env self) nil))
+  (setf (program self) nil)
+  (setf (env self) nil))
 
 (defun main ()
-   (catch 'end (lambda ()
-                  (format (standard-output) "BASIC version 0.1~%~%")
-                  (for ((st (create (class <state>))))
-                       (())
-                       (format (standard-output) "> ")
-                       (catch 'error (one-command st)))))
-   (format (standard-output) "See you later...~%"))
+  (catch 'end (lambda ()
+                (format (standard-output) "BASIC version 0.1~%~%")
+                (for ((st (create (class <state>))))
+                     (catch 'error (one-command st)))))
+  (format (standard-output) "See you later...~%"))
diff --git a/doc/bane.20.cdr15.md b/doc/bane.20.cdr15.md
index d27fd47..844eaee 100644
--- a/doc/bane.20.cdr15.md
+++ b/doc/bane.20.cdr15.md
@@ -24,6 +24,7 @@ Write an ISLisp program, making the following adaptations:
 | ----------------- | ------------------- |
 | (class x)         | (find-class 'x)     |
 | create            | make-instance       |
+| defglobal         | defvar              |
 | for               | do                  |
 | quotient          | /                   |
 | (standard-output) | *standard-output*   |
diff --git a/doc/breaking_rules.md b/doc/breaking_rules.md
index 0a88e01..70bcb56 100644
--- a/doc/breaking_rules.md
+++ b/doc/breaking_rules.md
@@ -49,7 +49,7 @@ 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.
 
-However, as stated in the introduction, this document differs from these in
+However, as stated in the introduction, I differ in
 arguing that it is possible to *refine* a prototype into a product.
 
 # Prototyping
@@ -72,15 +72,18 @@ Reasons for choosing Common Lisp include:
 * The existence of quicklisp.
   Popularity is not really a reason for choosing Common Lisp over ISLisp,
   but slotting into quicklisp *is*.
-* Limit to recommendations from the
+* Although the official ANSI standard is moribund,
+  quasi-standard libaries are recommended on the
   [awesome list](https://github.com/CodyReichert/awesome-cl),
   or [portability layers](https://github.com/CodyReichert/awesome-cl#portability-layers).
 * Contrary to a lot of other languages, it is fairly paradigm-agnostic.
 
 At the same time, I want a clean subset of CL,
-so cleave as close to ISLisp as practical.
-
-*TODO*: write CDR
+so cleave as close to ISLisp as practical
+\.[
+bane 2020
+\.]
+.
 
 It was decided to use the imperative/object-oriented paradigm,
 partly for familiarity in industry and
@@ -116,16 +119,28 @@ collyer cox
 \.]
 .
 
+### Run-time type-checking
+
+As stated above,
+`declare` 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)))
+```
+
 ## Rejected alternatives
 
 You could use an integrated environment.
 With Emacs and JSON-RPC
 (ELisp and ISLisp are not identical but are very similar),
-but I reject this because jsonrpc is outside this list and
+but I reject this because jsonrpc is not "blessed" and
 I don't want to maintain my own.
 
-DbC would be another nice-to-have,
-but I settle for `(declare`.
+Full DbC would be another nice-to-have,
+but I settle for a pattern using `(declare`.
 
 # Refinement to Production-Quality
 
@@ -141,6 +156,7 @@ First, ensure that the surrounding infrastructure is in place:
 * Test.
   Write FiveAM
   test cases.
+  Extend the simple run-time type-checking to contracts where possible.
 * Track. Start using a defect tracking system.
 
 Then, the following code & documentation improvements should be made:
@@ -149,12 +165,22 @@ Then, the following code & documentation improvements should be made:
 * Can use more of quicklisp, e.g. the trivial-\* libraries.
 * Port to platform.sh?
 
+Since we have a working prototype,
+it may make sense to write the documentation (and contracts, and tests) "bottom-up":
+
+1. Contracts
+2. Test cases
+3. Module interface specs
+4. Module guide, uses hierarchy
+5. Task hierarchy
+6. System requirements
+
 ## Documentation Details
 
 Depend only on GFM,
 in the same spirit as the software.
 The use of tools like
-PP and Pandoc is postponed indefinitely.
+PP and Pandoc should be minised.
 PlantUML *should* be used where it can replace ad-hoc text.
 
 Documents should be stored under git in a "doc" subdirectory of the project.
@@ -162,6 +188,14 @@ Documents should be stored under git in a "doc" subdirectory of the project.
 I think it is a good idea to keep the separation between library and UI code
 when using ltk.
 
+The following can be added as sections to the README:
+
+* Uses hierarchy (but at a module level of granularity)
+* Task hierarchy
+
+And a proper software requirements spec should be written filling in any blanks that the man pages leave.  
+The specification of input and output variables is best left at the level of tables and Basic English again.
+
 ### Library
 
 This was the subject of
@@ -177,32 +211,38 @@ However, some of this documentation is better in the source code:
 \.[
 basic english
 \.].
+* Although full design-by-contract may be out of reach
+  a poor-man's version can be used with public functions following a pattern.
+  This can also do some of the formal requirements.
+
+```lisp
+(defun f (x)
+  (declare (fixnum x))
+  (assert (precondition x))
+  (let ((res (+ x 1)))
+    (assert (postcondition res))
+    (the fixnum res)))
+```
 
 ### UI
 
-The following can be added as sections to the README:
-
-* Uses hierarchy (but at a module level of granularity)
-* Task hierarchy
-
-And a proper software requirements spec should be written filling in any blanks that the man pages leave.  
-The specification of input and output variables is best left at the level of tables and Basic English again.
-
-*TODO*: For the UI *technology*, is it best to skip local GUIs altogether and go
-straight to ParenScript, Backbone, etc.?
+ltk is great for local GUIs.
+However, a product may require HTMX and the platform.sh stack.
+Note that I prefer HTMX & ReST (following Fielding) to single-page applications
+(outside the very specific case of drawing on a canvas using ParenScript).
 
 ## Testing
 
-Unit (FiveAM) tests should be derived from the module interface specs.
+Unit (FiveAM) 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 should be derived from the requirements spec.
+System tests grow in parallel with the requirements spec.
 It's ok for system tests to use the same interfaces as the ltk code.
 All tests should be automated,
 except possibly for the UI/view layer.
-Q: These scripts could be generated from a literate test plan?
+Q: These scripts could be generated from a literate test plan? A: yes, probably one of the few places to use "PP".
 
-It would be nice to push some of the testing work "back" in the V model to contracts for the functions,
-but quid-pro-quo isn't really blessed.
+As much of the testing work should be pushed "back" in the V model to contracts for the functions,
+following the pattern above.
 
 # Conclusion
 
diff --git a/doc/refs b/doc/refs
index 9eeca05..d380cf2 100644
--- a/doc/refs
+++ b/doc/refs
@@ -1028,3 +1028,8 @@
 %T Basic English
 %B Wikipedia
 %O available: https://en.wikipedia.org/wiki/Basic_English [accessed 28 May 2020]
+
+%A Darren Bane
+%T An ISLisp-like subset of ANSI Common Lisp
+%C Ireland
+%D 21 Aug 2020