Discussion:
Emacs Lisp's "mapconcat" in Common Lisp?
Add Reply
B. Pym
2024-08-30 23:21:11 UTC
Reply
Permalink
It's a Common Lisp newbie here; I'm more experienced in Emacs Lisp. I
(mapconcat 'identity '("one" "two" "three") "-")
=> "one-two-three"
(let ((list '("one" "two" "three")))
(format nil "~{~a-~}~a" (butlast list) (car (last list))))
But I have a feeling that there could be a more elegant way. Is there?
Yes, write: (mapconcat 'identity '("one" "two" "three") "-") ; elegant!
(defun mapconcat (fun list sep)
(when list
(let ((~sep (with-output-to-string (*standard-output*)
(map nil (lambda (ch) (princ (if (char= #\~ ch) "~~" ch)))
sep))))
(format nil (format nil "~~A~~{~A~~A~~}" ~sep)
(funcall fun (first list))
(mapcar fun (rest list))))))
(mapconcat 'identity '("one" "two" "three") "-")
--> "one-two-three"
(mapconcat (lambda (x) (concatenate 'string "[" x "]")) '("one" "two" "three") "
~")
--> "[one]~[two]~[three]"
Gauche Scheme:

(define (mapconcat fun lst sep)
(reduce-right
(^(a b)
(apply string-append (map x->string (list a sep b))))
""
(map fun lst)))

(mapconcat values '(one "two" three) '-)
===>
"one-two-three"

(mapconcat square '(2 3 4) '---)
===>
"4---9---16"
B. Pym
2024-08-30 23:49:49 UTC
Reply
Permalink
Post by B. Pym
It's a Common Lisp newbie here; I'm more experienced in Emacs Lisp. I
(mapconcat 'identity '("one" "two" "three") "-")
=> "one-two-three"
(let ((list '("one" "two" "three")))
(format nil "~{~a-~}~a" (butlast list) (car (last list))))
But I have a feeling that there could be a more elegant way. Is there?
Yes, write: (mapconcat 'identity '("one" "two" "three") "-") ; elegant!
(defun mapconcat (fun list sep)
(when list
(let ((~sep (with-output-to-string (*standard-output*)
(map nil (lambda (ch) (princ (if (char= #\~ ch) "~~" ch)))
sep))))
(format nil (format nil "~~A~~{~A~~A~~}" ~sep)
(funcall fun (first list))
(mapcar fun (rest list))))))
(mapconcat 'identity '("one" "two" "three") "-")
--> "one-two-three"
(mapconcat (lambda (x) (concatenate 'string "[" x "]")) '("one" "two" "three") "
~")
--> "[one]~[two]~[three]"
(define (mapconcat fun lst sep)
(reduce-right
(^(a b)
(apply string-append (map x->string (list a sep b))))
""
(map fun lst)))
(mapconcat values '(one "two" three) '-)
===>
"one-two-three"
(mapconcat square '(2 3 4) '---)
===>
"4---9---16"
Shorter:

(define (mapconcat fun lst sep)
(string-join (map (compose x->string fun) lst) (x->string sep)))
Kaz Kylheku
2024-08-31 06:19:55 UTC
Reply
Permalink
Post by B. Pym
(define (mapconcat fun lst sep)
(string-join (map (compose x->string fun) lst) (x->string sep)))
"Concatenate" is a pleonasm for "catenate", which is based on a
Latin root for "chain". Chaining is implicitly together ("con").
Even the Unix dolts understood this, so we have /bin/cat
and strcat, and not /bin/concat and strconcat.
--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @***@mstdn.ca
Loading...