Xah Lee
2011-09-16 22:09:19 UTC
〈Programing Language: LISP Syntax Problem of Piping Functions〉
http://xahlee.org/comp/lisp_syntax_function_pipe.html
plain text version follows
─────────────────────────────────────────
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 sequencing functions.
Here's a example i frequently encounter in emacs lisp. I like to
change a string in several ways. 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))
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-sans-extension
(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-sans-
extension
(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:
file-name-nondirectory[fname] //
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[fname]
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:
The Concepts and Confusions of Prefix, Infix, Postfix and Fully
Nested Notations
Unix Pipe As Functional Language
Programing Language: A Ruby Illustration of Lisp Problems
Also note, that even Haskell and OCaml support postfix and prefix
syntax, but their syntax is a syntax soup. That is, it's one bunch of
ad hoc designs with no consistancy, systematic grammar, or
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.
Xah
http://xahlee.org/comp/lisp_syntax_function_pipe.html
plain text version follows
─────────────────────────────────────────
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 sequencing functions.
Here's a example i frequently encounter in emacs lisp. I like to
change a string in several ways. 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))
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-sans-extension
(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-sans-
extension
(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:
file-name-nondirectory[fname] //
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[fname]
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:
The Concepts and Confusions of Prefix, Infix, Postfix and Fully
Nested Notations
Unix Pipe As Functional Language
Programing Language: A Ruby Illustration of Lisp Problems
Also note, that even Haskell and OCaml support postfix and prefix
syntax, but their syntax is a syntax soup. That is, it's one bunch of
ad hoc designs with no consistancy, systematic grammar, or
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.
Xah