Object declarations


(Marc Knaup) #1

Hey guys,

I am working on a proposal which touches (and could even partially depend
on) another interesting concept which I think would be a great addition for
Swift.

Object declarations could be a way to declare a class or struct with
exactly one instance. They are perfect for singletons, anonymous subclasses
and to anonymously implement a protocol.

Here some examples how it could look like:

// singleton
object GlobalResource {
    func doSomething() { … }
}

let resource = GlobalResource

// could all be the same
resource.doSomething()
GlobalResource.doSomething()
GlobalResource.Type.doSomething()

// anonymous subclass
class ViewController: UIViewController {

    override func loadView() {
        view = object: UIView {
            // configure view
        }
    }
}

// anonymous protocol implementation
protocol TapHandler {
    func handleTap()
}

view.tapHandler = object: TapHandler {
    func handleTap() {
        // …
    }
}

Kotlin is an example for a a modern language which uses this concept:
https://kotlinlang.org/docs/reference/object-declarations.html

What do you think about such an addition?


(Jordan Rose) #2

-1. Enforced singletons lead to code that can't be unit-tested. Local types are occasionally convenient and they can't be unit-tested either, but spending one extra line to name the thing isn't going to hurt. You also can't pick an initializer here (at least not in this version).

IMHO, this just adds "another kind of thing" just to make code shorter, and "shorter" is not the right goal for Swift.

Best,
Jordan

···

On Dec 11, 2015, at 14:07, Marc Knaup via swift-evolution <swift-evolution@swift.org> wrote:

Hey guys,

I am working on a proposal which touches (and could even partially depend on) another interesting concept which I think would be a great addition for Swift.

Object declarations could be a way to declare a class or struct with exactly one instance. They are perfect for singletons, anonymous subclasses and to anonymously implement a protocol.

Here some examples how it could look like:

// singleton
object GlobalResource {
    func doSomething() { … }
}

let resource = GlobalResource

// could all be the same
resource.doSomething()
GlobalResource.doSomething()
GlobalResource.Type.doSomething()

// anonymous subclass
class ViewController: UIViewController {

    override func loadView() {
        view = object: UIView {
            // configure view
        }
    }
}

// anonymous protocol implementation
protocol TapHandler {
    func handleTap()
}

view.tapHandler = object: TapHandler {
    func handleTap() {
        // …
    }
}

Kotlin is an example for a a modern language which uses this concept:
https://kotlinlang.org/docs/reference/object-declarations.html

What do you think about such an addition?
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Brent Royal-Gordon) #3

-1. Enforced singletons lead to code that can't be unit-tested. Local types are occasionally convenient and they can't be unit-tested either, but spending one extra line to name the thing isn't going to hurt. You also can't pick an initializer here (at least not in this version).

I’ve also found lately that my singletons tend not to stay single; it usually turns out there’s some way to reuse them. -1 from me as well.

···

--
Brent Royal-Gordon
Architechies


(Riley Avron) #4

-1. Agreed for all of Jordan's reasons.

Riley

···

On 11 December 2015 at 14:55, Jordan Rose via swift-evolution < swift-evolution@swift.org> wrote:

-1. Enforced singletons lead to code that can't be unit-tested. Local
types are occasionally convenient and they can't be unit-tested either, but
spending one extra line to name the thing isn't going to hurt. You also
can't pick an initializer here (at least not in this version).

IMHO, this just adds "another kind of thing" just to make code shorter,
and "shorter" is not the right goal for Swift.

Best,
Jordan

On Dec 11, 2015, at 14:07, Marc Knaup via swift-evolution < > swift-evolution@swift.org> wrote:

Hey guys,

I am working on a proposal which touches (and could even partially depend
on) another interesting concept which I think would be a great addition for
Swift.

Object declarations could be a way to declare a class or struct with
exactly one instance. They are perfect for singletons, anonymous subclasses
and to anonymously implement a protocol.

Here some examples how it could look like:

// singleton
object GlobalResource {
    func doSomething() { … }
}

let resource = GlobalResource

// could all be the same
resource.doSomething()
GlobalResource.doSomething()
GlobalResource.Type.doSomething()

// anonymous subclass
class ViewController: UIViewController {

    override func loadView() {
        view = object: UIView {
            // configure view
        }
    }
}

// anonymous protocol implementation
protocol TapHandler {
    func handleTap()
}

view.tapHandler = object: TapHandler {
    func handleTap() {
        // …
    }
}

