branch: elpa/llama
commit b890bfb76aea8df253c5baf3a95df008b67dd1dc
Author: Jonas Bernoulli <jo...@bernoul.li>
Commit: Jonas Bernoulli <jo...@bernoul.li>

    Revive and give up on display magic
    
    No longer suggest using `l' instead but also give up
    on using `display' property to display it as ##(...).
---
 README.md | 106 +++++++++++++++++-------------------------
 llama.el  | 155 +++++++++++++++++---------------------------------------------
 2 files changed, 83 insertions(+), 178 deletions(-)

diff --git a/README.md b/README.md
index 7cc580ef7b..30189c2e12 100644
--- a/README.md
+++ b/README.md
@@ -1,65 +1,41 @@
-Compact syntax for short lambdas.
-
-Unfortunately compact syntax for short `lambda`s won't be added to
-Emacs anytime soon.  IMO the arguments as to why we would like to have
-that has been layed out convincingly but the proposal has been
-rejected anyway.
-
-Several packages exist that implement anonymous function literals,
-but until now they all either are waiting for a patch to the C part
-be merged into Emacs, or they depart too far from the ideal syntax.
-
-This package is another attempt.
-
-> **Update:** I have come up with a second syntax, which does not put
-> anything *before* the opening parenthesis and looks like `(l'foo %)`.
-> Unlike with my original `llama` idea I am no longer suggesting making
-> it look like some character(s) appear before the paren using font-lock
-> or similar trickery (see below).  If you so desire, then you could
-> however use `prettify-symbols-mode` to display it as e.g. `(ƒ'foo
-> %)`.  This approach is implemented in [`l`](https://git.sr.ht/~tarsius/l).
-
-In a stroke of luck I discovered a loophole that allows us to have
-almost the syntax that we want without having to convince anyone.
-
-    $(foo %)        is what I would have used if it were up to me.
-    #(foo %)        works just as well for me.
-    ##(foo %)       is similar enough to that.
-    (##foo %)       is the loophole that I discovered.
-
-Even though there is no space between the second `#` and `foo`, this
-last form is read as a list with three arguments `(## foo %)` and it
-is also indented the way we want!
-
-    (##foo %
-           bar)
-
-This is good enough for me, but with a bit of font-lock trickery,
-we can even get it to be display like this:
-
-    ##(foo %
-           bar)
-
-This is completely optional and you have to opt-in by enabling
-`llama-mode` (or the global variant `global-llama-mode`).
-
-An unfortunate edge-case exists that you have to be aware off; if
-no argument is placed on the same line as the function, then Emacs
-does not indent as we would want it too:
-
-    (##foo                                         ##(foo
-     bar)        which llama-mode displays as       bar)
-
-I recommend that in this case you simply write this instead:
-
-    (## foo                                        ##( foo
-        bar)     which llama-mode displays as          bar)
-
-It is my hope that this package helps to eventually get similar
-syntax into Emacs itself, by demonstrating that this is useful and
-that people want to use it.
-
-*Also see the [announcement](https://emacsair.me/2021/01/28/llama-0.1).*
-
-*Also see [`l`](https://git.sr.ht/~tarsius/l), my second attempt at
-faking such syntax.*
+This package implements the macro `##`, which provides compact
+syntax for short `lambda`, without actually being new syntax,
+which would be difficult to get merged into Emacs.  Past attempts
+to add syntax were met with determined pushback and the use of a
+macro was suggested as an alternative.
+
+The `##` macro, whose signature is `(## FN &rest args)`, expands
+to a `lambda` expressions, which wraps around its arguments.
+
+This `lambda` expression calls the function FN with arguments
+ARGS and returns its value.  Its own arguments are derived from
+symbols found in ARGS.  Each symbol from `%1` through `%9`, which
+appears in ARGS, is treated as a positional argument.  Missing
+arguments are named `_%N`, which keeps the byte-compiler quiet.
+In place of `%1` the shorthand `%` can be used, but only one of
+these two can appear in ARGS.  `%*` represents extra `&rest`
+arguments.
+
+Instead of:
+
+```elisp
+(lambda (a _ c &rest d)
+  (foo a (bar c) d))
+```
+
+you can use this macro and write:
+
+```elisp
+(##foo % (bar %3) %*)
+```
+
+which expands to:
+
+```elisp
+(lambda (% _%2 %3 &rest %*)
+  (foo % (bar %3) %*))
+```
+
+The name `##` was choosen because that allows (optionally)
+omitting the whitespace between it and the following symbol.
+It also looks similar to `#'function`.
diff --git a/llama.el b/llama.el
index 4baae2201e..250684b263 100644
--- a/llama.el
+++ b/llama.el
@@ -1,4 +1,4 @@
-;;; llama.el --- Anonymous function literals  -*- lexical-binding:t -*-
+;;; llama.el --- Compact syntax for short lambda  -*- lexical-binding:t -*-
 
 ;; Copyright (C) 2020-2022 Jonas Bernoulli
 
@@ -25,61 +25,41 @@
 
 ;;; Commentary:
 
-;; This package implements compact syntax for short `lambda's, without
-;; relying on a C patch to Emacs or adding an additional pair of
-;; parentheses.
-
-;; [!] I have come up with another approach that does not put anything
-;; [!] before the opening parenthesis: https://git.sr.ht/~tarsius/l.
-
-;; Unfortunately anonymous function literals won't be added to Emacs
-;; anytime soon.  The arguments as to why we would like to have that
-;; has been layed out convincingly but the proposal has been rejected
-;; anyway.
-
-;; Several packages exist that implement anonymous function literals,
-;; but until now they all either are waiting for a patch to the C part
-;; be merged into Emacs, or they depart too far from the ideal syntax.
-
-;; In a stroke of luck I discovered a loophole that allows us to have
-;; almost the syntax that we want without having to convince anyone.
+;; This package implements the macro `##', which provides compact
+;; syntax for short `lambda', without actually being new syntax,
+;; which would be difficult to get merged into Emacs.  Past attempts
+;; to add syntax were met with determined pushback and the use of a
+;; macro was suggested as an alternative.
+
+;; The `##' macro, whose signature is (## FN &rest args), expands
+;; to a `lambda' expressions, which wraps around its arguments.
+
+;; This `lambda' expression calls the function FN with arguments
+;; ARGS and returns its value.  Its own arguments are derived from
+;; symbols found in ARGS.  Each symbol from `%1' through `%9', which
+;; appears in ARGS, is treated as a positional argument.  Missing
+;; arguments are named `_%N', which keeps the byte-compiler quiet.
+;; In place of `%1' the shorthand `%' can be used, but only one of
+;; these two can appear in ARGS.  `%*' represents extra `&rest'
+;; arguments.
+
+;; Instead of:
 ;;
-;;   $(foo %)        is what I would have used if it were up to me.
-;;   #(foo %)        works just as well for me.
-;;   ##(foo %)       is similar enough to that.
-;;   (##foo %)       is the loophole that I discovered.
-
-;; Even though there is no space between the second # and `foo', this
-;; last form is read as a list with three arguments (## foo %) and it
-;; is also indented the way we want!
+;;   (lambda (a _ c &rest d)
+;;     (foo a (bar c) d))
 ;;
-;;   (##foo %
-;;          bar)
-
-;; This is good enough for me, but with a bit of font-lock trickery,
-;; we can even get it to be display like this:
+;; you can use this macro and write:
 ;;
-;;   ##(foo %
-;;          bar)
+;;   (##foo % (bar %3) %*)
 ;;
-;; This is completely optional and you have to opt-in by enabling
-;; `llama-mode' (or the global variant `global-llama-mode').
-
-;; An unfortunate edge-case exists that you have to be aware off; if
-;; no argument is placed on the same line as the function, then Emacs
-;; does not indent as we would want it too:
+;; which expands to:
 ;;
-;;   (##foo                                         ##(foo
-;;    bar)        which llama-mode displays as       bar)
+;;   (lambda (% _%2 %3 &rest %*)
+;;     (foo % (bar %3) %*))
 
-;; I recommend that in this case you simply write this instead:
-;;
-;;   (## foo                                        ##( foo
-;;       bar)     which llama-mode displays as          bar)
-
-;; It is my hope that this package helps to eventually get similar
-;; syntax into Emacs itself, by demonstrating that this is useful and
-;; that people want to use it.
+;; The name `##' was choosen because that allows (optionally)
+;; omitting the whitespace between it and the following symbol.
+;; It also looks similar to #'function.
 
 ;;; Code:
 
@@ -87,17 +67,16 @@
 
 ;;;###autoload
 (defmacro ## (fn &rest args)
-    "Return an anonymous function.
-
-The returned function calls the function FN with arguments ARGS
-and returns its value.
+    "Expand to a `lambda' expression that wraps around FN and ARGS.
 
-The arguments of the outer function are determined recursively
-from ARGS.  Each symbol from `%1' through `%9' that appears in
-ARGS is treated as a positional argument.  Missing arguments
-are named `_%N', which keeps the byte-compiler quiet.  `%' is
-a shorthand for `%1'; only one of these can appear in ARGS.
-`%*' represents extra `&rest' arguments.
+This `lambda' expression calls the function FN with arguments
+ARGS and returns its value.  Its own arguments are derived from
+symbols found in ARGS.  Each symbol from `%1' through `%9', which
+appears in ARGS, is treated as a positional argument.  Missing
+arguments are named `_%N', which keeps the byte-compiler quiet.
+In place of `%1' the shorthand `%' can be used, but only one of
+these two can appear in ARGS.  `%*' represents extra `&rest'
+arguments.
 
 Instead of:
 
@@ -113,13 +92,9 @@ which expands to:
   (lambda (% _%2 %3 &rest %*)
     (foo % (bar %3) %*))
 
-Note that there really does not have to be any whitespace
-between \"##\" and \"foo\"!
-
-If you enable `llama-mode' or `global-llama-mode', then the
-above is *displayed* as:
-
-  ##(foo % (bar %3) %*)"
+The name `##' was choosen because that allows (optionally)
+omitting the whitespace between it and the following symbol.
+It also looks a bit like #\\='function."
   (unless (symbolp fn)
     (signal 'wrong-type-argument (list 'symbolp fn)))
   `(lambda ,(llama--arguments args)
@@ -158,52 +133,6 @@ above is *displayed* as:
     (seq-doseq (elt data)
       (llama--collect elt args)))))
 
