munificent / craftinginterpreters

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

Design discussion Print statement #1054

Open badc0re opened 2 years ago

badc0re commented 2 years ago

Hi, just wondering if you were aware of this (probably you are), but just wanted to point out a possible idea:

var a = 1;
print(a);
1
print(a=123);
123
print(a);
123

I basically think that passing a Boolean for the Expression statement can solve this issue, that way you know if the expression can be used for assignments or not.

munificent commented 2 years ago

I'm not sure I follow. What is the issue you're trying to solve here?

badc0re commented 2 years ago

Assignment when calling print()?

Basically you can change a variable when having it as argument to the function, not sure if feature or bug.

cm1776 commented 2 years ago

Hello @badc0re

From Chapter 8: Statements and State we see that the grammar rule for a print statement is:

printStmt → "print" expression ";"

In the statement print(a=123); , (a=123) is an expression. The value of this expression is 123. And that is the value that was printed.

So what we have is a "feature" of the Lox language.

Sidewinder1138 commented 2 years ago

Yes and: remember that "print" is not a function, it's "baked-in" to the language. So that in your example, you don't actually need the parentheses, you could just do: print a=123; That looks a little weird, but it's valid, because as cm1776 stated, a=123 is a valid expression. Now, that expression does assign 123 to the variable a (that's the "side effect" of the expression), but then the expression evaluates to "123", so that is what is printed.

I agree that this feels kinda weird, and it might be interesting to try disallowing this kind of thing in your language. You could make assignment a Statement, instead of an Expression, and then it wouldn't be allowed in the "printStmt" since that needs an Expression. 🤔