1. 2

    It is off by default, but a potentially immense change concerns the handling of nil and a new keyword undef.


    btw, I notice that there is a new keyword, “undef”, not mentions in manual, is that just a undocumented feature or the doc just not the latest?

    I am grad you asked :-)

    Lua 5.4 has an experimental change that is off by default (to keep compatibility). We plan to keep this off in Lua 5.4 final. You can turn it on by compiling this version with the option -DLUA_NILINTABLE. As the name hints, this option allows nils in tables:

     t = {nil, nil, nil}
     for k,v in pairs(t) do print(k, v) end
    1	nil
    2	nil
    3	nil
    t[#t + 1] = nil
    for k,v in pairs(t) do print(k, v) end
    1	nil
    2	nil
    3	nil
    4	nil

    Once you have nils in tables, t[i]=nil does not remove elements from a table anymore. For that, you need to write t[i]=undef.

    No, this is not like JavaScript! ‘undef’ is NOT a value.

    t[i]=undef is a special syntax form that means “remove the key ‘i’ from table ‘t’”. You can only use ‘undef’ in three specific forms:

      t[i] = undef     -- remove a key from a table
      t[i] == undef    -- test whether a table has a key
      t[i] ~= undef    -- test whether a table has a key

    Any other use of ‘undef’ gives a syntax error.

    You still can create tables with holes, but you must get out of your way to do it.

    The nice thing about this syntax is that it is compatible with previous versions of Lua (as long as you do not use ‘undef’ for other stuff). In Lua 5.0/1/2/3, if you write ‘t[i] = undef’, you remove the element from the table. Even if we never change Lua to this new mode, even if you never use Lua 5.4, we think this syntax is a nice way to document whether an assignment is being done to remove an element from a table.

    (A search for the pattern ‘][ =~]*nil’ finds most of the places in your code where you could/should use undef instead of nil.)

    – Roberto

    1. 3

      Someone on Twitter pointed out to me that this is surprising (and maybe even a bug of sorts): Apparently Apple patches gem in such a way that it doesn’t install binaries to /usr/bin by default any longer.

      But that is surprising because your post-update gem was trying to install to /usr/bin. Out of curiosity, what is the default install directory for gems in the defaults file (grep for if defined? RUBY_FRAMEWORK_VERSION):


      I’m just wondering if the update to gem overwrote this patch. If so, that seems to be a bug: Apple tried to protect users from this kind of problem, but it should also forbid updating that defaults file.

      Update A few people tried the same global gem update and reported that the it installs a new defaults.rb file in /Library/Ruby/Gems. That defaults file is then read before the one patched by Apple, and boom: breakage when gem tries to install to /usr/bin. A relatively easy fix might be to patch the new defaults.rb by hand, so that it matches the Apple patch. It’s trivial change. I mention all this for future Googlers, but it may also help you now. Good luck!

      1. 5

        I looked into this, found that the /usr/bin/gem update --system isn’t installing anywhere inside /usr/bin or within the system Ruby at /System; it doesn’t have permissions to do that. Instead, the rubygems update is installing a new rubygems at /Library/Ruby/Site/2.0.0/, which is a sudo-writeable location under SIP; that is loaded by Ruby first before the version that comes with the OS, and it includes a version of rubygems/defaults.rb which lists /usr/bin as the default gem bindir. If you remove /Library/Ruby/Site/2.0.0/rubygems and /Library/Ruby/Site/2.0.0/rubygems.rb, gem will go back to using the original system-installed version and all will be fine; alternately, you can patch /Library/Ruby/Site/2.0.0/rubygems/defaults.rb to change the bindir.


        $ /usr/bin/ruby -e 'require "rubygems/defaults"; puts Gem.default_bindir'


        $ /usr/bin/ruby -e 'require "rubygems/defaults"; puts Gem.default_bindir'
      1. 6

        Taking something by a master and not reading their code until after a whack at the problem myself. http://norvig.com/ is a good source. Another was Thompson’s regex search paper – I did read it first, but the IBM 709 code was obscure enough to avoid spoilers. I’ve put this one up as a kind of problem set: https://github.com/darius/regexercise

        If it’s a problem you’re interested in, you can’t really lose: you either get schooled or you find a wrinkle that your chosen master didn’t.

        1. 4

          I worked through Little Schemer like this. I would cover their answers and try on my own, then check, compare etc. It was a great experience: humbling in a good way.

          Another book this works well for is K&R on C. There are tons of solutions to their exercises on Github, Bitbucket and personal websites. Try to solve first, then read around. Problem there, of course, is that the solutions are off very varied quality, and you don’t know in advance which are good, great, meh, terrible. Of course, you can think of that as training for reading real code: You never know what you’ll get.

          1. 2

            There’s an old book, The C Answer Book, for just this. (I haven’t read it.)

        1. 8

          So I should preface this by saying that I’m very much an amateur and self-taught. These definitely put the toy in toy implementation:

          • btree: A kind-of, sort-of drop-in replacement for tree in shell. (Twice actually: once taking advantage of bashisms and once using POSIX shell syntax only.)
          • toy-core: Minimal C implementation of a few basic utilities (cat, tail, head, and echo). I wanted to understand ring buffers better, so I was mostly interested in tail, but the whole thing was useful for practicing C.
          • llisp: This was inspired by reading Mary Rose Cook’s Little Lisp interpreter. I started a mini-Lisp in Lua. I lost steam after getting the most basic functionality, but would like to go back to it someday.
          1. 1

            Also interesting, and partially a follow-up to Barthes' essay, is Michel Foucault’s “What is an author?”. The only copies I can find online are pdfs, but this site has good selections: http://www9.georgetown.edu/faculty/irvinem/theory/Foucault-AuthorFunction.html.

            1. 2

              Part of me wants to complain about bias and write an alternate version of this – a version where (the best of) Analytic philosophy represents sane, clear and clear-eyed realism and (the worst of) Continental is merely dense writing, sound and fury signifying nearly nothing.

              But here’s what I hope is a better approach. My favorite philosopher of the 20th century was Bernard Williams. He was certainly British and steeped in the traditions of Oxford (where he was a student) and Cambridge (where he taught). But he doesn’t fit very well at all into the stereotypes of either Analytic or Continental philosophy. He spent much of his life demonstrating how thin and childish academic moral philosophy (of all flavors) was, and when he wrote a book on truth (a very Analytic topic), he used a methodology he derived in part from Nietzsche.

              So my more positive contribution is this: I suspect that the best philosophy doesn’t fit neatly into either of the two categories this post describes.

              1. 2

                There’s actually a lot of debate as to even if that particular dividing line makes lots of sense. For example, most people would consider Continental philosophy to be entirely idealist, but Deleuze was a materialist.

                1. 1

                  Yup. I’m more familiar with the (so-called) Analytic side, and nearly everyone I studied with wanted to disavow the label and/or significantly complicate the division.

                  Here’s another way to look at it: In my experience “Analytic” or “Continental” are labels you usually use of someone else, and only as an insult.