craftinginterpreters icon indicating copy to clipboard operation
craftinginterpreters copied to clipboard

use `fun` for declaring static class methods, not `class`.

Open kelnos opened this issue 8 years ago • 6 comments

Hope you don't mind my sending a PR for this suggestion, if you're interested in it.

First off, a huge thanks for writing this book! I've gone through the chapters you've written so far, and you've turned something that I thought was a scary black art into something digestible and approachable.

Anyhow... I was about to implement the first challenge on the Classes chapter: adding static class methods. Your challenge text suggests using class to denote static methods. I was thinking this has one major downside: it precludes the idea of being able to go further and, say, add support for inner classes, since it'd be hard/weird to disambiguate between the two cases.

Even regardless of that, reusing fun instead for this purpose seemed to fit better, given that it's a clear distinction between an instance method and a function attached to a class, and what are static methods but just functions attached to a class?

Consider this example:

class Foo {
  fun somethingStatic() {
    print "Look at all that static";
  }
}

print Foo.somethingStatic(); // Prints "Look at all that static".

Foo.hello = fun (what) {
  print "Hello " +what;
}
Foo.hello("world"); // Prints "Hello world".

Note that it also allows you to naturally assign anon functions to a class, using the same familiar syntax (assuming one implements the anon function challenge in the previous chapter).

My PR doesn't include changes to the answer code for this challenge, but I'd be happy to work up those changes if you agree with this idea.

kelnos avatar Nov 05 '17 06:11 kelnos

I agree. Maybe add a static keyword so functions can be declared as so?

ghost avatar Nov 05 '17 09:11 ghost

@dangee1705 I don't see a need for a static keyword just yet. Using fun is enough to disambiguate between instance and class methods.

kelnos avatar Nov 05 '17 21:11 kelnos

@kelnos yeah that's true

ghost avatar Nov 05 '17 21:11 ghost

Hmm, that's a good suggestion.

I went back and forth on whether or not fun should be used in the syntax for declaring normal instance methods. Ruby and Python use a keyword for method declarations (def) while C++ and others don't.

Not that it really matters since this is just an exercise, but I worry that using fun makes it look too much like a simple instance method. Maybe class fun?

munificent avatar Dec 10 '17 08:12 munificent

Hehe, yeah, in the end it's not that important. class fun would work; since fun is a keyword it can't be an actual class name, so there's no ambiguity.

kelnos avatar Dec 10 '17 08:12 kelnos

You can also think of it as an attribute of the class, and not the method/function. You don't need an instance of the class to invoke these objects. Maybe you should borrow from VB here instead? Something like:

module Math {
    square(n) {
        return n * n;
    }
}

print Math.square(3);

Then you implement modules as essentially single instance classes.

I realize this doesn't solve the problem of having a class with both instance methods and "static" methods. You'd have to go farther for that. But maybe your language doesn't need that feature. Maybe this is good enough?

chrisjbreisch avatar Jul 04 '22 17:07 chrisjbreisch