eshell 类似 brace-expansion 复制文件脚本

it is a vaporware, in other words it waits you write it.

I see. I’ve successfully implemented and tested it in this rep.

And it works.

Enjoy : -)

a naive implementation

(defun parse-paren-exp (list)
  (let ((syms nil))
    (dolist (i (-filter #'listp list))
      (let ((sym (gensym)))
        (setq list (-replace-first i sym list))
        (push (list sym i) syms)))
    (list list syms)))


(defun form-paren-exp (list vars)
  (let ((s (gensym)))
    (setq list `(push (concat ,@list) ,s))
    (dolist (x vars)
      (setq list `(dolist (,(car x) ,(list 'quote (cadr x)))
                    ,list)))
    `(let (,s)
       ,list
       (nreverse ,s))))

(defmacro paren-expand (&rest forms)
  (apply #'form-paren-exp (parse-paren-exp forms)))
(paren-expand "a" ("1" "2" "3") ("c" "d") ".txt")
;; => ("a1c.txt" "a1d.txt" "a2c.txt" "a2d.txt" "a3c.txt" "a3d.txt")
(pp (macroexpand '(paren-expand "a" ("1" "2" "3") ("c" "d") ".txt")))

(let
    (g26)
  (dolist
      (g24
       '("1" "2" "3"))
    (dolist
        (g25
         '("c" "d"))
      (push
       (concat "a" g24 g25 ".txt")
       g26)))
  (nreverse g26))

it’s just a trivial nested dolist combo push nreverse


bonus: APL ver.

      ⍪ {(×/⍴⍵)⍴⍵} '123' ∘.{'foo',⍺,'aa',⍵,'.jpg'} '4567'
 foo1aa4.jpg 
 foo1aa5.jpg 
 foo1aa6.jpg 
 foo1aa7.jpg 
 foo2aa4.jpg 
 foo2aa5.jpg 
 foo2aa6.jpg 
 foo2aa7.jpg 
 foo3aa4.jpg 
 foo3aa5.jpg 
 foo3aa6.jpg 
 foo3aa7.jpg 

这里的 ∘. 就是 -table

好像并沒有不对

$ echo foo_{1,2}{3,4,5}{5,6}
foo_135 foo_235 foo_145 foo_245 foo_155 foo_255 foo_136 foo_236 foo_146 foo_246 foo_156 foo_256
(loop for i in (-table-flat 'list '(1 2) '(3 4 5) '(5 6))
      collect (apply #'format "foo_%i%i%i" i))
("foo_135" "foo_235" "foo_145" "foo_245" "foo_155" "foo_255" "foo_136" "foo_236" "foo_146" "foo_246" "foo_156" "foo_256")

不過 nested brace 就沒辦法用 table 了

echo foo_{1,2}{3{a,b},4,5}
foo_13a foo_23a foo_13b foo_23b foo_14 foo_24 foo_15 foo_25

这个应该算是对于树这种数据结构的入门测试了吧

但还得分析字符串啊 还得能控制遍历的顺序呀

加一个! 可以设置优先级  优先级高的会被当做一个整体 在下次展开的时候优先级-1

{1,2}{3,4}{5,6} 会展开成
135 136 145 146 235 236 245 246

!{1,2}{3,4}{5,6} 会展开成
135 235 136 236 145 245 146 246

!{1,2}!!{3,4}{5,6} 会展开成
135 145 235 245 136 146 236 246

弄这么复杂,直接用directory-files API完事了,还支持正则匹配

你们这些写CL的用gensym的时候能不能用个有意义的prefix而不要用G? :slight_smile:

看sbcl里面的宏展开密密麻麻全是G就头大

我们读代码都是读 pattern 的,只有龙鸣才看 identifier。

Bash 给出的结果和你的不一样(如第二项):

~ $ bash
bash-3.2$ echo foo_{1,2}{3,4,5}{5,6}
foo_135 foo_136 foo_145 foo_146 foo_155 foo_156 foo_235 foo_236 foo_245 foo_246 foo_255 foo_256
bash-3.2$

搞这些春秋笔法没用 :unamused: 如果真按你说的那样就不会有人写macrostep这些辅助理解宏的东西了。

如果说macrostep这些是巫师发明给麻瓜用的辅助器具,我不可以说宏是麻瓜发明给巫师用来看猴(巫师)戏的玩具?

你说得不对

– 沃兹基 硕得

那我就不懂了,这段代码你觉得能起什么有意义的变量名,換成 a b c 就有意义了么。這论点和中文编程咋这么像呢?人家给代码起 idenifiter 是因为面向 end user。end user 都是大猪蹄子。你是个 pro 要有 pro 的器量,正经的程序员会说「这代码沒用中文我看不懂」么?你要是 end user 那还是「end user 都是大猪蹄子。」,本來就不是给你看的,为什么要看。normie 看不懂 Pricipia Mathemetica 要怪作者么?再換句說話,面向 end user 是因为写代码的時後客户就在边上看,我在这沒人付我錢为啥要白花这种心思。

(let
    (g7)
  (dolist
      (g4
       '("1" "2" "3"))
    (dolist
        (g5
         '("c" "d"))
      (dolist
          (g6
           '("g a" "h"))
        (push
         (concat "a" g4 g5 g6 ".txt")
         g7))))
  (nreverse g7))

wizard 用不用我不知道,反正我从沒用过 macrostep。不管函数也好宏也好,都是为了抽象,能从文档/trivial example 理解用法为什么还要浪費时间在研究实现细节上,Emacs 几万行 lisp 每行你都要看了才配用 Emacs?而且还要看宏展开过的版本?

只有龙鸣才看 identifier。

然而我用 fish shell 试的。

我又来指 typo 啦: 是 Principia Mathematica 哦😊

那你觉得 normie 呢?

我以为是什么俚语诶,咱英语不好,咱也不敢问啊

我觉得他的意思是 看不懂也就拼不对

或许是 农鸣 的音译?


破案了,Urban Dictionary 收录了这个词

然而有的巫师就喜欢写Avada Kedavra然后又什么文档用例都妹有,我只能用macrostep一点点拆开来看呗。咱总不能用枪指着别人要求写吧,咱也没付钱不是呐!

说正经的,你这个例子没有问题,毕竟3个g换成3个pat都是一样,就是怕有的人生成不同用途的变量的容器也用with-gensym偷懒批量制造一堆G出来精神污染而已。

这几天我看你说了我三次龙鸣。虽然显然我是不是龙鸣不是你的嘴皮子决定的,不过我很好奇你的龙鸣到底是什么标准:打专有名词出typo就是龙鸣?看糟糕的宏实现看不懂也是龙鸣?所以打字慢的程序员就不是好程序员了呗?

记错loop用法的算不算龙鸣?

纠结于别人错误的就是龙鸣