The cl-with Reference Manual

Table of Contents

Next: , Previous: , Up: (dir)   [Contents][Index]

The cl-with Reference Manual

This is the cl-with Reference Manual, version 0.0.1, generated automatically by Declt version 3.0 "Montgomery Scott" on Sun May 15 04:19:13 2022 GMT+0.


Next: , Previous: , Up: Top   [Contents][Index]

1 Introduction

WITH-

WITH- is a universal macro that:

BINDING single and multiple values

It is easy to bind one or more variables in a with- statement

(with- (i 9) (print i))              ;like (let ((i 9))...

(with- ((j k) (values 1 2))...)      ;like (multiple-value-bind (j k)(values 1 2)...

CLASS, STRUCT and CFFI object integration

More importantly, WITH- unifies the syntax for dealing with structs, classes, and foreign CFFI objects, extracting and rebinding slot accessors (automatically or selectively). The syntax establishes a clear distinction between existing object, temporary objects and newly-created object that are expected to outlive the statement.

Syntactically, it resembles a binding initialized with an existing object (:OLD), or newly-created object (:NEW or :TEMP). CFFI objects created as :TEMP are destroyed at the end of the scope.

(defstruct spoint x y)
(with- (pt :new 'spoint)
  (setf x 10 y 20)  ;with- automatically bound slot accessors
  pt)

(with- ((p   :temp :int)                              ; like with-foreign-object
        (gpt :temp (:struct gtk:g-point) "P1-")       ; prefixed: p1-x and p1-y 
        (spt :old 'q:spoint "P2-")                    ; existing instance, p2-x etc.
        (ppp :new 'graphics:point (h hor)(v ver)))    ; rename graphics::hor to h, etc.
  (setf p1-x p2-x              ;note that bindings are package-local!
        p1-y p2-y)             ;and prefixed to differentiate multiple objects
  (setf h (+ p1-x p2-x)
        v (- p1-x 3))
  ppp) ; return :new or :old object, never :temp objects!

License

BSD 3-clause License

Installation

Clone the repo into a visible directory and evaluate (ql:quickload "CL-WITH") or equivalent ASDF magic.

In your project, add system CL-WITH to the dependency list of your .asd file, and package WITH to your defpackage :USE line. ` This library requires uses (and internally depends on) CFFI and CLOSER-MOP.

Usage

(with- clause(s) body)

A with- statement may contain a single clause or a list of clauses. Each clause is a list. Each clause has access to bindings created by all previous clauses, and may create additional bindings.

WITH- macro aggregation

A clause may start with a shortened, keyword version of any existing with- macro, with the 'with-' prefix removed and : prepended). The rest of the list contains whatever the original macro expects for its parameters.

Example:

(with- (:open-file (s "test.txt" :direction :output))
  (print s "Hello"))

If the with-macro is in another package and is not imported, instead of using a keyword, use a quoted symbol with the package specification:

(with- ('another-package:foo ...)..) ; same as (another-package:with-foo ...

BINDING

A clause may start with a symbol, in which case it acts much like a let form. Any list elements that follow will be construed as the initialization form.

A list of symbols acts as a multiple-value-bind form.

(with- ((q "test.txt")
        (:open-file (s q))
        ((found status) (find-symbol "FOO")))
  (format t "~A ~A ~A " s found status))

The initializers for such bindings are regular Lisp code (that is, they are not WITH- clauses). Any symbols bound in previous clauses are available to initializers (perhaps this macro should be called with*. Needless to say, any local scopes established inside initializers are not visible to the main body. That is:

(with- ((j 100)
       (q (let ((invisible (+ j 99)))) ;j is visible here
            invisible)))
  (print q) ;199 - this is fine
  (print invisible); *** ERROR  invisible is not in scope!
)

STRUCT, CLASS or CFFI instance manipulation

A clause may also bind a slotted object or a CFFI foreign object:

(instance :new|:temp|:old type [prefix] [bindings]

INSTANCE

instance     If :old, a reference to an existing object or a symbol 
             bound to an existing object; or
	     If :new or :temp -- a symbol that will be bound to 
	     a newly created object.

DISPOSITION

disposition  :new  to create a new object and bind to 'instance'
             :temp as above, but destroyed on exit if foreign
	     :old  to use an existing, bound 'instance'

:NEW clauses create a new object of type specified by type and create a lexical binding to the symbol instance. Since instance is lexical, you must return or assign the object prior to leaving the scope if you need it later. This is especially important for foreign objects, since no automatic deallocation takes place for objects created with the :NEW clause.

:TEMP clauses likewise create a new object of type and bind it to inst, but telegraph the intention to never use such an object outside the established scope. CFFI objects are automatically destroyed; Lisp objects are abandoned to be garbage collected later. You must not return or assign such objects outside the established scope.

:OLD clauses operate on existing objects - objects already bound to inst. For slotted objects, bindings are created as usual.

TYPE

type         A quoted symbol signifying struct or class name
             A symbol whose symbol-value is a type
	     A keyword denoting a simple CFFI type such as :int
	     A list representing a cffi type such as (:STRUCT ...)

The TYPE parameter specifies the type of the object for this clause. Note that Lisp class and struct types are quoted, while CFFI types such as (:struct foo) are not quoted.

For the sake of brevity, a variable containing a CFFI type may be used - as an unquoted symbol.

PREFIX

prefix       A string to be appended to all slot accessors for this instance
             Optional; default is ""

Prefix should generally be capitalized unless you truly intend to use lowercase symbols.

BINDINGS

bindings     One or more bindings in the format acceptable to 'with-slots' or 
             'with-foreign-slots', as appropriate.  Optional; defaults to
			 automatic extraction and rebinding of all slots in local package

If no bindings are specified, package-local bindings with names identical to the type's slot names will be generated. If one or more bindings are specified, only those bindings will be generated.

Bindings are always specified as package-local symbols; WITH- automatically deals with package issues.

The usual binding syntax for each slot binding is one of:

name                
(name slotname)

CFFI slotted objects also allow binding pointers to slots using one of:

(:pointer name)
(name :pointer slotname)

Example

(with- (p   :temp :int)                              ; like with-foreign-object
       (gpt :temp (:struct gtk:g-point) "P1-")       ; prefixed: p1-x and p1-y 
       (spt :old 'q:spoint "P2-")                    ; existing instance, p2-x etc.
       (ppp :new 'graphics:point "" (h hor)(v ver))  ; rename graphics::hor to h, etc.
(setf p1-x p2-x              ;note that bindings are package-local!
        p1-y p2-y)             ;and prefixed to differentiate multiple objects
  (setf h (+ p1-x p2-x)
        v (- p1-x 3))
  ppp) ```

BUILT-IN CFFI TYPE INSTANCES

Built-in CFFI types such as :INT are supported using a slightly different clause syntax

(instance :new|:temp|:old type [value-accessor] [pointer-accessor]

As usual, a clause may describe an existing binding (or actual data) in instance - or create a new one. In the case of :TEMP disposition, it will also be destroyed and should not be used outside of its scope.

In most cases, the INSTANCE parameter is a symbol bound to the pointer. By default, an automatic value accessor is generated, using the same name prefixed with *; i.e. clause (foo :temp :int) creates an environment in which *foo is the value accessor and foo is a pointer accessor.

It is always possible to choose different accessor names using the VALUE-ACCESSOR and POINTER-ACCESSOR parameters.

If INSTANCE parameter is not a symbol but an actual pointer, :OLD disposition must be used. Since there is no symbolic name to start with, default accessor names are PTR and VAL. This may be sufficient if only one clause is used; otherise, it is best to specify the names of both pointer and value accessors for each clause.

POINTER ACCESSOR

If POINTER-ACCESSOR is specified, it may be used to fetch the object's foreign pointer.

If it is not specified, a pointer accessor called PTR will be generated ONLY IF INST IS NOT A SYMBOL. This is done since there is no way to access the pointer otherwise. If INSTANCE is a symbol it is bound to the pointer and may be used freely.

VALUE ACCESSOR

If VALUE-ACCESSOR parameter is specified, it may be used to fetch the value of the object pointer using the specified TYPE.

If no VALUE-ACCESSOR parameter is specified, a value accessor will be automatically generated using INSTANCE prefixed with an asterisk if it's a symbol. If it is not a symbol, the default value accessor name is "VAL"

Example:

(defparameter *q* (foreign-alloc :int :initial-element 3 ))
(defparameter *r* (foreign-alloc :int :initial-element 5 ))

(with- ((z :new :int)     ;inst is a symbol, so *z is value accessor
        (#.*q* :old :int) ;inst is not a symbol; default VAL accessor
	    (*r* :old :int val-r)) ;VAL-R is specified - better than **R* :)
  (setf *z (+ val val-r))
  z)                     ;inst z is a valid pointer accessor

Notes

CL-WITH provides an additional macro WITH-CODE which may be used as part of the with- stack to evaluate arbitrary code for side-effects.

(with- (p :temp :int)
       (:code (format t "Allocated ~A~%" p))
	   ...

Next: , Previous: , Up: Top   [Contents][Index]

2 Systems

The main system appears first, followed by any subsystem dependency.


Previous: , Up: Systems   [Contents][Index]

2.1 cl-with

Author

stacksmith <fpgasm@apple2.x10.mx>

License

BSD 3-clause

Description

WITH- group with- macros, allocate objects and rebind slots

Version

0.0.1

Dependencies
Source

cl-with.asd (file)

Components

Next: , Previous: , Up: Top   [Contents][Index]

3 Files

Files are sorted by type and then listed depth-first from the systems components trees.


Previous: , Up: Files   [Contents][Index]

3.1 Lisp


Next: , Previous: , Up: Lisp files   [Contents][Index]

3.1.1 cl-with.asd

Location

cl-with.asd

Systems

cl-with (system)


Next: , Previous: , Up: Lisp files   [Contents][Index]

3.1.2 cl-with/package.lisp

Parent

cl-with (system)

Location

package.lisp

Packages

with


Next: , Previous: , Up: Lisp files   [Contents][Index]

3.1.3 cl-with/util.lisp

Dependency

package.lisp (file)

Parent

cl-with (system)

Location

util.lisp

Internal Definitions

Next: , Previous: , Up: Lisp files   [Contents][Index]

3.1.4 cl-with/with-foreign-slots.lisp

Dependency

util.lisp (file)

Parent

cl-with (system)

Location

with-foreign-slots.lisp


Previous: , Up: Lisp files   [Contents][Index]

3.1.5 cl-with/with.lisp

Dependency

with-foreign-slots.lisp (file)

Parent

cl-with (system)

Location

with.lisp

Exported Definitions
Internal Definitions

Next: , Previous: , Up: Top   [Contents][Index]

4 Packages

Packages are listed by definition order.


Previous: , Up: Packages   [Contents][Index]

4.1 with

Source

package.lisp (file)

Use List
Exported Definitions
Internal Definitions

Next: , Previous: , Up: Top   [Contents][Index]

5 Definitions

Definitions are sorted by export status, category, package, and then by lexicographic order.


Next: , Previous: , Up: Definitions   [Contents][Index]

5.1 Exported definitions


Previous: , Up: Exported definitions   [Contents][Index]

5.1.1 Macros

Macro: with- DESCRIPTOR-OR-DESCRIPTORS &body BODY

Expand descriptors, which may be:
* Existing with-foo forms, specified as (:open-file ...);
* Let-like forms, e.g. (x 5);
* Multiple-value-bind-like forms, ((x y z)(foo));
* Slots of structs, class instances or foreign objects:
(p :temp :int); create a foreign :int called p
(gpt :old (:struct gtk-g-point) "P1-") make slots x and y of an existing GTK point object called gpt available as ’p1-x’ and ’p1-y’.
Refer to docs for more examples

Package

with

Source

with.lisp (file)

Macro: with-code (&rest CODE) &body BODY
Package

with

Source

with.lisp (file)


Previous: , Up: Definitions   [Contents][Index]

5.2 Internal definitions


Next: , Previous: , Up: Internal definitions   [Contents][Index]

5.2.1 Special variables

Special Variable: *banlist*
Package

with

Source

with.lisp (file)

Special Variable: cpoint
Package

with

Source

with.lisp (file)


Next: , Previous: , Up: Internal definitions   [Contents][Index]

5.2.2 Macros

Macro: bancheck INST DESCRIPTOR
Package

with

Source

with.lisp (file)

Macro: listify THING
Package

with

Source

util.lisp (file)

Macro: with-many (DESCRIPTOR &rest DESCRIPTORS) &body BODY
Package

with

Source

with.lisp (file)

Macro: with-one DESCRIPTOR &body BODY
Package

with

Source

with.lisp (file)

Macro: with-with (SYMBOL &rest REST) &body BODY
Package

with

Source

with.lisp (file)


Next: , Previous: , Up: Internal definitions   [Contents][Index]

5.2.3 Functions

Function: as-string THING

Create a string from thing. If thing is a list or tree, flatten

Package

with

Source

util.lisp (file)

Function: catstring &rest THINGS

Convert every thing to a string, and return concatenation.

Package

with

Source

util.lisp (file)

Function: clause-get-prefix-binds PARAMS
Package

with

Source

with.lisp (file)

Function: copy-point INSTANCE
Package

with

Source

with.lisp (file)

Function: default-bindings PREFIX SLOTS
Package

with

Source

with.lisp (file)

Function: find-symbol-or-die NAME PACKAGE &rest REST
Package

with

Source

util.lisp (file)

Function: fix-cffi-bindings PREFIX BINDS SLOTS
Package

with

Source

with.lisp (file)

Function: fix-lisp-bindings PREFIX BINDS SLOTS
Package

with

Source

with.lisp (file)

Function: make-point &key (X X) (Y Y)
Package

with

Source

with.lisp (file)

Function: parse-foreign-built-in-type-params INST CFFITYPE PARAMS
Package

with

Source

with.lisp (file)

Function: point-p OBJECT
Package

with

Source

with.lisp (file)

Function: point-x INSTANCE
Function: (setf point-x) VALUE INSTANCE
Package

with

Source

with.lisp (file)

Function: point-y INSTANCE
Function: (setf point-y) VALUE INSTANCE
Package

with

Source

with.lisp (file)

Function: symbolicate &rest THINGS
Package

with

Source

util.lisp (file)


Next: , Previous: , Up: Internal definitions   [Contents][Index]

5.2.4 Generic functions

Generic Function: get-new-clause INST CLASS BODY &rest REST
Package

with

Methods
Method: get-new-clause INST (CFFITYPE foreign-built-in-type) BODY &rest REST
Source

with.lisp (file)

Method: get-new-clause INST (CFFITYPE foreign-type) BODY &rest REST
Source

with.lisp (file)

Method: get-new-clause INST (CLASS class) BODY &rest REST
Source

with.lisp (file)

Generic Function: get-old-clause INST CLASS BODY &rest REST
Package

with

Methods
Method: get-old-clause INST (CFFITYPE foreign-built-in-type) BODY &rest REST
Source

with.lisp (file)

Method: get-old-clause INST (CFFITYPE foreign-type) BODY &rest REST
Source

with.lisp (file)

Method: get-old-clause INST (CLASS class) BODY &rest REST
Source

with.lisp (file)

Generic Function: get-slots CLASS
Package

with

Methods
Method: get-slots (CFFITYPE foreign-type)
Source

with.lisp (file)

Method: get-slots (CLASS class)
Source

with.lisp (file)

Generic Function: get-temp-clause INST CLASS BODY &rest REST
Package

with

Methods
Method: get-temp-clause INST (CFFITYPE foreign-built-in-type) BODY &rest REST
Source

with.lisp (file)

Method: get-temp-clause INST (CFFITYPE foreign-type) BODY &rest REST
Source

with.lisp (file)

Method: get-temp-clause INST (CLASS class) BODY &rest REST
Source

with.lisp (file)

Generic Function: get-type-info TYPE CLAUSE &optional RECURSING
Package

with

Methods
Method: get-type-info (CLASS standard-class) CLAUSE &optional RECURSING
Source

with.lisp (file)

Method: get-type-info (CLASS structure-class) CLAUSE &optional RECURSING
Source

with.lisp (file)

Method: get-type-info (TYPE foreign-type) CLAUSE &optional RECURSING
Source

with.lisp (file)

Method: get-type-info (TYPE symbol) CLAUSE &optional RECURSING
Source

with.lisp (file)

Method: get-type-info (TYPE cons) CLAUSE &optional RECURSING
Source

with.lisp (file)

Method: get-type-info TYPE CLAUSE &optional RECURSING
Source

with.lisp (file)


Next: , Previous: , Up: Internal definitions   [Contents][Index]

5.2.5 Structures

Structure: point ()
Package

with

Source

with.lisp (file)

Direct superclasses

structure-object (structure)

Direct slots
Slot: x
Readers

point-x (function)

Writers

(setf point-x) (function)

Slot: y
Readers

point-y (function)

Writers

(setf point-y) (function)


Previous: , Up: Internal definitions   [Contents][Index]

5.2.6 Classes

Class: cpoint ()
Package

with

Source

with.lisp (file)

Direct superclasses
  • translatable-foreign-type (class)
  • foreign-struct-type (class)

Previous: , Up: Top   [Contents][Index]

Appendix A Indexes


Next: , Previous: , Up: Indexes   [Contents][Index]

A.1 Concepts

Jump to:   C   F   L  
Index Entry  Section

C
cl-with.asd: The cl-with․asd file
cl-with/package.lisp: The cl-with/package․lisp file
cl-with/util.lisp: The cl-with/util․lisp file
cl-with/with-foreign-slots.lisp: The cl-with/with-foreign-slots․lisp file
cl-with/with.lisp: The cl-with/with․lisp file

F
File, Lisp, cl-with.asd: The cl-with․asd file
File, Lisp, cl-with/package.lisp: The cl-with/package․lisp file
File, Lisp, cl-with/util.lisp: The cl-with/util․lisp file
File, Lisp, cl-with/with-foreign-slots.lisp: The cl-with/with-foreign-slots․lisp file
File, Lisp, cl-with/with.lisp: The cl-with/with․lisp file

L
Lisp File, cl-with.asd: The cl-with․asd file
Lisp File, cl-with/package.lisp: The cl-with/package․lisp file
Lisp File, cl-with/util.lisp: The cl-with/util․lisp file
Lisp File, cl-with/with-foreign-slots.lisp: The cl-with/with-foreign-slots․lisp file
Lisp File, cl-with/with.lisp: The cl-with/with․lisp file

Jump to:   C   F   L  

Next: , Previous: , Up: Indexes   [Contents][Index]

A.2 Functions

Jump to:   (  
A   B   C   D   F   G   L   M   P   S   W  
Index Entry  Section

(
(setf point-x): Internal functions
(setf point-y): Internal functions

A
as-string: Internal functions

B
bancheck: Internal macros

C
catstring: Internal functions
clause-get-prefix-binds: Internal functions
copy-point: Internal functions

D
default-bindings: Internal functions

F
find-symbol-or-die: Internal functions
fix-cffi-bindings: Internal functions
fix-lisp-bindings: Internal functions
Function, (setf point-x): Internal functions
Function, (setf point-y): Internal functions
Function, as-string: Internal functions
Function, catstring: Internal functions
Function, clause-get-prefix-binds: Internal functions
Function, copy-point: Internal functions
Function, default-bindings: Internal functions
Function, find-symbol-or-die: Internal functions
Function, fix-cffi-bindings: Internal functions
Function, fix-lisp-bindings: Internal functions
Function, make-point: Internal functions
Function, parse-foreign-built-in-type-params: Internal functions
Function, point-p: Internal functions
Function, point-x: Internal functions
Function, point-y: Internal functions
Function, symbolicate: Internal functions

G
Generic Function, get-new-clause: Internal generic functions
Generic Function, get-old-clause: Internal generic functions
Generic Function, get-slots: Internal generic functions
Generic Function, get-temp-clause: Internal generic functions
Generic Function, get-type-info: Internal generic functions
get-new-clause: Internal generic functions
get-new-clause: Internal generic functions
get-new-clause: Internal generic functions
get-new-clause: Internal generic functions
get-old-clause: Internal generic functions
get-old-clause: Internal generic functions
get-old-clause: Internal generic functions
get-old-clause: Internal generic functions
get-slots: Internal generic functions
get-slots: Internal generic functions
get-slots: Internal generic functions
get-temp-clause: Internal generic functions
get-temp-clause: Internal generic functions
get-temp-clause: Internal generic functions
get-temp-clause: Internal generic functions
get-type-info: Internal generic functions
get-type-info: Internal generic functions
get-type-info: Internal generic functions
get-type-info: Internal generic functions
get-type-info: Internal generic functions
get-type-info: Internal generic functions
get-type-info: Internal generic functions

L
listify: Internal macros

M
Macro, bancheck: Internal macros
Macro, listify: Internal macros
Macro, with-: Exported macros
Macro, with-code: Exported macros
Macro, with-many: Internal macros
Macro, with-one: Internal macros
Macro, with-with: Internal macros
make-point: Internal functions
Method, get-new-clause: Internal generic functions
Method, get-new-clause: Internal generic functions
Method, get-new-clause: Internal generic functions
Method, get-old-clause: Internal generic functions
Method, get-old-clause: Internal generic functions
Method, get-old-clause: Internal generic functions
Method, get-slots: Internal generic functions
Method, get-slots: Internal generic functions
Method, get-temp-clause: Internal generic functions
Method, get-temp-clause: Internal generic functions
Method, get-temp-clause: Internal generic functions
Method, get-type-info: Internal generic functions
Method, get-type-info: Internal generic functions
Method, get-type-info: Internal generic functions
Method, get-type-info: Internal generic functions
Method, get-type-info: Internal generic functions
Method, get-type-info: Internal generic functions

P
parse-foreign-built-in-type-params: Internal functions
point-p: Internal functions
point-x: Internal functions
point-y: Internal functions

S
symbolicate: Internal functions

W
with-: Exported macros
with-code: Exported macros
with-many: Internal macros
with-one: Internal macros
with-with: Internal macros

Jump to:   (  
A   B   C   D   F   G   L   M   P   S   W  

Next: , Previous: , Up: Indexes   [Contents][Index]

A.3 Variables

Jump to:   *  
C   S   X   Y  
Index Entry  Section

*
*banlist*: Internal special variables

C
cpoint: Internal special variables

S
Slot, x: Internal structures
Slot, y: Internal structures
Special Variable, *banlist*: Internal special variables
Special Variable, cpoint: Internal special variables

X
x: Internal structures

Y
y: Internal structures

Jump to:   *  
C   S   X   Y  

Previous: , Up: Indexes   [Contents][Index]

A.4 Data types

Jump to:   C   P   S   W  
Index Entry  Section

C
cl-with: The cl-with system
Class, cpoint: Internal classes
cpoint: Internal classes

P
Package, with: The with package
point: Internal structures

S
Structure, point: Internal structures
System, cl-with: The cl-with system

W
with: The with package

Jump to:   C   P   S   W