From 4e91b92dadc3586bee22191382b103e8a16b7add Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 4 Apr 2018 06:49:40 -0700 Subject: macro param lists: remove colon hack. Going forward, when : appears as the argument of an optional parameter in destructuring, it is treated as an ordinary object, and not as "this argument is missing". That is now a feature of function calls only. Rationale: interferes with macros. For instance, the pattern (test : then else) doesn't correctly express the arguments of if, because (if x y :) eats the semicolon. The defaulting behavior is not useful because usually there is no default value for optional structure, other than nil. * eval.c (bind_macro_params): Only implement the colon hack under compatibility with 190. * share/txr/stdlib/place.tl (defplace gethash, defplace fun, defplace symbol-function, defplace symbol-macro, defplace symbol-value): Remove uses of : for defaulting the ssetter argument. This illustrates how useless the feature is for macro destructuring; all these just replace with nil. * txr.1: Clarify that macro parameter lists don't implement the colon trick. It was never explicitly specified that this is the case, but could have been inferred from the statements which indicate that macro parameter lists copy the features of function parameter lists. Added compat notes. --- eval.c | 2 +- share/txr/stdlib/place.tl | 10 +++++----- txr.1 | 24 ++++++++++++++++++++++-- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/eval.c b/eval.c index 73efc9e3..e16e8075 100644 --- a/eval.c +++ b/eval.c @@ -1232,7 +1232,7 @@ static val bind_macro_params(val env, val menv, val params, val form, } if (consp(form)) { - if (optargs && car(form) == colon_k) { + if (optargs && opt_compat && opt_compat <= 190 && car(form) == colon_k) { form = cdr(form); goto noarg; } diff --git a/share/txr/stdlib/place.tl b/share/txr/stdlib/place.tl index d9fa60b3..6b4a1019 100644 --- a/share/txr/stdlib/place.tl +++ b/share/txr/stdlib/place.tl @@ -623,7 +623,7 @@ (macrolet ((,getter () ^(cdr ,',entry-sym)) (,setter (val) ^(sys:rplacd ,',entry-sym ,val))) ,body)))) - : + nil (deleter ^(macrolet ((,deleter () (if ,have-default-p @@ -763,7 +763,7 @@ ^(macrolet ((,getter () ^(fun ,',sym)) (,setter (val) ^(sys:setqf ,',sym ,val))) ,body)) - : + nil (deleter ^(macrolet ((,deleter (:env env) (when (lexical-fun-p env ',sym) @@ -805,7 +805,7 @@ (macrolet ((,getter () ^(call (car ,',gs-sym))) (,setter (val) ^(call (cdr ,',gs-sym) ,val))) ,body)))) - : + nil (deleter ^(macrolet ((,deleter () ^(fmakunbound ,',sym-expr))) ,body))) @@ -821,7 +821,7 @@ (macrolet ((,getter () ^(cdr ,',binding-sym)) (,setter (val) ^(sys:rplacd ,',binding-sym ,val))) ,body)))) - : + nil (deleter ^(macrolet ((,deleter () ^(mmakunbound ,',sym-expr))) ,body))) @@ -837,7 +837,7 @@ (macrolet ((,getter () ^(cdr ,',binding-sym)) (,setter (val) ^(sys:rplacd ,',binding-sym ,val))) ,body)))) - : + nil (deleter ^(macrolet ((,deleter () ^(makunbound ,',sym-expr))) ,body))) diff --git a/txr.1 b/txr.1 index 443dedeb..6d6c5055 100644 --- a/txr.1 +++ b/txr.1 @@ -30454,6 +30454,19 @@ parameter inside has a restricted scope in a nested parameter list: its parameter will capture just that part of the argument material which matches that parameter list, rather than the entire argument list. +The processing of macro parameter lists omits the feature that when the +keyword symbol +.code : +(colon) given as the argument to an optional parameter, that argument is +treated as a missing argument. This special logic is implemented only +in the function argument passing mechanism, not in the binding of macro +parameters to object structure. If the colon symbol appears in the object +structure and is matched against an optional parameter, it is an +ordinary value. That parameter is considered present, and takes on +that +.code : +keyword symbol as its value. + .TP* "Dialect Note:" In ANSI Common Lisp, the lambda list keyword @@ -63254,8 +63267,15 @@ function neglected to perform initializations, and didn't invoke finalization on the structure object if an exception was thrown during reinitialization. Thus, contrary to documented requirements, reinitialization of a structure didn't behave -like fresh construction. This behavior is replicated if compatibility -with 190 or earlier is requested. +like fresh construction. Also, until \*(TX 190, macro parameter +lists implemented the requirement that a +.code : +(colon keyword symbol) argument to an optional +was treated as a missing argument, triggering argument-defaulting behavior. +That requirement was removed; the colon symbol behaves as an ordinary value +under destructuring with macro parameter lists. +All these behaviors are restored in compatibility +with version 190 or earlier. .IP 188 Until \*(TX 188, .codn equal -based -- cgit v1.2.3