Skip to content

Clarify the scoping nature of fields #61

Open
@leonerd

Description

@leonerd

The RFC as it stands does not give enough clarity on the scoping nature of field names. In particular, all of the examples simply use unique field ... names at the level of the class block itself, so they don't sufficiently explain various cornercases.

Lets for now entirely ignore the generated method names for :reader or :writer attributes, or the constructor behaviour of a :param, and think purely about the field as an internal storage mechanism.

I can imagine any of several different models.

1. my-like

Since already we're saying that fields are private within a given class; that methods even in a directly derived subclass cannot see them, I wonder if they are lexically scoped within the block that declares them. I could see a model in which they scope the same as my variables. Compare the analogy of:

package Red {
  { my $x = 1; sub one { return $x; } }
  { my $x = 2; sub two { return $x; } }
}

class Blue {
  { field $f { 1 }  method one { return $f } }
  { field $f { 2 }  method two { return $f } }
}

This has a notable upside, in that if an individual method wanted to do some sort of per-instance memoization, it can hide a field variable in its own little block to act as a storage cache; in a similar way to the way regular subs can:

class Example {
  {
    field $cache;
    method calculate_thing {
      return $cache //= do { expensive code goes here };
    }
  }
  # other code and methods here can't see $cache
}

That variable is now hidden from all the other methods, and name clashes don't matter.

I like this model because it means that these fields (names beginning with $ or other sigils) scope the same way as lexical variables. Similar looking things behave similarly.

2. method-like

Alternatively, I could imagine that the set of field names declared on a class is visible once throughout the class. By analogy to how package subs are callable even between physically-separate parts of the same package, I could imagine that fields are similarly visible:

package Red { sub func { ... } }
# now we're back in main package

package Red { func() } # calls the function defined earlier

class Blue { field $f; }

class Blue { method m { $f++ } }

In this arrangement, it doesn't matter what block-level scope a field is declared in. Once created for a given class it now exists, just once, in any code that's part of that class.

I don't like this model because it makes these fields scope the same as methods, even though they look superficially like lexicals. It's a subtle and complex model to try to explain to people.

3. Some other model?

There may be some other ideas, but so far I can't think of another good one.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    FeedbackCor Proposal Feedback

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions