3

I would like to define this function:

(defun . (object method &rest args)
 (apply (plist-get object method) args))

But, not surprisingly I get: if: Dot in wrong context

Not surprising because it looks like a cons cell and isn't. I can use some other character like @ or function name like dot, but it seems like it should be possible to use . too. Is there any way to do something like that?

The application is for a closure that defines a plist of functions, and I want something like a dot notation to access them.

This does work, but the double dot is a little unconventional from what I am used to:

(setq c (let ((counter 0))
      (list :inc (lambda (&optional dx)
               "Increment counter by DX (default=1)."
               (incf counter (or dx 1))))))


(defun .. (object method &rest args)
  (apply (plist-get object method) args))

(.. c :inc)
Drew
  • 77,472
  • 10
  • 114
  • 243
John Kitchin
  • 11,891
  • 1
  • 20
  • 42

2 Answers2

3

Yes, you can.

(defun \. (&optional n)
  "This is Lisp function `.'.
It just invokes`forward-char`."
  (interactive "p")
  (forward-char n))

C-h f . tells you about it.

M-x . RET invokes it interactively.

(\. 42) and (\.) invoke it from Lisp.

As you can see, you need to escape the . (with a backslash) when using the function name in Lisp.

Drew
  • 77,472
  • 10
  • 114
  • 243
  • Enabler! Now we're going to have a "backslash-dot" library! – ebpa Apr 17 '17 at 01:13
  • 1
    Hope not. It was already misguided (IMHO) to use just - as a library prefix. Too clever by half. ;-) – Drew Apr 17 '17 at 01:15
  • This didn't work for me in emacs 25.1.1, I still get the wrong dot context error. Is there anything special needed to make it work? – John Kitchin Apr 17 '17 at 01:16
  • @JohnKitchin Works for me in 25.1.1. Have the backslash in both places (definition and invocation)? – ebpa Apr 17 '17 at 01:20
  • Hm. it does work in a clean emacs... Thanks for confirming. – John Kitchin Apr 17 '17 at 01:22
  • It works with a clean emacs for some reason. I use C-x C-e at the end of the defun.

    I am accepting this answer because it is simpler to make the function.

    – John Kitchin Apr 17 '17 at 01:30
2

The answer is: You can define a function named . but it does not help you much. The problem is not that you cannot define a function named . but that the evaluation of such a function is rather complicated.

(eval
 '(setq c (let ((counter 0))
        (list :inc (lambda (&optional dx)
             "Increment counter by DX (default=1)."
             (incf counter (or dx 1))))))
 t)

(fset (intern ".") (lambda (object method &rest args)
             (apply (plist-get object method) args)))

;;; Evaluation of the function named `.':
(funcall (intern ".") c :inc)

You cannot evaluate it as (. c :inc) because you get the "dot in wrong context"-error.

Tobias
  • 33,167
  • 1
  • 37
  • 77
  • Interesting. It looks like the version below also works with this: (. c :inc). I guess if it takes an escape to do it, then .. doesn't seem so bad! – John Kitchin Apr 17 '17 at 01:27