~qeef/qeef.srht.site

cc0dc7226ef1ae75675b4af3ebf7efaca1700cb7 — Jiri Vlasak 6 months ago 41d22e0
Update cl notes draft
1 files changed, 181 insertions(+), 0 deletions(-)

M hugo/content/notes/cl-notes.md
M hugo/content/notes/cl-notes.md => hugo/content/notes/cl-notes.md +181 -0
@@ 1002,3 1002,184 @@ the method's specialized parameters."


# 17. CLOS: Classes
## `defclass`
defines user data type

	(defclass name (direct-superclass-name*)
	  (slot-specifier*))

Use `make-instance` function to create new instance.


## Slots
Slot is place that can hold a value, accesed by `slot-value` function
(`setf`able).

`print-object` function prints an object.


## Object Initialization
By default, slots are unbound (uninitialized).
- `:initarg` in `defclass` specify a name used as a keyword to
  `make-instance`
- `:initform` in `defclass` specify a Lisp expression used to compute a
  value if no `initarg` passed to `make-instance`
- define a method on the generic function `initialize-instance` that is
  called by `make-instance`


## Accessor functions
accessor:

	(defgeneric customer-name (account))

	(defmethod customer-name ((account bank-account))
	  (slot-value account 'customer-name))

setf function:

	(defun (setf customer-name) (name account)
	  (setf (slot-value account 'customer-name) name))

generic setf function:

	(defgeneric (setf customer-name) (value account))

	(defmethod (setf customer-name) (value (account bank-account))
	  (setf (slot-value account 'customer-name) value))

use as:

	(setf (customer-name *account*) "Sally Sue")

	(customer-name *account*)

create reader/writer functions automatically in `defclass`:
- `:reader` specifies a name of a generic function accepting object,
  returning slot
- `:writer` used to create a generic function and method to set the slot
  value
- `:accessor` creates reader/writer with the same name
- `:documentation`


## `with-slots`, `with-accessors`

	(with-slots (slot*) instance-form
	  body-form*)

`with-accessors` more-or-less the same (needs `(name accessor)` as
`slot*`) and preferred


## Class-allocated Slots
Use `:class` to make the slot shared by all instances. `:instance` is
the default.


## Slots and Inheritance
Merging of inherited slot specifiers.


## Multiple Inheritance
Ordering superclass list (class precedence list): by generation (first
super class, then super-super class) and when multiple inheritance --
"classes earlier in the list are considered more specific".

`call-next-method` in primary method calls the next method from class
precedence list. Probably better to use `:after` methods than rely on
convention that `call-next-method` would be called.


# 18. `format`
- directives start with a tilde `~`, ends with a single character
- between them are prefix parameters
	- `v` => format consume one argument and use the value as prefix
	  parameter
	- `#` => evaluated as the number of remaining format arguments
	- `,` => skip prefix parameter
- between prefix parameters and format directive, `:` (add `,` between
  every three digits) and `@` (add `+` to positive numbers) slightly
  changes output
- `~%` new line, do not consume argument
- `~&` fresh line, i.e. new line only when no new line
- `~5$` print float, 5 decimal places, consume one argument
- `~,5f` print float, 5 decimal places, consume one argument
- `~a` aesthetic output, consume one arg.
- `~s` tries output that could be readable by `read` (1 arg)
- `~c` emit character (1 arg)
- integer values directives:
	- `~d` (decimal), `~x` (hexadecimal), `~o` (octal), `~b`
	  (binary), `~r` (radix, first param is a base 2 to 36)
	- first param is padding length, second padding char, third
	  separator character, fourth number of digits per group
- floating point directives:
	- `~f` (decimal), `~e` (always computerized scientific
	  notation), `~g` (general, only for tabular), `~$` (monetary)
- `~r` print number as english words
- `~:p` "s" for plurals, `:` to reuse the previous (format) argument,
  `~:@p` "y" or "ies" based on plurals
- `~(` and `~)` in between to lowercase, `~@(` capitalize the first
  word, `~:(` capitalize all words, `~:@` to uppercase
- `~[` and `~]` is conditional directive, in between clauses separated
  by `~;` -- takes 1 arg that is 0-based index to "in between clauses",
  if `~:;` then the last clause is the default, if `~#[` clause selected
  based on the number of remaining (format) arguments, if `~:[` only two
  clauses -- 1st if arg. is nil, the second otherwise, if `~@[` only one
  clause -- if not nil, reuse the argument in clause
- `~{` and `~}` is iterative directive -- iterate over the lements of a
  list, `~^` -- stop iteration immediately when no more elemnts in the
  list, if `~@{` then the remaining (format) arguments processed as a
  list, within `~{` and `~}`, `#` is number of remaining elements of the
  list, nested iteration with `~@{`, `~:}` forces loop to run at least
  once event the list is empty
- `~*` skip one argument, `~:*` jump to previous argument (next
  directive reuse it), when prefix parameter (number) used, it jumps the
  number of arguments, when combined with `@`, the index is absolute
  (0-based)


# 19. Condition System
_Signal_ a condition, _handle_ it, and _restart_.

A _condition_ contains particular detailed info about what/why/when/how
signaled.

- `define-condition` macro to define condition class, but `slot-value`
  does not work, use `:reader` or `:accessor`
- `make-condition` function to make instance of condition
- `error` function (that calls lower-level function `signal`) to signal
  an error

A _condition handler_ needs to be established before a condition is
signaled (above call to `signal`/`error` function on the call stack) to
avoid ending in the debugger.

- `handler-case` macro establishes handler that unwinds the stack to the
  place it has been established and the runs some code. this is the
  closest to the exception handling in the other programming languages.

defined as:

	(handler-case expression
	  error-clause*)

where each `error-clause` is:

	(condition-type ([var]) code)

The code that actually recovers from errors is put into _restarts_
invoked by condition handlers.

`restart-case` macro establishes a restart -- similar to `handler-case`,
but "condition-type" doesn't need to be the name of a condition type --
it should say what the restart do.

`handler-bind` establishes a condition handler that invokes a restart:

	(handler-bind (binding*) form*)

TODO ...


# 24. Parsing Binary Files (practical)