emacs.d/clones/lisp/www.cliki.net/CMUCL Hints.html

291 lines
34 KiB
HTML
Raw Normal View History

2022-10-07 15:47:14 +02:00
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>CLiki: CMUCL Hints</title>
<link rel="alternate" type="application/atom+xml" title="ATOM feed of edits to current article"
href="https://www.cliki.net/site/feed/article.atom?title=CMUCL%20Hints">
<link rel="stylesheet" href="static/css/style.css">
<link rel="stylesheet" href="static/css/colorize.css">
</head>
<body>
<span class="hidden">CLiki - CMUCL Hints</span>
<div id="content"><div id="content-area"><div id="article-title">CMUCL Hints</div><div id="article">A collection of miscellaneous hints and tips for <a href="CMUCL.html" class="category">CMUCL</a> users - some also apply to the <a href="CMUCL.html" class="category">CMUCL</a> spin-off, <a href="SBCL.html" class="category">SBCL</a>.<p><h3>Informative top-level prompt</h3><p>Courtesy of <a href="Paul&#32;Foley.html" class="internal">Paul Foley</a>: FWIW, I like to add
<div class="code"><span class="nonparen"> <span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_in-package.html" class="symbol">in-package</a> <span class="string">"COMMON-LISP"</span></span>)</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defparametercm_defvar.html" class="symbol"><i><span class="symbol">defvar</span></i></a> <span class="special">*last-package*</span> <a href="https://www.cliki.net/site/HyperSpec/Body/any_nil.html" class="symbol">nil</a></span>)</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defparametercm_defvar.html" class="symbol"><i><span class="symbol">defvar</span></i></a> <span class="special">*cached-prompt*</span></span>)</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defun.html" class="symbol"><i><span class="symbol">defun</span></i></a> tpl-prompt <span class="paren2">(<span class="nonparen"></span>)</span>
<span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_whencm_unless.html" class="symbol">unless</a> <span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_eq.html" class="symbol">eq</a> <span class="special">*last-package*</span> <a href="https://www.cliki.net/site/HyperSpec/Body/var_stpackagest.html" class="symbol"><span class="special">*package*</span></a></span>)</span>
<span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_setf.html" class="symbol">setf</a> <span class="special">*cached-prompt*</span>
<span class="paren4">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_concatenate.html" class="symbol">concatenate</a> '<a href="https://www.cliki.net/site/HyperSpec/Body/any_string.html" class="symbol">string</a> <span class="paren5">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_or.html" class="symbol">or</a> <span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_firstcm_s_inthcm_tenth.html" class="symbol">first</a> <span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_package-nicknames.html" class="symbol">package-nicknames</a> <a href="https://www.cliki.net/site/HyperSpec/Body/var_stpackagest.html" class="symbol"><span class="special">*package*</span></a></span>)</span></span>)</span>
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_package-name.html" class="symbol">package-name</a> <a href="https://www.cliki.net/site/HyperSpec/Body/var_stpackagest.html" class="symbol"><span class="special">*package*</span></a></span>)</span></span>)</span>
<span class="string">"&gt; "</span></span>)</span></span>)</span>
<span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_setf.html" class="symbol">setf</a> <span class="special">*last-package*</span> <a href="https://www.cliki.net/site/HyperSpec/Body/var_stpackagest.html" class="symbol"><span class="special">*package*</span></a></span>)</span></span>)</span>
<span class="special">*cached-prompt*</span></span>)</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_setf.html" class="symbol">setf</a> <span class="special">*prompt*</span> #'tpl-prompt</span>)</span></span></div><p>to my lisp.core, so I get a "USER&gt; " prompt that changes as I change packages instead of the horrible default "* " prompt.<p>Correct package name for CMUCL 19a changes
<div class="code"><span class="nonparen"><span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_in-package.html" class="symbol">in-package</a> <span class="string">"LISP"</span></span>)</span></span></div><p>To achieve the same effect in SBCL, use:<p><div class="code"><span class="nonparen"><span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defparametercm_defvar.html" class="symbol"><i><span class="symbol">defvar</span></i></a> <span class="special">*last-package*</span> <a href="https://www.cliki.net/site/HyperSpec/Body/any_nil.html" class="symbol">nil</a></span>)</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defparametercm_defvar.html" class="symbol"><i><span class="symbol">defvar</span></i></a> <span class="special">*cached-prompt*</span> <a href="https://www.cliki.net/site/HyperSpec/Body/any_nil.html" class="symbol">nil</a></span>)</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defun.html" class="symbol"><i><span class="symbol">defun</span></i></a> package-prompt <span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/syscla_stream.html" class="symbol">stream</a></span>)</span>
<span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_whencm_unless.html" class="symbol">unless</a> <span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_eq.html" class="symbol">eq</a> <span class="special">*last-package*</span> <a href="https://www.cliki.net/site/HyperSpec/Body/var_stpackagest.html" class="symbol"><span class="special">*package*</span></a></span>)</span>
<span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_setf.html" class="symbol">setf</a> <span class="special">*cached-prompt*</span>
<span class="paren4">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_concatenate.html" class="symbol">concatenate</a> '<a href="https://www.cliki.net/site/HyperSpec/Body/any_string.html" class="symbol">string</a> <span class="paren5">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_or.html" class="symbol">or</a> <span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_firstcm_s_inthcm_tenth.html" class="symbol">first</a> <span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_package-nicknames.html" class="symbol">package-nicknames</a> <a href="https://www.cliki.net/site/HyperSpec/Body/var_stpackagest.html" class="symbol"><span class="special">*package*</span></a></span>)</span></span>)</span>
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_package-name.html" class="symbol">package-name</a> <a href="https://www.cliki.net/site/HyperSpec/Body/var_stpackagest.html" class="symbol"><span class="special">*package*</span></a></span>)</span></span>)</span>
<span class="string">"&gt; "</span></span>)</span></span>)</span>
<span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_setf.html" class="symbol">setf</a> <span class="special">*last-package*</span> <a href="https://www.cliki.net/site/HyperSpec/Body/var_stpackagest.html" class="symbol"><span class="special">*package*</span></a></span>)</span></span>)</span>
<span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_terpricm_fresh-line.html" class="symbol">terpri</a></span>)</span>
<span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_writecm_p_rintcm_princ.html" class="symbol">princ</a> <span class="special">*cached-prompt*</span> <a href="https://www.cliki.net/site/HyperSpec/Body/syscla_stream.html" class="symbol">stream</a></span>)</span></span>)</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_setf.html" class="symbol">setf</a> <span class="special">sb-int:*repl-prompt-fun*</span> #'package-prompt</span>)</span>
</span></div><p><h4>Using the prompt with <a href="ilisp.html" class="internal">ilisp</a>
</h4>
If you want to use the prompt above in a ilisp buffer, add the following
to you emacs startup-file (.emacs):<p><div class="code"><span class="nonparen"><span class="paren1">(<span class="nonparen">add-hook 'cmulisp-hook
<span class="paren2">(<span class="nonparen"><i><span class="symbol">lambda</span></i> <span class="paren3">(<span class="nonparen"></span>)</span>
<span class="paren3">(<span class="nonparen"><i><span class="symbol">setq</span></i> comint-prompt-regexp
<span class="string">"^</span><span class="string">\\</span><span class="string">([0-9]+</span><span class="string">\\</span><span class="string">]+</span><span class="string">\\</span><span class="string">|</span><span class="string">\\</span><span class="string">*</span><span class="string">\\</span><span class="string">|[-a-zA-Z0-9]*</span><span class="string">\\</span><span class="string">[[0-9]+</span><span class="string">\\</span><span class="string">]:</span><span class="string">\\</span><span class="string">|[-A-Z0-9]*&gt;</span><span class="string">\\</span><span class="string">) "</span></span>)</span>
</span>)</span></span>)</span>
</span></div><p><h3>Turning off GC messages</h3><p>... is as easy as setting <tt>ext:*gc-verbose*</tt> to <tt>NIL</tt>.<p><h3>Behaviour of setq at top-level</h3><p>When
<div class="code"><span class="nonparen"><span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/spefor_setq.html" class="symbol"><i><span class="symbol">setq</span></i></a> foo <span class="string">"bar"</span></span>)</span></span></div>
is entered at top-level, <tt>foo</tt> is declared special automagically.
The variable <tt>ext:*top-level-auto-declare*</tt> can be used to change this behaviour;
see <div class="code"><span class="nonparen"><span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_describe.html" class="symbol">describe</a> '<span class="special">ext:*top-level-auto-declare*</span></span>)</span></span></div> for details.<p><h3>Undoing a special declaration</h3><p>If you find that you've accidentally created a special, you can undo it. CMUCL keeps this information in a database you can query/modify using <tt>ext:info</tt>.
<pre>
* (setf x nil)
Warning: Declaring X special.
NIL
;; Uh oh
* (ext:info :variable :kind &#039;x)
:SPECIAL
T
;; This changes X back to a lexical
* (setf (ext:info :variable :kind &#039;x) :global)
:GLOBAL
</pre><p>This works on SBCL too, using <tt>sb-ext:info</tt><p><h3>Using the <a href="MOP.html" class="internal">MOP</a>
</h3><p>The MOP in <a href="CMUCL.html" class="internal">CMUCL</a> is based on PCL and works pretty much like <a href="AMOP.html" class="internal">AMOP</a> describes.
There is however an oddity with it that has to do with ``wrapper'' classes,
the details of which I (dan) unfortunately can't remember (so, somebody please
edit this). Anyway, a reasonable fix is to work in a package that shadows
a bunch of symbols from PCL instead of picking up the default versions in COMMON-LISP :<p><div class="code"><span class="nonparen"><span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defpackage.html" class="symbol"><i><span class="symbol">defpackage</span></i></a> <span class="string">"MY-PACKAGE"</span>
<span class="paren2">(<span class="nonparen"><span class="keyword">:shadowing-import-from</span> PCL <a href="https://www.cliki.net/site/HyperSpec/Body/acc_find-class.html" class="symbol">FIND-CLASS</a> <a href="https://www.cliki.net/site/HyperSpec/Body/stagenfun_class-name.html" class="symbol">CLASS-NAME</a> <a href="https://www.cliki.net/site/HyperSpec/Body/syscla_built-in-class.html" class="symbol">BUILT-IN-CLASS</a> <a href="https://www.cliki.net/site/HyperSpec/Body/fun_class-of.html" class="symbol">CLASS-OF</a></span>)</span>
... </span>)</span>
</span></div><p><h3>Running Lisp programs from the shell prompt</h3><p>Note that this works on Linux systems only (tested on Slackware 7.0 by the original poster). Depends on having a kernel compiled with the binfmt_misc module enabled, and root access to setup binfmt_misc. Any user can run the scripts.<p><pre>
From: &quot;Vladimir V. Zolotych&quot; &lt;gsmith@eurocom.od.ua&gt;
Subject: Re: echo program
Newsgroups: comp.lang.lisp
Date: Wed, 28 Feb 2001 20:19:54 +0200
Organization: DCS-EuroCom ISP
Here is the summary (Thanks to Paul Foley and
Rudolf Schlatte)
Using Slackware 7.0
The CL echo program (file ECHO.lisp)
(loop for arg in *command-line-strings* as i upfrom 0 do
(format t &quot;~&amp;arg[~D] = ~S&quot; i arg))
(terpri)
Shell script (file /usr/local/lib/batch)
#!/bin/sh
exec /usr/local/bin/lisp -batch -load $*
Settings for binfmt_misc
# cd /proc/sys/fs/binfmt_misc/
# echo &#039;:CMUCL:M::FASL FILE::/usr/local/lib/batch:&#039; &gt;register
Running ECHO.x86f
$ echo.x86f 1 2 3
; Loading #p&quot;/home/vlz/.cmucl-init.lisp&quot;.
; Loading #p&quot;/home/vlz/cmucl/echo/echo.x86f&quot;.
arg[0] = &quot;/usr/local/bin/lisp&quot;
arg[1] = &quot;-batch&quot;
arg[2] = &quot;-load&quot;
arg[3] = &quot;./echo.x86f&quot;
arg[4] = &quot;1&quot;
arg[5] = &quot;2&quot;
arg[6] = &quot;3&quot;
$
--
Vladimir Zolotych gsmith@eurocom.od.ua
</pre><p>(also see <a href="http://users.actrix.co.nz/mycroft/runlisp.html">this page</a>)<p><hr><p>Note that it'd be even better to use <code>${1+&quot;$@&quot;}</code> instead
of <code>$*</code> in the shell script to pass through all the
parameters untouched.<p>Explanation:<p><code>$*</code> first concatenates all parameters, separating
them with space (the first character of <code>$IFS</code>, in fact),
and after that, splits them again according to <code>$IFS</code>.
My suggestion does NOT do this. This matters when some parameters
contain whitespace, such as
<code>/some/program -name &#039;Hannah Schroeter&#039;</code><p>-- Hannah Schröter <a href="mailto:hannah@schlund.de"></a><code>hannah@schlund.de</code>, 22 May 2001<p>
<hr><p>Note that debian provides a wrapper ``cmucl-run'' with the cmucl package, which can be used with binfmt-support for binfmt_misc goodness.<p><hr>
<h3>CMUCL shell scripts</h3><p>This is an alternative method to the linux-specific binfmt_misc method above, which should work on all Unix platforms. It consists of using a small trampoline program which invokes the CMUCL runtime with a rewritten argv. Your shell script looks something like<p><div class="code"><span class="nonparen">#!/usr/bin/cmucl-trampoline \
-quiet -batch -noinit
!#
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_format.html" class="symbol">format</a> <a href="https://www.cliki.net/site/HyperSpec/Body/any_t.html" class="symbol">t</a> <span class="string">"~&amp;Hello, world!~%"</span></span>)</span></span></div><p>You need to <a href="http://emarsden.chez.com/downloads/">download</a> the cmucl-trampoline program, and your image must contain a reader macro which treats <tt>#!..!#</tt> as comments (there is example lisp in the code). <p>Another way relies on your shell automatically interpreting executable files not marked with #! itself:
<div class="code"><span class="nonparen">":" <span class="comment">; exec lisp -load "$0" -eval '(quit)'</span></span></div>
or, to compile it first:
<div class="code"><span class="nonparen">":" <span class="comment">; exec lisp -eval "(compile-file \"$0\")" -load `basename $0 .lisp`.x86f -eval '(quit)'</span></span></div><p>Here is what I (<a href="Erik&#32;Enge.html" class="internal">Erik Enge</a>) use to write Lisp <a href="Unix&#32;shell&#32;scripting.html" class="internal">shellscripts</a>:<p><pre>
#!/bin/sh
# -*- mode: sh -*-
# $Id: runlisp,v 1.3 2003/04/22 02:33:53 erik Exp $
# $Source: /home/cvsd/repo/bin/runlisp,v $
# A handy script to run Lisp as shellscripts. In the top of your
# file, put:
#
# #!/usr/bin/env runlisp
#
# and stick runlisp (this script) somewhere in your path. Then you
# can have regular-looking shellscripts that are written in Lisp.
# If you have another Lisp implementation and know what arguments to
# pass to it for this to work, feel free to add it and send me
# (erik@nittin.net) the patch.
if [ -f /usr/bin/sbcl ]; then
/usr/bin/sbcl --noinform --disable-debugger --eval &#039;(set-dispatch-macro-character #\# #\! (lambda (stream bang number) (declare (ignore bang number)) (read-line stream) t))&#039; --load $1 --eval &#039;(quit)&#039;
elif [ -f /usr/bin/lisp ]; then
/usr/bin/lisp -quiet -batch -noinit -eval &#039;(set-dispatch-macro-character #\# #\! (lambda (stream bang number) (declare (ignore bang number)) (read-line stream) t))&#039; -load $1 -eval &#039;(quit)&#039;
else
echo &quot;$0: could not find a Lisp I know how to call&quot;
fi
</pre><p><hr><p><h3>CLX over ssh-forwarded displays</h3><p>The standard <a href="CLX.html" class="internal">CLX</a> function <tt>OPEN-DISPLAY</tt> doesn't correctly extract the display number from the <tt>DISPLAY</tt> environment variable. This is a problem you might run into when using CLX on an ssh-forwarded X11 session. Indeed, ssh typically sets <tt>$DISPLAY</tt> to <tt>remotehost:10</tt>, and forwards port 6010 on the remote host to port 6000 (or whatever port the local X11 server is running on) on the local host. CLX will unsuccessfully try to connect to <tt>remotehost:0</tt>.<p>The solution is to use the CMUCL-specific function <tt>EXT:OPEN-CLX-DISPLAY</tt> instead of <tt>XLIB:OPEN-DISPLAY</tt>. This function will parse the <tt>DISPLAY</tt> environment variable to extract the display and screen numbers.<p>Note that the version of CLX distributed with CMUCL includes a number of extensions to the original code. It is able to extract X11 authorization cookies from the file mentioned by the <tt>XAUTHORITY</tt> environment variable (defaulting to <tt>~/.Xauthority</tt>), and it includes hooks into CMUCL's <tt>SERVE-EVENT</tt> facility.<p>NB: Many people seem to find that this does not work for them, as the question of how to use CLX locally without turning off access control is a frequent question on c.l.lisp and the CMUCL mailing list.<p>
<hr><p><h3>SERVE-EVENT example</h3><p>An example of CMUCL's SERVE-EVENT facility, that allows you to handle multiple concurrent network connections and file handles, without using multithreading. The program is a port forwarder, or redirector. It redirects TCP connections to another port on another machine. Get it from <a href="http://emarsden.chez.com/downloads/">http://emarsden.chez.com/downloads/</a>. <p>
<hr><p><h3>Adding commandline switches</h3><p>Certain implementations such as <a href="CLISP.html" class="internal">CLISP</a> have a <tt>-c</tt> commandline switch that allows you to invoke the file compiler from the shell. CMUCL's commandline switches are user-extensible, so you can emulate this behaviour with code such as the following, in your <tt>site-init.lisp</tt> or <tt>~/.cmucl-init</tt> initialization files. <p><div class="code"><span class="nonparen"><span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/speope_fletcm_scm_macrolet.html" class="symbol"><i><span class="symbol">macrolet</span></i></a> <span class="paren2">(<span class="nonparen"><span class="paren3">(<span class="nonparen"><i><span class="symbol">with-batch-processing</span></i> <span class="paren4">(<span class="nonparen">&amp;body body</span>)</span>
`<span class="paren4">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_handler-case.html" class="symbol">handler-case</a> <span class="paren5">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_prog1cm_prog2.html" class="symbol">prog1</a> <a href="https://www.cliki.net/site/HyperSpec/Body/any_t.html" class="symbol">t</a> ,@body</span>)</span>
<span class="paren5">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/contyp_serious-condition.html" class="symbol">serious-condition</a> <span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/contyp_condition.html" class="symbol">condition</a></span>)</span>
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_format.html" class="symbol">format</a> <a href="https://www.cliki.net/site/HyperSpec/Body/var_stdebug-i_ace-outputst.html" class="symbol"><span class="special">*error-output*</span></a> <span class="string">"Error in batch processing:~%~A~%"</span>
<a href="https://www.cliki.net/site/HyperSpec/Body/contyp_condition.html" class="symbol">condition</a></span>)</span>
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_finish-ou_clear-output.html" class="symbol">finish-output</a> <a href="https://www.cliki.net/site/HyperSpec/Body/var_stdebug-i_ace-outputst.html" class="symbol"><span class="special">*error-output*</span></a></span>)</span>
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/speope_throw.html" class="symbol"><i><span class="symbol">throw</span></i></a> 'lisp::%end-of-the-world 1</span>)</span></span>)</span>
<span class="paren5">(<span class="nonparen"><span class="keyword">:no-error</span> <span class="paren6">(<span class="nonparen">value</span>)</span>
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/sym_declare.html" class="symbol">declare</a> <span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/dec_ignorecm_ignorable.html" class="symbol">ignore</a> value</span>)</span></span>)</span>
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/speope_throw.html" class="symbol"><i><span class="symbol">throw</span></i></a> 'lisp::%end-of-the-world 0</span>)</span></span>)</span></span>)</span></span>)</span></span>)</span>
<span class="paren2">(<span class="nonparen"><i><span class="symbol">ext:defswitch</span></i> <span class="string">"compile"</span>
#'<span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_lambda.html" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren4">(<span class="nonparen">switch</span>)</span>
<span class="paren4">(<span class="nonparen"><i><span class="symbol">with-batch-processing</span></i>
<span class="paren5">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_mapccm_ma_istcm_mapcon.html" class="symbol">mapc</a> #'<a href="https://www.cliki.net/site/HyperSpec/Body/fun_compile-file.html" class="symbol">compile-file</a> <span class="paren6">(<span class="nonparen">ext:cmd-switch-words switch</span>)</span></span>)</span></span>)</span></span>)</span></span>)</span>
<span class="paren2">(<span class="nonparen"><i><span class="symbol">ext:defswitch</span></i> <span class="string">"compile-and-load"</span>
#'<span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_lambda.html" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren4">(<span class="nonparen">switch</span>)</span>
<span class="paren4">(<span class="nonparen"><i><span class="symbol">with-batch-processing</span></i>
<span class="paren5">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_mapccm_ma_istcm_mapcon.html" class="symbol">mapc</a> #'<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_lambda.html" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren1">(<span class="nonparen">file</span>)</span> <span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_compile-file.html" class="symbol">compile-file</a> file <span class="keyword">:load</span> <a href="https://www.cliki.net/site/HyperSpec/Body/any_t.html" class="symbol">t</a></span>)</span></span>)</span>
<span class="paren6">(<span class="nonparen">ext:cmd-switch-words switch</span>)</span></span>)</span></span>)</span></span>)</span></span>)</span>
</span>)</span> <span class="comment">; macrolet
</span></span></div><p>Now you can use the following to compile (and load) from the command
line:<p><pre>
lisp -compile-and-load demo.lisp demo2.lisp
</pre><p>If errors are encountered during processing, CMUCL is aborted, with a
return value of 1, otherwise it returns 0 (i.e. success). This can be combined with the <tt>-quiet</tt> flag (put it at the start of the
commandline) if wanted.<p>An alternative to this form of interaction with the file compiler is to load the files and compile them from a stream, so you don't have any FASL files hanging around on disk (thus avoiding problems with binary compatibility between different CMUCL releases), yet still benefit from compiled performance. You can do this with code such as:<p><div class="code"><span class="nonparen"><span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defun.html" class="symbol"><i><span class="symbol">defun</span></i></a> process-switch-demon <span class="paren2">(<span class="nonparen">switch</span>)</span>
<span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/speope_letcm_letst.html" class="symbol"><i><span class="symbol">let</span></i></a> <span class="paren3">(<span class="nonparen"><span class="paren4">(<span class="nonparen">files <span class="paren5">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_copy-list.html" class="symbol">copy-list</a> <span class="paren6">(<span class="nonparen">ext:cmd-switch-words switch</span>)</span></span>)</span></span>)</span></span>)</span>
<span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_push.html" class="symbol">push</a> #'<span class="paren4">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_lambda.html" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren5">(<span class="nonparen"></span>)</span>
<span class="paren5">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_dolist.html" class="symbol">dolist</a> <span class="paren6">(<span class="nonparen">file files</span>)</span>
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_format.html" class="symbol">format</a> <a href="https://www.cliki.net/site/HyperSpec/Body/var_stterminal-iost.html" class="symbol"><span class="special">*terminal-io*</span></a>
<span class="string">"~&amp;;;; Processing compiled code from ~A.~%"</span> file</span>)</span>
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_with-open-file.html" class="symbol"><i><span class="symbol">with-open-file</span></i></a> <span class="paren1">(<span class="nonparen">s file</span>)</span>
<span class="paren1">(<span class="nonparen">ext:compile-from-stream s</span>)</span></span>)</span></span>)</span></span>)</span>
<span class="special">*run-actions*</span></span>)</span></span>)</span></span>)</span>
<span class="paren1">(<span class="nonparen"><i><span class="symbol">ext:defswitch</span></i> <span class="string">"process"</span> #'process-switch-demon</span>)</span>
</span></div><p><i>Adapted from article <tt>87g06vubxi.fsf@orion.bln.pmsf.de</tt> posted to comp.lang.lisp by Pierre Mai, on 2001-11-30.</i><p><hr><p><h3>"Advise" facilities</h3><p>In CMUCL 18e and later, use fwrappers; the encapsulation mechanism described below is deprecated.<p>from the release notes for CMUCL 17f:<p><pre>
-- The encapsulation mechanism (similar to advise facilities) has been
revamped to work on SETF function names as well as symbols.
EXT:ENCAPSULATED-DEFINITION
Returns whatever definition is stored for name, regardless of whether
it is encapsulated. Unlike FDEFINITION, this does not strip off the
encapsulation. This is SETF&#039;able.
EXT:ENCAPSULATE
Replaces the definition of name with a function that binds name&#039;s
arguments a variable named argument-list, binds name&#039;s definition to a
variable named basic-definition, and EVAL&#039;s body in that context. Type
is whatever you would like to associate with this encapsulation for
identification in case you need multiple encapsuations of the same
name.
EXT:UNENCAPSULATE
Removes name&#039;s most recent encapsulation of the specified type.
EXT:ENCAPSULATED-P
Returns t if name has an encapsulation of the given type, otherwise
nil.
EXT:*SETF-FDEFINITION-HOOK*
A list of functions invoked by (SETF FDEFINITION) before storing the
new value. Each hook function must take the function name and the
new-value.
</pre><p><u>also see</u>: section 3.10.1 of the CMUCL Users' Manual; <code>(describe
&#039;ext:encapsulate)</code><p><hr><p><h3>Command line editing and auto completion with CMUCL</h3><p>For the rare cases when you don't use <a href="ILISP.html" class="internal">ILISP</a> but invoke
CMUCL directly from the command line:<p><ol>
<li>Get <a href="rlwrap.html" class="internal">rlwrap</a> and build
it.
</li>
<li>Put something like
<pre class="inline">alias cmucl="rlwrap cmucl"</pre>
into your <tt>~/.bashrc</tt> (or <tt>~/.profile</tt> or whatever).
</li>
<li>Put <a href="http://web.archive.org/web/20160623235740/http://weitz.de/files/cmucl_completions">this
file</a> into your home directory, call it <tt>~/.cmucl_completions</tt>.
</li>
<li>Optionally adjust your <tt>~/.inputrc</tt> file (actually the
file where <tt>$INPUTRC</tt> points to). I added the line
<pre class="inline">TAB: complete</pre>
because rlwrap binds this key to <tt>menu-complete</tt>.
</li>
</ol><p>Note that recent <a href="https://tiswww.case.edu/php/chet/readline/rltop.html">readline</a>
versions include an example program rlfe that does almost the same
thing as rlwrap. I think <a href="rlwrap.html" class="internal">rlwrap</a> is nicer, though.<p>For those of you on <a href="Debian.html" class="internal">Debian</a>, <b>cle</b> that does pretty much the same thing
(but no tab-completion) is packaged on testing.<p><hr><p><h3>Allegro-like REPL commands</h3><p>To get top-level commands like <code>:load &quot;foo.lisp&quot;</code> either use <a href="Paul&#32;Foley.html" class="internal">Paul Foley</a>'s <a href="Toplevel.html" class="internal">Toplevel</a> or Peder O. Klingenberg's <a href="http://heim.ifi.uio.no/~pok/download/commands.lisp">http://heim.ifi.uio.no/~pok/download/commands.lisp</a>.<p><hr>
<a href="programming&#32;tips.html" class="category">programming tips</a></div></div>
<div id="footer" class="buttonbar"><ul><li><a href="CMUCL&#32;Hints.html">Current version</a></li>
<li><a href="https://www.cliki.net/site/history?article=CMUCL%20Hints">History</a></li>
<li><a href="https://www.cliki.net/site/backlinks?article=CMUCL%20Hints">Backlinks</a></li><li><a href="https://www.cliki.net/site/edit-article?title=CMUCL%20Hints&amp;from-revision=3799556722">Edit</a></li><li><a href="https://www.cliki.net/site/edit-article?create=t">Create</a></li></ul></div>
</div>
<div id="header-buttons" class="buttonbar">
<ul>
<li><a href="https://www.cliki.net/">Home</a></li>
<li><a href="https://www.cliki.net/site/recent-changes">Recent Changes</a></li>
<li><a href="CLiki.html">About</a></li>
<li><a href="Text&#32;Formatting.html">Text Formatting</a></li>
<li><a href="https://www.cliki.net/site/tools">Tools</a></li>
</ul>
<div id="search">
<form action="https://www.cliki.net/site/search">
<label for="search_query" class="hidden">Search CLiki</label>
<input type="text" name="query" id="search_query" value="" />
<input type="submit" value="search" />
</form>
</div>
</div>
<div id="pageheader">
<div id="header">
<span id="logo">CLiki</span>
<span id="slogan">the common lisp wiki</span>
<div id="login"><form method="post" action="https://www.cliki.net/site/login">
<label for="login_name" class="hidden">Account name</label>
<input type="text" name="name" id="login_name" class="login_input" />
<label for= "login_password" class="hidden">Password</label>
<input type="password" name="password" id="login_password" class="login_input" />
<input type="submit" name="login" value="login" id="login_submit" /><br />
<div id="register"><a href="https://www.cliki.net/site/register">register</a></div>
<input type="submit" name="reset-pw" value="reset password" id="reset_pw" />
</form>
</div>
</div>
</div>
</body></html>