aardappel / lobster

The Lobster Programming Language

Home Page:http://strlen.com/lobster

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Odd name clash with members of different classes.

MortimerSnerd opened this issue · comments

I'm not 100% sure this is a bug, but it is aggravating. And a little too much code to drop for a discord question.

The basic idea is I have a class or struct that has a inline method that elides the this. when referencing fields, in the mod1 module. Like this:

import vec
//import mod2

struct LS:
   start: xy_f
   extent: xy_f

   def endpoint() -> xy_f:
      return start + extent


let s = LS{xy_0, xy_1}
print(s.endpoint())

It works fine, until I add a mod2, which has a class with a start() method, and uncomment the import for it in mod1:

class SomeObj:
   def start():
      return this

Now when I run mod1, I get this error:

mod1.lobster(9): error: illegal start of expression: `+`
in:       return start + extent
at:              ^^^^^

I did this with two modules for brevity, but in my real program, this happens where mod1 and mod2 don't import each other, but mod3 happens to import both of them.

When I ran into this yesterday, mod1 was a utility module I copy between projects that has common data/functions that's been there a while. I ran into this problem after adding a flatbuffers schema where I can't rename the fields without rewriting JSON files. So my only other workaround is to add this. qualification to the places where the name clashes until it runs again. Not the end of the world, but it does seem like an odd clash. Why does it worry about the start() in the SomeObj namespace when LS is a struct with no relation to it?

The problem is the way it is currently implemented is that start() looks like a top-level function with a SomeObj argument, and only the type-checker can easily distinguish this based on types. Meanwhile, in the parser, it sees start and needs to decide if its a field or a function call without (), and it makes the wrong decision because it has no type information yet.

I'll have a look and see how best distinguish these to make it prefer the field. In general I want to move more of these decisions to the type checker, but I am not sure if that is possible in this case.

In the end was not that hard to fix. We already preferred local variables over these parenthesis-less-calls, but not fields in scope for some reason. Totally made sense to do so, and didn't affect any existing code.