Lisp

1. Common Lisp   cl common lisp

properties


ID: af0ed8bb-4b45-42f9-b8be-82b8ea7935a3
CREATED:
AKA: CL


edges

Common Lisp
common-lisp-libraries
CL ANSI Standard Draft
CLHS Starting Points
quotes
CDR - Common Lisp Document Repository
<- SBCL
<- ECL


The most powerful dialect of the most expressive language.

'Common' Lisp (CL) refers to any implementation of the ANSI CL Standard which fully describes the language.

CL began appearing in the Lisp world around 1984 and the spec itself was finalized in 1994. For the most part, the spec is a good enough baseline for a complete, high-level general-purpose language - which says a lot for a 30+ yr old description of a language without a reference implementation (that I know of).

Today () the best implementation of ANSI CL available is SBCL.

1.1. Basic Syntax

properties


ID: df41336d-5185-4047-9644-e25925529f08
CREATED:


  • Pragmatic Parsing in Common Lisp - ACM Lisp Pointers 4, 2 (Apr/Jun 1991), 3-15.
  • CLiki: Case sensitivity

    The common misconception is that Common Lisp is case insensitive. This is not true - symbols in Common Lisp are case sensitive.

    By default, the Common Lisp reader is case-converting: all unescaped characters in a symbol name get upper-cased. This gives the practical effect of making it seem as though symbol case doesn't matter. This is desirable behavior for interfacing with other case-insensitive languages (such as Fortran), but a pain to interface with case-sensitive ones (such as C).

    Luckily the behavior of the reader can be customized via readtable-case.

    The one that might seem to be most useful for having case-sensitive symbols at first glance is :preserve, however remember that all code read in with the default setting (:upcase) is in upper-case, as are all the standard Common Lisp symbols (this is defined by the standard), so this means you will need to spell out all CL and external symbols IN ALL UPPERCASE. To make this less annoying, the :invert readtable-case is the most practical: all-lowercase symbol names become uppercase, all-uppercase become lowercase, and mixed-case stays mixed-case (the important part for case sensitivity). The Lisp printer outputs symbol names correctly this way by default. The only problem now becomes inconsistent spelling of a symbol in all lowercase or all uppercase in old code that expects case conversion. But otherwise you can get case sensitivity for your software by setting readtable-case to :invert today.

1.1.1. S-Expressions

properties


ID: 4e502dc1-c22d-444e-b4c0-864876f0cdf5
CREATED:


edges

wiki


1.1.2. common-lisp unicode support

properties


ID: db68087d-cc4c-462d-b4e0-bbda756dc37c
CREATED:


logbook
  • State "NOTE" from
