Discussion:
Programing Language: LISP Syntax Problem of Piping Functions
(too old to reply)
Xah Lee
2011-09-16 22:09:19 UTC
Permalink
〈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
John Wiegley
2011-09-17 02:22:48 UTC
Permalink
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
The problem you're describing happens a lot in Python and C++ too.
(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.
With edebug, this is quite easy to debug.

I generally write this:

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

Not perfect, but I'm not sure I need to make radical changes to Lisp syntax
just to avoid this, either.

John
Piotr Chamera
2011-09-17 09:39:28 UTC
Permalink
Post by Xah Lee
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
(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
(...)
You can always cook a macro to simplify this.

For example (in Common Lisp):

(defmacro sequential (marker &rest operations)
(labels ((make-step (ops)
(if (null (cdr ops))
(car ops)
(substitute-if
(make-step (cdr ops))
(lambda (x) (eq x marker))
(car ops)))))
(make-step (reverse operations))))

; usage
(sequential :x
(+ 1 2)
(* :x 5)
(/ 23 :x))

(macroexpand-1
'(sequential :x
(file-name-sans-extension (file-name-nondirectory fname))
(replace-regexp-in-string "-" " " :x)
(replace-regexp-in-string "_002d" "-" :x))
)
Post by Xah Lee
(REPLACE-REGEXP-IN-STRING "_002d" "-"
(REPLACE-REGEXP-IN-STRING "-" " "
(FILE-NAME-SANS-EXTENSION (FILE-NAME-NONDIRECTORY FNAME))))


Probably this has many traps I am not aware of,
but seems to work in simple cases.
Pascal J. Bourguignon
2011-09-17 15:45:08 UTC
Permalink
Post by Piotr Chamera
Post by Xah Lee
Programing Language: LISP Syntax Problem of Piping Functions
You can always cook a macro to simplify this.
; usage
(sequential :x
(+ 1 2)
(* :x 5)
(/ 23 :x))
If the OP ever gave more attention to what was written in cll than to
his own navel, he would have long know about such macros.

For example,
http://groups.google.com/group/comp.lang.lisp/msg/456d141214e1f575?hl=en
but there are much older posts on the same subject.
--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.
Xah Lee
2011-09-18 06:14:29 UTC
Permalink
a decade ago, i didn't know lisp macro, but due to my admiration of
its Mathematica kinship and the grand-daddy of AI, i thought lisp
macros is a wonderful thing, powerful thing, a thing that allows one
to make arbitrary changes to the language's syntax on the fly.

today, i know, that lisp macros is the most motherfucking fuck in the
whole world of science in computer language.

which fuckhead invented lisp macros hack? I don't presume it's the
same guy who invented lisp. Anyone care to recite the history of lisp
macro?

without being knowledgeable of lisp macro history, my educated guess
is that its the forerunner that evolved into pattern matching proper a
la Mathematica.

Xah ∑ http://xahlee.org/
David Kastrup
2011-09-18 08:16:52 UTC
Permalink
Post by Xah Lee
a decade ago, i didn't know lisp macro, but due to my admiration of
its Mathematica kinship and the grand-daddy of AI, i thought lisp
macros is a wonderful thing, powerful thing, a thing that allows one
to make arbitrary changes to the language's syntax on the fly.
Nonsense. You can't change the reader syntax. Whether or not you are
using macros, the expressions you evaluate are read in completely
first. Macros don't change the syntax but rather the evaluation order.
Post by Xah Lee
today, i know, that lisp macros is the most motherfucking fuck in the
whole world of science in computer language.
which fuckhead invented lisp macros hack? I don't presume it's the
same guy who invented lisp. Anyone care to recite the history of lisp
macro?
What problem do you have? It is a rather basic concept easily
implemented. The typical evaluator can be written (omitting the error
cases) as

(defun eval-list (list)
(if (atom list) list
(cons (eval (car list)) (eval-list (cdr list)))))

(defun eval (elem)
(if (atom elem) elem
(let ((head (eval (car elem))))
(if (macrop head) (eval (apply head (cdr elem)))
(apply head (eval-list (cdr elem)))))))

The last two lines are all that it takes to implement macros vs
functions.

That's much more straightforward than backquotes which are often
convenient (but not required) in connection with macros.
Post by Xah Lee
without being knowledgeable of lisp macro history, my educated guess
is that its the forerunner that evolved into pattern matching proper a
la Mathematica.
What would make this an "educated guess"? I can see no connection with
pattern matching whatsoever.
--
David Kastrup
Pascal J. Bourguignon
2011-09-18 08:19:17 UTC
Permalink
Post by David Kastrup
Post by Xah Lee
without being knowledgeable of lisp macro history, my educated guess
is that its the forerunner that evolved into pattern matching proper a
la Mathematica.
What would make this an "educated guess"? I can see no connection with
pattern matching whatsoever.
A better question would be "What education?"
Specifically, "What education Xah Lee ever received?"
--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.
Antti J Ylikoski
2011-09-19 15:33:33 UTC
Permalink
Post by Pascal J. Bourguignon
Post by David Kastrup
Post by Xah Lee
without being knowledgeable of lisp macro history, my educated guess
is that its the forerunner that evolved into pattern matching proper a
la Mathematica.
What would make this an "educated guess"? I can see no connection with
pattern matching whatsoever.
A better question would be "What education?"
Specifically, "What education Xah Lee ever received?"
Well -- perhaps the poster is referring to the fact that the parameter
list of a macro is sort of pattern matched with the actual argument
SEXP, which behaviour has been duplicated for the programmer in the
DESTRUCTURING-BIND.

Cheers, andy
Xah Lee
2011-09-18 22:19:41 UTC
Permalink
Post by Xah Lee
which fuckhead invented lisp macros hack? I don't presume it's the
same guy who invented lisp. Anyone care to recite the history of lisp
macro?
answer:
https://plus.google.com/u/0/112757647855302148298/posts/ZAE5mMdvxc4

Xah
Xah Lee
2011-09-18 22:26:23 UTC
Permalink
Post by Xah Lee
which fuckhead invented lisp macros hack? I don't presume it's the
same guy who invented lisp. Anyone care to recite the history of lisp
macro?
answer: https://plus.google.com/u/0/112757647855302148298/posts/ZAE5mMdvxc4
 Xah
also of interest, if you want to know what i think of the various lang
creators.

https://plus.google.com/u/0/112757647855302148298/posts/dYs3vKyQwti

if you need a g+ invite, click on the link at bottom of:
http://xahlee.org/funny/whats_is_googleplus.html

i have 144 invite left.

Xah
David Kastrup
2011-09-19 07:50:06 UTC
Permalink
Post by Xah Lee
Post by Xah Lee
which fuckhead invented lisp macros hack? I don't presume it's the
same guy who invented lisp. Anyone care to recite the history of lisp
macro?
answer: https://plus.google.com/u/0/112757647855302148298/posts/ZAE5mMdvxc4
 Xah
also of interest, if you want to know what i think of the various lang
creators.
I'd rather read Bukowski in the original.
--
David Kastrup
WJ
2012-03-25 00:23:16 UTC
Permalink
Post by Xah Lee
〈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
(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
(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
(replace-regexp-in-string "_002d" "-"
(replace-regexp-in-string "-" " "
(file-name-sans-
extension
(file-name-
nondirectory fname))))
(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
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.
file-name-nondirectory[fname]
Clojure has the "threading" macros -> and ->>.

user=> (-> -3 (Math/abs) (Math/sqrt) (Math/exp))
5.6522336740340915
WJ
2012-12-16 22:52:18 UTC
Permalink
Post by WJ
Clojure has the "threading" macros -> and ->>.
user=> (-> -3 (Math/abs) (Math/sqrt) (Math/exp))
5.6522336740340915
user=> (-> -3 Math/abs Math/sqrt Math/exp)
5.6522336740340915

Loading...