From 72e321922b438c58285314c5c816b211cdec70ef Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sat, 6 Feb 2021 00:18:23 -0800 Subject: matcher: @(as) must always bind fresh variable. It is documented that as binds a new variable. Furthermore, it used to be called let. Yet, it back-references. Let's fix it. * share/txr/stdlib/match.tl (compile-new-var-match): New function: like compile-var-match but binds new variable, as if back-referencing didn't exist. (compile-as-match): Use compile-new-var-match. * txr.1: Improve as documentation. Clarify that it binds a fresh variable, and that pattern is processed in its scope. Include an example with circular structure. --- txr.1 | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) (limited to 'txr.1') diff --git a/txr.1 b/txr.1 index 21c2fd2e..e54097bf 100644 --- a/txr.1 +++ b/txr.1 @@ -40273,10 +40273,13 @@ operator matching against an association list. .desc The .code as -pattern operator allows the entire object matched by a -.meta pattern -to be bound to a the variable given by -.metn name . +pattern operator binds the corresponding object to a fresh variable given by +.metn name , +similarly to the Lisp +.code let +operator. If another variable called +.meta name +exists, it is shadowed; thus, no back-referencing is performed. The .meta name @@ -40290,17 +40293,29 @@ then no name is bound. Thus .mono .meti @(as nil << pattern ) .onom -is equivalent to just +is equivalent to .metn pattern . - -If +Otherwise, .meta pattern -matches, then +processed in a scope in which the new .meta name -is included among the variables, and receives the entire -object matched by +binding is already visible. + +The +.code as +operator succeeds if .meta pattern -as its value. +matches. + +Note: the +.code and +operator can be used to bind a variable to an object, with back-referencing, in +parallel with other patterns which also match the object. However, all of the +elements of +.code and +are in separate scopes; back-referencing among branches of an +.code and +isn't possible. .TP* Example: @@ -40308,7 +40323,11 @@ as its value. ;; w captures the entire (1 2 3) list: (when-match @(as w (@a @b @c)) '(1 2 3) (list w a b c)) - -> ((1 2 3) 1 2 3) + --> ((1 2 3) 1 2 3) + + ;; match a list which has itself as the third element + (when-match @(as a (1 2 @a 4)) '#1=(1 2 #1# 4) :yes) + --> :yes .brev .coNP Pattern operator @ with -- cgit v1.2.3