EXT:ETHEEXT:LETF & EXT:LETF*EXT:MEMOIZEDEXT:WITH-COLLECTEXT:COMPILE-TIME-VALUEEXT:WITH-GENSYMSEXT:REMOVE-PLISTEXT:WITH-HTML-OUTPUT and EXT:WITH-HTTP-OUTPUTEXT:OPEN-HTTP and macro EXT:WITH-HTTP-INPUTCUSTOM:*HTTP-LOG-STREAM*EXT:BROWSE-URLCUSTOM:*HTTP-PROXY*EXT:CANONICALIZECLISP 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-COLLECTSimilar 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 LISTs 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 ((&KEYfoo1 foo2)&BODYbody) `(... ,foo1 ... ,foo2 ... ,@body)) (defmacro with-foo-bar ((&RESTopts&KEYbar1 bar2&ALLOW-OTHER-KEYS)&BODYbody) `(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-INPUTDefined 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-URLFunction (
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:CANONICALIZEIf you want to canonicalize a value before further processing it, you
can pass it to EXT:CANONICALIZE together with a SEQUENCE of FUNCTIONs:
( will call EXT:CANONICALIZE value functions
&KEY (test 'EQL) (max-iter 1024))functions 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 | Last modified: 2010-07-07 |