Presence. [value.isEmpty ? nil : value]

Code often has next expression:

    ...
    return value.isEmpty ? nil : value
}

It looks useless and incompact, my proposition to integrate in future versions property presence, that influenced me from Rails.

In result:

    ...
    return value.presence
}
Code
//
//  Presence.swift
//  Swift
//
//  Created by Dmytro Pylypenko on 31/07/2018.
//  Copyright © 2018. All rights reserved.
//

import Foundation

protocol Emptyable {
    var isEmpty: Bool { get }
}

protocol Presencable: Emptyable {
    var presence: Self? { get }
}

extension Presencable {
    var presence: Self? {
        return isEmpty ? nil : self
    }
}

extension Set: Presencable, Emptyable {
}

extension ArraySlice: Presencable, Emptyable {
}

extension Array: Presencable, Emptyable {
}

// etc

Example:

let arr = [1, 3]
arr.dropFirst(2).presence // nil
arr.presence // arr

Epilogue:
Also it would be good to add protocol empty natively to specific objects.

Thoughts?

present? and presence make sense in Rails because, as a Web Framework, you often have to deal with empty strings and them being used to indicate the absence of some value (due to the way the Web works).

I'm not sure if those concept make that much sense in a general purpose programming language context. If so, one would have to define what the appropriate level of generality is. But IMHO, the weak typing context of the web that necessitates the conflation of empty string and nil is rather something best avoided in other contexts; so I'd rather see this as being part of some library than something that is in the stdlib.

Purpose of present?, presence, blank?, empty? and other not related to strings only, but part of architecture where you work with nullable values, not initialized empty one. I can't say that it has direct correlation that depends on Web Framework sense.

I'm all for an Empty protocol. It makes it explicit that something can be empty. EmptyRepresentable would be a better name. Its definition:

protocol EmptyRepresentable {
  var isEmpty: Bool { get }
  var empty: Self { get }
}

Implementation for Array:

extension Array: EmptyRepresentable {
  public var isEmpty: Bool {
    return self.startIndex == self.endIndex
  }

  public var empty: Array {
    return []
  }
}

Combined with a NonEmpty type, this could make for a good evolution proposal.

(Also, together with a Combinable protocol the user could then create a Monoid-like existential, EmptyRepresentable & Combinable, without "polluting" the Standard Library with mathematical terms.)

But "nullable values" are Optionals in a strongly typed context.

I can understand the need for a general type coercion mechanism, where you want to take weakly typed input from whatever context (e.g. CSV files, web forms, JSON, etc.) and force it into particular types (with some error handling for when this isn't possible), but that's rather something that should be considered more generally with special validation / coercion libraries (like dry-validation for Ruby), and not something that should have a special case just for nil.

Thanks for link.

We are about different approaches.
There is no reason to allocate empty objects, when you can work with optionals.

There's no need to introduce new protocols.

extension Collection {
  public var nonEmpty: Self? {
    return isEmpty ? nil : self
  }
}

There is, for custom data types.
Cause not only collection could be empty, but encapsulated objects too.

If you're seeing this everywhere it smells like you want a type. pointfree offers a package for nonempty sequences. I suspect that if you plumb this through, it'll force you to explicitly handle the empty case along API usage edges rather than making it an intrinsic part of the API itself.

Array<T>? is usually a code smell.

1 Like

I think any optional collection is probably not that great, that would include String? in my view.

Yes, this seems designed to make going the “wrong direction” easier, when I would suggest that in almost all cases it is better to collapse this by removing the Optional wrapper and turning the .none/nil case into an empty collection. I'm struggling to think of any good use case for collapsing this distinction the other way.

What is benefit empty collection over nullable on your thoughts?

Optimal:
text?.presence?.trimmingCharacters(in: .whitespacesAndNewlines)

The problem is that if you allow both "empty collection" and "nil" it's not immediately clear what the semantic difference between the two is.

If for some reason you really need the distinction, it might be better to come up with a better type, e.g. an enum with different semantically labeled cases or so.

Coincidentally, would it be possible to (type-safely) implement a NonEmptyString type in Swift?

2 Likes

Imagine that we have some struct with @type, @data and @prediction values, where data and prediction are collection. Not always @prediction has data, and we have choice to build struct with useless @prediction data allocation or put nil, that indicates – we don't need further operations with it in current process.
Next in code we have some behavioral layer, where we use the struct and setup rendering depended on this values. There is no any direct reason to pass empty collection, instead we need to render only if value exist what means we put real data for further processing, and each allocation of collection that can have empty or not – makes no sense.

That’s interesting. If I had a User object with a non-required nickname field, would you type that field as String and represent a missing nickname with an empty string? Or did I read your argument too literally?

Like an @objc optional protocol requirement? If so then I would probably rewrite to be a regular protocol with nickname as non optional. If somebody gives me a bunch of whitespace for a nick name then I’d rather trim that to be an empty String and then just check if the string is empty to considered it . If the nickname is optional, I still have to make sure the string is not empty or just white space. Optional collections only make sense to me if they can never be empty.

1 Like

I’d disagree with this on data integrity grounds.

nil indicates there is no value.
“” indicates there is a value and it is empty.

If I want to determine whether the user explicitly declared an empty value for the field, this differentiation means everything. For Boolean options this is even more relevant and helpful.

There are certainly cases where nil values don’t make sense, which is why having optional being a separate thing in the language is great. I also encourage any devs working with me to carefully evaluate whether the optional makes sense before making an optional collection or optional value, as it is indeed adding a case.

Nevertheless, I think this is a slippery slope to demonising things that are language features for good reason, much like has happened with the ‘!’ operator.

2 Likes

Sure. To each their own. Im only talking about collection like types. If is important to make the distinction between and empty string and no string provided then awesome. I just find it useless in my workflow.

I think we all agree on that. We were only talking about collections where optionality gives you two quite similar “empty” values to think about – a nil collection and an empty collection. For booleans optionality certainly does make sense, for collections I can see how having just a single “empty” value helps, and strings (as collections of characters) are somewhere in between I guess. Of course, if you really need an explicit “N/A case” different from an “empty case”, there’s no discussion to be had.