#874 Field setters: val => it

tactics Wed 16 Dec 2009

Currently, when a field has a setter, Fantom automatically introduces a variable called val. I know this is used because C# uses value, but it doesn't quite sit with me to introduce a non-keyworded variable into scope by convention.

It sounds like we may eventually change to the storage operator back to &, as per Andy's comments on 870). If we do, this proposal is worth some consideration.

I came up with a few alternatives to the current syntax. Currently, field setters look like this:

// old way, example used in the docs
class Thing
{
  Int id := 0
  {
    get { echo("get id"); return *id }
    set { echo("set id"); *id = val }
  }
}

The line set { echo("set id"); *id = val } is the setter. The val keyword is introduced into scope implicitly, holding the value of the RHS of the assignment.

Like I said, I don't like using convention to introduce variables. I'd rather use a keyworded variable. Since the conception of the field model, we have introduced a special identifier for just such a situation: it. The it variable has the semantics that it holds the value of an implicit parameter introduced into the current scope. Right now, that means an it-block, but it isn't a stretch to imagine its use here too.

class Thing
{
  Int id := 0
  {
    get { echo("get id"); return *id }
    set { echo("set id"); *id = it } // binds set value to it
  }
}

Since setters under this plan look like an it block, we could easily allow the setter to be defined as any closure expression. That is, we could use it blocks, as per the example above, or we could use a non-it-block closure, like this next example:

class Thing
{
  Int id := 0
  {
    get { echo("get id"); return *id }
    set |x| { echo("set id"); *id = x } // binds set value to x
  }
}

This syntax is nice because it gives us freedom to choose the name of the variable introduced. We can then use set |newVal| { echo("set id"); *id = newVal } if val is a slot name or if we plan to use it blocks inside the setter.

The only issue semantically with this approach is getters end up looking like it-blocks with nothing bound to it.

What do you guys think?

alexlamsl Thu 17 Dec 2009

This might be off-topic, but does that mean it-block is basically syntax sugar for:

|V it->| {...}

In fact - does it matter if we have return in an it-block, when the return type is Void anyway?

brian Thu 17 Dec 2009

This might be off-topic, but does that mean it-block is basically syntax sugar fo

Mostly but it is more than that because it gets special treatment just like this does inside an instance method.

What do you guys think?

You are right I just copied C# with the implicit val parameter. But I totally agree now that we have the it keyword that would make way more sense. So I think it is a great idea!

I am not ready to say we should do the set |x| { ...} part of your proposal yet. I am not sure we really need that (we could always add it later).

So proposal on the floor is to replace setter implicit val parameter with it. I'm definitely for this change.

andy Thu 17 Dec 2009

Seems fine with me.

ivan Thu 17 Dec 2009

+1 for it, -1 for set |x|, because this will allow to specify type which may differ from field type.

brian Thu 17 Dec 2009

Promoted to ticket #874 and assigned to brian

brian Thu 17 Dec 2009

Renamed from Syntax for accessor methods to Field setters: val => it

brian Sun 20 Dec 2009

Ticket resolved in 1.0.48

You now use the it keyword instead of the implicit variable val inside a field setter to access the value being assigned.

In most cases you will receive a warning and things will continue to compile. I will remove the warning completely in the following build.

However if you were using val inside a closure, then you will need to rework your code a bit since it is not available inside a closure. Just assign it to a local variable:

// old code
3.times { echo(val) }

// new code
newVal := it
3.times { echo(newVal) }

Login or Signup to reply.