5 ms·
Inexperienced Emacs Lisp programmers coming to this site for the first time should be aware that Xah Lee's code is generally not very idiomatic. He discusses it
by dfan 11y ago
Inexperienced Emacs Lisp programmers coming to this site for the first time should be aware that Xah Lee's code is generally not very idiomatic. He discusses it himself here: http://ergoemacs.org/misc/emacs_lisp_coding_style_language_idioms_controversy.html http://ergoemacs.org/misc/emacs_lisp_coding_style_language_i...
- kazinator 11y agoI'm an experienced Lisp programmer and most of it looks fine to me from a random sampling, as far as formatting goes. Sometimes a closing parenthesis is on a line by itself: (defun foo () ... ) (let ((x y) (z w) ) ...) Historically, it's not been unheard of that Lisp experts (even implementors) do this sort of thing. Exhibit A, randomly picked source file inside CLISP: http://sourceforge.net/p/clisp/clisp/ci/default/tree/src/clos-class0.lisp http://sourceforge.net/p/clisp/clisp/ci/default/tree/src/clo... Some of Xah's indentation is inconsistent: (function (one space) indent like data) (function (two space indent) like code)) Not too much stands out otherwise; the code is readable. I'd have to read deeper to see whether things that are usually done one way are done differently for no good reason. What I would consider "unidiomatic" would be, for instance: (if (not (null list)) ...) rather than (if list ...) (Any Lisp dialect requiring code such the former is labelled differently, namely "idiotic".)
- PuercoPop 11y agoI perused a couple of links. This code [0] is pretty much unidiomatic. Closing parens one per line and using setq all over the place. [0]: http://ergoemacs.org/emacs/elisp_grep_string_inside_tag.html http://ergoemacs.org/emacs/elisp_grep_string_inside_tag.html
- kazinator 11y agoThat is pretty atrocious. All the initializing setq's could just be init forms in the let. Now you might think that this is also unidiomatic: (setq totalCnt (1+ totalCnt)) Turns out, though, that Elisp doesn't have modify macros, except in the CL compatibility package. What Xah is doing is the same as the accepted SO answer for incrementing a local variable: http://stackoverflow.com/questions/6858894/how-to-increment-local-variables-in-elisp http://stackoverflow.com/questions/6858894/how-to-increment-...
- PuercoPop 11y agoFirst I forgot to add I Xah Lee's ergo emacs was a valuable resource when learning Emacs. AFAIR it succintly explained emacs base abstractions. On the setq, I what I meant was iterating through setqs and while (and I seem to recall even catch/throw) as agumonkey mentioned. Then again, 'in my mind', idiomatic elisp uses cl-lib :D. so (cl-incf total-count) would be better. snakeCase is unidiomatic as well.
- agumonkey 11y agoUsing lisp to while/set... sigh. This is old age emacs lisp. We need more dash.el. Unfortunately we'd need a more stream/functional buffer API ? I was thinking of porting scheme regexp SRFI because it felt a better fit than re-search-*.
- PuercoPop 11y agoAs far as dash.el goes, I find lispm's critique of dash.el pretty convincing[0]. However a more profilic emacs coder fried of mine is undeterred and keeps using modern emacs lisp. I think much of the community does as well. [0]: https://www.reddit.com/r/lisp/comments/29ufoc/it_is_not_hard_to_read_lisp_code/cioznk5 https://www.reddit.com/r/lisp/comments/29ufoc/it_is_not_hard... About Scheme's regexp SRFI, have you seen rx.el? Not quite but I like it myself.
- agumonkey 11y agoIIUC rx.el is a sexp dsl/interface to build vanilla regex down the line right ? from what I remember about scheme SRFI is not the 'syntax' but the return values, you get streams of match, then you can leverage, folds and maps. lispm point is nice (and no one can argue about evaluation order and count), but beside the battle-tested aspect, `loop` scares the crap out of me. That's even more a reason to prefer things that avoids it in my mind, mentally small building blocks and patterns versus huge macro-based sublanguages. Yes general and probably super-efficiently implemented, but .. nah.
- lispm 11y agoSee this Xah Lee Elisp code: (defvar xah-left-brackets '("(" "{" "[" "<" "〔" "【" "〖" "〈" "《" "「" "『" "“" "‘" "‹" "«" ) "List of left bracket chars.") (progn ;; make xah-left-brackets based on xah-brackets (setq xah-left-brackets '()) (dotimes (x (- (length xah-brackets) 1)) (when (= (% x 2) 0) (push (char-to-string (elt xah-brackets x)) xah-left-brackets))) (setq xah-left-brackets (reverse xah-left-brackets))) (defvar xah-right-brackets '(")" "]" "}" ">" "〕" "】" "〗" "〉" "》" "」" "』" "”" "’" "›" "»") "list of right bracket chars.") (progn (setq xah-right-brackets '()) (dotimes (x (- (length xah-brackets) 1)) (when (= (% x 2) 1) (push (char-to-string (elt xah-brackets x)) xah-right-brackets))) (setq xah-right-brackets (reverse xah-right-brackets))) In CL this is just: (defun every-nth (seq start n &aux (len (length seq))) (loop for i = start then (+ i n) while (< i len) collect (elt seq i))) (defvar xah-left-brackets (every-nth xah-brackets 0 2)) (defvar xah-right-brackets (every-nth xah-brackets 1 2)) Write useful building blocks. Don't duplicate code. Get rid of low level imperative code. Bonus points for a more efficient version for lists.
- xahlee 11y agohi PuercoPop, that code is meant to be run as a script (emacs --script filename), so i used setq is possibly more proper. But, this is just post-fact defense, as lots my pages began as quick blogs. As you know, CL has controversial status in gnu emacs dev community. e.g. http://ergoemacs.org/emacs/elisp_common_lisp_in_emacs.html http://ergoemacs.org/emacs/elisp_common_lisp_in_emacs.html I myself avoid it, because i don't like CL. I'm going to tuck in the hanging parens in a few days. Thank you for the criticism. (thanks to many others here too)
- kazinator 11y agoBut stuff like (let (var1 (var2 0)) (when condition (setq var1 (var1-initializer-form)) ...))) is just silly. Only the inner scope of the when uses var1, or any of the vars; it could just be: (when condition (let ((var1 (var1-initializer-form)) (var2 0)) ...)) Never do two-step initialization of a variable without an excellent reason; it's just sloppy otherwise.
- copsarebastards 11y ago> (Any Lisp dialect requiring code such the former is labelled differently, namely "idiotic".) Yeah, but for idiots like me who sometimes make mistakes, having a type system that catches errors for me helps sometimes. There are plenty of times in languages that treat null as false-y where I've put completely the wrong variable in and gotten no useful feedback from my interpreter because it type-checks just fine and the error doesn't become apparent until 50 lines of code later in a completely different function. Besides, if you're frequently writing code like this, it's probably because you don't understand what you're doing and are working at the wrong level of abstraction for your problem. If you're recursing over items in a list, it's almost certain you should be using a higher-order function.
- deleted 11y ago[deleted]
- brudgers 11y agoI'd say that inexperienced Lisp programmers are likely to be classed as inexperienced based on far deeper issues than formatting. The sort of things that keep code from running correctly or at all. YMMV.
- iak8god 11y agoCan you recommend a tutorial that uses idiomatic Emacs Lisp and covers both "why" and "how" of Emacs Lisp at a level appropriate for someone who's used CL and Emacs a lot but has never noticed that he needs ELisp?
- blue1 11y agoI've also used CL and Emacs a lot; only very recently I've read both GNU Emacs Lisp manuals (introduction and reference). I think as a CL user in a couple of hours you can get an idea of what you can do, and more or less how.
- catern 11y agoThe manuals built in to Emacs are good, check M-x info.
- current_call 11y agowhy should we, spend the time to educate each other about formatting, and spend the thousands hours semi-manually do so perhaps with help of paredit, when we could have it to automatically and transparently? This is sort of funny coming from a guy who isn't using the shift key properly. Language conventions make communication easy. It's why $_ should be used. It's why "ain't" isn't a word and the subject comes before the verb.