ponyc icon indicating copy to clipboard operation
ponyc copied to clipboard

Unable to use object literal field in constructor

Open Theodus opened this issue 9 years ago • 6 comments

In objects you can do the following:

class Foo
  let _x: USize = 0
  let _y: USize = _x

But when this is done for object literals as so:

let x = object
  let _x: USize = 0
  let _y: USize = _x
end

it gives the following error:

can't find declaration of '_x', did you mean 'x'?
      let _y: USize = _x
                      ^

Theodus avatar Oct 01 '16 00:10 Theodus

Can you label this as discuss at sync @theodus? If it gets resolved before the sync, the label can be removed.

SeanTAllen avatar Oct 01 '16 00:10 SeanTAllen

Sure thing!

Theodus avatar Oct 01 '16 00:10 Theodus

I think it's because in the most common use case for object literals, you would assign values taken from the surrounding context, whereas a class, there is no surrounding context other than the fields of the class itself, so that's what is searched.

To be honest, I didn't even know your first (class) example was valid Pony. If that's intentionally allowed, then I think it makes sense to make object literals behave in the same way (if it's feasible to do so), so that we obey the principle of least surprise.

So that means first I think we have to confirm that the first example is an intentional feature, and not an accidental feature. Then we'd have to determine if it is technically feasible to support making object literals behave the same way.

jemc avatar Oct 01 '16 04:10 jemc

I don't really have a preference over this being a feature of the language. I agree that it should be consistent between classes and object literals.

Theodus avatar Oct 03 '16 16:10 Theodus

I think this is a very interesting and somewhat deep issue. Perhaps the right solution is to allow implicit closing over variables in both lambdas and object literals, and find a nice clean way to do both?

sylvanc avatar Oct 05 '16 20:10 sylvanc

One thing that's somewhat annoying about object literals is that unlike lambdas, you have to be explicit about the type of a capture, e.g.

let x: USize = 1
object
  let x: USize = x
end

Else you'll get "expected mandatory type declaration on field after x".

Note that the name is allowed to be the same which isn't really shadowing since you aren't able to access to outer scope without making the reference.

malthe avatar Oct 15 '16 09:10 malthe