Proposal: Bitmask-style syntax for Method Chaining


(Chuquimia, Max) #1

Greetings, fellow Swiftlets!

I am very interested to hear what you guys think about method chaining in a
similar style to Swift’s bitmask handling.
Yes, there’s a healthy discussion on “Setup Closures”, but let’s
dispatch_async to start a new (albeit parallel) thread regarding a neat way
to access properties.
No doubt you’ve found yourself writing something similar to the following:

someViewController.view.layer.shadowColor = UIColor.grayColor().CGColor
someViewController.view.layer.shadowRadius = 5.0
someViewController.view.layer.shadowOffset = CGSizeMake(0.0, 0.5)
someViewController.view.layer.shadowOpacity = 0.75

It can be disturbing to see someViewController.view.layer repeated so many
times, however we are currently unable to refactor these lines without
subclassing and possibly affecting other areas of implementation.

What I propose is a natural way of assigning properties on layer with a
syntax we are all already used to:

someViewController.view.layer = [
    .shadowColor = UIColor.grayColor().CGColor,
    .shadowRadius = 5.0,
    .shadowOffset = CGSizeMake(0.0, 0.5),
    .shadowOpacity = 0.75
]

Which is of course similar to our belovèd
someViewController.view.autoresizingMask
= [.FlexibleWidth, .FlexibleHeight]

Of course, this is an extreme example of keypath length, however I believe
this language feature would still be beneficial for shorter keypaths (think
accessing self within closures or the recent proposal to reinstate self.)

Using [] instead of {} eliminates the risk of ambiguity if a method
such as func
layer(c: Void -> Void) has been defined in the view’s class. Apart from
that, I can’t think of any possible conflicts, and as it’s an addition
there will be no migration required when moving to a new language version

Interested in your thoughts,

MaxC


(Etan Kissling) #2

What about this?

let l = someViewController.view.layer
l.shadowColor = UIColor.grayColor().CGColor
l.shadowRadius = 5.0
l.shadowOffset = CGSizeMake(0.0, 0.5)
l.shadowOpacity = 0.75

···

On 15 Dec 2015, at 22:48, Chuquimia, Max via swift-evolution <swift-evolution@swift.org> wrote:

Greetings, fellow Swiftlets!

I am very interested to hear what you guys think about method chaining in a similar style to Swift’s bitmask handling.
Yes, there’s a healthy discussion on “Setup Closures”, but let’s dispatch_async to start a new (albeit parallel) thread regarding a neat way to access properties.
No doubt you’ve found yourself writing something similar to the following:

someViewController.view.layer.shadowColor = UIColor.grayColor().CGColor
someViewController.view.layer.shadowRadius = 5.0
someViewController.view.layer.shadowOffset = CGSizeMake(0.0, 0.5)
someViewController.view.layer.shadowOpacity = 0.75
It can be disturbing to see someViewController.view.layer repeated so many times, however we are currently unable to refactor these lines without subclassing and possibly affecting other areas of implementation.

What I propose is a natural way of assigning properties on layer with a syntax we are all already used to:

someViewController.view.layer = [
    .shadowColor = UIColor.grayColor().CGColor,
    .shadowRadius = 5.0,
    .shadowOffset = CGSizeMake(0.0, 0.5),
    .shadowOpacity = 0.75
]
Which is of course similar to our belovèd someViewController.view.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]

Of course, this is an extreme example of keypath length, however I believe this language feature would still be beneficial for shorter keypaths (think accessing self within closures or the recent proposal to reinstate self.)

Using [] instead of {} eliminates the risk of ambiguity if a method such as func layer(c: Void -> Void) has been defined in the view’s class. Apart from that, I can’t think of any possible conflicts, and as it’s an addition there will be no migration required when moving to a new language version

Interested in your thoughts,

MaxC

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Jakob Egger) #3

You can already do something similar to this using blocks:

({
  $0.shadowColor = UIColor.grayColor().CGColor
  $0.shadowRadius = 5.0
  $0.shadowOffset = CGSizeMake(0.0, 0.5)
  $0.shadowOpacity = 0.75
})(someViewController.view.layer)

or using optional unwrapping:

if let layer = someViewController.view.layer as CGLayer? {
  layer.shadowColor = UIColor.grayColor().CGColor
  layer.shadowRadius = 5.0
  layer.shadowOffset = CGSizeMake(0.0, 0.5)
  layer.shadowOpacity = 0.75
}

···

On 15 Dec 2015, at 22:48, Chuquimia, Max via swift-evolution <swift-evolution@swift.org> wrote:
What I propose is a natural way of assigning properties on layer with a syntax we are all already used to:

someViewController.view.layer = [
    .shadowColor = UIColor.grayColor().CGColor,
    .shadowRadius = 5.0,
    .shadowOffset = CGSizeMake(0.0, 0.5),
    .shadowOpacity = 0.75
]


(Jacob Bandes-Storch) #4

I'm not sure if this is truly different from the "Setup Closures"
discussion. Wouldn't some of that proposed syntax achieve exactly the same
goal?

someViewController.view.layer.{
    shadowColor = UIColor.grayColor().CGColor,
    shadowRadius = 5.0,
    shadowOffset = CGSizeMake(0.0, 0.5),
    shadowOpacity = 0.75
}

Jacob Bandes-Storch

···

On Wed, Dec 16, 2015 at 3:27 AM, Jakob Egger via swift-evolution < swift-evolution@swift.org> wrote:

On 15 Dec 2015, at 22:48, Chuquimia, Max via swift-evolution < > swift-evolution@swift.org> wrote:

What I propose is a natural way of assigning properties on layer with a
syntax we are all already used to:

someViewController.view.layer = [
    .shadowColor = UIColor.grayColor().CGColor,
    .shadowRadius = 5.0,
    .shadowOffset = CGSizeMake(0.0, 0.5),
    .shadowOpacity = 0.75
]

You can already do something similar to this using blocks:

({
$0.shadowColor = UIColor.grayColor().CGColor
$0.shadowRadius = 5.0
$0.shadowOffset = CGSizeMake(0.0, 0.5)
$0.shadowOpacity = 0.75
})(someViewController.view.layer)

or using optional unwrapping:

if let layer = someViewController.view.layer as CGLayer? {
layer.shadowColor = UIColor.grayColor().CGColor
layer.shadowRadius = 5.0
layer.shadowOffset = CGSizeMake(0.0, 0.5)
layer.shadowOpacity = 0.75
}

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution