The clj-con Reference Manual

Table of Contents

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

The clj-con Reference Manual

This is the clj-con Reference Manual, version 0.1.0, generated automatically by Declt version 3.0 "Montgomery Scott" on Wed Oct 13 10:27:07 2021 GMT+0.


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

1 Introduction

About

clj-con defines a set of concurrency operations modeled after their Clojure counterparts. Sample operators include future, promise, deref, deliver, and atom. See the exported symbols in package.lisp for the full list.

Or, if you're familiar with the Clojure Cheatsheet, the project implements the following:

Cheatsheet Screenshot

along with promise and deliver.

Usage

If you didn't get this via quickload from the quickload repo (because it isn't there yet), add it to your ~/quicklisp/localprojects/ directory, update/wipe the system-index.txt file accordingly, and then you can quickload it.

;; See 'local-projects' note in preceding paragraph            
(ql:quickload :clj-con) ; to use the code

or

;; To run the test (again, see 'local-projects' note)
(ql:quickload :clj-con-test)
(clj-con-test:run-tests)

Implementation Status

The current implementation was tested on sbcl and abcl successfully (with 20 iterations of run-tests on each, because, you know, threads and all).

The definitions are meant to be portable and are implemented entirely on Bordeaux Threads, but for those same reasons they aren't terribly efficient (as BT has no condition variable broadcast, no compare-and-set, and so on). At some point I could see adding some optimized conditional compilations.

Differences from Clojure

reset-vals! and swap-vals! return vectors in Clojure but return multiple values here. I couldn't see the point of returning vectors when CL has no destructuring bind (outside of LOOP?) that works on vectors. At least you can use multiple-value-bind if you want.

atom package conflict

If you're going to (use :clj-con), note that atom requires a (:shadowing-import-from #:clj-con #:atom). I'm open to better ways to do this, I'm not much practiced in the arts of Common Lisp packages.

Use of interrupt-thread by future-cancel

The Java Virtual Machine's threading tools are really a marvelous thing. If you've been in that ecosystem a long time, going back to pthreads with some of its limitations (or lisp oddities built on them), will feel fragile, and reading the various SBCL source comments on interrupt-thread doesn't do much to prevent that feeling.

As this implementation is more a trial balloon than anything else, have a care about repeatedly interrupting threads or using complicated mission critical handlers in the threads unless you have taken to heart the use of WITHOUT-INTERRUPTS and other implementation dependent things. I didn't hit any problems with my simple tests but that isn't saying much.

Non-Goals

There is no attempt here to bring clojure syntax or persistent data structures to Common Lisp. Fortunately neither of those things is particularly prevalent in Clojure's concurrency operator model, at least not in the clojure.core namespace.

Some enterprising person might want to make a readtable that maps @ to deref, assuming it doesn't conflict with ,@, but that hasn't been done here so you'll just have to call deref.

Blocking Queues?

If you're missing clojure.core.async and want some blocking queues for producer/consumer situations, take a look at the lparallel.queue package (ql:quickload :lparallel). Unlike clojure.core.async it has a peek operator which I find useful when I need to speculatively try something on a queue element without losing FIFO ordering.

Feedback welcome

(reverse "moc.liamg@ynnet.evad")


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 clj-con

Author

Dave Tenny

License

MIT

Description

Implements Clojure-styled concurrency operations such as ‘future‘ and ‘promise‘.

Version

0.1.0

Dependency

bordeaux-threads

Source

clj-con.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 clj-con.asd

Location

clj-con.asd

Systems

clj-con (system)

Packages

clj-con-asd


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

3.1.2 clj-con/package.lisp

Parent

clj-con (system)

Location

package.lisp

Packages

clj-con


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

3.1.3 clj-con/clj-con.lisp

Parent

clj-con (system)

Location

clj-con.lisp

Exported Definitions
Internal Definitions

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

3.1.4 clj-con/atom.lisp

Parent

clj-con (system)

Location

atom.lisp

Exported Definitions
Internal Definitions

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

4 Packages

Packages are listed by definition order.


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

4.1 clj-con-asd

Source

clj-con.asd

Use List

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

4.2 clj-con

Functions and macros that implement concurrency operations styled after Clojure operators such as ‘future‘ and ‘promise‘. Note that timeouts in this module are also similar to those found in Clojure and/or the JVM and are expressed as millisecond values, even though Common Lisp normally specifies timeouts as seconds (or fractions thereof).

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


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

5.1.1 Macros

Macro: future &body BODY

Takes a body of expressions and yields a future object that will
invoke the body in another thread, and will cache the result and
return it on all subsequent calls to deref. If the computation has
not yet finished, calls to deref will block, unless the variant of
deref with timeout is used. See also - realized?.

Note that multiple-value returns are lost, only the first (assumed) value is returned.

Package

clj-con

Source

clj-con.lisp (file)


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

5.1.2 Functions

Function: atom &optional X

Creates and returns an Atom with an initial value of x.
Does not support validator and metadata arguments of the Clojure equivalent.

Package

clj-con

Source

atom.lisp (file)

Function: atom? OBJECT
Package

clj-con

Source

atom.lisp (file)

Function: compare-and-set! ATOM OLDVAL NEWVAL

Atomically sets the value of atom to newval if and only if the current value of the atom is identical (EQ) to oldval. Returns T if set happened, else NIL.

Package

clj-con

Source

atom.lisp (file)

Function: deliver PROMISE VAL

Delivers the supplied value to the promise, allowing the return of any blocked derefs. A subsequent call to deliver on a promise will have no effect.
Returns val.

Package

clj-con

Source

clj-con.lisp (file)

Function: future-call THUNK

Takes a function of no args and yields a future object that will invoke the function in another thread, and will cache the result and return it on all subsequent calls to deref. If the computation has not yet finished, calls to deref will block, unless the variant of deref with timeout is used. See also - realized?.

Package

clj-con

Source

clj-con.lisp (file)

Function: future-cancel FUTURE

Cancels the future, if possible.
Returns T if the cancellation request is successful, NIL if it is not.
Note that interrupting threads in CL is not as tidy as clojure See SB-THREAD::INTERRUPT-THREAD. Unless threads are carefully using sb-sys:without-interrupts,
their unwind handlers may not work right. Don’t expect something as robust as the JVM’s InterruptedException.

Package

clj-con

Source

clj-con.lisp (file)

Function: future-cancelled? FUTURE

Return T if the future was explicitly (and successfully) cancelled, NIL otherwise.

Package

clj-con

Source

clj-con.lisp (file)

Function: future-done? FUTURE

Return T if future is done, NIL otherwise.
It is ’done’ if it is in any state other than :ready (thus hasn’t started, or is executing the supplied forms).

Package

clj-con

Source

clj-con.lisp (file)

Function: future? OBJECT
Package

clj-con

Source

clj-con.lisp (file)

Function: promise ()

Returns a promise object that can be read with ‘deref‘ and set, once only, with ‘deliver‘. Calls to deref prior to delivery will block unless the variant of deref with timeout is used. All subsequent derefs will return the same delivered value without blocking. See also - ‘realized?‘.

Package

clj-con

Source

clj-con.lisp (file)

Function: reset! ATOM NEWVAL

Sets the value of atom to newval without regard for the current value. Returns newval.

Package

clj-con

Source

atom.lisp (file)

Function: reset-vals! ATOM NEWVAL

Sets the value of atom to newval. Returns multiple values ’(old new), the value of the atom before and after the reset.

Package

clj-con

Source

atom.lisp (file)

Function: swap! ATOM F &rest ARGS

Atomically swaps the value of atom to be:
(apply f current-value-of-atom args). Note that f may be called multiple times, and thus should be free of side effects. Returns the value that was swapped in.

Package

clj-con

Source

atom.lisp (file)

Function: swap-vals! ATOM F &rest ARGS

Atomically swaps the value of atom to be:
(apply f current-value-of-atom args). Note that f may be called
multiple times, and thus should be free of side effects. Returns un-Clojure-y multiple values ‘(old new)‘, the value of the atom before and after the swap.

Package

clj-con

Source

atom.lisp (file)


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

5.1.3 Generic functions

Generic Function: deref THING &optional TIMEOUT-MS TIMEOUT-VAL

Used on various objects to obtain a value from an asynchronous construct.

When applied to an atom, yields the current value of the atom.

When applied to a future, will block if computation not complete.
If the future completed unsuccessfully, deref will signal either cancellation-exception
or execution-exception depending on whether it was cancelled or unwound due to unhandled conditions.

When applied to a promise, will block until a value is delivered.

When called with timeout options (valid only for promises and futures),
can be used for blocking and will return
timeout-val if the timeout (in milliseconds) is reached before a
value is available. See also - realized?.

Package

clj-con

Source

clj-con.lisp (file)

Methods
Method: deref (ATOM atom) &optional TIMEOUT-MS TIMEOUT-VAL
Source

atom.lisp (file)

Method: deref (F future) &optional TIMEOUT-MS TIMEOUT-VAL
Method: deref (P promise) &optional TIMEOUT-MS TIMEOUT-VAL
Generic Function: realized? X

Returns true if a value has been produced for a promise or future, nil otherwise.

Package

clj-con

Source

clj-con.lisp (file)

Methods
Method: realized? (F future)
Method: realized? (P promise)

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

5.1.4 Structures

Structure: atom ()
Package

clj-con

Source

atom.lisp (file)

Direct superclasses

structure-object (structure)

Direct methods

deref (method)

Direct slots
Slot: lock
Readers

atom-lock (function)

Writers

(setf atom-lock) (function)

Slot: value
Readers

atom-value (function)

Writers

(setf atom-value) (function)

Structure: future ()

A future object returned by the ‘future‘ macro.

Package

clj-con

Source

clj-con.lisp (file)

Direct superclasses

structure-object (structure)

Direct methods
Direct slots
Slot: thread
Readers

future-thread (function)

Writers

(setf future-thread) (function)

Slot: status
Readers

future-status (function)

Writers

(setf future-status) (function)

Slot: promise
Readers

future-promise (function)

Writers

(setf future-promise) (function)

Structure: promise ()

A promise object as created by the ‘promise‘ function.

Package

clj-con

Source

clj-con.lisp (file)

Direct superclasses

structure-object (structure)

Direct methods
Direct slots
Slot: condition-variable
Readers

promise-condition-variable (function)

Writers

(setf promise-condition-variable) (function)

Slot: lock
Readers

promise-lock (function)

Writers

(setf promise-lock) (function)

Slot: waiter-count
Readers

promise-waiter-count (function)

Writers

(setf promise-waiter-count) (function)

Slot: value
Readers

promise-value (function)

Writers

(setf promise-value) (function)


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

5.2 Internal definitions


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

5.2.1 Macros

Macro: with-future-lock FUTURE &body BODY

Execute body with the future locked.

Package

clj-con

Source

clj-con.lisp (file)


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

5.2.2 Functions

Function: atom-lock INSTANCE
Function: (setf atom-lock) VALUE INSTANCE
Package

clj-con

Source

atom.lisp (file)

Function: atom-value INSTANCE
Function: (setf atom-value) VALUE INSTANCE
Package

clj-con

Source

atom.lisp (file)

Function: copy-atom INSTANCE
Package

clj-con

Source

atom.lisp (file)

Function: copy-future INSTANCE
Package

clj-con

Source

clj-con.lisp (file)

Function: copy-promise INSTANCE
Package

clj-con

Source

clj-con.lisp (file)

Function: future-promise INSTANCE
Function: (setf future-promise) VALUE INSTANCE
Package

clj-con

Source

clj-con.lisp (file)

Function: future-status INSTANCE
Function: (setf future-status) VALUE INSTANCE
Package

clj-con

Source

clj-con.lisp (file)

Function: future-thread INSTANCE
Function: (setf future-thread) VALUE INSTANCE
Package

clj-con

Source

clj-con.lisp (file)

Function: make-atom &key (LOCK LOCK) (VALUE VALUE)
Package

clj-con

Source

atom.lisp (file)

Function: make-future &key (THREAD THREAD) (STATUS STATUS) (PROMISE PROMISE)
Package