-(defvar llama--keywords
-  '(("(##" (0 (llama--transpose)))))
-
-(defun llama--transpose ()
-  (and (not (nth 8 (syntax-ppss)))
-       `(face nil display "##(")))
-
-(defvar-local llama--display-already-managed nil)
-
-;;;###autoload
-(define-minor-mode llama-mode
-  "Toggle Llama mode.
-
-When Llama mode is enabled then forms like (##foo %) are
-displayed as ##(foo %) instead.
-
-You can enable this mode locally in desired buffers, or use
-`global-llama-mode' to enable it in all `emacs-lisp-mode'
-buffers."
-  :init-value nil
-  (cond
-   (llama-mode
-    (font-lock-add-keywords nil llama--keywords)
-    (add-to-list 'font-lock-extra-managed-props 'display)
-    (when (memq 'display font-lock-extra-managed-props)
-      (setq llama--display-already-managed t)))
-   (t
-    (font-lock-remove-keywords nil llama--keywords)
-    (if llama--display-already-managed
-        (setq llama--display-already-managed nil)
-      (setq font-lock-extra-managed-props
-            (delq 'display font-lock-extra-managed-props)))
-    (with-silent-modifications
-      (remove-text-properties (point-min) (point-max) '(display nil)))))
-  (font-lock-flush))
-
-;;;###autoload
-(define-globalized-minor-mode global-llama-mode
-  llama-mode llama--turn-on-mode
-  :group 'lisp)
-
-(defun llama--turn-on-mode ()
-  (when (and (not llama-mode)
-             (derived-mode-p 'emacs-lisp-mode))
-    (llama-mode 1)))
-
 ;;; _
 (provide 'llama)
 ;; Local Variables:

Reply via email to