Kotlin is an example for a a modern language which uses this concept:
https://kotlinlang.org/docs/reference/object-declarations.html

What do you think about such an addition?
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

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


(Kevin Lundberg) #5

It's an interesting idea, but I have to agree from a not-promoting-singletons standpoint. One can just add a static let to a class to return an instance and make the init private to get similar behavior.

···

On Dec 11, 2015, at 5:55 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:

-1. Enforced singletons lead to code that can't be unit-tested. Local types are occasionally convenient and they can't be unit-tested either, but spending one extra line to name the thing isn't going to hurt. You also can't pick an initializer here (at least not in this version).

IMHO, this just adds "another kind of thing" just to make code shorter, and "shorter" is not the right goal for Swift.

Best,
Jordan

On Dec 11, 2015, at 14:07, Marc Knaup via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Hey guys,

I am working on a proposal which touches (and could even partially depend on) another interesting concept which I think would be a great addition for Swift.

Object declarations could be a way to declare a class or struct with exactly one instance. They are perfect for singletons, anonymous subclasses and to anonymously implement a protocol.

Here some examples how it could look like:

// singleton
object GlobalResource {
    func doSomething() { … }
}

let resource = GlobalResource

// could all be the same
resource.doSomething()
GlobalResource.doSomething()
GlobalResource.Type.doSomething()

// anonymous subclass
class ViewController: UIViewController {

    override func loadView() {
        view = object: UIView {
            // configure view
        }
    }
}

// anonymous protocol implementation
protocol TapHandler {
    func handleTap()
}

view.tapHandler = object: TapHandler {
    func handleTap() {
        // …
    }
}

Kotlin is an example for a a modern language which uses this concept:
https://kotlinlang.org/docs/reference/object-declarations.html

What do you think about such an addition?
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

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


(Thorsten Seitz) #6

I like it. Just a minor suggestion: as an object is a value and not a type it should have a name starting with lower case, i.e.

object globalResource { ... }

-Thorsten

···

Am 11.12.2015 um 23:07 schrieb Marc Knaup via swift-evolution <swift-evolution@swift.org>:

Hey guys,

I am working on a proposal which touches (and could even partially depend on) another interesting concept which I think would be a great addition for Swift.

Object declarations could be a way to declare a class or struct with exactly one instance. They are perfect for singletons, anonymous subclasses and to anonymously implement a protocol.

Here some examples how it could look like:

// singleton
object GlobalResource {
    func doSomething() { … }
}

let resource = GlobalResource

// could all be the same
resource.doSomething()
GlobalResource.doSomething()
GlobalResource.Type.doSomething()

// anonymous subclass
class ViewController: UIViewController {

    override func loadView() {
        view = object: UIView {
            // configure view
        }
    }
}

// anonymous protocol implementation
protocol TapHandler {
    func handleTap()
}

view.tapHandler = object: TapHandler {
    func handleTap() {
        // …
    }
}

Kotlin is an example for a a modern language which uses this concept:
https://kotlinlang.org/docs/reference/object-declarations.html

What do you think about such an addition?

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


(Jerome Duquennoy) #7

I am working on a software in which singleton has been used in tons of places to "simplify" design.
Today, some parts of the code base are pretty impossible to test, and hard to evolve since all parts have strong links with other parts.

So I completely agree with Jordan : the singleton is a template that should be used in very specific cases and with care. I think making it a first citizen of the language by dedicating a keyword to it will not push good code design.

Jerome

···

Le 12 déc. 2015 à 01:09, Riley Avron via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> a écrit :

-1. Agreed for all of Jordan's reasons.

Riley

On 11 December 2015 at 14:55, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
-1. Enforced singletons lead to code that can't be unit-tested. Local types are occasionally convenient and they can't be unit-tested either, but spending one extra line to name the thing isn't going to hurt. You also can't pick an initializer here (at least not in this version).

IMHO, this just adds "another kind of thing" just to make code shorter, and "shorter" is not the right goal for Swift.

Best,
Jordan

On Dec 11, 2015, at 14:07, Marc Knaup via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Hey guys,

I am working on a proposal which touches (and could even partially depend on) another interesting concept which I think would be a great addition for Swift.

Object declarations could be a way to declare a class or struct with exactly one instance. They are perfect for singletons, anonymous subclasses and to anonymously implement a protocol.

Here some examples how it could look like:

