Programing Language: LISP Syntax Problem of Piping Functions

Perm url with updates:

Programing Language: LISP Syntax Problem of Piping Functions

Xah Lee, 2011-09-16

One of the annoying problem of the lisp nested syntax is the problem of creating a function chain (aka unix pipe, filtering, stream).

Here's a example i frequently encounter in emacs lisp. I want to apply several different functions to a string, one after the other. Example:

(setq fname (file-name-sans-extension (file-name-nondirectory fname)))
(setq fname (replace-regexp-in-string "-" " " fname))
(setq fname (replace-regexp-in-string "_002d" "-" fname))

Note the repeated reset of a variable. I don't want that. I want to avoid mutable variables; it's bad in functional programing. So, one should do like this:

(replace-regexp-in-string "_002d" "-"
 (replace-regexp-in-string "-" " "
   (file-name-nondirectory fname))))

But that has several problems. It's hard to debug. Also, in conventional lisp code formatting, “emacs-lisp-mode” would format it like this (expand your window width to prevent line wrapping):

(replace-regexp-in-string "_002d" "-"
                          (replace-regexp-in-string "-" " "
                                                     (file-name-nondirectory fname))))

Alternative is a one-liner formatting, but it's hard to read and edit:

(replace-regexp-in-string "_002d" "-" (replace-regexp-in-string "-" " " (file-name-sans-extension (file-name-nondirectory fname))))

If lisp has adopted its early concept of M-expression as syntax wrapper, then it could be written like this using a postfix syntax like unix's pipe |. Here, i show it using Mathematica syntax:

fname //
file-name-nondirectory //
file-name-sans-extension //
Function[replace-regexp-in-string["-", " ", #]] //
Function[replace-regexp-in-string["_002d", "-", #]]

The // is similiar to unix's pipe | operator.

or in Mathematica's prefix notation, with @ as the prefix operator:

Function[replace-regexp-in-string["_002d", "-", #]] @
Function[replace-regexp-in-string["-", " ", #]] @
file-name-sans-extension @
file-name-nondirectory @

Note that in functional languages (e.g. Haskell, OCaml), they have both prefix and postfix operators. Usually the space character is used as context-sensitive implicit prefix operator. e.g. f x means “f” applied to “x”, and f a b c means (((f a) b) c). In Ruby, Perl, usually they have postfix operator desguised as calling object's methods. In perl, it's ->, in Ruby, it's just a dot ..

For detail, see:

Also note, although Haskell and OCaml have postfix and prefix operators, but these lang's syntax in general are syntax soups. That is, it's one bunch of ad hoc designs with no consistancy, no systematic grammar, no mathematical foundation. They are not much better than the syntax soup of C-like langs. The symbols are used promiscuously (see: Problems of Symbol Congestion in Computer Languages (ASCII Jam; Unicode; Fortress)) and the forms are idiosyncratic, e.g. i++, ++i, for(;;){}, while(){}, 0x123, expr1 ? expr2 : expr3, sprint(…%s…,…), …. The only language i know whose syntax approaches a systematic grammar is Mathematica. See: The Concepts and Confusions of Prefix, Infix, Postfix and Fully Nested Notations and Math Notations, Computer Languages, and the “Form” in Formalism.

Popular posts from this blog

Browser User Agent Strings 2012

11 Years of Writing About Emacs

does md5 creates more randomness?