clj-con

Source

clj-con.lisp (file)

Function: make-promise &key (CONDITION-VARIABLE CONDITION-VARIABLE) (LOCK LOCK) (WAITER-COUNT WAITER-COUNT) (VALUE VALUE)
Package

clj-con

Source

clj-con.lisp (file)

Function: promise-condition-variable INSTANCE
Function: (setf promise-condition-variable) VALUE INSTANCE
Package

clj-con

Source

clj-con.lisp (file)

Function: promise-lock INSTANCE
Function: (setf promise-lock) VALUE INSTANCE
Package

clj-con

Source

clj-con.lisp (file)

Function: promise-p OBJECT
Package

clj-con

Source

clj-con.lisp (file)

Function: promise-realized? P

True if value has been supplied, caller must lock before calling.

Package

clj-con

Source

clj-con.lisp (file)

Function: promise-value INSTANCE
Function: (setf promise-value) VALUE INSTANCE
Package

clj-con

Source

clj-con.lisp (file)

Function: promise-waiter-count INSTANCE
Function: (setf promise-waiter-count) VALUE INSTANCE
Package

clj-con

Source

clj-con.lisp (file)

Function: update-future-status FUTURE NEW-STATUS

Acquire a lock on the future and update its status to ‘new-status‘. Return the old status.

Package

clj-con

Source

clj-con.lisp (file)


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

5.2.3 Conditions

Condition: cancellation-exception ()

Signalled by deref (in the calling thread) when a a ‘future‘ thread was cancelled. Named for similarity to clojure/java behavior on deref.

Package

clj-con

Source

clj-con.lisp (file)

Direct superclasses

error (condition)

Condition: execution-exception ()

Signalled by deref (in the calling thread) when a ‘future‘ thread unwound its stack with an unhandled signal. Named for similarity to clojure/java behavior on deref.

Package

clj-con

Source

clj-con.lisp (file)

Direct superclasses

error (condition)

Condition: thread-interrupted ()

The thread-interrupted condition is signalled in ‘future‘ threads when ‘future-cancel‘ is called.

Package

clj-con

Source

clj-con.lisp (file)

Direct superclasses

condition (condition)


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
clj-con.asd: The clj-con․asd file
clj-con/atom.lisp: The clj-con/atom․lisp file
clj-con/clj-con.lisp: The clj-con/clj-con․lisp file
clj-con/package.lisp: The clj-con/package․lisp file

F
File, Lisp, clj-con.asd: The clj-con․asd file
File, Lisp, clj-con/atom.lisp: The clj-con/atom․lisp file
File, Lisp, clj-con/clj-con.lisp: The clj-con/clj-con․lisp file
File, Lisp, clj-con/package.lisp: The clj-con/package․lisp file

L
Lisp File, clj-con.asd: The clj-con․asd file
Lisp File, clj-con/atom.lisp: The clj-con/atom․lisp file
Lisp File, clj-con/clj-con.lisp: The clj-con/clj-con․lisp file
Lisp File, clj-con/package.lisp: The clj-con/package․lisp file

Jump to:   C   F   L  

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

A.2 Functions

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