// singleton
object GlobalResource {
    func doSomething() { … }
}

let resource = GlobalResource

// could all be the same
resource.doSomething()
GlobalResource.doSomething()
GlobalResource.Type.doSomething()

// anonymous subclass
class ViewController: UIViewController {

    override func loadView() {
        view = object: UIView {
            // configure view
        }
    }
}

// anonymous protocol implementation
protocol TapHandler {
    func handleTap()
}

view.tapHandler = object: TapHandler {
    func handleTap() {
        // …
    }
}

Kotlin is an example for a a modern language which uses this concept:
https://kotlinlang.org/docs/reference/object-declarations.html

What do you think about such an addition?
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

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

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


(Chris Lattner) #8

-1 from me as well. In addition to those points, syntax optimizing shared global state encourages its use. This is problematic for threading and many other things as well.

-Chris

···

On Dec 11, 2015, at 4:09 PM, Riley Avron via swift-evolution <swift-evolution@swift.org> wrote:

-1. Agreed for all of Jordan's reasons.

Riley

On 11 December 2015 at 14:55, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
-1. Enforced singletons lead to code that can't be unit-tested. Local types are occasionally convenient and they can't be unit-tested either, but spending one extra line to name the thing isn't going to hurt. You also can't pick an initializer here (at least not in this version).

IMHO, this just adds "another kind of thing" just to make code shorter, and "shorter" is not the right goal for Swift.

Best,
Jordan

On Dec 11, 2015, at 14:07, Marc Knaup via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Hey guys,

I am working on a proposal which touches (and could even partially depend on) another interesting concept which I think would be a great addition for Swift.

Object declarations could be a way to declare a class or struct with exactly one instance. They are perfect for singletons, anonymous subclasses and to anonymously implement a protocol.

Here some examples how it could look like:

// singleton
object GlobalResource {
    func doSomething() { … }
}

let resource = GlobalResource

// could all be the same
resource.doSomething()
GlobalResource.doSomething()
GlobalResource.Type.doSomething()

// anonymous subclass
class ViewController: UIViewController {

    override func loadView() {
        view = object: UIView {
            // configure view
        }
    }
}

// anonymous protocol implementation
protocol TapHandler {
    func handleTap()
}

view.tapHandler = object: TapHandler {
    func handleTap() {
        // …
    }
}

Kotlin is an example for a a modern language which uses this concept:
https://kotlinlang.org/docs/reference/object-declarations.html

What do you think about such an addition?
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

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

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


(Marc Knaup) #9

Actually it's both - an object and a type. It's an object which describes
itself.

Btw. I have the same problem with enum cases. They're values so why are
they uppercase?

···

On Fri, Dec 11, 2015 at 11:25 PM, Thorsten Seitz <tseitz42@icloud.com> wrote:

I like it. Just a minor suggestion: as an object is a value and not a type
it should have a name starting with lower case, i.e.

object globalResource { ... }

-Thorsten

Am 11.12.2015 um 23:07 schrieb Marc Knaup via swift-evolution < > swift-evolution@swift.org>:

Hey guys,

I am working on a proposal which touches (and could even partially depend
on) another interesting concept which I think would be a great addition for
Swift.

Object declarations could be a way to declare a class or struct with
exactly one instance. They are perfect for singletons, anonymous subclasses
and to anonymously implement a protocol.

Here some examples how it could look like:

// singleton
object GlobalResource {
    func doSomething() { … }
}

let resource = GlobalResource

// could all be the same
resource.doSomething()
GlobalResource.doSomething()
GlobalResource.Type.doSomething()

// anonymous subclass
class ViewController: UIViewController {

    override func loadView() {
        view = object: UIView {
            // configure view
        }
    }
}

// anonymous protocol implementation
protocol TapHandler {
    func handleTap()
}

view.tapHandler = object: TapHandler {
    func handleTap() {
        // …
    }
}

Kotlin is an example for a a modern language which uses this concept:
https://kotlinlang.org/docs/reference/object-declarations.html

What do you think about such an addition?

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


(Andrey Tarantsov) #10

I think that anonymous classes got lost amongst all the singletonphobia here, and yet making an anonymous local delegate class is often helpful.

Perhaps we don't need an additional keyword, though; something like this could work too:

view.delegate = class: SomeDelegate {
  ...
}()

or perhaps you want a slightly customized object:

view = class: UITextField {
  func canBecomeFirstResponder() -> Bool { return false }
}()

