unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Sweeter Emacs Lisp
@ 2013-07-14  2:22 fgallina
  2013-07-14 11:36 ` Dmitry Gutov
                   ` (5 more replies)
  0 siblings, 6 replies; 45+ messages in thread
From: fgallina @ 2013-07-14  2:22 UTC (permalink / raw)
  To: emacs-devel

Hello all,

The last months I've been playing with Clojure[0] a lot, within its
primitives I found the following functionality exquisite and I think it
may be time for Emacs Lisp to evolve and provide similar stuff making
easier/more-fun to write code in it. Here's a detailed list with
examples of what I would want to see as part of core Emacs Lisp:

  + The *threading* macros "->" and "->>":

  ;; clojure.core/->
  ;; ([x] [x form] [x form & more])
  ;; Macro
  ;;  Threads the expr through the forms. Inserts x as the
  ;;  second item in the first form, making a list of it if it is not a
  ;;  list already. If there are more forms, inserts the first form as the
  ;;  second item in second form, etc.

  (setq tag (cons "<p>" "</p>"))

  (defun tag-desc (tag)
    (concat (upcase (car tag)) "."))

  (defun tag-desc-stripped (tag)
    (upcase (replace-regexp-in-string "[<\\/> ]" "" (car tag))))

  ;; with threading macros
  (defun tag-desc (tag)
    (-> (car tag) (upcase) (concat ".")))

  (defun tag-desc-strip (tag)
    (->> (car tag) (replace-regexp-in-string "[<\\/> ]" "") (upcase)))

  + when-let, if-let:

  ;; clojure.core/when-let
  ;; ([bindings & body])
  ;; Macro
  ;;  bindings => binding-form test
  ;;  When test is true, evaluates body with binding-form bound to the value of test
  ;;-------------------------
  ;; clojure.core/if-let
  ;; ([bindings then] [bindings then else & oldform])
  ;; Macro
  ;;  bindings => binding-form test
  ;;  If test is true, evaluates then with binding-form bound to the value of
  ;;  test, if not, yields else

    (let ((pos (re-search-backward "regex" nil t)))
      (when pos
        (list pos (match-string-no-properties 0))))

    (when-let ((pos (re-search-backward "regex" nil t)))
       (list pos (match-string-no-properties 0)))

  + *we need a built-in core mapcan (could be called mapcat), filter and
  sequence concatenation (could be called cat?) function that doesn't
  depends on cl-lib*. This is fundamental stuff isn't it? Why is such a
  need to require a library for it?

  + Destructuring in defun and let: This looks weirder than I thought
  because of our (ab)use of parens everywhere, but I feel this is
  something brillant to have as part of the core language.

  ;; http://clojure.org/special_forms#binding-forms

  (setq tag (cons "<p>" "</p>"))

  (defun fmt-tag (tag)
    (let ((open (car tag))
          (close (cdr tag)))
      (format open close)))

  ;; defun destructuring
  (defun fmt-tag ((open close))
    (format open close))

  ;; let destructuring
  (defun fmt-tag (tag)
    (let (((open close) tag))
      (format open close)))

  + make `let` work like `let*`: "let's" stop confusing newcomers.

  + hash-tables: how come that working with hash-tables is such a pain?
    I love how they are function of themselves in clojure and that
    there's reader syntax for them.

  (setq tags (make-hash-table))
  (puthash tags :p "</p>")
  (puthash tags :span "</span>")
  (gethash :span tags) ; -> "</p>"

  ;; clojuresque version
  (setq tags {:p "</p>" :span "</span>"})
  (:p tags) ; -> "</p>"
  (tags :p) ; -> "</p>"
  (:html tags) ; -> nil
  (tags :html) ; -> signals error

  ;; Another option is just using the hash-table itself as a function
  ;; and don't signal an error if a third arg is provided as the
  ;; default.

  (tags :html) ; -> signals error
  (tags :html "<html>") ; -> "<html>"

This is a quick list from the top of my head but there's more (for
instance, cond with less parens and reader syntax for anonymous
functions), but I'd like to have some comments first WRT the
possibilities and acceptance.

My high level idea is that we'd have all this stuff in a single file and
my hope is that it could be implemented a such way that is compatible
with older versions of Emacs (say down to 22).

Users of older Emacs will just need to require this file in their .emacs
to use packages that use these new utilities, but in newer Emacs
releases, these things will be considered core stuff and no require will
be needed whatsoever.

I hope we can do some brainstorming a bit. My goal with this is to find
ways to evolve Emacs Lisp a bit further by providing facilities that
allow writting cleaner and more redeable code while allowing for
backwards compatibility.


[0] http://clojure.org/

--
Regards,
Fabián



^ permalink raw reply	[flat|nested] 45+ messages in thread

end of thread, other threads:[~2013-08-10 16:27 UTC | newest]

Thread overview: 45+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-14  2:22 Sweeter Emacs Lisp fgallina
2013-07-14 11:36 ` Dmitry Gutov
2013-07-14 11:53   ` Vitalie Spinu
2013-07-14 12:38     ` Aurélien Aptel
2013-07-14 13:25     ` Xue Fuqiao
2013-07-14 14:16     ` Pascal J. Bourguignon
2013-07-14 14:22 ` Lars Magne Ingebrigtsen
2013-07-14 16:27   ` Juanma Barranquero
2013-07-14 19:43     ` Lars Magne Ingebrigtsen
2013-07-15  3:20   ` Dmitry Gutov
2013-07-15  5:03     ` Stephen J. Turnbull
2013-07-16 20:23       ` Dmitry Gutov
2013-07-17 14:04         ` Lars Magne Ingebrigtsen
2013-07-17 15:07           ` Dmitry Gutov
2013-07-16  2:15   ` Miles Bader
2013-07-16  9:12     ` Stefan Monnier
2013-07-14 16:18 ` Josh
2013-07-14 16:30   ` Juanma Barranquero
2013-07-14 17:14     ` Josh
2013-07-14 17:18       ` Juanma Barranquero
2013-07-15  6:05         ` Lars Brinkhoff
2013-07-15  7:04   ` Stefan Monnier
2013-07-15 13:30     ` Bozhidar Batsov
2013-07-16  2:26       ` Miles Bader
2013-07-16  6:08         ` Thien-Thi Nguyen
2013-07-16 14:07           ` Drew Adams
2013-07-16  9:11       ` Stefan Monnier
2013-07-14 17:24 ` Andreas Schwab
2013-07-16  2:13 ` Miles Bader
2013-07-16  6:14   ` Stephen J. Turnbull
2013-07-16  9:07   ` Stefan Monnier
2013-07-16 11:09     ` Juanma Barranquero
2013-07-16 12:25       ` Andreas Schwab
2013-07-16 13:04         ` Thierry Volpiatto
2013-07-16 13:42         ` Juanma Barranquero
2013-07-16 14:38           ` Andreas Schwab
2013-07-16 14:42             ` Juanma Barranquero
2013-07-16 20:57       ` Stefan Monnier
2013-07-22 15:24 ` Stefan Monnier
2013-07-22 16:33   ` Thien-Thi Nguyen
2013-07-22 21:04     ` Stefan Monnier
2013-07-23  4:37       ` Thien-Thi Nguyen
2013-08-10  2:52         ` Stefan Monnier
2013-08-10 10:08         ` Pascal J. Bourguignon
2013-08-10 16:27           ` Drew Adams

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).