emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] Clojure-like syntactic sugar for an anonymous function liter


From: Oleh
Subject: Re: [PATCH] Clojure-like syntactic sugar for an anonymous function literal
Date: Thu, 22 Jan 2015 18:22:13 +0100

>>     #(foo bar) should translate to (short-lambda (foo bar))
>
> Hmm...
>
> Not completely sure where I stand on this.

Thanks for the consideration in any case. And I'm glad that I asked
this, even if it doesn't lead to a change.

> A few notes:
> - I like the generality of CL reader macros.
> - But extending elisp-mode to understand what's going on (and "do the
>   right thing") with each new reader macro is not easy.
>   So I'm currently against addition of CL style reader macros.

This is good to know. What initially pushed me into this was seeing
code that uses `dash.el' and not understanding what `dash.el' does,
since it provides not just plain functions, but second order functions
that control the flow of the program. That meant that I had to learn
it whether I wanted to or not, even if I'm not using it in any of my
packages.

I'm afraid that making CL style macros available to the public would
lead to more 3rd party extensions defining control structures used by
other 3rd party extensions. My opinion is that only the core should be
allowed to do that. Or at least the 3rd party control flow structures
should not propagate.

But people want sugar, and that's what `dash.el' gives to them. My
#(...) could be a quick fix for that.

>   In this sense your #(...) proposal is not too bad because the new
>   syntax is largely compatible with what we have already (e.g. the (...)
>   part is parsed in the normal way).

Am I right in the assumption that only current #(...) syntax is that
of #("foo" ...)? Nothing other than propertized strings uses it?

> - In "(lambda (x) (foo bar))" the main problem for me is the visual length,
>   so I use pretty-symbols-mode to make it look like (λ (x) (foo bar)).
>   #(foo bar) is still shorter, tho, so I like this.

For some people, removing one set of parens could be more important
than shortening `lambda' to `λ'.  I like either way.

> - I'm a functional programmer at heart, so I like making higher-order
>   functions more accessible.
> - But the current Elisp implementation is not good at handling function
>   calls efficiently, so offering a very short syntax like #(foo bar) is
>   kind of lying to the programmer.

Note that #(foo %) is open to optimizations: it doesn't have to be
exactly (lambda (%) (foo %)), it just has to behave like it. I'm not
sure if that helps.

> - Elisp has the particularity that it's used by a very large number of
>   people who don't actually know/understand the language, and will never
>   really learn it.  OT1H (add-hook 'foo-mode-hook #(define-key toto titi))
>   looks simpler, but OTOH having more equivalent syntaxes leads to more
>   confusion for beginners.
>
> So I'm not dead set against it, but I'm not really sure it'd be an
> improvement either.

Just to show you that weird things are happening either way:

    (defun projectile-unixy-system-p ()
      "Check to see if unixy text utilities are installed."
      (--all? (executable-find it) '("grep" "cut" "uniq")))

Here's the implementation of `--all?'. It did not make sense to me
until I've spent an hour figuring it out.

    (defmacro --all? (form list)
      "Anaphoric form of `-all?'."
      (declare (debug (form form)))
      (let ((a (make-symbol "all")))
        `(let ((,a t))
           (--each-while ,list ,a (setq ,a ,form))
           (---truthy? ,a))))

Here's the 100% equivalent implementation of `--all?':

    (defmacro --all? (form list)
      "Anaphoric form of `-all?'."
      (declare (debug (form form)))
      `(cl-every (lambda (it) ,form) ,list))

Here's how `projectile-unixy-system-p' could be implemented with the
new reader macro:

    (defun projectile-unixy-system-p ()
      "Check to see if unixy text utilities are installed."
      (cl-every #(executable-find %) '("grep" "cut" "uniq")))

2 chars longer than the impl. with `dash', 1 char shorter if `every'
was used in place of `cl-every'.  I just want 3rd party packages to
use the core Emacs more, so that they are easier to read.

> Of course, your proposal has 2 parts:
> - the #(...) reader syntax.
> - the new macro.
> They work together but can also be used separately.  E.g. we could have
> just the macro and write things like (mapcar (code (+ % 1)) list).
> And we could have just the #(...) syntax and give it any meaning we like.

You're right on this one. Let me just recall the point of familiarity:
there's a lot of Clojure programmers coming to Emacs, thanks to CIDER.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]