EXT:ETHE
EXT:LETF
& EXT:LETF*
EXT:MEMOIZED
EXT:WITH-COLLECT
EXT:COMPILE-TIME-VALUE
EXT:WITH-GENSYMS
EXT:REMOVE-PLIST
EXT:WITH-HTML-OUTPUT
and EXT:WITH-HTTP-OUTPUT
EXT:OPEN-HTTP
and macro EXT:WITH-HTTP-INPUT
CUSTOM:*HTTP-LOG-STREAM*
EXT:BROWSE-URL
CUSTOM:*HTTP-PROXY*
EXT:CANONICALIZE
CLISP comes with some extension macros, mostly defined in the
file macros3.lisp
and loaded from the file init.lisp
during make:
EXT:ETHE
(
enforces a type check in both interpreted and compiled code.
EXT:ETHE
value-type
form
)
These macros are similar to LET
and LET*
, respectively,
except that they can bind places, even places with multiple values.
Example:
(letf (((values a b) form)) ...)
is equivalent to
(multiple-value-bind (a b) form ...)
while
(letf (((first l) 7)) ...)
is approximately equivalent to
(LET*
((#:g1 l) (#:g2 (first #:g1))) (UNWIND-PROTECT
(PROGN
(SETF
(first #:g1) 7) ...) (SETF
(first #:g1) #:g2)))
(
memoizes the primary value of EXT:MEMOIZED
form
)form
from its first evaluation.
EXT:WITH-COLLECT
Similar to the LOOP
's
COLLECT
construct, except that it is looks more "Lispy" and can appear
arbitrarily deep. It defines local macros (with MACROLET
) which
collect objects given to it into lists, which are then returned as
multiple values. E.g.,
(ext:with-collect (c0 c1) (dotimes (i 10) (if (oddp i) (c0 i) (c1 i)))) ⇒(1 3 5 7 9)
; ⇒(0 2 4 6 8)
returns two LIST
s as multiple values.
Sometimes one may want to call an expensive function at
compilation time and write the primary value into the #P".fas"
file,
thus speeding up loading the #P".fas"
file.
E.g., let your file primes.lisp
be
(defun primes-list (limit)
"Return the list of all primes smaller than LIMIT."
...)
(defvar *all-primes* (compile-time-value (primes-list MOST-POSITIVE-FIXNUM
)))
Then
(LOAD
"primes.lisp")
primes-list
and *all-primes*
will be NIL
.
(COMPILE-FILE
"primes.lisp")
primes-list
(and
will probably take a long time) and will write the resulting list
into (COMPILE-FILE-PATHNAME
"primes.lisp")
(LOAD
(COMPILE-FILE-PATHNAME
"primes.lisp"))
primes-list
but *all-primes*
will be the list computed during
compilation.An alternative is to save a memory image, which is faster than #P".fas"
file but less portable.
Similar to its namesake from Paul Graham's book “On Lisp”, this macro is useful for writing other macros:
(with-gensyms ("FOO-" bar baz zot) ...)
expands to
(let ((bar (gensym "FOO-BAR-")) (baz (gensym "FOO-BAZ-")) (zot (gensym "FOO-ZOT-"))) ...)
Similar to REMOVE
and REMF
, this function removes some
properties from a property list. It is non-destructive and thus can be
used on &REST
arguments to remove some keyword parameters, e.g.,
(defmacro with-foo ((&KEY
foo1 foo2)&BODY
body) `(... ,foo1 ... ,foo2 ... ,@body)) (defmacro with-foo-bar ((&REST
opts&KEY
bar1 bar2&ALLOW-OTHER-KEYS
)&BODY
body) `(with-foo (,@(remove-plist opts :bar1 :bar2) ... ,bar1 ... ,bar2 ... ,@body))) (defun foo-bar () (with-foo-bar (:bar1 1 :foo2 2) ...))
here WITH-FOO
does not receive the
:BAR1 1
argument from FOO-BAR
.
Defined in inspect.lisp
, these macros are useful
for the rudimentary HTTP server defined there.
EXT:OPEN-HTTP
and
macro EXT:WITH-HTTP-INPUT
Defined in
clhs.lisp
,
they allow downloading data over the Internet using the HTTP protocol.
(
opens
a socket connection to the EXT:OPEN-HTTP
url &KEY
:IF-DOES-NOT-EXIST
:LOG)url
host,
sends the GET request,
and returns two values: the SOCKET:SOCKET-STREAM
and content length.
(EXT:WITH-HTTP-INPUT (
binds variable
url) &BODY
body)variable
to the SOCKET:SOCKET-STREAM
returned by EXT:OPEN-HTTP
and executes the body
.
(EXT:WITH-HTTP-INPUT ((
additionally binds variable
contents
) url) &BODY
body)contents
to the content length.
EXT:OPEN-HTTP
will check CUSTOM:*HTTP-PROXY*
on startup and parse the environment variable
HTTP_PROXY
if CUSTOM:*HTTP-PROXY*
is NIL
.
The :LOG
argument binds CUSTOM:*HTTP-LOG-STREAM*
.
CUSTOM:*HTTP-LOG-STREAM*
Function EXT:OPEN-HTTP
logs its actions to CUSTOM:*HTTP-LOG-STREAM*
which is initially set to *TERMINAL-IO*
.
EXT:BROWSE-URL
Function (
calls a browser on the URL. EXT:BROWSE-URL
url &KEY
:BROWSER
:OUT
)browser
(defaults to CUSTOM:*BROWSER*
) should be a valid keyword in the CUSTOM:*BROWSERS*
association list.
:OUT
specifies the stream where the progress messages are printed
(defaults to *STANDARD-OUTPUT*
).
CUSTOM:*HTTP-PROXY*
If you are behind a proxy server, you will need to set CUSTOM:*HTTP-PROXY*
to
a LIST
(name:password host port)
.
By default, the environment variable http_proxy
is used, the
expected format is "name:password@host:port"
.
If no #\@
is present,
name
and password
are NIL
.
If no #\:
is present,
password
(or port
) is NIL
.
Use function (EXT:HTTP-PROXY
to reset
&OPTIONAL
(STRING
(EXT:GETENV
"http_proxy")))CUSTOM:*HTTP-PROXY*
.
EXT:CANONICALIZE
If you want to canonicalize a value
before further processing it, you
can pass it to EXT:CANONICALIZE
together with a SEQUENCE
of FUNCTION
s:
(
will call EXT:CANONICALIZE
value
functions
&KEY
(test 'EQL
) (max-iter 1024))function
s on
value
until it stabilizes under test
(which should be a valid HASH-TABLE-TEST
) and return the stabilized
value and the number of iterations the stabilization required.
E.g., clx/new-clx
uses it together with
XLIB:*CANONICALIZE-ENCODING*
to fix the broken encoding names returned by the X Window System (e.g., convert
"iso8859-1"
to "ISO-8859-1"
)
before passing them over to EXT:MAKE-ENCODING
. If you encounter an EXT:ENCODING
ERROR
in clx/new-clx
, you can augment this variable to avoid it.
These notes document CLISP version 2.49.93+ | Last modified: 2018-02-19 |