davidson (02/01/83)
I. Introduction The latest version of Franz Lisp contains the ability to declare single character infix operators to read. I have written some code to create an infix operator, default / (pronounced pipe), which provides a handy notation for nested monadic functions analogous to the pipe syntax in the UNIX shell, or to record field selection in Pascal and C. Pipe was previously available only within my function defining macro `to'. II. Definition By Example Example one, printing a person's mother's maiden name: (print person/mother/father/name/last/car) which the reader expands to (print (car (last (name (father (mother (person))))))) This first example can also be written as (print person/mother/father/name/last/1) since pipe translates integer functions into appropriate selection functions. Example two, a slow way to reverse a list: (def reverse (lambda (l) (if l (append1 l/cdr/reverse l/1) ) ) ) which the reader expands to (def reverse (lambda (l) (if l (append1 (reverse (cdr l)) (car l)) ) ) ) III. Limitations Pipe cannot be employed at the top level, nor when it begins a list, i.e., (l/cdr) expands to ((cdr l)) Also, a read error will occur when pipe is the last symbol in a list: (this that /) However, it is perfectly fine to have pipe do double duty as a regular lisp function: (/ this that) expands to itself. IV. Choice Of Pipe Character The default pipe character is `/'. If you wish another character to be used, set the value of pipeop-char to be that character. You may be concerned about the use of `/', since slash is frequently desired as part of the spelling of atom names. I have found, however, that if I use strings for filenames instead of quoted atoms (a better practice anyway), that I no longer want slashes in atom names. V. The Code Note: If you are on sdcsvax, ignore the rest of this message and look at the message I've posted to `lisp'. File pipeop.l: (declare (localf pipeop-n)) (declare (special pipeop-char)) (cond ((not (boundp 'pipeop-char)) (setq pipeop-char '\/))) (def pipeop (lambda (q) (cond ((null q) (tconc nil pipeop-char)) ((null (car q)) (tconc nil pipeop-char)) (t (rplaca (cdr q) ((lambda (f x) (cond ((numberp f) (pipeop-n f x)) (t (list f x)) ) ) (read) (cadr q) ) ) q ) ) ) ) (def pipeop-n (lambda (n x) (cond ((eq n 1) (list 'car x)) ((eq n 2) (list 'cadr x)) ((eq n 3) (list 'caddr x)) (t (list 'nthelem n x)) ) ) ) (setsyntax pipeop-char 'vinfix-macro 'pipeop)