(
(setf atom-lock): Internal functions
(setf atom-value): Internal functions
(setf future-promise): Internal functions
(setf future-status): Internal functions
(setf future-thread): Internal functions
(setf promise-condition-variable): Internal functions
(setf promise-lock): Internal functions
(setf promise-value): Internal functions
(setf promise-waiter-count): Internal functions

A
atom: Exported functions
atom-lock: Internal functions
atom-value: Internal functions
atom?: Exported functions

C
compare-and-set!: Exported functions
copy-atom: Internal functions
copy-future: Internal functions
copy-promise: Internal functions

D
deliver: Exported functions
deref: Exported generic functions
deref: Exported generic functions
deref: Exported generic functions
deref: Exported generic functions

F
Function, (setf atom-lock): Internal functions
Function, (setf atom-value): Internal functions
Function, (setf future-promise): Internal functions
Function, (setf future-status): Internal functions
Function, (setf future-thread): Internal functions
Function, (setf promise-condition-variable): Internal functions
Function, (setf promise-lock): Internal functions
Function, (setf promise-value): Internal functions
Function, (setf promise-waiter-count): Internal functions
Function, atom: Exported functions
Function, atom-lock: Internal functions
Function, atom-value: Internal functions
Function, atom?: Exported functions
Function, compare-and-set!: Exported functions
Function, copy-atom: Internal functions
Function, copy-future: Internal functions
Function, copy-promise: Internal functions
Function, deliver: Exported functions
Function, future-call: Exported functions
Function, future-cancel: Exported functions
Function, future-cancelled?: Exported functions
Function, future-done?: Exported functions
Function, future-promise: Internal functions
Function, future-status: Internal functions
Function, future-thread: Internal functions
Function, future?: Exported functions
Function, make-atom: Internal functions
Function, make-future: Internal functions
Function, make-promise: Internal functions
Function, promise: Exported functions
Function, promise-condition-variable: Internal functions
Function, promise-lock: Internal functions
Function, promise-p: Internal functions
Function, promise-realized?: Internal functions
Function, promise-value: Internal functions
Function, promise-waiter-count: Internal functions
Function, reset!: Exported functions
Function, reset-vals!: Exported functions
Function, swap!: Exported functions
Function, swap-vals!: Exported functions
Function, update-future-status: Internal functions
future: Exported macros
future-call: Exported functions
future-cancel: Exported functions
future-cancelled?: Exported functions
future-done?: Exported functions
future-promise: Internal functions
future-status: Internal functions
future-thread: Internal functions
future?: Exported functions

G
Generic Function, deref: Exported generic functions
Generic Function, realized?: Exported generic functions

M
Macro, future: Exported macros
Macro, with-future-lock: Internal macros
make-atom: Internal functions
make-future: Internal functions
make-promise: Internal functions
Method, deref: Exported generic functions
Method, deref: Exported generic functions
Method, deref: Exported generic functions
Method, realized?: Exported generic functions
Method, realized?: Exported generic functions

P
promise: Exported functions
promise-condition-variable: Internal functions
promise-lock: Internal functions
promise-p: Internal functions
promise-realized?: Internal functions
promise-value: Internal functions
promise-waiter-count: Internal functions

R
realized?: Exported generic functions
realized?: Exported generic functions
realized?: Exported generic functions
reset!: Exported functions
reset-vals!: Exported functions

S
swap!: Exported functions
swap-vals!: Exported functions

U
update-future-status: Internal functions

W
with-future-lock: Internal macros

Jump to:   (  
A   C   D   F   G   M   P   R   S   U   W  

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

A.3 Variables

Jump to:   C   L   P   S   T   V   W  
Index Entry  Section

C
condition-variable: Exported structures

L
lock: Exported structures
lock: Exported structures

P
promise: Exported structures

S
Slot, condition-variable: Exported structures
Slot, lock: Exported structures
Slot, lock: Exported structures
Slot, promise: Exported structures
Slot, status: Exported structures
Slot, thread: Exported structures
Slot, value: Exported structures
Slot, value: Exported structures
Slot, waiter-count: Exported structures
status: Exported structures

T
thread: Exported structures

V
value: Exported structures
value: Exported structures

W
waiter-count: Exported structures

Jump to:   C   L   P   S   T   V   W  

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

A.4 Data types

Jump to:   A   C   E   F   P   S   T  
Index Entry  Section

A
atom: Exported structures

C
cancellation-exception: Internal conditions
clj-con: The clj-con system
clj-con: The clj-con package
clj-con-asd: The clj-con-asd package
Condition, cancellation-exception: Internal conditions
Condition, execution-exception: Internal conditions
Condition, thread-interrupted: Internal conditions

E
execution-exception: Internal conditions

F
future: Exported structures

P
Package, clj-con: The clj-con package
Package, clj-con-asd: The clj-con-asd package
promise: Exported structures

S
Structure, atom: Exported structures
Structure, future: Exported structures
Structure, promise: Exported structures
System, clj-con: The clj-con system

T
thread-interrupted: Internal conditions

Jump to:   A   C   E   F   P   S   T