Of course, we could just use a named local class, like others have pointed out, but unless you really want to name that thing (and the name would often be stupid), that's a just workaround for a lack of anonymous classes.

A.


(Thorsten Seitz) #11

Actually it's both - an object and a type. It's an object which describes itself.

If it was a type then I would expect to be able to
- derive a subclass from it
- use it as type in variable or parameter declarations

I don't think either makes sense, or does it?

Btw. I have the same problem with enum cases. They're values so why are they uppercase?

Hmm, good point. Guess I'm just used to it :slight_smile:

-Thorsten

···

Am 11.12.2015 um 23:28 schrieb Marc Knaup <marc@knaup.koeln>:

On Fri, Dec 11, 2015 at 11:25 PM, Thorsten Seitz <tseitz42@icloud.com> wrote:
I like it. Just a minor suggestion: as an object is a value and not a type it should have a name starting with lower case, i.e.

object globalResource { ... }

-Thorsten

Am 11.12.2015 um 23:07 schrieb Marc Knaup via swift-evolution <swift-evolution@swift.org>:

Hey guys,

I am working on a proposal which touches (and could even partially depend on) another interesting concept which I think would be a great addition for Swift.

Object declarations could be a way to declare a class or struct with exactly one instance. They are perfect for singletons, anonymous subclasses and to anonymously implement a protocol.

Here some examples how it could look like:

// singleton
object GlobalResource {
    func doSomething() { … }
}

let resource = GlobalResource

// could all be the same
resource.doSomething()
GlobalResource.doSomething()
GlobalResource.Type.doSomething()

// anonymous subclass
class ViewController: UIViewController {

    override func loadView() {
        view = object: UIView {
            // configure view
        }
    }
}

// anonymous protocol implementation
protocol TapHandler {
    func handleTap()
}

view.tapHandler = object: TapHandler {
    func handleTap() {
        // …
    }
}

Kotlin is an example for a a modern language which uses this concept:
https://kotlinlang.org/docs/reference/object-declarations.html

What do you think about such an addition?

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


(Marc Knaup) #12

@Andrey

   - Note that it should also be possible to create structs anonymously as
   they also can implement protocols.
   - Delegates are a bit tricky because they are usually retained weakly so
   the anonymous object would be deallocated immediately.
   - Also using "class: XYZ {}" doesn't allow creating named objects
like "class object
   EmptyObject {}".

When talking about singletons people tend to first think at a very large
scale and about abstraction, factories, testability and whatever.
It's the little things which capture my interest more, like NSNull for
example.

class object NSNull {}

Or maybe a JSON Null:

protocol JSONNode {}
struct JSON {
    struct object Null: JSONNode {}
    struct Bool { … } // not an object but a type

    // …
}

Now the interesting part about a singleton NSNull (or the JSON one) is that
it represents both, a type and an instance.

array.append(NSNull)

Note that we cannot use a class and call NSNull() as this would create a
new instance instead of returning the singleton instance.
We would have to make a silly workaround like NSNull.null or
NSNull.sharedInstance.

Examples for JSON.Null:

jsonArray.append(JSON.Null) // used as instance

if jsonNode is JSON.Null { // used as type
   // …
}

let expectedJsonTypes: [JSONNode.Type] = [JSON.Null, JSON.Bool, …]

if jsonNode is JSON.Null { // used as type
   // …
}
if jsonNode == JSON.Null { // used as instance (assuming Equatable
conformance)
   // …
}

···

On Sat, Dec 12, 2015 at 2:29 AM, Andrey Tarantsov via swift-evolution < swift-evolution@swift.org> wrote:

I think that anonymous classes got lost amongst all the singletonphobia
here, and yet making an anonymous local delegate class is often helpful.

Perhaps we don't need an additional keyword, though; something like this
could work too:

view.delegate = class: SomeDelegate {
  ...
}()

or perhaps you want a slightly customized object:

view = class: UITextField {
  func canBecomeFirstResponder() -> Bool { return false }
}()

Of course, we could just use a named local class, like others have pointed
out, but unless you really want to name that thing (and the name would
often be stupid), that's a just workaround for a lack of anonymous classes.

A.

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


#13

I think anonymous classes run counter to Swift's goals of clarity. You don't even have to pollute your whole module with the class, you can declare a private class in the same file and use it where you need it. This is, in my opinion far cleaner. Additionally, anonymous classes are really difficult for people to understand if they've not encountered the concept before.

