
Find-cmd.el: an elegant way to build up complex find(1) expressions - wtbob
https://www.emacswiki.org/emacs/Find
======
wtbob
Posting because I think it's a nice example of how clean s-expression-based
syntax can be:

    
    
        (find-cmd '(prune (name ".svn" ".git" ".CVS"))
                  '(and (or (name "*.pl" "*.pm" "*.t")
                            (mtime "+1"))
                        (fstype "nfs" "ufs"))))
    

instead of:

    
    
        "find '/home/phil/' \\( \\( -name '.svn' -or -name '.git' -or
         -name '.CVS' \\) -prune -or -true \\) \\( \\( \\( -name '*.pl'
         -or -name '*.pm' -or -name '*.t' \\) -or -mtime '+1' \\) -and \\(
         -fstype 'nfs' -or -fstype 'ufs' \\) \\)"
    

to steal the example on the page.

~~~
JadeNB
Although I also like s-expressions, I'm not sure that this example is so
persuasive; a lot of the visual complexity of the (awful) second example comes
from having to go through so many hoops of escaping. (After writing the
argument below, it occurs to me that I may be attacking a strawman, in the
sense that you weren't claiming that `find-cmd`'s is the _only_ readable way
to write code, just that it is _a_ readable way.)

The following is a thought experiment; I know that it's illegal shell syntax.
If we just replace `\\\\(\\\\)` by `()` and remove spaces, then we get:

    
    
         find_noesc '/home/phil/'
              (( -name '.svn' -or -name '.git' -or -name '.CVS') -prune
              -or -true)
              ((( -name '*.pl' -or -name '*.pm' -or -name '*.t' )
                   -or -mtime '+1')
              -and ( -fstype 'nfs' -or -fstype 'ufs'))
    

(By the way, isn't there a missing `-and` before `-prune` there? Also,
couldn't we convert the `-or -true` to an `-or` with the second clause, as the
`find-cmd` example does? I'm no `find` aficionado.) If we imagine a more usual
in- and pre-fix calling convention, and that this removes the need for the
quotes, and then if we drop the home directory (which isn't specified in the
`find-cmd` call either), then we get something like:

    
    
         find_infix
              ((name='.svn' || name='.git' || name='.CVS')
                   && prune)
         ||   (((name='*.pl' || name='*.pm' || name='*.t')
                   || mtime='+1')
              && (fstype='nfs' || fstype='ufs'))
    

Perl-style junctions
([http://doc.perl6.org/type/Junction](http://doc.perl6.org/type/Junction))
could make it look even better:

    
    
         find_infix
              (name='.svn'|'.git'|'.CVS' && prune)
         ||   ((name='*.pl'|'*.pm'|'*.t' || mtime='+1') && fstype='nfs'|'ufs')
    

At this stage, I think that it's fair to call it a matter of opinion which
style looks better.

