From 602555a3178f8fa46ef68d162509717dc82ed1c0 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 9 Dec 2015 06:49:32 -0800 Subject: Bugfix: ifa must allow dwim expressions. * share/txr/stdlib/ifa.tl (ifa): Accept dwim expressions as the condition. Moreover, treat [f x] as a one-argument call, even though it is the two-argument form (dwim f x). * txr.1: Documented. --- share/txr/stdlib/ifa.tl | 9 ++++++--- txr.1 | 24 +++++++++++++++++++----- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/share/txr/stdlib/ifa.tl b/share/txr/stdlib/ifa.tl index aa406bbd..cefb38eb 100644 --- a/share/txr/stdlib/ifa.tl +++ b/share/txr/stdlib/ifa.tl @@ -35,11 +35,12 @@ (first test))) ^(ifa ,(second test) ,else ,then)) (t (let* ((sym (first test)) - (args (rest test)) + (args (if (eq 'dwim sym) (cddr test) (cdr test))) (n-candidate-args [count-if candidate-p args]) (pos-candidate (or [pos-if candidate-p args] 0))) (unless (or (lexical-fun-p e sym) (and (or (functionp (symbol-function sym)) + (eq sym 'dwim) (null (symbol-function sym))))) (throwf 'eval-error "ifa: test expression must be \ \ a simple function call")) @@ -55,12 +56,14 @@ ^(let (,*(zip btemps before-it)) (placelet ((it ,it-form)) (let (,*(zip atemps after-it)) - (if (,sym ,*btemps it ,*atemps) + (if (,sym ,*(if (eq 'dwim sym) ^(,(second test))) + ,*btemps it ,*atemps) ,then ,else)))))) (let* ((temps (mapcar (ret (gensym)) args)) (it-temp [temps pos-candidate])) ^(let* (,*(zip temps args) (it ,it-temp)) - (if (,sym ,*temps) ,then ,else))))))))) + (if (,sym ,*(if (eq 'dwim sym) ^(,(second test))) + ,*temps) ,then ,else))))))))) (defmacro conda (. pairs) (tree-case pairs diff --git a/txr.1 b/txr.1 index dc863543..4d7a28a9 100644 --- a/txr.1 +++ b/txr.1 @@ -12271,12 +12271,24 @@ expression: .IP 1. The .meta cond -expression must be either an atom, or a function call form: -a compound expression with a symbol in the leftmost position -which resolves to a function. Otherwise the +expression must be either an atom, a function call form, +or a +.code dwim +form. Otherwise the .code ifa expression is ill-formed, and throws an exception at -macro-expansion time. +macro-expansion time. For the purposes of these rules, +a +.code dwim +form is considered as a function call expression, whose first +argument is the second element of the form. That is to say, +.code [f x] +which is equivalent to +.code (dwim f x) +is treated similarly to +.code (f x) +as a one-argument call. + .IP 2. If the .meta cond @@ -12301,7 +12313,9 @@ operator. .IP 4. If .meta cond -is a function call with exactly one argument, then the +is a function call or +.code dwim +expression with exactly one argument, then the .code it variable is bound to the argument expression, except when the function being called is -- cgit v1.2.3