12

I learnt . /path/to/file in bash is used to execute a file. Just out of curiosity, I eval something like the following in Emacs

(. 123)
     ⇒ 123

(read "(. 123)")
     ⇒ 123

It looks like Emacs simply reads (. 123) as 123, what happened?

Drew
  • 75,699
  • 9
  • 109
  • 225
xuchunyang
  • 14,302
  • 1
  • 18
  • 39
  • `.` is not a function. `.` is not a variable. Nothing happened -- zip, zero, zilch, nada. – lawlist Nov 04 '16 at 07:33
  • @lawlist It seems to be a bit more complicated than that. E.g. `qsdf` is not a function either, but `(qsdf 123)` yields `void function...`. And `(. 123 456)` yields a syntax error `". in wrong context"`. – T. Verron Nov 04 '16 at 07:38
  • 1
    Looks like an edge case in the reader to me... – wasamasa Nov 04 '16 at 07:39
  • 1
    Btw, the equivalent of bash's `.` (or `source`) in elisp is probably `load`. – T. Verron Nov 04 '16 at 07:41
  • `(. 123)` on https://www.tutorialspoint.com/execute_lisp_online.php gives `*** - READ from #: token "." not allowed here`. In emacs: `(boundp '.)` → `nil` and `(fboundp '.)` → `nil`. I.e., the effect described by you is very strange! – Tobias Nov 04 '16 at 07:56
  • Almost certainly to do with fixing up reading dotted pairs. – icarus Nov 04 '16 at 08:01

1 Answers1

15

It looks like Emacs simply reads (. 123) as 123, what happened?

That's exactly what happened. To back it up with sources:

if (ch == '.')
  {
    if (!NILP (tail))
      XSETCDR (tail, read0 (readcharfun));
    else
      val = read0 (readcharfun);
    read1 (readcharfun, &ch, 0);

    if (ch == ')')
      {
        if (doc_reference == 1)
          return make_number (0);
        if (doc_reference == 2 && INTEGERP (XCDR (val)))
          /* ... */
        return val;
      }
    invalid_syntax (". in wrong context");
  }

This is the special case for read_list in lread.c. Normally a . is treated by setting the cdr of the previously read tail by whatever follows. However in the case there is no tail (like when reading (. 123)), the next thing is read and returned as is. Personally, I'd expect that to lead to an invalid syntax error, but I'm sure someone put the special case there to work around peculiarly terrible sources. I've tried out how other Lisp interpreters behave for fun and none of csi, pil and sbcl do permit reading this, so it may be worth a bug report.

edit: Guile behaves the same, MIT-Scheme doesn't. There goes my theory of this behavior being a GNU thing...

wasamasa
  • 21,803
  • 1
  • 65
  • 97