···

On Dec 11, 2015, at 19:48, Marc Knaup via swift-evolution <swift-evolution@swift.org> wrote:

@Andrey
Note that it should also be possible to create structs anonymously as they also can implement protocols.
Delegates are a bit tricky because they are usually retained weakly so the anonymous object would be deallocated immediately.
Also using "class: XYZ {}" doesn't allow creating named objects like "class object EmptyObject {}".
When talking about singletons people tend to first think at a very large scale and about abstraction, factories, testability and whatever.
It's the little things which capture my interest more, like NSNull for example.

class object NSNull {}

Or maybe a JSON Null:

protocol JSONNode {}
struct JSON {
    struct object Null: JSONNode {}
    struct Bool { … } // not an object but a type

    // …
}

Now the interesting part about a singleton NSNull (or the JSON one) is that it represents both, a type and an instance.

array.append(NSNull)

Note that we cannot use a class and call NSNull() as this would create a new instance instead of returning the singleton instance.
We would have to make a silly workaround like NSNull.null or NSNull.sharedInstance.

Examples for JSON.Null:

jsonArray.append(JSON.Null) // used as instance

if jsonNode is JSON.Null { // used as type
   // …
}

let expectedJsonTypes: [JSONNode.Type] = [JSON.Null, JSON.Bool, …]

if jsonNode is JSON.Null { // used as type
   // …
}
if jsonNode == JSON.Null { // used as instance (assuming Equatable conformance)
   // …
}

On Sat, Dec 12, 2015 at 2:29 AM, Andrey Tarantsov via swift-evolution <swift-evolution@swift.org> wrote:
I think that anonymous classes got lost amongst all the singletonphobia here, and yet making an anonymous local delegate class is often helpful.

Perhaps we don't need an additional keyword, though; something like this could work too:

view.delegate = class: SomeDelegate {
  ...
}()

or perhaps you want a slightly customized object:

view = class: UITextField {
  func canBecomeFirstResponder() -> Bool { return false }
}()

Of course, we could just use a named local class, like others have pointed out, but unless you really want to name that thing (and the name would often be stupid), that's a just workaround for a lack of anonymous classes.

A.

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

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


(Marc Knaup) #14

The type is still necessary in various locations:

Generics:
let x = SomeGenericClass<SingletonObject>

Type checking:
let x: Any = SingletonObject
let x: SingletonObject? = x as? SingletonObject

Passing the type dynamically:
func foo(type: Any.Type) { … }
foo(SingletonObject)

Since there can only be one instance the "object class" (if it isn't a
struct) would be final.

···

On Fri, Dec 11, 2015 at 11:34 PM, Thorsten Seitz <tseitz42@icloud.com> wrote:

Am 11.12.2015 um 23:28 schrieb Marc Knaup <marc@knaup.koeln>:

Actually it's both - an object and a type. It's an object which describes
itself.

If it was a type then I would expect to be able to
- derive a subclass from it
- use it as type in variable or parameter declarations

I don't think either makes sense, or does it?

Btw. I have the same problem with enum cases. They're values so why are
they uppercase?

Hmm, good point. Guess I'm just used to it :slight_smile:

-Thorsten

On Fri, Dec 11, 2015 at 11:25 PM, Thorsten Seitz <tseitz42@icloud.com> > wrote:

I like it. Just a minor suggestion: as an object is a value and not a
type it should have a name starting with lower case, i.e.

object globalResource { ... }

-Thorsten

Am 11.12.2015 um 23:07 schrieb Marc Knaup via swift-evolution < >> swift-evolution@swift.org>:

Hey guys,

I am working on a proposal which touches (and could even partially depend
on) another interesting concept which I think would be a great addition for
Swift.

Object declarations could be a way to declare a class or struct with
exactly one instance. They are perfect for singletons, anonymous subclasses
and to anonymously implement a protocol.

Here some examples how it could look like:

// singleton
object GlobalResource {
    func doSomething() { … }
}

let resource = GlobalResource

// could all be the same
resource.doSomething()
GlobalResource.doSomething()
GlobalResource.Type.doSomething()

// anonymous subclass
class ViewController: UIViewController {

    override func loadView() {
        view = object: UIView {
            // configure view
        }
    }
}

// anonymous protocol implementation
protocol TapHandler {
    func handleTap()
}

view.tapHandler = object: TapHandler {
    func handleTap() {
        // …
    }
}

