File: PROGN_bang_.html

package info (click to toggle)
acl2 3.1-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 36,712 kB
  • ctags: 38,396
  • sloc: lisp: 464,023; makefile: 5,470; sh: 86; csh: 47; cpp: 25; ansic: 22
file content (64 lines) | stat: -rw-r--r-- 3,405 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<html>
<head><title>PROGN_bang_.html  --  ACL2 Version 3.1</title></head>
<body text=#000000 bgcolor="#FFFFFF">
<h2>PROGN!</h2>evaluate some forms, not necessarily <a href="EVENTS.html">events</a>
<pre>Major Section:  <a href="EVENTS.html">EVENTS</a>
</pre><p>

<strong>WARNING!</strong>  This event is intended for advanced users who, in essence,
want to build extensions of ACL2.  See see <a href="DEFTTAG.html">defttag</a>, in particular, the
``WARNING'' there.<p>

<code>Progn!</code> can be used like <code><a href="PROGN.html">progn</a></code>, even in <a href="BOOKS.html">books</a>.  But unlike
<code><a href="PROGN.html">progn</a></code>, <code>progn!</code> does not require its constituent forms to be
<a href="EVENTS.html">events</a> (see <a href="EMBEDDED-EVENT-FORM.html">embedded-event-form</a>).  (However, see <a href="MAKE-EVENT.html">make-event</a> for a
``Restriction to the Top Level'' that still applies under a call of
<code>progn!</code>.)<p>

Because <code>progn!</code> allows non-events, it differs from <code>progn</code> in another
important respect: <code>progn!</code> is illegal unless there is an active ttag;
see <a href="DEFTTAG.html">defttag</a>.<p>

See <code>book/misc/hacker.lisp</code> for two macros, <code>with-raw-mode</code> and
<code>with-redef-allowed</code>, each defined in terms of <code>progn!</code>, that allow
arbitrary forms in contexts that would normally require legal embedded event
forms.
<p>
Given a form <code>(progn! form1 form2 ... formk)</code>, ACL2 will evaluate each
<code>formi</code> in turn (for i from 1 to k).  If a form returns more than one value
(see <a href="MV.html">mv</a>) where the first value returned is not <code>nil</code>, then no later form
will be evaluated and the result returned by the <code>progn!</code> call will be
<code>(mv erp val state)</code> for some non-<code>nil</code> value <code>erp</code>, signifying an
error (see <a href="LD-ERROR-TRIPLES.html">ld-error-triples</a>).  Otherwise the evaluation is considered to
have succeeded, and will continue on later forms.<p>

The normal undoing mechanism does not generally apply to forms within a
<code>progn!</code> that are not legal ACL2 <a href="EVENTS.html">events</a> (see <a href="EMBEDDED-EVENT-FORM.html">embedded-event-form</a>).
In particular, note that a non-<code><a href="LOCAL.html">local</a></code> call of <code>progn!</code> in an
<code><a href="ENCAPSULATE.html">encapsulate</a></code> event will generally be evaluated twice: once on each pass.
This fact is worth keeping in mind if you are using <code>progn!</code> to change the
state of the system; ask yourself if it is acceptable to apply that
state-changing operation more than once.<p>

The following rather sophisticated example illustrates the power of
<code>progn!</code>.  Here, <code>state-global-let*</code> is an advanced programming feature
that binds <a href="STATE.html">state</a> global variables (see <a href="STATE.html">state</a>, in particular the
discussion of the global table) to values.

<pre>
(progn!<p>

 (remove-untouchable 'ld-redefinition-action nil)<p>

 (state-global-let*
  ((ld-redefinition-action '(:doit . :overwrite)))<p>

  (defund foo (x)
    (cons x x)))

 (push-untouchable 'ld-redefinition-action nil))
 </pre>

<br><br><br><a href="acl2-doc.html"><img src="llogo.gif"></a> <a href="acl2-doc-index.html"><img src="index.gif"></a>
</body>
</html>