Re: Avoid nil in output

 new new list compose Reply to this message Top page
Attachments:
+ (text/plain)
+ (text/html)

Delete this message
Author: Kaz Kylheku
Date:  
To: txr-users
Old topics: Re: Avoid nil in output
Subject: Re: Avoid nil in output

The approach exemplified by multi-remove will be directly supported in TXR 91 thanks to features that are already in the repository.

There is a new function called multi which distributes any list filtering function (such as remove-if) over multiple lists.

multi is only three simple lines of C, the first and last of which use the same operation:

val multi(val func, val lists)
{
  val transposed = mapcarv(list_f, lists);     
  val processed = funcall1(func, transposed);
  return mapcarv(list_f, processed);           
}

It's just: transpose columns and rows, filter the result through the given function and, transpose back.

Thanks to a new variant of the op operator called ap, the multi-remove call that I gave in the prior posting can be expressed using multi like this:

(multi (op remove-if (ap null @1)) balk1 balk2 balk3)

It's only slightly more complicated than using the multi-remove function, but much more general.

The syntax (ap ...) is sugar for (lambda (listarg) (apply (op ...) listarg)).  It produces a one-element function which takes a list.  When called, it aplies its list argument as arguments to an op-generated function: "ap" is "applicative op".

On 12.03.2014 22:02, Kaz Kylheku wrote:

On 12.03.2014 21:53, Kaz Kylheku wrote:

It could be turned into a general-purpose "multi-remove" function. Are you sitting down?

@(do
   (defun multi-remove (test-fun . lists)
     [apply mapcar list
            [apply mappend [iff test-fun
                                (lambda rest)
                                (chain list list)] lists]]))
@(bind (balk1 balk2 balk3) ((nil "b" nil "d")
                            ("e" "f" "g" "h")
                            ("i" "j" "k" "l")))
@(set (balk1 balk2 balk3) @(multi-remove (op null @1) balk1 balk2 balk3))
@(output)
@  (repeat)
@balk1 @balk2 @balk3
@  (end)
@(end)

(lambda rest), by the way, is a function that accepts any number of arguments and returns nil. In TXR Lisp it can now be written (lambda (. rest)).

This (lambda rest) is not necessary; nil can be used in its place even though it isn't a function.  The reason for that is that the iff operator has special checks for nil, and treats it as if were (lambda rest).  That is to say, it treats nil as "I have no function to call, so just return nil".