Kotlin is an example for a a modern language which uses this concept:
https://kotlinlang.org/docs/reference/object-declarations.html

What do you think about such an addition?

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


(Marc Knaup) #15

Well anonymous objects are one way object declarations could be used. They
may or may not be reduce clarity - I have no strong preference here.

But they can also be named. This is what interests me most.

Additionally when the compiler knows that there is always exactly one
instance it can probably optimize the code even further.
But I cannot answer that question.

···

On Mon, Dec 14, 2015 at 1:17 AM, Cole Kurkowski <crk@fastmail.com> wrote:

I think anonymous classes run counter to Swift's goals of clarity. You
don't even have to pollute your whole module with the class, you can
declare a private class in the same file and use it where you need it. This
is, in my opinion far cleaner. Additionally, anonymous classes are really
difficult for people to understand if they've not encountered the concept
before.

On Dec 11, 2015, at 19:48, Marc Knaup via swift-evolution < > swift-evolution@swift.org> wrote:

@Andrey

   - Note that it should also be possible to create structs anonymously
   as they also can implement protocols.
   - Delegates are a bit tricky because they are usually retained weakly
   so the anonymous object would be deallocated immediately.
   - Also using "class: XYZ {}" doesn't allow creating named objects like
   "class object EmptyObject {}".

When talking about singletons people tend to first think at a very large
scale and about abstraction, factories, testability and whatever.
It's the little things which capture my interest more, like NSNull for
example.

class object NSNull {}

Or maybe a JSON Null:

protocol JSONNode {}
struct JSON {
    struct object Null: JSONNode {}
    struct Bool { … } // not an object but a type

    // …
}

Now the interesting part about a singleton NSNull (or the JSON one) is
that it represents both, a type and an instance.

array.append(NSNull)

Note that we cannot use a class and call NSNull() as this would create a
new instance instead of returning the singleton instance.
We would have to make a silly workaround like NSNull.null or
NSNull.sharedInstance.

Examples for JSON.Null:

jsonArray.append(JSON.Null) // used as instance

if jsonNode is JSON.Null { // used as type
   // …
}

let expectedJsonTypes: [JSONNode.Type] = [JSON.Null, JSON.Bool, …]

if jsonNode is JSON.Null { // used as type
   // …
}
if jsonNode == JSON.Null { // used as instance (assuming Equatable
conformance)
   // …
}

On Sat, Dec 12, 2015 at 2:29 AM, Andrey Tarantsov via swift-evolution < > swift-evolution@swift.org> wrote:

I think that anonymous classes got lost amongst all the singletonphobia
here, and yet making an anonymous local delegate class is often helpful.

Perhaps we don't need an additional keyword, though; something like this
could work too:

view.delegate = class: SomeDelegate {
  ...
}()

or perhaps you want a slightly customized object:

view = class: UITextField {
  func canBecomeFirstResponder() -> Bool { return false }
}()

Of course, we could just use a named local class, like others have
pointed out, but unless you really want to name that thing (and the name
would often be stupid), that's a just workaround for a lack of anonymous
classes.

A.

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

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


(Thorsten Seitz) #16

You are right!
That means can keep the upper case name :slight_smile:

-Thorsten

···

Am 11.12.2015 um 23:43 schrieb Marc Knaup <marc@knaup.koeln>:

The type is still necessary in various locations:

Generics:
let x = SomeGenericClass<SingletonObject>

Type checking:
let x: Any = SingletonObject
let x: SingletonObject? = x as? SingletonObject

Passing the type dynamically:
func foo(type: Any.Type) { … }
foo(SingletonObject)