(defmacro λ (&rest symbols-and-expr)
  `(lambda ,(butlast symbols-and-expr)
     ,@(last symbols-and-expr)))

(mapcar (λ x (* x x)) '(1 2 3 4))

;; other tremendously useful characters:
'|αβγδεζηθικλμνξοπρστυϕχψω|
'|ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥϕΧΨΩ|
'|ℝℕℤℚ∥√∡∞∝ℵ∅∫|
'|¬∀∃∨∧⊥∈⊂∪∩⇐⇔⇒↦|

1.2. CLOS

properties


ID: 8bc4ff14-f001-4515-ac1f-fd59ef8ef506
CREATED:


edges

Fundamentals of CLOS
Object Reorientation: Generic Functions
CLHS Chapter 7
<- EIEIO


1.2.1. Method Combination

properties


ID: 4e7b8135-3d53-4739-9a72-563971a5b876
CREATED:


edges

28.1.7.2. Standard Method Combination
28.1.7.3. Declarative Method Combination
28.1.7.4. Built-in Method Combination Types
CLHS Macro DEFINE-METHOD-COMBINATION


  • simple built-in method combination types

The names of the built-in method combination types are +, and, append, list, max, min, nconc, or, progn, and standard.

(define-method-combination xor :identity-with-one-argument t)

1.2.2. MOP

properties


ID: f9d8eead-51ab-4589-a5c2-2569ea1b7abd
CREATED:
AKA: Meta-Object Protocol


edges

MOP: Concepts


1.3. Types

properties


ID: 3f613b5a-6aae-4852-a4d8-c322c271e6eb
CREATED:


'(arithmetic-error function simple-condition array generic-function
  simple-error atom hash-table simple-string base-char integer
  simple-type-error base-string keyword simple-vector bignum list
  simple-warning bit logical-pathname single-float bit-vector long-float
  standard-char broadcast-stream method standard-class built-in-class
  method-combination standard-generic-function cell-error nil
  standard-method character null standard-object class number
  storage-condition compiled-function package stream complex
  package-error stream-error concatenated-stream parse-error string
  condition pathname string-stream cons print-not-readable
  structure-class control-error program-error structure-object
  division-by-zero random-state style-warning double-float ratio symbol
  echo-stream rational synonym-stream end-of-file reader-error t error
  readtable two-way-stream extended-char real type-error file-error
  restart unbound-slot file-stream sequence unbound-variable fixnum
  serious-condition undefined-function float short-float unsigned-byte
  floating-point-inexact signed-byte vector
  floating-point-invalid-operation simple-array warning
  floating-point-overflow simple-base-string floating-point-underflow
  simple-bit-vector)
ARITHMETIC-ERROR
FUNCTION
SIMPLE-CONDITION
ARRAY
GENERIC-FUNCTION
SIMPLE-ERROR
ATOM
HASH-TABLE
SIMPLE-STRING
BASE-CHAR
INTEGER
SIMPLE-TYPE-ERROR
BASE-STRING
KEYWORD
SIMPLE-VECTOR
BIGNUM
LIST
SIMPLE-WARNING
BIT
LOGICAL-PATHNAME
SINGLE-FLOAT
BIT-VECTOR
LONG-FLOAT
STANDARD-CHAR
BROADCAST-STREAM
METHOD
STANDARD-CLASS
BUILT-IN-CLASS
METHOD-COMBINATION
STANDARD-GENERIC-FUNCTION
CELL-ERROR
NIL
STANDARD-METHOD
CHARACTER
NULL
STANDARD-OBJECT
CLASS
NUMBER
STORAGE-CONDITION
COMPILED-FUNCTION
PACKAGE
STREAM
COMPLEX
PACKAGE-ERROR
STREAM-ERROR
CONCATENATED-STREAM
PARSE-ERROR
STRING
CONDITION
PATHNAME
STRING-STREAM
CONS
PRINT-NOT-READABLE
STRUCTURE-CLASS
CONTROL-ERROR
PROGRAM-ERROR
STRUCTURE-OBJECT
DIVISION-BY-ZERO
RANDOM-STATE
STYLE-WARNING
DOUBLE-FLOAT
RATIO
SYMBOL
ECHO-STREAM
RATIONAL
SYNONYM-STREAM
END-OF-FILE
READER-ERROR
T
ERROR
READTABLE
TWO-WAY-STREAM
EXTENDED-CHAR
REAL
TYPE-ERROR
FILE-ERROR
RESTART
UNBOUND-SLOT
FILE-STREAM
SEQUENCE
UNBOUND-VARIABLE
FIXNUM
SERIOUS-CONDITION
UNDEFINED-FUNCTION
FLOAT
SHORT-FLOAT
UNSIGNED-BYTE
FLOATING-POINT-INEXACT
SIGNED-BYTE
VECTOR
FLOATING-POINT-INVALID-OPERATION
SIMPLE-ARRAY
WARNING
FLOATING-POINT-OVERFLOW
SIMPLE-BASE-STRING
FLOATING-POINT-UNDERFLOW
SIMPLE-BIT-VECTOR

1.3.1. Pathnames

properties


ID: 6935daca-1ad0-45b0-97e5-f59745f06ad9
CREATED:


edges

sbcl#pathnames
CLHS: System Class PATHNAME


;;; FIXME: the below shouldn't really be here, but in documentation
;;; (chapter 19 makes a lot of requirements for documenting
;;; implementation-dependent decisions), but anyway it's probably not
;;; what we currently do.
;;;
;;; Unix namestrings have the following format:
;;;
;;; namestring := [ directory ] [ file [ type [ version ]]]
;;; directory := [ "/" ] { file "/" }*
;;; file := [^/]*
;;; type := "." [^/.]*
;;; version := "." ([0-9]+ | "*")
;;;
;;; Note: this grammar is ambiguous. The string foo.bar.5 can be
;;; parsed as either just the file specified or as specifying the
;;; file, type, and version. Therefore, we use the following rules
;;; when confronted with an ambiguous file.type.version string:
;;;
;;; - If the first character is a dot, it's part of the file. It is not
;;; considered a dot in the following rules.
;;;
;;; - Otherwise, the last dot separates the file and the type.
;;;
;;; Wildcard characters:
;;;
;;; If the directory, file, type components contain any of the
;;; following characters, it is considered part of a wildcard pattern
;;; and has the following meaning.
;;;
;;; ? - matches any one character
;;; * - matches any zero or more characters.
;;; [abc] - matches any of a, b, or c.
;;; {str1,str2,...,strn} - matches any of str1, str2, ..., or strn.
;;;   (FIXME: no it doesn't)
;;;
;;; Any of these special characters can be preceded by an escape
;;; character to cause it to be treated as a regular character.
  1. Logical Pathnames
    properties


    ID: bbdc87f1-cece-474f-905e-d02401e82510
    CREATED:


    edges

    Zach Beane Common Lisp – Logical pathnames and eager parsing
    CLHS: System Class LOGICAL-PATHNAME


    A pathname that uses a namestring syntax that is implementation-independent, and that has component values that are implementation-independent. Logical pathnames do not refer directly to filenames.

    ;;; Logical pathnames have the following format:
    ;;;
    ;;; logical-namestring ::=
    ;;;      [host ":"] [";"] {directory ";"}* [name] ["." type ["." version]]
    ;;;
    ;;; host ::= word
    ;;; directory ::= word | wildcard-word | **
    ;;; name ::= word | wildcard-word
    ;;; type ::= word | wildcard-word
    ;;; version ::= pos-int | newest | NEWEST | *
    ;;; word ::= {uppercase-letter | digit | -}+
    ;;; wildcard-word ::= [word] '* {word '*}* [word]
    ;;; pos-int ::= integer > 0
    ;;;
    ;;; Physical pathnames include all these slots and a device slot.
    

1.3.2. Simple Types

properties


ID: 62417b14-efff-448d-92c0-5b0e99a180ee
CREATED:


'(simple-array
  simple-base-string
  simple-bit-vector
  simple-string
  simple-type-error
  simple-vector

  simple-condition
  simple-error
  simple-warning)
SIMPLE-ARRAY
SIMPLE-BASE-STRING
SIMPLE-BIT-VECTOR
SIMPLE-STRING
SIMPLE-TYPE-ERROR
SIMPLE-VECTOR
SIMPLE-CONDITION
SIMPLE-ERROR
SIMPLE-WARNING

1.4. Conditions

properties


ID: 1535ca58-7141-4886-a1c0-90e4f29fc2c9
CREATED:


edges

CLHS: Chapter 9
Common Lisp: condition system
Conditions (ANSI Common Lisp)
Common Lisp: A Tutorial on Conditions and Restarts
Conditions and Restarts in Common Lisp – Talking with a Lisp
29. Conditions
CLHS: Chapter 9


  • - the CL condition still baffles me - it is deeply expressive but I find it difficult to use. This might just be because there's nothing nearly as capable in other langs I've used.
  • serious-condition implies the need for user input, signaled with error instead of signal or warn.
  • CLHS style recommendations CLHS: Section 9.1.3.1
    • uppercase first letter, use complete sentences and correct punctuation.
    • don't prefix the message with things like 'Error: ' or even a newline. That's the job of the condition reporter
    • it is permissible to embed newlines in messages (just not before or after)
    • Avoid use of the #\Tab character
    • Don't mention the containing function. That's the job of the debugger

1.5. Reader

properties


ID: d185b690-d2f8-46b9-a32d-2a95f0ee6d82
CREATED:


  • quick tip for reader macros - don't forget importance of the . syntactic sugar

    '(foo . #.(list 1 2 3))
    
    FOO 1 2 3
    (let ((a (list 1 2 3)))
      (equalp
       `(0 . ,a)
       ;; OR
       `(0 ,@a)))
    
    T
    

1.6. Printer

properties


ID: 0cdc5eb0-a12a-4276-8382-0b81f661a2a8
CREATED:


edges

CLHS: Chapter 22


1.6.1. Pretty Printer

properties


ID: 681706ba-d885-46bf-93ba-c8e051c79aeb
CREATED:


edges

CLHS: Section 22.2
XP: A Common Lisp Pretty Printing System (1989)


Permits programs to redefine the way in which code is displayed and allow pretty printing to be applied to complex data structures.

The 'prettiness' of any particular output is somewhat subjective but in general the pretty printer allows individual programs to achieve an arbitrary degree of aesthetic control.

The pretty printer is driven entirely by dispatch based on the value of *PRINT-PPRINT-DISPATCH* which is modified using SET-PPRINT-DISPATCH.

  • Dynamic Control of the Arrangement of Output

    The actions of the pretty printer when a piece of output is too large to fit in the space available can be precisely controlled. Three concepts underlie the way these operations work—logical blocks, conditional newlines, and sections.

    Whenever possible, the pretty printer displays the entire contents of a section on a single line. However, if the section is too long to fit in the space available, line breaks are inserted at conditional newline positions within the section.

  • tip: make sure to use the variables in code - for example the *PRINT-PRETTY* var can be used to indicate color output is allowed in PRINT-OBJECT methods.

A primary goal of pretty printing is to keep the output between a pair of margins. The column where the output begins is taken as the left margin. If the current column cannot be determined at the time output begins, the left margin is assumed to be zero. The right margin is controlled by print-right-margin.

1.7. Debugging

properties


ID: 4d5f7613-0441-4f69-b559-24f12ae39e15
CREATED:


edges

CLHS: Section 25.1.2


1.8. Format Directives

properties


ID: 852b2c7f-238e-480d-ad63-3b5b53c58929
CREATED:


edges

Pretty Print Table Data in Common Lisp
A Few FORMAT Recipes


(let ((list-fmt "~@{~a ~^~}"))
  (format nil list-fmt) ;; ""
  (format nil list-fmt 1 2 3))
1 2 3 
  • Note that the extension mechanism (~/foo/) is clunky - the character / isn't allowed in the function designator.
  • The core includes an annotation system (WIP )
    • annotations are similar to format directives, just with a different prefix character - usually % (emacs style).
    • annotations are expanded as early as possible into a FORMAT control-string

1.9. Functions

properties


ID: ebbc665a-10c3-46a3-8052-4f46bc9ac2b1
CREATED:


edges

5.2. Functions


1.9.1. Lambda Expressions

properties


ID: 7555f8c6-5dd5-4607-ae1f-32643bf03ba9
CREATED:


edges

5.2.2. Lambda-Expressions


This is not SBCL specific, but according to the ANSI Common Lisp standard.

Convert a Lambda Expression as List to a Function

These are your options:

CL-USER 168 > (funcall (coerce '(lambda (x) (* x x)) 'function) 4) 16

CL-USER 169 > (funcall (compile nil '(lambda (x) (* x x))) 4) 16

CL-USER 170 > (funcall (eval '(lambda (x) (* x x))) 4) ; because LAMBDA is a macro, too 16 CL-USER 171 > (funcall (eval '(function (lambda (x) (* x x)))) 4) 16

Note though that the lambda expression is referencing the null lexical environment. Thus it has no access to any lexical variables from the surrounding code.

Lambda expressions are not function objects

Why is a lambda expression not a function?

Because it is just a list, not code. To make a lambda expression into code, you have to turn it into a function object.

Some other (often older) Lisps allow you to use lambda expressions as code, but not Common Lisp. This is defined by the standard.

You can't do (funcall '(lambda (x) (+ x x)) 3). You have to convert the lambda expression into a function object first.

FUNCTION is a special operator -> syntax+semantics

(funcall (function (struct-slot1 struct1)) 3)

This is a syntax error, already. FUNCTION is a special operator and expects a function name or a lambda expression. (struct-slot1 struct1) is neither. (struct-slot1 struct1) is code which retrieves a value from a structure. But it is not a function name, which would be a symbol or a list (setf <some-symbol>). It is also not a lambda expression, which would be something like (lambda (…) . ..).

1.9.2. Thunk

properties


ID: d69c0095-59e3-4005-8360-f928c3ace460
CREATED:


  • from tagbody in Lisp discord

the inventors of the thunk recalling that the term "was coined after they realized (in the wee hours after hours of discussion) that the type of an argument in Algol-60 could be figured out in advance with a little compile-time thought […] In other words, it had 'already been thought of'; thus it was christened a thunk, which is 'the past tense of "think" at two in the morning'.

1.10. Loop

properties


ID: 439a02f1-afcf-4ba3-bdf4-0304d152ba6f
CREATED:


edges

-> SB-LOOP
LOOP for Black Belts


Most of the so-called iteration control clauses start with the loop keyword for, or its synonym as,2 followed by the name of a variable. What follows after the variable name depends on the type of for clause.

The subclauses of a for clause can iterate over the following:

,* Ranges of numbers, up or down, by specified intervals ,* The individual items of a list ,* The cons cells that make up a list ,* The elements of a vector, including subtypes such as strings and bit vectors ,* The pairs of a hash table ,* The symbols in a package ,* The results of repeatedly evaluating a given form

A single loop can have multiple for clauses with each clause naming its own variable. When a loop has multiple for clauses, the loop terminates as soon as any for clause reaches its end condition. For instance, the following loop:

(loop for item in list for i from 1 to 10 do (something))

will iterate at most ten times but may stop sooner if list contains fewer than ten items.

The Parts of a LOOP

You can do the following in a LOOP:

,* Step variables numerically and over various data structures ,* Collect, count, sum, minimize, and maximize values seen while looping ,* Execute arbitrary Lisp expressions ,* Decide when to terminate the loop ,* Conditionally do any of these

Additionally, LOOP provides syntax for the following:

,* Creating local variables for use within the loop ,* Specifying arbitrary Lisp expressions to run before and after the loop proper

The basic structure of a LOOP is a set of clauses, each of which begins with a loop keyword.1 How each clause is parsed by the LOOP macro depends on the keyword. Some of the main keywords, which you saw in Chapter 7, are for, collecting, summing, counting, do, and finally.

Iterating over a hash table or package is slightly more complicated because hash tables and packages have different sets of values you might want to iterate over–the keys or values in a hash table and the different kinds of symbols in a package. Both kinds of iteration follow the same pattern. The basic pattern looks like this:

(loop for var being the things in hash-or-package …)

For hash tables, the possible values for things are hash-keys and hash-values, which cause var to be bound to successive values of either the keys or the values of the hash table. The hash-or-package form is evaluated once to produce a value, which must be a hash table.

To iterate over a package, things can be symbols, present-symbols, and external-symbols, which cause var to be bound to each of the symbols accessible in a package, each of the symbols present in a package (in other words, interned or imported into that package), or each of the symbols that have been exported from the package. The hash-or-package form is evaluated to produce the name of a package, which is looked up as if by FIND-PACKAGE or a package object. Synonyms are also available for parts of the for clause. In place of the, you can use each; you can use of instead of in; and you can write the things in the singular (for example, hash-key or symbol).

Finally, since you'll often want both the keys and the values when iterating over a hash table, the hash table clauses support a using subclause at the end of the hash table clause.

(loop for k being the hash-keys in h using (hash-value v) …) (loop for v being the hash-values in h using (hash-key k) …)

Both of these loops will bind k to each key in the hash table and v to the corresponding value. Note that the first element of the using subclause must be in the singular form.4

If none of the other for clauses supports exactly the form of variable stepping you need, you can take complete control over stepping with an equals-then clause. This clause is similar to the binding clauses in a DO loop but cast in a more Algolish syntax. The template is as follows:

(loop for var = initial-value-form [ then step-form ] …)

As usual, var is the name of the variable to be stepped. Its initial value is obtained by evaluating initial-value-form once before the first iteration. In each subsequent iteration, step-form is evaluated, and its value becomes the new value of var. With no then part to the clause, the initial-value-form is reevaluated on each iteration to provide the new value. Note that this is different from a DO binding clause with no step form.

The step-form can refer to other loop variables, including variables created by other for clauses later in the loop. For instance:

(loop repeat 5 for x = 0 then y for y = 1 then (+ x y) collect y) ==> (1 2 4 8 16)

However, note that each for clause is evaluated separately in the order it appears. So in the previous loop, on the second iteration x is set to the value of y before y changes (in other words, 1). But y is then set to the sum of its old value (still 1) and the new value of x. If the order of the for clauses is reversed, the results change.

(loop repeat 5 for y = 1 then (+ x y) for x = 0 then y collect y) ==> (1 1 2 4 8)

Often, however, you'll want the step forms for multiple variables to be evaluated before any of the variables is given its new value (similar to how DO steps its variables). In that case, you can join multiple for clauses by replacing all but the first for with and. You saw this formulation already in the LOOP version of the Fibonacci computation in Chapter 7. Here's another variant, based on the two previous examples:

(loop repeat 5 for x = 0 then y and y = 1 then (+ x y) collect y) ==> (1 1 2 3 5)

  • The possible verbs are collect, append, nconc, count, sum, maximize, and minimize. Also available as synonyms are the present participle forms: collecting, appending, nconcing, counting, summing, maximizing, and minimizing.
  • As an extra bit of syntactic sugar, within the first loop clause, after the test form, you can use the variable it to refer to the value returned by the test form. For instance, the following loop collects the non-NIL values found in some-hash when looking up the keys in some-list: (loop for key in some-list when (gethash key some-hash) collect it)

1.11. Concurrency

properties


ID: d9062d16-09f0-4c48-99ac-2e26407fc75b
CREATED:


edges

-> Asynchrony
<< lparallel
Threads, concurrency, parallelism


1.12. Macros

properties


ID: 1ccb1faa-6e41-4b4f-877f-4382bc250e53
CREATED:


edges

Let Over Lambda


1.12.1. Compiler Macros

properties


ID: 961d0c81-11f0-49e2-8ccb-9c31f6b6528d
CREATED:


edges

CLHS: Section 3.2.2.1


1.13. Applications

properties


ID: 475491e1-eacd-4759-be06-1c027e91f565
CREATED:


1.13.1. screenshotbot-oss

properties


ID: 54d32d4a-93fe-4f4d-9207-f291dbb1edc6
CREATED:


edges

screenshotbot/screenshotbot-oss


A Screenshot Testing service to tie with your existing Android, iOS and Web screenshot tests.

1.13.2. Nyxt

properties


ID: c57d3869-02d6-4e5d-bb09-804d18c07124
CREATED:


edges

Nyxt browser: The hacker's browser


1.13.3. Lem

properties


ID: 10097b58-8a54-4ce2-84e9-ff15d4d0f5bf
CREATED:


edges

Lem


1.13.4. StumpWM

properties


ID: abcd966f-fd1b-4679-b956-fc4891647668
CREATED:


edges

Stump Window Manager


1.13.5. Genera

properties


ID: b34c6e3f-6559-4d7e-a554-b7b83ccc4d8c
CREATED:


edges

>> Symbolics


1.14. Libraries

properties


ID: 82d4dffa-070c-4ead-b317-9f9b6820e2c1
CREATED:


1.14.1. CL-PPCRE

properties


ID: f666c1b5-2900-44a2-85ba-2afb029d32ab
CREATED:


edges

– [BROKEN LINK: github:edicl/cl-ppcre]
doc


CL-PPCRE is a portable regular expression library for Common Lisp which has the following features:

  • It is compatible with Perl (especially when used in conjunction with cl-interpol, to allow compatible parsing of regexp strings).
  • It is pretty fast.
  • It is portable between ANSI-compliant Common Lisp implementations.
  • It is thread-safe.
  • In addition to specifying regular expressions as strings like in Perl you can also use S-expressions.
  • It comes with a BSD-style license so you can basically do with it whatever you want.

1.14.2. one-more-re-nightmare

properties


ID: cc72c2c8-8a05-432e-8e7a-844eb6c9ac15
CREATED:


edges

The one-more-re-nightmare compiler
– [BROKEN LINK: github:telekons/one-more-re-nightmare?]


1.14.3. CLIM   gui

properties


ID: d68d93f2-dbeb-410c-8fee-af71d3a4b0a0
CREATED:


edges

CLIM 2 Specification - Common Lisp Interface Manager CLIM II Specification


  1. McCLIM
    properties


    ID: b93f8626-0816-4de6-b6bd-9c796be468e8
    CREATED:


    edges

    McCLIM - A powerful GUI toolkit for Common Lisp
    Guided Tour (2006)
    src
    McCLIM User's Manual


    McCLIM is a FOSS implementation of the Common Lisp Interface Manager specification.

    • Frame Redefinition

      By default when the application frame class is redefined with the macro clim:define-application-frame panes and layouts of the existing instances are not changed. To update the frame programmer must call the function reinitialize-instance. The function may be called on a running frame ouside of its event loop.

      McCLIM extends the macro clim:define-application-frame to update existing frames automatically when the new option :reinitialize-frames is not nil. Instances are updated by defining a method update-instance-for-redefined-class :after and making all instances obsolete. Then a slot of each adopted frame is read to trigger the update without delay.

      • When the option is nil (a default) then nothing happens.
      • When the option is t then all instances are updated by calling on them the function reinitialize-instance (running frames are updated immedietely and the reset whenever the implementation chose to call the function update-instance-for-redefined-class).
      • When the option is a plist then additionally this plist is prepended to initargs applied to the function reinitialize-instance.

1.14.4. CLX   gui

properties


ID: 54ea6883-851d-4829-8f71-889aa7f58c45
CREATED:


edges

sharplispers/clx


clx/extensions

1.14.5. Shirakumo

properties


ID: 503387d8-fa9c-4269-99bc-1d29415ab290
CREATED:


edges

Shirakumo · GitHub


Shinmera runs an indie-game studio based on CL and has contributed well over 10% of the Quicklisp ecosystem. Impressive effort and worthy of a dedicated info node here.

  1. Radiance   web
    properties


    ID: 1beb282b-8c4d-4561-a293-07439d0367ae
    CREATED:


    edges

    Shirakumo/radiance: A Common Lisp web application environment


  2. Alloy   gui
    properties


    ID: 8af234c8-1455-4dc8-a2df-e6d5b5777606
    CREATED:


    edges

    Shirakumo/alloy: A new user interface protocol and toolkit implementation


  3. Framebuffers
    properties


    ID: e70d50df-d897-4a5f-a669-fa5dc3f94b23
    CREATED:


    edges

    Shirakumo/framebuffers: A library for portable framebuffer access


1.14.6. Fukamachi

properties


ID: 0fa56fd5-0b93-4b2f-be00-8197275bb5ef
CREATED:


edges

fukamachi (Eitaro Fukamachi) · GitHub


Tokyo-based Lisp hacker and web developer with some excellent CL packages.

  1. quri
    properties


    ID: df045d95-a55e-4e87-a450-cf683e0ebd19
    CREATED:


    edges

    GitHub - fukamachi/quri: Yet another URI library for Common Lisp


  2. clack   web
    properties


    ID: c9515816-fc3a-4976-a5ed-138cbec83aa9
    CREATED:


    edges

    GitHub - fukamachi/clack: Web server abstraction layer for Common Lisp


    • lack the core of clack

      Lack is a Common Lisp library which allows web applications to be constructed of modular components. It was originally a part of Clack, however it's going to be rewritten as an individual project since Clack v2 with performance and simplicity in mind.

      The scope is defining Lack applications and wrapping it up with Lack middlewares. On the other hand, Clack is an abstraction layer for HTTP and HTTP servers and provides unified API.

  3. woo   web
    properties


    ID: 98b691b5-a617-438e-80ec-fb31588bcc3e
    CREATED:


    edges

    GitHub - fukamachi/woo: A fast non-blocking HTTP server on top of libev


  4. sxql   sql
    properties


    ID: ac5922a8-06c6-4608-8305-ec42ceea4ee9
    CREATED:


    edges

    GitHub - fukamachi/sxql: An SQL generator for Common Lisp.


1.14.7. Coalton

properties


ID: 20ea4fcc-e435-4738-93f3-a29572f0919b
CREATED:


edges

src
The Coalton Language


Coalton is an efficient, statically typed functional programming language that supercharges Common Lisp.

1.14.8. Gambol   prolog

properties


ID: a911344d-aed1-4603-a46f-e8edf53756f5
CREATED:


edges

CLiki: Gambol
-> Prolog


See also A Common Prolog

  • in any case we basically always want to drop into a Read-Query-Print loop
  • in Common Prolog this function is called RQP

1.14.9. lparallel

properties


ID: c560dc07-8c9c-42bc-9ce1-634630d26981
CREATED:


edges

Lisp in Parallel : lparallel | (ql:quickload :lparallel)
>> Concurrency


  • provides thread-pools in the form of kernels
  • our implementation in the core is very similar but we use the 'thread-pool' terminology. We also provide a general purpose KERNEL slot for many types of objects including thread-pools and workers. For workers the kernel is called to start the worker loop and in thread-pools it is called with a single keyword argument to change the state of the thread-pool.

1.14.10. parenscript   js

properties


ID: c42732ce-9ef1-408b-a9dd-2424d05de398
CREATED:


edges

Parenscript
-> Javascript


  • Compiling Parenscript | jsloop

    Parenscript is a subset of Common Lisp that compiles to JavaScript. The emphasis is on the fact that it strives to produce minimal JavaScript like 1:1 as much as possible. Unlike ClojureScript which produces a lot of dependent code because of the use of Google Closure library for everything.

1.14.11. jscl   js

properties


ID: 3addee17-b990-4a6d-9767-071969ed9d0e
CREATED:


edges

jscl-project/jscl: A Lisp-to-JavaScript compiler bootstrapped from Common Lisp
-> Javascript


A CL to JS compiler

  • supplies a light js runtime with a web worker
  • lisp code compiled directly to js stream
  • supports CL/JS ffi

1.14.12. Symbolics

properties


ID: b8d8538c-7be9-4271-bf8e-897e9ba5b6ad
CREATED:


edges

<< Genera


  • TODO find web source to link to
  • /var/lib/symbolics/sys.sct
    • demo/organ.lisp
    • io/iterators.lisp
    • io/rtc.lisp (fsm)
  • wisdom from clim/demo/thinkadot.lisp:

    ;;; in all node-state stuff, t = left, nil = right
    (defstruct td-node
      (direction t)
      left-successor
      right-successor
      x
      y
      (color-phase nil)
      (entry-p nil))
    

1.14.13. CL-GSERVER

properties


ID: 0aa28dd2-d424-4021-a775-095439dffd7a
CREATED:
AKA: Sento


edges

– [BROKEN LINK: github:mdbergmann/cl-gserver]


An actor framework

1.14.14. C-mera

properties


ID: 26cd6032-0e6e-4f9b-ae9f-2b88aa95dafc
CREATED:


edges

– [BROKEN LINK: github:kiselgra/c-mera]


C-Mera is a particularly powerful Lisp system - it's a source2source transpiler built entirely on Lisp Macros.

It can be a bit difficult to navigate the source, and in our case mimick it in our own implementation - our fork is in SYN/GEN, and utilizes AST nodes from OBJ/AST - it is not limited to just C languages and so the design may be quite different in some places.

The first oddity in C-Mera's source comes in the system definition c-mera.asd. All packages and symbol exports are set here with several variables defined for lists of symbols.

CL-SYMBOLS
all external symbols in the COMMON-LISP package
DEFAULT-EXPORTS
default package exports
C-MERA-BACKEND
global ast + slot symbols

In the case of C we have the following symbols bound:

C-BACKEND
ast + slot symbols
C-SYMBOLS
list used for package definition with shadowed symbols and for the cm/lisp scope switch
C-SYNTAX
symbols not shadowed but exported
C-EXPORTS
the full list of exports - includes C-SYMBOLS, C-SYNTAX, DEFAULT-EXPORTS, and CL-SYMBOLS
C-SWAP
(append C-SYMBOLS C-SYNTAX)

Next the actual packages are defined with the help of a DEFPACKAGE* macro. There are four variations - the core package (C-MERA), the backend package (CM-C), the user package (CMU-C), and swap packages (CMS-C). The core package never changes and is used by the backend packages, but NOT by the user packages. In both cases the C variants of the backend and user packages are imported into subsequent packages defined and swap packages are defined as empty.

ALL PACKAGES then get their own systems defined with dependencies assigned like so: C-MERA - CM-C - CMU-C - CMS-C

(asdf:defsystem c-mera
  :name "c-mera"
  :version "1.1.0"
  :serial t
  :components ((:file "src/c-mera/version")
           (:file "src/c-mera/cmd")
           (:file "src/c-mera/nodes")
           (:file "src/c-mera/utils")
           (:file "src/c-mera/traverser")
           (:file "src/c-mera/pretty")
           (:file "src/c-mera/c-mera"))
  :depends-on ("net.didierverna.clon.core"))

;; ...

(asdf:defsystem cm-c
  :name "c-mera c"
  :version "1.1.0"
  :serial t
  :components ((:file "src/c-mera/c-mera")
           (:file "src/c/utils")
           (:file "src/c/nodes")
               (:file "src/c/traverser")
               (:file "src/c/pretty")
           (:file "src/c/syntax")
           (:file "src/c/reader")
           (:file "src/c/cm-c"))
  :depends-on ("c-mera"))

;; ...

(asdf:defsystem cmu-c
  :name "c-mera user c"
  :version "1.1.0"
  :components ((:file "src/c/cmu-c"))
  :depends-on ("c-mera"
           "cm-c"))

;; ...

(asdf:defsystem cms-c
  :name "c-mera swap c"
  :version "1.1.0"
  :depends-on ("cmu-c"))

1.14.15. Swank

properties


ID: a69e0d55-e25f-4332-8fdc-aad2843ba649
CREATED:


edges

-> SLIME


The server and protocol components of SLIME. Included in the same repo.

See also swank-client which provides a client-side-only protocol implementation.

Swank is TCP-based and unencrypted by default.

1.14.16. Elephant

properties


CREATED:
ID: d0fc3dc0-3ff9-442c-9eb2-97661a4a4cbe


edges

The Elephant Persistent Object Database
src


  • similar goals to XDB, but not lisp-native (provides systems for BDB and CLSQL)
  • our own STORE protocol is quite similar
notes

  • tons of useful documentation in the doc/ subdir

one thing I haven't thought much about is how and when to initialize the 'stored index' containing an ordered collection of lisp values - figure out 'warm boot'.

The use of persistent objects makes coding concise, convenient, and powerful, and makes persistence almost invisible to the programmer. However, Elephant also allows the same basic data dictionary of key/value retrieval that BerkeleyDB provides.

(in our case RDB)

While Elephant can use either RDBMSs or Berkeley DB as a data store, the model it supports is that of objects stored in persistent indices. Unlike systems such as Hibernate for Java, the user does not need to construct or worry about a mapping from the object space into the database. Elephant relies on LISP rather than SQL for its data manipulation language. Elephant is designed to be a simple and convenient tool for the programmer.

Concepts:

  • store controller (store)
  • persistent sets (psets)
  • Btrees - sorted order persistent KV abstraction
  • stored values - most lisp values including standard objects/arrays, can be used as either key or value in a btree
  • persistent objects - objects where most slot values are stored in the data store and IO performed on slot access. Storing a persistent object in a btree only store a reference for object identity.
  • object indexing - the ability to lookup and sort objects by their slot values rather than by explicit inclusion in a collection.
  • transactions - dx for executing operations on objects or collects (transaction/txn)

Basic operation is OPEN-STORE with a spec (cons where car is a backend kw), do stuff, then CLOSE-STORE. Alternatively WITH-OPEN-STORE.

What values live between lisp sessions is called liveness. Liveness in a store is determined by whether the value can be reached from the root of the store. The root is a special BTree in which other BTrees and lisp values can be stored. This BTree has a special interface through the store controller. (There is a second root BTree called the class root which will be discussed later.)

use ADD-TO-ROOT to put something into the root object and GET-FROM-ROOT to retrieve it. See also ROOT-EXISTSP, REMOVE-FROM-ROOT, MAP-ROOT. The root object itself can be accessed from the store itself.

important notes:

'This will affect all aggregate types: objects, conses, hash-tables, et cetera.'

  • Lisp identity can't be preserved - if you get an object from the index, store as a lisp variable and then get it again, the two objects won't be EQ.
  • Nested aggregates are stored in one buffer
  • Mutated substructure does not persist
  • Serialization and deserialization can be costly
  • Merge-conflicts in heavily multi-process/threaded situations
  • persistent classes
    • serialized by their OID and class
    • slot values are store separately (and invisible to the user), keyed by OID and slot
    • loading (deserializing) a persistent class instantiates the object or finds it in a cache if it already exists.
    • the cache is a weak hash-table.
    • slot values are NOT loaded until you ask for them. persisted slots don't have space allocated for them because we read from the DB.
    • Changes persist immediately
    • serde of persistent classes is fast, much faster than ordinary clos objects.
    • do not suffer from merge conflicts
    • declares all slots be persistent by default - use :transient t for non-persistent.
    • class slots with :allocation :class are never persisted

Persistent classes may inherit from other classes. Slots inherited from persistent classes remain persistent. Transient slots and slots inherited from ordinary classes remain transient. Ordinary classes cannot inherit from persistent classes – otherwise persistent slots could not be stored!

to simulate a new lisp session: FLUSH-INSTANCE-CACHE

Using persistent objects has implications for the performance of your system. Note that the database is read every time you access a slot. This is a feature, not a bug, especially in concurrent situations: you want the most recent commits by other threads, right? This can be used as a weak form of IPC. But also note that in particular, if your slot value is not an immediate value or persistent object, reading will cons or freshly allocate storage for the value.

Gets are not an expensive operation; you can perform thousands to tens of thousands of primitive reads per second. However, if you're concerned, cache large values in memory and avoid writing them back to disk as long as you can.

  • persistent collections
    • pset and btree are the solutions provided for the setf problem

Each provides persistent addition, deletion and mutation of elements, but the pset is a simple data structure that may be more efficient in memory and time than the more general btree.

The pset is also a very convenient data structure for enabling a persistent slot contain a collection that can be updated without deserializing and/or reserializing a list, array or hash table on every access.

The only difference is the api used to manipulate it. Instead of slot accessors, we use insert, remove, map and find.

There is one drawback to persistent sets and that is that they are not garbage collected. Over time, orphaned sets will eat up alot of disk space. Therefore you need to explicitly free the space or resort to more frequent uses of the migrate procedure to compact your database. The pset supports the drop-pset

However, given that persistent objects have the same explicit storage property, using psets to create collection slots is a nice match.

BTrees are collections of key-value pairs ordered by key with a log(N) random access time and a rich iteration mechanism. Like persistent sets, they solve all the collection problems of the prior sections. Every key-value pair is stored independently in Elephant just like persistent object slots.

The primary interface to btree objects is through get-value. You use setf get-value to store key-value pairs. This interface is very similar to gethash.

In addition to the hash-table like interface, btree stores pairs sorted by the lisp value of the key, lowest to highest. This is works well for numbers, strings, symbols and persistent objects, but due to serialization semantics may be strange for other values like arrays, lists, standard-objects, etc.

see MAP-BTREE

  • indexing persistent classes

(defsclass foo () () (:index t))

Notice the class argument ``:index t''. This tells Elephant to store a reference to this class. Under the covers, there are a set of btrees that keep track of classes

GET-INSTANCES-BY-CLASS returns all created instances, or more efficiently for iteration MAP-CLASS

Elephant makes no guarantee about the ordering of class elements, so you cannot depend on the insertion ordering

If we want ordered elements.. use slot indices!

(defsclass foo () ((a :index t) (b :index t)))

get-instances-by-value will retrieve all instances that are equal to the value argument, with the equality relation defined by the database backend.

TODO: GET-INSTANCES-BY-RANGE

To map over duplicate values, use the :value keyword argument. To map by range, use the :start and :end arguments.

MAP-CLASS-INDEX

  • Transactions
    • use WITH-TRANSACTION macro
    • no dynamic nesting and idempotent side-effects
    • to perform a group of transactions, use ENSURE-TRANSACTION for each unit, which will reuse an existing transaction if there is one.
    • the side effects of the body must be the same no matter how many times the body is executed

The best rule-of-thumb is to ensure that transaction bodies are purely functional as above, except for side effects to persistent objects and btrees.

If you really do need to execute side-effects into lisp memory, such as writes to transient slots, make sure they are idempotent and that other processes cannot read the written values until the transaction completes.

We cannot have infinitely sized transactions due to the finite size of the data store's memory cache. Large operations (such as loading data into a database) need to be split into a sequential set of smaller transactions. When dealing with persistent objects a good rule of thumb is to keep the number of objects touched in a transaction well under 1000.

on to the guide..

  • all lisp objects are stored by value
  • native byte ordering
  • Atomic Types

    • nil has it's own special tag in the serializer so it is easily

    identifiable. nil is an awkward value as it is also a boolean. The boolean value t is stored as the symbol 'T.

    • Bignums are broken into a sequence of fixnum-sized chunks and

    assembled by masking words onto the bignum. This is awfully expensive, but it's always correct and fully portable.

    • A rational is merely a ratio of two integers stored as fixnums or bignums.
    • A complex is a pair of floating point values, rationals or integers.
    • Standalone chars are represented by their char-code and are stored in 32-bit format to ensure that all lisps are stored correctly.
    • Symbols are stored as two strings, the package name and the symbol name in that package. When deserialized, the target package is searched for and the symbol is interned in that package.
  • Aggregate Types
    • Cons is simply stored as a cons record containing two nested elements. Linear lists are not treated specially (i.e. no cdr-coding) by the serializer.
    • Arrays are stored as sequences of nested, serialized elements. The array parameters are also stored so that arrays with fill pointers, adjustable arrays can be stored and reconstructed. The only arrays that cannot be reproduced are displaced arrays, which are copied by value and reconstructed as standard arrays during deserialization.
    • Hash tables are stored as a sequence of key-value pairs, where the key and value can be any serializable value. On deserialization, the reconstructed key and value quantities are written incrementally into the hash table. The hash table does remember it's test, rehash size and threshold and it's total count. The final size of the new hash table is set to (* (/ size reshash-threshold) rehash-size).
    • Structure objects are serialized using the metaprotocol. Each slot where the value is bound is serialized by serializing the slot name and the value in sequence. The underlying lisp must support the struct-constructor method so that a new, empty instance of the structure can be created and then populated by the stored keys and values.
    • Instances of subclasses of standard-object are stored almost identically to structs. The type of the object is stored and the object slots with bound values are serialized as slotname-value pairs. To read an object of this type, the lisp image must have the class defined and it must have at least the slots that are stored on disk. There is no good method for schema evolution (redefining objects to have less slots) of ordinary classes.

After initialization of a stored object the following state has been created:

placeholder instance
in memory, storage for oid, spec, lisp instance data and transient slot values. mediates access to stored values, does not persist itself.
cached reference
weak reference to instance in the store object cache
memory references
a normal reference to the instance may be retained by the caller
database slot values
the data store contains the stored slot values that were initialized, indexed by the object id and slot name
database references
if placeholder instance is written to a stored slot, added to a btree, or the class is indexed, a reference to the instance was added to the data store. This reference consists of an OID and a class name. If this reference is reachable, then the stored object can be reconstructed using the :FROM-OID keyword argument.

If you manually create an object using an OID which already exists in the database, initargs to make-instance take precedence over existing values in the database, which in turn take precedence over any initforms defined in the class.

  • LIFETIMES

The distributed nature of persistent instance storage results in some interesting behaviors, especially with respect to transient slots. The prior section detailed the state of the system after the original initialization of an object. The object can then be in a number of different states:

resident
the canonical state of an in-use stored object
unreferenced, unreclaimed
all memory refs dropped but placeholder hasn't been reclaimed. Weak pointer still exists in object cache. If a database ref is fetched, the cached value will be used.
Non-resident
The object only exists as reachable database refs and slot values. This is the state after GC of the placeholder.
Recreated
An intermediary state where a non-resident object is fetched from the data store and its placeholder must be recreated prior to the object entering residency state.
  • when a ref is deserialized, its OID is used to lookup the object in the store object cache. If this fails the instance is created with a call such as:

    (make-instance 'sclass :from-oid 2000 :store *store*)
    
  • :from-oid inhibits some make-instance behavior

A good policy is to initialize transient values using an :after method on initialize-instance. This allows you to initialize transient values using either system defaults or persistent slot values. That way you can ensure that the transient slots are always in a consistent state when accessed by the application, regardless of when the placeholder object was recreated.

In general, transient slots are a good place for intermediate values in a computation or to cache frequently read items to avoid deserialization overhead. indexed-btree is an example of this approach, an in-memory hash is cached in the transient slot for reads and writes are mirrored to a serialized hash in a persistent slot. The :after method just copies the persistent hash value to the transient slot.

Creating a set-valued slot:

(defsclass my-set ()
  ((set-slot :accessor set-slot :initform nil :set-valued t)))

see SET-INSERT, SET-LIST

  • Association Slots

Assocation slots allow you to create relationships between objects in your system. In the following set of examples two classes are created, a 'job' class and a 'person' class. These classes are related in that each person can only be associated with one job, but a job might have multiple people associated with it. To capture this relationship in Elephant you can use Association slots.

You can enable/disable class indexing for an entire class. When you disable indexing all references to instances of that class are lost. If you re-enable class indexing only newly created classes will be stored in the class index. You can manually restore them by using find-class-index to get the clas index BTree if you have an alternate in-memory index.

You can add/remove a secondary index for a slot. So long as the class index remains, this can be done multiple times without losing any data.

There is also a facility for defining 'derived slots'. These can be non-slot parameters which are a function of the class's persistent slot values. For example you can use an index to keep an alternate representation available for fast indexing. If an object has an x,y coordinate, you could define a derived index for r,theta which stored references in polar coordinates. These would be ordered so you could iterate over a class-index to get objects in order of increasing radius from the origin or over a range of theta.

Thus, the question of if and how a given class should be indexed is very flexible and dynamic, and does not need to be determined at the beginning of your development. This represents the ability to ``late bind'' the decision of what to index.

In general, there is always a tradeoff: an indexed slot increases storage associated with that slot and slows down write operations. Reads however remain as fast as for unindexed persistent slots. The Elephant system makes it simple to choose where and when one wants to utilize this tradeoff.

  • see also src/elephant/classindex-utils.lisp - documents tools for handling class redefs and polcies that should be used for synchronization.
  • *default-indexed-class-sync-policy* values:
    • :class - class is master, indices are deleted for any slots no longer indexed
    • :db - db is master, class indexing annotations are updated so slots which satisfy class-indexedp-by-name are isomorphic to the existing indices in the db.
    • :union - expected result - updates the class to match any existing indices and creates new ones.
  • BTrees
    • core data structure, Elephant directly exposes it
    • basic API is: get-value, remove-kv
    • Sorting is done first by primitive type (string, standard-class, array, etc) and then by value within that type. The type order and internal sorting constraint is:
      • Numbers - effectively coerced to double float and sorted relatively
      • strings - varwidth - width type sorted separately?? hmm
      • pathnames,symbols - sorted by string radix then lexically
      • aggregates sorted by type in following order then arbitrary: stored instance refs, cons, hash-table, standard objects, arrays, structs, then nil.
      • not GC'd (like ssets) - use drop-btree to delete all KV pairs and return storage - the OID used will not be recovered.
  • Btree Cursors
    • used to traverse btrees one KV at a time
    • must be created inside a transaction - made with call to make-cursor method of btree. Make sure to close cursor when stack is unwound, best to use with-btree-cursor.
    • can duplicate cursors with cursor-duplicate - avoids overhead
    • two states: initialized or uninitialized
    • to initialize:
      • cursor-first or cursor-last
      • cursor-set or cursor-set-range
    • once initialized cursor can be incremented or decremented - O(1)
      • cursor-next or cursor-prev
    • can use cursors for side effects: cursor-put replace the value without incrementing and cursor-delete deletes the KV pair and becomes uninitialized.
  • BTree Indexing
    • indexed-btree maintains a set of btree-index instances which provide alternative indexing algos.
    • Each index is itself a btree with values matched to the keys of the parent btree.
    • Index is created with add-index
    • important property of btree-index: allows duplicate keys. No dupes allowed in btree and indexed-btree.
    • index cursors are just like btree cursors except you can get the main btree value instead of the indexed valued. parallel set of operations - cursor-pnext for example returns (exists, key, primary-btree-value, index-value = primary-btree-key).

The big difference between btree cursors and index cursors is that indices can have duplicate key values. This means we have to choose between incrementing over elements, unique key-values or only within a duplicate segment. There are cursor operations for each:

  • Simple move - standard btree ops and cursor-pnext/cursor-pprev
  • Move to different KV (cursor-pnext-nodup and cursor-pprev-nodup)
  • Move to next duplicate KV (cursor-pnext-dup and cursor-pprev-dup)
  • after incrementing through a set of dupes the last NEXT operation returns nil indicating no more dupes - consequence is the cursor is uninitialized and needs to be reset.

Shared Resource Locks:

  • store connection table
  • instance cache
  • circularity buffer pool for serializer
  • static-streams for FFI (rw: is this needed?)

You can trace execute-transaction to see the sequence of calls that occur dynamically and detect where and how many transactions are and are not happening.

  • Repository migration and upgrade (see tests migrate1-5)
    • single generic migrate function

It is assumed that typically migrate will be called on two repositories and all live objects (those reachable in the root or class-root) will be copied to the target repository via recursive calls to migrate for specific objects.

Migrate will not handle:

  • circular lists
  • Indexed classes only have their class index copied if you use the top level migration.
  • one-time activity - should close the source store after validation
  • cannot currently migrate a store that has more data than your main memory. (rw: we can probably fix this)
  • OID equivalence is not maintained - can overload the migrate method to accomplish this

To customize migration overload a version of migrate to specialize on your specific persistent class type.

(defmethod migrate ((dst store-controller) (src my-class)))

In the body of this method you can call (call-next-method) to get a destination repository object with all the slots copied over to the target repository which you can then overwrite. To avoid the default persistent slot copying, bind the dynamic variable *inhibit-slot-writes* in your user method using with-inhibited-slot-copy a convenience macro.

  • Performance is usually measured in transactions per second. Database reads are cheap.

All data written to the data store ends up in a BTree slot using a transaction. There are two databases, one for persistent slot values and one for btrees. The mapping of Elephant objects is quite simple.

Persistent slots are written to a btree using a unique key and the serialized value being written. The key is the oid of the persistent object concatenated to the serialized name of the slot being written. This ordering groups slots together on the disk

1.14.17. IOLib

properties


ID: 894ce499-1ce7-4051-a921-661995fe42b2
CREATED:


edges

– [BROKEN LINK: github:sionescu/iolib]


IOLib is a portable I/O library for ANSI Common Lisp. It includes socket interfaces for network programming with IPV4/IPV6 TCP and UDP, an I/O multiplexer that includes nonblocking I/O, a DNS resolver library, and a pathname library.

  • depends on libfixposix

1.15. Systems

properties


ID: a6911466-c135-488c-a67e-689f22592a44
CREATED:


Systems are not part of the ANSI CL spec. They are classes defined by the ASDF package.

A system is a collection of Lisp files that together constitute an application or a library, and that should therefore be managed as a whole. A system definition describes which source files make up the system, what the dependencies among them are, and the order they should be compiled and loaded in.

Defining Systems

  • There are some other adhoc solutions out there but nothing that caught steam. If you want to work with the rest of the CL ecosystem you basically need to use ASDF.

1.15.1. ASDF

properties


ID: fb68413a-acd8-4107-bfb5-48ce32be8842
CREATED:


edges

info


  • makes use of (call-with-x thunk) -> (with-x ,@body) often
  • with-upgradability wrappers all over the place for backwards-compatibility
  1. Sessions
    properties


    ID: 2a62e513-65a6-49f0-9965-d25710186bc3
    CREATED:


    asdf:session
    An ASDF session with a cache to memoize some computations

    The ASDF session cache is used to memoize some computations. It is instrumental in achieving:

    • Consistency in the view of the world relied on by ASDF within a given session. Inconsistencies in file stamps, system definitions, etc., could cause infinite loops (a.k.a. stack overflows) and other erratic behavior.
    • Speed and reliability of ASDF, with fewer side-effects from access to the filesystem, and no expensive recomputations of transitive dependencies for input-files or output-files.
    • Testability of ASDF with the ability to fake timestamps without actually touching files.

1.16. Packages

properties


ID: 92dd3f0e-4789-4016-a623-48af3c45cd05
CREATED:


edges

CLHS: Macro DEFPACKAGE
-> Package Managers


  • CLHS: Function SHADOW
  • :intern
    The symbols named by the argument symbol-names are found or created in the package being defined. The :intern option interacts with the :use option, since inherited symbols can be used rather than new ones created.

It is recommended that the entire package definition is put in a single place, and that all the package definitions of a program are in a single file. This file can be loaded before loading or compiling anything else that depends on those packages. Such a file can be read in the COMMON-LISP-USER package, avoiding any initial state issues.

  • SBCL supports some additions to defpackage (:lock and :implement) - uiop and our own defpkg supports even more (:recycle, etc)
  • SBCL Package Locks
  • :implement

    Each package has a list of associated implementation packages. A locked package, and the symbols whose home package it is, can be modified without violating package locks only when *package* is bound to one of the implementation packages of the locked package.

    Unless explicitly altered by defpackage, sb-ext:add-implementation-package, or sb-ext:remove-implementation-package each package is its own (only) implementation package.

  • Package-local nicknames

1.17. Tools

properties


ID: 7f63f416-efcb-4926-8370-b626c4349c45
CREATED:


1.17.1. lisp-critic

properties


ID: d0796fff-4a90-42a5-8213-93e2cb5c9465
CREATED:


edges

src
CS325 Code Testing Tools


The Lisp Critic scans your code for instances of bad Lisp programming practice.

? (critique
          (defun count-a (lst)
            (setq n 0)
            (dolist (x lst)
              (if (equal x 'a)
                (setq n (+ n 1))))
            n))
    ----------------------------------------------------------------------
    Don't use SETQ inside DOLIST to accumulate values for N.
    Use DO. Make N a DO variable and don't use SETQ etc at all.
    ----------------------------------------------------------------------
    You have an IF with no else branch. If the return value of the IF
    matters, you should explicitly say what the else returns, e.g., NIL.
    If the return value doesn't matter, use WHEN or UNLESS.
    ----------------------------------------------------------------------
    INCF would be simpler to add 1 to N than SETQ
    ----------------------------------------------------------------------
    GLOBALS!! Don't use global variables, i.e., N
    ----------------------------------------------------------------------
    Unless something special is going on, use EQL, not EQUAL.
    ----------------------------------------------------------------------
    Don't use (+ N 1), use (1+ N) for its value or (INCF N) to change N,
    whichever is appropriate here.
    ----------------------------------------------------------------------

1.18. Blogs

properties


ID: f677579e-a644-444f-90e6-442909f94ef8
CREATED:


1.18.1. Structural Insight

properties


ID: a1002554-61eb-4f72-ac62-f497ffe6c15e
CREATED:


edges

Structural insight


  1. Fexpr
    properties


    ID: 9c02fb15-967b-4294-a8ac-1327f1ec0de1
    CREATED:


    edges

    Structural insight: Fexpr


1.19. History

properties


ID: fb444369-a3e2-4451-8afc-e29571e706de
CREATED:


1.19.1. T

properties


ID: 3951ac2e-dc3d-4c25-b0ab-7b1daac53b47
CREATED:


edges

History of T


  • interesting to note the dualities in 'truthiness' across different runtimes. 'YES' 'NO', 'TRUE' 'FALSE', 1 0, 'OK' 'ERR'

1.19.2. CAR and CDR

properties


ID: 377a92dd-8e6e-4183-bd8a-70c47902d4d8
CREATED:


edges

History of CAR and CDR


1.19.3. LAP   asm

properties


ID: f8f4d3ea-663a-4a8e-a9a8-f0d7813c710f
CREATED:


edges

spec


The LISP 2 Assembly Program

1.19.4. NASA

properties


CREATED:
ID: b5bb2fc8-df98-4c2e-9b83-e3fb6d3ff9ab


edges

Ames AI Branch 1992 Report
Coordinating Complex Problem-Solving Among Distributed Intelligent Agents


There are several famous Lisp stories retold by some JPL OGs - interesting stuff. What is less-known is the general infrastructure, ops, and planning software which Common Lisp was used for.

For my part I am less interested in the remote debugger and JPL side of things, but extremely interested in the Mission Control and network-based planning systems mentioned in various places.

See also: Working Notes from The 1992 AAAI Spring Symposium on Practical Approaches to Scheduling

  1. GERRY
    properties


    CREATED:
    ID: 9fbbcfa5-1ac5-4e2a-b807-b6cadd05653b


    GERRY was an intelligent, rule-based scheduling system deployed at the NASA Ames Research Center to aid test engineers and human schedulers.

1.19.5. Foreign Function Interface

properties


ID: 203517c3-8324-471e-b932-56ead04d8e1a
CREATED:
AKA: FFI


edges

wiki


Originally a term from the Common Lisp spec 😮

1.20. Books

properties


ID: 04d98054-94f2-47d1-8af4-751c10827ee8
CREATED:


1.20.1. PAIP

properties


ID: 91c00d39-6541-4b29-8d6b-a5b8c770cab0
CREATED:


edges

>> Expert System


Paradigms of Artificial Intelligence Programming by Peter Norvig

1.20.2. PCL

properties


ID: 53d96196-24d4-4737-93d0-a282f2cf5c0b
CREATED:


edges

Practical Common Lisp
CLiki: Practical Common Lisp


Practical Common Lisp - Peter Seibel

1.20.3. LoL

properties


ID: 11b9f51e-4d47-41ba-814f-aa6738a65881
CREATED:


edges

Let Over Lambda
thephoeron/let-over-lambda


Let Over Lambda by Doug Hoyte

1.20.4. Land of Lisp

properties


ID: 2b73b4e2-495a-4af0-9777-294196ad7f4d
CREATED:


edges

landoflisp


1.21. Package Managers

properties


ID: d41019fd-ca88-4608-af00-9e7a84dcd49f
CREATED:


edges

<- Packages


  • Quicklisp is the defacto standard
  • ASDF compatibility is assumed
  • Package and System namespace separation is a problem

1.21.1. Qlot

properties


ID: e310d8ec-2a13-4a8e-aa15-db29738656b9
CREATED:


edges

GitHub - fukamachi/qlot: A project-local library installer for Common Lisp


1.21.2. Vend

properties


ID: 6027aa9f-e3f6-4cf8-8c20-caef166a5126
CREATED:


edges

GitHub - fosskers/vend: Manage your Common Lisp project dependencies.


1.21.3. OCICL

properties


ID: 1f1a5a5d-de86-461f-a209-9d81298d9a7c
CREATED:


edges

– [BROKEN LINK: github:ocicl/ocicl]


An OCI-based ASDF system distribution and management tool for Common Lisp

1.21.4. Quicklisp

properties


ID: 0b568dbe-fc89-4ce6-be86-fd18d1d2d5c0
CREATED:


edges

Quicklisp beta
quicklisp (Zach Beane) · GitHub


Quicklisp is a library manager for Common Lisp. It works with your existing Common Lisp implementation to download, install, and load any of over 1,500 libraries with a few simple commands.

  1. Ultralisp
    properties


    ID: 6cfca9d2-8d3d-4725-a08f-349e08fd44e3
    CREATED:


    edges

    Ultralisp - Fast Common Lisp Repository


    An alternative distribution for Quicklisp - tracks git branches.

2. Scheme   scm

properties


ID: cce00db3-1428-4380-aa5d-8d2ec767b873
CREATED:


edges

The Scheme Programming Language
Scheme Requests for Implementation


Andersen, Leif, Stephen Chang, and Matthias Felleisen. 2017. “Super 8 languages for making movies (functional pearl).” Proc. acm program. lang. 1 (ICFP). https://doi.org/10.1145/3110274.

2.1. Racket

properties


ID: 74140b0d-af83-4516-ac70-b62bfa3de68d
CREATED:


edges

Racket
The Racket Reference


  • Andersen, Chang, and Felleisen (2017) from the PLT guys at NEU - Racket

2.1.1. Contracts

properties


ID: c1fdfebb-0dec-420d-abf9-aec7a2de5633
CREATED:


edges

Contracts
-> Contract Programming


2.1.2. Concurrency

properties


ID: 79ecc4f2-f223-4045-a31a-565192efaf49
CREATED:


edges

11 Concurrency and Parallelism
-> Asynchrony
<< lparallel


2.2. Guile

properties


ID: 66e2ab9a-51e3-4360-b7ad-0b38eb0dd6e5
CREATED:


edges

info
GNU's programming and extension language GNU Guile


2.3. scsh

properties


ID: c37d4dc5-0b09-4908-ab0a-e36f51f7d624
CREATED:


edges

scheme/scsh


A Unix shell embedded in scheme

3. Lisp Machine Lisp

properties


ID: e21c02a5-5039-42c2-8416-aa5d45e70cb6
CREATED:


edges

Lisp Machine Lisp - Wikipedia
-> Lisp Machine


Maclisp->Zetalisp

4. Elisp   emacs elisp el

properties


ID: 6c69c42b-3d0a-48bf-a5ad-43b350477387
CREATED:
AKA: Emacs Lisp


edges

Elisp info
An Introduction to Programming in Emacs Lisp - GNU Project - Free Software Foundation (FSF)
>> Emacs


4.1. use-package

properties


ID: 42ffc518-9c9c-4c59-9145-233aa58c6362
CREATED:


edges

info


Declarative package configuration for Emacs.

4.2. Threads

properties


ID: 5510378f-d1a7-4642-8a24-ada2d7f7e54d
CREATED:


edges

ref


4.3. Widgets

properties


ID: 95427021-7e0c-4657-9b70-a7ed874fe35a
CREATED:


edges

info


(require 'widget)

(eval-when-compile
  (require 'wid-edit))

(defvar widget-example-repeat)

(defun widget-example ()
  "Create the widgets from the Widget manual."
  (interactive)
  (switch-to-buffer "*Widget Example*")
  (kill-all-local-variables)
  (make-local-variable 'widget-example-repeat)
  (let ((inhibit-read-only t))
    (erase-buffer))
  (remove-overlays)
  (widget-insert "Here is some documentation.\n\n")
  (widget-create 'editable-field
         :size 13
         :format "Name: %v " ; Text after the field!
         "My Name")
  (widget-create 'menu-choice
         :tag "Choose"
         :value "This"
         :help-echo "Choose me, please!"
         :notify (lambda (widget &rest ignore)
               (message "%s is a good choice!"
                    (widget-value widget)))
         '(item :tag "This option" :value "This")
         '(choice-item "That option")
         '(editable-field :menu-tag "No option" "Thus option"))
  (widget-create 'editable-field
         :format "Address: %v"
         "Some Place\nIn some City\nSome country.")
  (widget-insert "\nSee also ")
  (widget-create 'link
         :notify (lambda (&rest ignore)
               (widget-value-set widget-example-repeat
                         '("En" "To" "Tre"))
               (widget-setup))
         "other work")
  (widget-insert
   " for more information.\n\nNumbers: count to three below\n")
  (setq widget-example-repeat
    (widget-create 'editable-list
               :entry-format "%i %d %v"
               :notify
               (lambda (widget &rest ignore)
             (let ((old (widget-get widget
                        ':example-length))
                   (new (length (widget-value widget))))
               (unless (eq old new)
                 (widget-put widget ':example-length new)
                 (message "You can count to %d." new))))
               :value '("One" "Eh, two?" "Five!")
               '(editable-field :value "three")))
  (widget-insert "\n\nSelect multiple:\n\n")
  (widget-create 'checkbox t)
  (widget-insert " This\n")
  (widget-create 'checkbox nil)
  (widget-insert " That\n")
  (widget-create 'checkbox
         :notify (lambda (&rest ignore) (message "Tickle"))
         t)
  (widget-insert " Thus\n\nSelect one:\n\n")
  (widget-create 'radio-button-choice
         :value "One"
         :notify (lambda (widget &rest ignore)
               (message "You selected %s"
                    (widget-value widget)))
         '(item "One") '(item "Another One.")
         '(item "A Final One."))
  (widget-insert "\n")
  (widget-create 'push-button
         :notify (lambda (&rest ignore)
               (if (= (length
                   (widget-value widget-example-repeat))
                  3)
                   (message "Congratulation!")
                 (error "Three was the count!")))
         "Apply Form")
  (widget-insert " ")
  (widget-create 'push-button
         :notify (lambda (&rest ignore)
               (widget-example))
         "Reset Form")
  (widget-insert "\n")
  (use-local-map widget-keymap)
  (widget-setup))
widget-example

4.4. EIEIO

properties


ID: da96454b-fc70-4a5c-bd7a-e66d148eb1d9
CREATED:


edges

ref
-> CLOS


4.5. Display

properties


ID: dd393948-c526-4216-bf9b-5869a7121933
CREATED:


edges

ref


4.5.1. Ewoc   gui

properties


ID: 114b1269-7400-45a7-ac41-17032015ffaa
CREATED:


edges

ref


4.5.2. Native Widgets

properties


ID: 401e2cbd-2769-4c73-979e-ca98f4f6208c
CREATED:


edges

ref


4.5.3. SVG Images

properties


ID: c3aeb32d-5353-40e3-9817-c086f6beb58b
CREATED:


edges

ref


4.5.4. Icons

properties


ID: eb112a07-aef7-4369-81f3-a50282bad8cc
CREATED:


edges

Icons (GNU Emacs Lisp Reference Manual)


4.5.5. Buttons

properties


ID: 9aed2656-f389-4a2b-8425-f6eeb546e901
CREATED:


edges

Buttons (GNU Emacs Lisp Reference Manual)


4.6. Faces

properties


ID: 291cd491-b88c-4d52-b500-e7cc3095b3f1
CREATED:


edges

info


Emacs can display text in several different styles, called faces. Each face can specify various face attributes, such as the font, height, weight, slant, foreground and background color, and underlining or overlining. Most major modes assign faces to the text automatically, via Font Lock mode.

(describe-function 'list-faces-display)
list-faces-display is an interactive native-comp-function in
‘faces.el’.

It is bound to C-<down-mouse-2> <df>.
It can also be invoked from the menu: Edit → Text Properties.

(list-faces-display &optional REGEXP)

Inferred type: (function (&optional t) boolean)

List all faces, using the same sample text in each.
The sample text is a string that comes from the variable
‘list-faces-sample-text’.

If REGEXP is non-nil, list only those faces with names matching
this regular expression.  When called interactively with a prefix
argument, prompt for a regular expression using ‘read-regexp’.

  Probably introduced at or before Emacs version 19.17.

A “face” is a collection of graphical attributes for displaying text: font, foreground color, background color, optional underlining, etc. Faces control how Emacs displays text in buffers, as well as other parts of the frame such as the mode line.

4.7. Modes

properties


ID: 8e912802-3969-4352-9a13-25f434bb1402
CREATED:


4.7.1. Outline

properties


ID: e69bdfe7-3e00-4c67-a5ec-8cd86e117db8
CREATED:


4.7.2. Allout

properties


ID: 40e5417f-6830-4cb7-8353-4b5a7a08010c
CREATED:


A minor mode similar to Outline mode but with more features and different syntax.

Headings are denoted by the underscore character _ in a comment line followed by a heading character - the simplest of which are the alternating pair . and ,.

In allout-mode headings space is significant - it is used to determine the nesting level of each heading. Add a space to shift inward, delete a space (relative to the previous heading) to shift outward.

This is how an outline can look (but sans indentation) with stylish prefixes:

  • Top level

.* A topic . + One level 3 subtopic . . One level 4 subtopic . . A second 4 subtopic . + Another level 3 subtopic . #1 A numbered level 4 subtopic . #2 Another . ! Another level 4 subtopic with a different distinctive bullet . #4 And another numbered level 4 subtopic

This would be an outline with stylish prefixes inhibited (but the numbered and other distinctive bullets retained):

  • Top level

.* A topic . * One level 3 subtopic . * One level 4 subtopic . * A second 4 subtopic . * Another level 3 subtopic . #1 A numbered level 4 subtopic . #2 Another . ! Another level 4 subtopic with a different distinctive bullet . #4 And another numbered level 4 subtopic

Stylish and constant prefixes (as well as old-style prefixes) are always respected by the topic maneuvering functions, regardless of this variable setting.

`comment-start' strings that do not end in spaces are tripled in the header-prefix, and an `_' underscore is tacked on the end, to distinguish them from regular comment strings. `comment-start' strings that do end in spaces are not tripled, but an underscore is substituted for the space.

Allout outline mode is a minor mode that provides extensive outline oriented formatting and manipulation. It enables structural editing of outlines, as well as navigation and exposure. It also is specifically aimed at accommodating syntax-sensitive text like programming languages. (For example, see the allout code itself, which is organized as an allout outline.)

In addition to typical outline navigation and exposure, allout includes:

  • topic-oriented authoring, including keystroke-based topic creation, repositioning, promotion/demotion, cut, and paste
  • incremental search with dynamic exposure and reconcealment of hidden text
  • adjustable format, so programming code can be developed in outline-structure
  • easy topic encryption and decryption, symmetric or key-pair
  • "Hot-spot" operation, for single-keystroke maneuvering and exposure control
  • integral outline layout, for automatic initial exposure when visiting a file
  • independent extensibility, using comprehensive exposure and authoring hooks

and many other features.

Distinctive bullets are not cycled when topics are shifted or otherwise automatically rebulleted, so their marking is persistent until deliberately changed. Their significance is purely by convention, however. Some conventions suggest themselves:

`(' - open paren – an aside or incidental point `?' - question mark – uncertain or outright question `!' - exclamation point/bang – emphatic `[' - open square bracket – meta-note, about item instead of item's subject `\"' - double quote – a quotation or other citation `=' - equal sign – an assignment, some kind of definition `^' - carat – relates to something above

Some are more elusive, but their rationale may be recognizable:

`+' - plus – pending consideration, completion `_' - underscore – done, completed `&' - ampersand – addendum, furthermore

\(Some other non-plain bullets have special meaning to the software. By default:

`~' marks encryptable topics – see `allout-topic-encryption-bullet' `#' marks auto-numbered bullets – see `allout-numbered-bullet'.)

See `allout-plain-bullets-string' for the standard, alternating bullets.

4.7.3. Org   org

properties


ID: cea03181-b97b-494d-b362-28056416469d
CREATED:


edges

Org mode for GNU Emacs
info


  1. Org Babel
    properties


    ID: 9cfcee92-d862-400f-a80f-7bb538b27b45
    CREATED:


    edges

    info
    The Library of Babel


  2. Org Export
    properties


    ID: d26e1dac-f9cc-47a0-9a61-f32463247ec9
    CREATED:


    edges

    Org Export Reference Documentation
    info


    1. HTML
      properties


      ID: 9cb4a1c7-4798-4ac9-8958-9e3d86673d95
      CREATED:


      edges

      info


  3. Refile and Copy
    properties


    ID: f46c1c20-c958-4068-bf0c-bf6f4f77546f
    CREATED:


    edges

    info
    My org-refile workflow - Yiming Chen


  4. org-info.js
    properties


    ID: 09edda89-63e0-4496-84eb-764fb9b0b7c3
    CREATED:


    edges

    info
    EMACS ORG-INFO.JS
    -> Javascript


  5. Syntax   syn
    properties


    ID: e1ef06a0-2c19-44fe-9afc-c216671c9ca4
    CREATED:


    edges

    Org Syntax


    Elements can be stratified into “headings”, “sections”, “greater elements”, and “lesser elements”, from broadest scope to narrowest. Along with objects, these sub-classes define categories of syntactic environments. Only headings, sections, property drawers, and planning lines are context-free1, 2, every other syntactic component only exists within specific environments. This is a core concept of the syntax.

    Expanding on the stratification of elements, lesser elements are elements that cannot contain any other elements. As such, a paragraph is considered a lesser element. Greater elements can themselves contain greater elements or lesser elements. Sections contain both greater and lesser elements, and headings can contain a section and other headings.

    • Blank lines are considered a part of a preceding element.

    To simplify references to common collections of objects, we define two useful sets. The minimal set of objects refers to plain text, text markup, entities, LaTeX fragments, superscripts and subscripts. The standard set of objects refers to the entire set of objects, excluding citation references and table cells.

  6. Org Element API
    properties


    ID: bdf4ac96-f9a6-47ea-a27a-89a8d2b20ba7
    CREATED:


    edges

    Org Element API


  7. Org Protocol
    properties


    ID: d0590d0b-4be3-447b-a549-1c927be0c745
    CREATED:


    javascript:location.href = 'org-protocol://capture?' +
      new URLSearchParams({
        template: "i",
        url: location.href,
        title: document.title,
        body: window.getSelection()})
    
    org-protocol-protocol-alist
    

4.8. Autotype

properties


ID: d0af9d29-bbcd-405c-8c48-e3e933d71b25
CREATED:


edges

info


  • Emacs Auto-Insert Text in New Files
  • autoinsert
  • hippie expand usually replaces dabbrev-expand
    • hippie-expand-try-function-list
  • executable-insert / executable-set-magic
  • abbrevs
  • dabbrevs
    • dynamic abbrevs - write a few chars and expand something you wrote earlier
  • tempo
  • skeleton

    (describe-function 'skeleton-insert)
    
    skeleton-insert is an autoloaded native-comp-function in
    ‘skeleton.el’.
    
    (skeleton-insert SKELETON &optional REGIONS STR)
    
    Insert the complex statement skeleton SKELETON describes very concisely.
    
    With optional second argument REGIONS, wrap first interesting point
    (‘_’) in skeleton around next REGIONS words, if REGIONS is positive.
    If REGIONS is negative, wrap REGIONS preceding interregions into first
    REGIONS interesting positions (successive ‘_’s) in skeleton.
    
    An interregion is the stretch of text between two contiguous marked
    points.  If you marked A B C [] (where [] is the cursor) in
    alphabetical order, the 3 interregions are simply the last 3 regions.
    But if you marked B A [] C, the interregions are B-A, A-[], []-C.
    
    The optional third argument STR, if specified, is the value for the
    variable ‘str’ within the skeleton.  When this is non-nil, the
    interactor gets ignored, and this should be a valid skeleton element.
    
    When done with skeleton, but before going back to ‘_’-point, add
    a newline (unless ‘skeleton-end-newline’ is nil or ‘_’-point is at end
    of line), and run the hook ‘skeleton-end-hook’.
    
    SKELETON is made up as (INTERACTOR ELEMENT ...).  INTERACTOR may be nil if
    not needed, a prompt-string or an expression for complex read functions.
    
    If ELEMENT is a string or a character it gets inserted (see also
    ‘skeleton-transformation-function’).  Other possibilities are:
    
            \n	go to next line and indent according to mode, unless
                    this is the first/last element of a skeleton and point
                    is at bol/eol
            _	interesting point, interregion here
            -	interesting point, no interregion interaction, overrides
                    interesting point set by _
            >	indent line (or interregion if > _) according to major mode
            @	add position to ‘skeleton-positions’
            &	do next ELEMENT if previous moved point
            |	do next ELEMENT if previous didn’t move point
            -NUM	delete NUM preceding characters (see ‘skeleton-untabify’)
            resume:	skipped, continue here if quit is signaled
            nil	skipped
    
    After termination, point will be positioned at the last occurrence of -
    or at the first occurrence of _ or at the end of the inserted text.
    
    Note that \n as the last element of the skeleton only inserts a
    newline if not at eol.  If you want to unconditionally insert a newline
    at the end of the skeleton, use "\n" instead.  Likewise with \n
    as the first element when at bol.
    
    Further elements can be defined via ‘skeleton-further-elements’.
    ELEMENT may itself be a SKELETON with an INTERACTOR.  The user is prompted
    repeatedly for different inputs.  The SKELETON is processed as often as
    the user enters a non-empty string.  C-g terminates skeleton insertion, but
    continues after ‘resume:’ and positions at ‘_’ if any.  If INTERACTOR in
    such a subskeleton is a prompt-string which contains a ".. %s .." it is
    formatted with ‘skeleton-subprompt’.  Such an INTERACTOR may also be a list
    of strings with the subskeleton being repeated once for each string.
    
    Quoted Lisp expressions are evaluated for their side-effects.
    Other Lisp expressions are evaluated and the value treated as above.
    Note that expressions may not return t since this implies an
    endless loop.  Modes can define other symbols by locally setting them
    to any valid skeleton element.  The following local variables are
    available:
    
            str	first time: read a string according to INTERACTOR
                    then: insert previously read string once more
            help	help-form during interaction with the user or nil
            input	initial input (string or cons with index) while reading str
            v1, v2	local variables for memorizing anything you want
    
      Probably introduced at or before Emacs version 22.1.
    
    
    (define-skeleton local-variables-section
     "Insert a local variables section.  Use current comment syntax if any."
     (completing-read "Mode: " obarray
           (lambda (symbol)
             (if (commandp symbol)
             (string-match "-mode$" (symbol-name symbol))))
           t)
     '(save-excursion
        (if (re-search-forward page-delimiter nil t)
      (error "Not on last page")))
     comment-start "Local Variables:" comment-end \n
     comment-start "mode: " str
     & -5 | '(kill-line 0) & -1 | comment-end \n
     ( (completing-read (format "Variable, %s: " skeleton-subprompt)
             obarray
             (lambda (symbol)
               (or (eq symbol 'eval)
               (custom-variable-p symbol)))
             t)
       comment-start str ": "
       (read-from-minibuffer "Expression: " nil read-expression-map nil
              'read-expression-history) | _
       comment-end \n)
     resume:
     comment-start "End:" comment-end \n)
    

4.9. Overlays

properties


ID: 358a0e2b-b5e0-47ad-9c70-7bb72b1c548f
CREATED:


edges

ref


5. Clojure   clj

properties


ID: 45c83abe-cff5-4d00-9f01-f61c55525ca9
CREATED:


edges

Clojure
>> JVM


6. Arc

properties


ID: 2094bd8c-4a95-4430-a126-9a56255380f4
CREATED:


edges

Arc: Table of Contents


7. MLisp

properties


ID: b7c0c96b-2555-4436-9231-42670db24838
CREATED:


edges

wiki


7.1. M-expression

properties


ID: c32b20a7-11fc-4ab6-ae55-cc121b423a66
CREATED:


edges

wiki


  • History of Lisp

    The project of defining M-expressions precisely and compiling them or at least translating them into S-expressions was neither finalized nor explicitly abandoned. It just receded into the indefinite future, and a new generation of programmers appeared who preferred internal notation to any FORTRAN-like or ALGOL-like notation that could be devised.

8. CGOL

properties


ID: f49136cd-0a8e-412b-9fc0-75afb70502e2
CREATED:


edges

wiki


mm in cgol:

for i in 1 to n do
  for k in 1 to n do
    (ac := 0;
     for j in 1 to n do
        ac := ac + a(i,j)*b(j,k);
     c(i,k) := ac)

9. Cursed Lisp   cc

properties


ID: 22821eaa-7457-4dfd-b150-cd5835ae05d4
CREATED:


The designated name for the specific flavor of Common Lisp used and developed by The Compiler Company.

Our language is cursed because it is non-portable - as in the language provided is not built with the typical Lisper's idea of portability. We do not limit ourselves to the CL ANSI specification, and never support implementations beyond our own selection of SBCL builds.

When using the term Cursed Lisp in place of Common Lisp we are most likely trying to highlight specific capabilities of the Cursed Lisp environment which should not be considered in a 'pure ANSI CL' context.

Similarly, when referring to a language with the prefix Cursed like Cursed C or Cursed Rust, we are referring to our internal syntax specifications of these languages which have a special relationship with Cursed Lisp and contain 'symbolic bridges' between each other.