munificent / craftinginterpreters

Repository for the book "Crafting Interpreters"
http://www.craftinginterpreters.com/
Other
9.02k stars 1.06k forks source link

Making print into a function #131

Closed jDomantas closed 7 years ago

jDomantas commented 7 years ago

In the third chapter there was a note about how making print a statement is a little hack to allow testing the interpreter before we have working functions. Now that we have implemented functions, this hack is quite easy to fix - all you need is defining a native function:

globals.define("print", new LoxCallable() {
    @Override
    public int arity() {
        return 1;
    }

    @Override
    public Object call(Interpreter interpreter, List<Object> arguments) {
        System.out.println(stringify(arguments[0]));
        return null;
    }
});

and then removing the machinery required to lex, parse, and interpret print statements. Given that this was noted to be a hack and its solution now is very simple, I think it could be mentioned somewhere. I think it could be either a note or a challenge - the language would not change for us, but some readers might be interested to learn that language hacks could be fixed afterwards.

munificent commented 7 years ago

Huh, I hadn't considered circling back and fixing the language. I'm hesitant to do this for a couple of reasons:

  1. It means there are really two Loxes, one with print statements (no parentheses for the argument) and one with a print function (parenthesized) message. Readers who try to run a snippet of code written for one Lox in an interpreter of the other will be annoyed that it doesn't work.

    In particular, if they were to take some of the very first samples in the beginning of the book, and run them under the interpreter they build from this repo, they won't work. That doesn't seem like a great first experience. (Anyone whose tried to run Python 2 programs in Python 3 knows what I'm talking about.)

    I could fix that by making print statements require parentheses too. That would require going back and reworking some stuff in the book, but it's not impossible.

  2. I try to minimize the amount of code in early chapters that gets deleted or reworked in later chapters. I don't want the book to read like a big pile of diffs. It might be frustrating to tell readers to delete code that just wrote.

  3. We would have to do this "add a hack and then later remove it dance" twice. In Part 3 of the book, we start over from scratch on the new interpreter in C. There, again, we will have several chapters where we want to be able to display output before we reach the point where we can do function calls. In fact, there's an even bigger gap in that part.

    I worry it would be even more annoying to readers to have to re-add the hack in clox after they went through the trouble to remove it once already.

Given all that, it seems simplest to me to just leave print statements as they are. Remember, the goal of the book is to teach you how to implement your language. Lox itself doesn't need to be without flaws.

However, the 12 thumbs ups tell me my intuition may be wrong here. I do like the idea of making this a challenge. Would that be sufficient?

jDomantas commented 7 years ago

Making this into a challenge seems to be a good idea - there are already challenges that suggest to improve the language. This one would also give readers an opportunity to fiddle with native functions a bit more.

munificent commented 7 years ago

OK, I added some more meat to the aside about the print statement. Hopefully that helps. :)