Since there can only be one instance the "object class" (if it isn't a struct) would be final.

On Fri, Dec 11, 2015 at 11:34 PM, Thorsten Seitz <tseitz42@icloud.com> wrote:

Am 11.12.2015 um 23:28 schrieb Marc Knaup <marc@knaup.koeln>:

Actually it's both - an object and a type. It's an object which describes itself.

If it was a type then I would expect to be able to
- derive a subclass from it
- use it as type in variable or parameter declarations

I don't think either makes sense, or does it?

Btw. I have the same problem with enum cases. They're values so why are they uppercase?

Hmm, good point. Guess I'm just used to it :slight_smile:

-Thorsten

On Fri, Dec 11, 2015 at 11:25 PM, Thorsten Seitz <tseitz42@icloud.com> wrote:
I like it. Just a minor suggestion: as an object is a value and not a type it should have a name starting with lower case, i.e.

object globalResource { ... }

-Thorsten

Am 11.12.2015 um 23:07 schrieb Marc Knaup via swift-evolution <swift-evolution@swift.org>:

Hey guys,

I am working on a proposal which touches (and could even partially depend on) another interesting concept which I think would be a great addition for Swift.

Object declarations could be a way to declare a class or struct with exactly one instance. They are perfect for singletons, anonymous subclasses and to anonymously implement a protocol.

Here some examples how it could look like:

// singleton
object GlobalResource {
    func doSomething() { … }
}

let resource = GlobalResource

// could all be the same
resource.doSomething()
GlobalResource.doSomething()
GlobalResource.Type.doSomething()

// anonymous subclass
class ViewController: UIViewController {

    override func loadView() {
        view = object: UIView {
            // configure view
        }
    }
}

// anonymous protocol implementation
protocol TapHandler {
    func handleTap()
}

view.tapHandler = object: TapHandler {
    func handleTap() {
        // …
    }
}

Kotlin is an example for a a modern language which uses this concept:
https://kotlinlang.org/docs/reference/object-declarations.html

What do you think about such an addition?

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


#17

Ahh, I misunderstood a piece of your initial proposal. I don't have any strong opposition to a named object declaration, and there have been several occasions where I might have used such a construct (whether or not you're a fan of singletons they are very much a part of Cocoa and associated software).

That being said there are concerns (unit testing especially as was already mentioned) that may cause problems.

···

On Dec 13, 2015, at 18:28, Marc Knaup <marc@knaup.koeln> wrote:

Well anonymous objects are one way object declarations could be used. They may or may not be reduce clarity - I have no strong preference here.

But they can also be named. This is what interests me most.

Additionally when the compiler knows that there is always exactly one instance it can probably optimize the code even further.
But I cannot answer that question.

On Mon, Dec 14, 2015 at 1:17 AM, Cole Kurkowski <crk@fastmail.com> wrote:
I think anonymous classes run counter to Swift's goals of clarity. You don't even have to pollute your whole module with the class, you can declare a private class in the same file and use it where you need it. This is, in my opinion far cleaner. Additionally, anonymous classes are really difficult for people to understand if they've not encountered the concept before.

On Dec 11, 2015, at 19:48, Marc Knaup via swift-evolution <swift-evolution@swift.org> wrote:

@Andrey
Note that it should also be possible to create structs anonymously as they also can implement protocols.
Delegates are a bit tricky because they are usually retained weakly so the anonymous object would be deallocated immediately.
Also using "class: XYZ {}" doesn't allow creating named objects like "class object EmptyObject {}".
When talking about singletons people tend to first think at a very large scale and about abstraction, factories, testability and whatever.
It's the little things which capture my interest more, like NSNull for example.

class object NSNull {}

Or maybe a JSON Null:

protocol JSONNode {}
struct JSON {
    struct object Null: JSONNode {}
    struct Bool { … } // not an object but a type

    // …
}

Now the interesting part about a singleton NSNull (or the JSON one) is that it represents both, a type and an instance.

array.append(NSNull)

Note that we cannot use a class and call NSNull() as this would create a new instance instead of returning the singleton instance.
We would have to make a silly workaround like NSNull.null or NSNull.sharedInstance.

Examples for JSON.Null:

jsonArray.append(JSON.Null) // used as instance

if jsonNode is JSON.Null { // used as type
   // …
}

let expectedJsonTypes: [JSONNode.Type] = [JSON.Null, JSON.Bool, …]

if jsonNode is JSON.Null { // used as type
   // …
}
if jsonNode == JSON.Null { // used as instance (assuming Equatable conformance)
   // …
}

On Sat, Dec 12, 2015 at 2:29 AM, Andrey Tarantsov via swift-evolution <swift-evolution@swift.org> wrote:
I think that anonymous classes got lost amongst all the singletonphobia here, and yet making an anonymous local delegate class is often helpful.

Perhaps we don't need an additional keyword, though; something like this could work too:

view.delegate = class: SomeDelegate {
  ...
}()

or perhaps you want a slightly customized object:

view = class: UITextField {
  func canBecomeFirstResponder() -> Bool { return false }
}()

Of course, we could just use a named local class, like others have pointed out, but unless you really want to name that thing (and the name would often be stupid), that's a just workaround for a lack of anonymous classes.

A.

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

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