summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-07-21 20:37:59 -0700
committerKaz Kylheku <kaz@kylheku.com>2015-07-21 20:37:59 -0700
commit701d5ff8c6a2d4ca6023be345faf4f085db6c689 (patch)
treeabe7bc64bb157ddbba61b4dedf37b795912eeade
parentdd270e9350901f7b750364d167dcd880038cb86f (diff)
downloadtxr-701d5ff8c6a2d4ca6023be345faf4f085db6c689.tar.gz
txr-701d5ff8c6a2d4ca6023be345faf4f085db6c689.tar.bz2
txr-701d5ff8c6a2d4ca6023be345faf4f085db6c689.zip
* share/txr/stdlib/place.tl (defplace cdr): Change deletion
semantics so that (del (cdr x)) is symmetric with (del (car x)). * txr.1: Update documentation.
-rw-r--r--ChangeLog7
-rw-r--r--share/txr/stdlib/place.tl6
-rw-r--r--txr.136
3 files changed, 41 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index ea191850..b15a3860 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
2015-07-21 Kaz Kylheku <kaz@kylheku.com>
+ * share/txr/stdlib/place.tl (defplace cdr): Change deletion
+ semantics so that (del (cdr x)) is symmetric with (del (car x)).
+
+ * txr.1: Update documentation.
+
+2015-07-21 Kaz Kylheku <kaz@kylheku.com>
+
* eval.c (eval_init): Register new split function.
* lib.c (split_func): New static function.
diff --git a/share/txr/stdlib/place.tl b/share/txr/stdlib/place.tl
index f7e468cf..1d748d99 100644
--- a/share/txr/stdlib/place.tl
+++ b/share/txr/stdlib/place.tl
@@ -327,7 +327,11 @@
^(macrolet ((,ssetter (val) ^(sys:rplacd ,',cell ,val)))
,body))
(deleter
- ^(macrolet ((,deleter () ^(zap (cdr ,',cell))))
+ ^(macrolet ((,deleter ()
+ (with-gensyms (tmp)
+ (with-update-expander (cgetter csetter) ',cell nil
+ ^(let ((,tmp (,cgetter)))
+ (prog1 (cdr ,tmp) (,csetter (car ,tmp))))))))
,body)))
(defplace (vecref vector index :whole args) body
diff --git a/txr.1 b/txr.1
index c7e68ceb..7123f898 100644
--- a/txr.1
+++ b/txr.1
@@ -13499,6 +13499,20 @@ because
.code pop
is defined on an empty list.
+The abstract concept behind deleting a
+.code car
+is that physically deleting this field from a cons,
+thereby breaking it in half, would result in just the
+.code cdr
+remaining. Though fragmenting a cons in this manner is impossible,
+deletion simulates it by replacing the place which previously held the
+cons, with that cons'
+.code cdr
+field. This semantics happens to coincide with deleting the first element
+of a list by a
+.code pop
+operation.
+
.coNP Accessors @ cdr and @ rest
.synb
.mets (cdr << object )
@@ -13563,18 +13577,26 @@ and is modifiable.
A
.code cdr
-place supports deletion, according to the following equivalence:
+place supports deletion, according to the following near equivalence:
.cblk
- (del (cdr obj)) <--> (zap (cdr obj))
+ (del (cdr place)) <--> (prog1 (cdr place)
+ (set place (car place)))
.cble
-Note that this is different from the delete semantics of
+Of course,
+.code place
+is evaluated only once.
+
+Note that this is symmetric with the delete semantics of
.code car
-in that
-.code obj
-is not required to be a place, and must not be
-.codn nil .
+in that the cons stored in
+.code place
+goes away, as does the
+.code cdr
+field, leaving just the
+.codn car ,
+which takes the place of the original cons.
.TP*
Example: