;;; -*- lexical-binding: t -*-

Apparently I did not get the memo that hell had actually frozen over:

To use lexical binding, an Emacs-lisp source file must set a file-variable `lexical-binding' to t in the file header, e.g., by using a first line like:

;;; -*- lexical-binding: t -*-

Even in a source file that uses lexical binding, global variables declared with `defvar' are always dynamically bound.

Previously, previously.

Tags: , , ,

25 Responses:

  1. jwz says:

    I know it's like lurking near a blind intersection and hoping for a car crash, but I really, really hope that

    (let ((lexical-scope nil))

    does something insane. Also, can you change things so that the variable lexical-scope is itself lexically scoped? Because at that point I think you'll be able to taste colors. And not just regular colors, I mean like ultraviolet.

    • Chas. Owens says:

      Not the same thing, but there is this in Perl 5:


      $Internals::{(grep /only/i => keys %Internals::)[0]}(\!1,0);

      ${\(8==D)} = print;

      print 5 > 42 ? true : false, "\n";

      print eval "5 > 42" ? true : false, "\n"

      Extra points are awarded for understanding why 5 > 42 is considered false, but eval "5 > 42" is considered true.

      • Leolo says:

        5 > 42 is comparison statement, "5 > 42" is a constant string. Please explain to me in what universe these should both be true or both false.

        • Chas. Owens says:

          In the first case, five is not greater than forty-two, so it should be false (and false does in fact print). In the second case we are evaling a string that contains the same code. This should produce the same result, but, because of the evilness above, the conditional operator sees it as true (and, therefore, true is printed).

          The evilness is getting hold of the memory location where the canonically false value (ie the value returned by 5 > 42, !1, and 8 == 'D'), making it writable, and then changing it to 1 (a true value).

          The first comparison isn't affected because of constant folding. The compiler sees that only constants are involved and goes ahead and works out the result. Since the code that mucks with the value of the canonically false hasn't run yet (it is still compiling), it performs as we would expect. The second comparison is hidden from the compiler inside a string, so it is not affected by constant folding and is run at runtime. By that point, the value has been modified. Since 1 is true, the unexpected branch of the conditional operator is returned.

            • Chas. Owens says:

              What part or parts do you find confusing. I am sitting in an ICU right now and don't have easy access to my laptop (so I can't easily post code to provide examples of what I said).

              • jwz says:

                I'm not confused; video is relevant.

                • Chas. Owens says:

                  Ah, I wasn't able to watch the video in the hospital. In Perl 5's defense, this isn't fucked-up-ness that you can normally see; you actually have to go out of your way to fuck around with perl's internals to get this to happen (rather than it being a weird part of how the language is specified).

                  Of course, at this point I understand so much of the Perl 5 internals and am so Stockholmed that I am not certain I would recognize a WAT if one were pointed out to me.

                  I guess $s = "a"; $s++ resulting in $s holding "b", but $s-- being -1 is a Perl 5 WAT. And prototypes in Perl 5 are pretty WAT inducing. Oh, and I still find scalar(@a, @b) to be counter-intuitive, so I guess I am not that far gone.

          • Leolo says:

            This was what I get for posting on Christmas. I didn't fully read your code, just the 5 > 42 vs "5 > 42" bit. And yes, your analysis is correct. The ability to redefine internals is a feature of Perl that can be used for good or evil. So Don't Do That.

      • jonathan says:

        Clearly, the compiler saw 8==D, correctly detected a crass ascii penis attempt and decided to fuck with you thereafter.

  2. Tim says:

    So I'm a Lisp ignoramus -- I know there are lots of lists and parentheses involved, and not much more. I'm trying to grasp the history of this by googling. Do I understand it correctly that prior to hell freezing over, all variables were effectively global variables in Emacs Lisp? And furthermore that RMS was in favor of this?

    p.s. If the stars were Right, there would be a parody of that RMS portrait akin to the glorious "One Nation Under Cthulu" Photoshop. Oh internet, why have you let me down?

    • jwz says:

      In Perl terms, it's as if my didn't exist and all variables were local.

      • Jeremy Leader says:

        ... somewhat similar to Perl 4, where my didn't exist and all variables were global unless you explicitly declared them local.

    • ardgedee says:

      Is it sufficient that the drawing has a prominent copyright notice rather than a copyleft?

  3. James says:

    CHANGES THAT ONLY AFFECT ADVANCED USERS

    [1] In Zwei, m-X Visit Other Window in Other Microcode works again.

    • jwz says:

      Wow, I haven't seen this in years. I am awash in SYS:%NOSTALGIA.

      • Perry says:

        You know that there are samizdat copies of Genera floating around that you can boot inside of OS X, right?

        • jwz says:

          I was aware, but I haven't tried.

          • Noah F says:

            There's a 'sploder emulator that works pretty well too.

            The last time anyone tried to boot one of our physical sploders, smoke came out of the monitor. I think the computer history museum is only interested in the contents of the boxes of tapes.

            • Josh says:

              I'd love to get my hands on an Explorer, on fire or not. If you need or want to get rid of them, I can give them a good home...