[swift-evolution] Ad hoc enums / options

Patrick Smith pgwsmith at gmail.com
Wed Jun 1 09:07:09 CDT 2016


Lots of people have added their 2¢ now, you probably have about 10 dollars worth, but here goes.

While it looks nice and short, I think it has a range of drawbacks:
- It’s not a real type that can participate in protocols or extensions.
- Discourages DRY coding, because some people will think they are taking the easy way out, and even copy and paste this same declaration multiple times.
- Encourages adding subtypes to functions instead of types. Swift seems primarily type-focused more than function-focused. I remember seeing someone write their solution as an extension to UIImage, which was a nice way to do it. This subtype would be best conceptually as UIImage.FitOperation (use with multiple methods!) not scaleAndCropImage.Operation (use once!)

The beauty of Swift is that you can add methods to value types. This opens up interesting, more reusable solutions such as:


enum ContentFit {
  case fit
  case fill
  
  func adjust(size contentSize: CGSize, within bounds: CGRect) -> CGRect {
    let (widthFactor, heightFactor) = (bounds.size.width / contentSize.width, bounds.size.height / contentSize.height)
    let scaleFactor: CGFloat
    switch self {
    case .fit: scaleFactor = min(widthFactor, heightFactor)
    case .fill: scaleFactor = max(widthFactor, heightFactor)
    }
    
    let adjustedSize = CGSize(width: contentSize.width * scaleFactor, height: contentSize.height * scaleFactor)
    let adjustedOrigin = CGPoint(x: (bounds.size.width - adjustedSize.width) / 2.0, y: (bounds.size.height - adjustedSize.height) / 2.0)
    return CGRect(origin: adjustedOrigin, size: adjustedSize)
  }
}


That way you break functions up into smaller chunks, while also making the types more useful in themselves.

(For context, Erica’s original post is here: http://ericasadun.com/2016/05/31/swift-rewrite-challenge/ <http://ericasadun.com/2016/05/31/swift-rewrite-challenge/>)

Patrick

> On 1 Jun 2016, at 2:16 AM, Erica Sadun via swift-evolution <swift-evolution at swift.org> wrote:
> 
> Here's a function signature from some code from today:
> 
> func scaleAndCropImage(
>     image: UIImage,
>     toSize size: CGSize,
>     fitImage: Bool = true
>     ) -> UIImage {
> 
> 
> And here's what I want the function signature to actually look like:
> 
> func scaleAndCropImage(
>     image: UIImage,
>     toSize size: CGSize,
>     operation: (.Fit | .Fill) = .Fit
>     ) -> UIImage {
> 
> 
> where I don't have to establish a separate enumeration to include ad-hoc enumeration-like semantics for the call. A while back, Yong hee Lee introduced anonymous enumerations (and the possibility of anonymous option flags) but the discussion rather died.
> 
> I'm bringing it up again to see whether there is any general interest in pursuing this further as I think the second example is more readable, appropriate, and Swifty than the first, provides better semantics, and is more self documenting.
> 
> Thanks for your feedback,
> 
> -- Erica
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160602/32155d64/attachment.html>


More information about the swift-evolution mailing list