/*Let it be*/ func() -> @discardable Bool {} /*Rather Than*/ @discardableResult func() -> Bool {}

So it would be:

func() -> @discardable Bool { }

Rather than:

@discardableResult func() -> Bool { }

i'd say:

func foo() -> discardable Bool {
    ...
}

if we were starting from scratch

It could be even better if someone could perhaps find a shorter word that

is a synonym for the word "discardable", that would be as explicit in
intent as the word "discardable" is in such context, yet be written with
fewer characters.

Mike

···

On Sat, 7 Oct 2017 07:48:08 +0100, <swift-evolution-request@swift.org> wrote:

Personally I would prefer all the modified to go on the right, so that the declaration is sorted from most important to least left to right. EG:

Instead of:

    @disguardableResult public async mutating func x() throws -> Bool

I would prefer something like:

    func x() -> Bool @ throws disguardableResult public async mutating

Where @ introduces a list of space separated modifiers.

That’s why I also prefer:

   let x: Int // Swift

over:

   const int x // C

And moving the where clause to the end of the declaration.

Unfortunately I am not sure this is practical at this stage.

-- Howard.

···

On 10 Oct 2017, at 5:21 am, Mike Kluev via swift-evolution <swift-evolution@swift.org> wrote:

On Sat, 7 Oct 2017 07:48:08 +0100, <swift-evolution-request@swift.org> wrote:
So it would be:

func() -> @discardable Bool { }

Rather than:

@discardableResult func() -> Bool { }

i'd say:

func foo() -> discardable Bool {
    ...
}

if we were starting from scratch

It could be even better if someone could perhaps find a shorter word that
is a synonym for the word "discardable", that would be as explicit in
intent as the word "discardable" is in such context, yet be written with
fewer characters.

Mike

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

I would prefer something like:

    func x() -> Bool @ throws disguardableResult public async mutating

Where @ introduces a list of space separated modifiers.

make it more English :slight_smile:

public async mutating throwing func foo() -> discardable Bool {
    ...
}

Unfortunately I am not sure this is practical at this stage.

true :frowning:

Mike

···

On 9 October 2017 at 20:43, Howard Lovatt <howard.lovatt@gmail.com> wrote:

This idea was discussed long ago and the present design was selected. At
this point in Swift Evolution, source-breaking changes are in scope only if
the status quo is demonstrably harmful.

···

On Mon, Oct 9, 2017 at 17:16 Mike Kluev via swift-evolution < swift-evolution@swift.org> wrote:

On 9 October 2017 at 20:43, Howard Lovatt <howard.lovatt@gmail.com> wrote:

I would prefer something like:

    func x() -> Bool @ throws disguardableResult public async mutating

Where @ introduces a list of space separated modifiers.

make it more English :slight_smile:

public async mutating throwing func foo() -> discardable Bool {
    ...
}

Unfortunately I am not sure this is practical at this stage.

true :frowning:

Mike

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

This idea was discussed long ago and the present design was selected. At
this point in Swift Evolution, source-breaking changes are in scope only if
the status quo is demonstrably harmful.

changes like discussed are not necessarily source-breaking: you can allow
@discardableResult for a while (along with deprecating it at some point) in
addition to having a newer preferred way - should we decide there is a
preferred way.

As for the line-length, I don’t buy this argument, because placement of
line breaks is just personal preference, and keywords/annotations created
by gluing together two words should imho avoided wherever possible (not
only because the increased character count).

+1. same here on both counts. multi-word compound and @ symbol makes names
ugly. it feels it was done intentionally to indicate a "temporary" "to be
cleaned later" nature of a feature (it is a very good choice for @objc)

and if "fileprivate" is ugly because it is two words glued together (*)
maybe there is another name for it? just "file"? "domestic" ?

Mike
(* the very concept of "file private" is a bit ugly from a traditional
languages perspective).

···

On 10 October 2017 at 07:02, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:
on Mon, 09 Oct 2017 20:07:13 +0200 Tino Heth <tinoheth@me.com> wrote:

But this design was discussed in the proposal as a "future direction", because @discardableResult was chosen partially because it was easier to implement. It says so [in the proposal][1]. This is why we write formal proposals, Xiaodi—so we remember why we made the decisions we made.

  * * *

Now, the proposal specifically suggests we delay `@discardable` "until such time as there's a strong motivation to use such an approach". Do we have such a motivation?

I actually think we do (although it may not be strong enough). Currently, we have two types—`Void` (as well as optionals, of any depth, wrapping `Void`) and `Never`—which are "implicitly discardable". That is, you don't need to mark a function which returns those types with `@discardableResult`; it inherently is. This is currently handled with [an ad-hoc test][2], but I think we should consider strengthening and opening up this mechanism.

Why? Because there are other types we would like to be implicitly discardable. You can already make an argument for types like `Array<Void>`, but concurrency will bring types like `Future<Void>` which could get pretty strong benefits from it. Since we're planning to leave a lot of async stuff to userspace, there ought to be a userspace way to mark types as implicitly discardable. And if discardability stems from the type system, it's pretty natural to make ad-hoc discardibility a property attached to the type, too.

(We could then mark `Never` with @discardable, make tuples discardable unless one of their elements is not discardable, make optionals discardable if the type they wrap is discardable, and—et voilà!—we have a nice, general language feature with as little magic as we can manage.)

  [1]: https://github.com/apple/swift-evolution/blob/master/proposals/0047-nonvoid-warn.md#future-directions
  [2]: https://github.com/apple/swift/blob/e907031d3d4555e917ca3ad7fffeac7f580331a0/lib/Sema/TypeCheckStmt.cpp#L991

···

On Oct 9, 2017, at 11:02 PM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:

This idea was discussed long ago and the present design was selected.

--
Brent Royal-Gordon
Architechies

IMO everyday app building would rarely need to use functions with discardable results. This is more an issue with libraries or frameworks that support a fluent interface (e.g. that return self) where an operator chain can be stopped at any point, unless it clearly doesn’t make sense, in which case @discardableResult would not be advised. I am building such a library. It has 200+ uses of @discardableResult and I don’t have a problem with it in it’s current form (especially since it can go on the line before the function). It’s an annotation for a specialized purpose, hence the very specific nomenclature.

···

On Oct 10, 2017, at 7:48 PM, Mike Kluev via swift-evolution <swift-evolution@swift.org> wrote:

On 10 October 2017 at 07:02, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:
This idea was discussed long ago and the present design was selected. At this point in Swift Evolution, source-breaking changes are in scope only if the status quo is demonstrably harmful.

changes like discussed are not necessarily source-breaking: you can allow @discardableResult for a while (along with deprecating it at some point) in addition to having a newer preferred way - should we decide there is a preferred way.

on Mon, 09 Oct 2017 20:07:13 +0200 Tino Heth <tinoheth@me.com <mailto:tinoheth@me.com>> wrote:
As for the line-length, I don’t buy this argument, because placement of line breaks is just personal preference, and keywords/annotations created by gluing together two words should imho avoided wherever possible (not only because the increased character count).

+1. same here on both counts. multi-word compound and @ symbol makes names ugly. it feels it was done intentionally to indicate a "temporary" "to be cleaned later" nature of a feature (it is a very good choice for @objc)

and if "fileprivate" is ugly because it is two words glued together (*) maybe there is another name for it? just "file"? "domestic" ?

Mike
(* the very concept of "file private" is a bit ugly from a traditional languages perspective).

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

David James

This idea was discussed long ago and the present design was selected.

But this design was discussed in the proposal as a "future direction",
because @discardableResult was chosen partially because it was easier to
implement. It says so [in the proposal][1]. This is why we write formal
proposals, Xiaodi—so we remember why we made the decisions we made.

You're right that it was chosen in part because it was easier to implement.

But this does not at all mean that "@discardable" is the blessed future
direction; whether it is wise ever to adopt the "@discardable" design was
not thoroughly evaluated--it was simply decided that, for Swift 3,
@discardableResult was preferable to @discardable in the totality of things.

In my view, this means the "@discardable" idea needs to meet a higher bar
than a never-before presented idea, not a lower one.

* * *

Now, the proposal specifically suggests we delay `@discardable` "until
such time as there's a strong motivation to use such an approach". Do we
have such a motivation?

I actually think we do (although it may not be strong enough). Currently,
we have two types—`Void` (as well as optionals, of any depth, wrapping
`Void`) and `Never`—which are "implicitly discardable". That is, you don't
need to mark a function which returns those types with
`@discardableResult`; it inherently is. This is currently handled with [an
ad-hoc test][2], but I think we should consider strengthening and opening
up this mechanism.

Why? Because there are other types we would like to be implicitly
discardable. You can already make an argument for types like `Array<Void>`,
but concurrency will bring types like `Future<Void>` which could get pretty
strong benefits from it. Since we're planning to leave a lot of async stuff
to userspace, there ought to be a userspace way to mark types as implicitly
discardable. And if discardability stems from the type system, it's pretty
natural to make ad-hoc discardibility a property attached to the type, too.

(We could then mark `Never` with @discardable, make tuples discardable
unless one of their elements is not discardable, make optionals discardable
if the type they wrap is discardable, and—et voilà!—we have a nice, general
language feature with as little magic as we can manage.)

[1]: https://github.com/apple/swift-evolution/blob/master/
proposals/0047-nonvoid-warn.md#future-directions
[2]: https://github.com/apple/swift/blob/e907031d3d4555e917ca3ad7fffeac
7f580331a0/lib/Sema/TypeCheckStmt.cpp#L991

I am not sure this is entirely wise, for a few reasons.

a) I sure don't know why you'd want to return `Void?`, but if you do, it
doesn't follow that it should be discardable simply because `Void` is
discardable. It may well be so, or it may be (for some odd reason) that
it's the return type of a pure function that certainly shouldn't be
discardable.

b) Based on (a), I don't think that types composed of discardable types are
therefore discardable. I need to think this through further.

c) If you reject (b), then this brings up a larger issue.
`@discardableResult` is an attribute of the function; here, you're saying
that not only should the _spelling_ be moved to the other side of the
function arrow, but that the attribute should apply to the type. Would we
then have to invent a new overriding attribute for functions that return
`@discardable` types which don't want their return value to be discardable?
Like, a `@nondiscardableResult func foo() -> Void? /* implicitly
discardable type */`? I think this further demonstrates how it's not really
the type but the function that we want to annotate.

d) Does a class that override a `@discardable` type inherit that
annotation? If not, they it's kind of a weird exception to the inheritance
thing, no? If so, then we'd need a @nondiscardable annotation to do
type-level overrides of @discardable.

e) `Never` was explicitly designed to have no magic that any other
uninhabited enum would not get. To stick with this design, every enum
without any cases would have to be implicitly `@discardable`. This might be
surprising.

f) Speaking of enums: if types are discardable, then some errors are
discardable. By contrast, we do not currently have a `@discardableError`
annotation. What does it mean if a function throws a "discardable error"?
Can we choose not to catch it?

···

On Wed, Oct 18, 2017 at 9:29 PM, Brent Royal-Gordon <brent@architechies.com> wrote:

On Oct 9, 2017, at 11:02 PM, Xiaodi Wu via swift-evolution < > swift-evolution@swift.org> wrote:

let me guess: you put it on a different line exactly because it is in it's
current ugly form :slight_smile:

personally, if "x: inout Int" is in it's current form (vs. "@inputOutput x:
Int") so shall be "discardable Int", i see no principle difference between
them to make one looking it is from a different planet altogether.

Mike

···

On 12 October 2017 at 09:34, David James <davidbjames1@gmail.com> wrote:

IMO everyday app building would rarely need to use functions with
discardable results. This is more an issue with libraries or frameworks
that support a *fluent interface* (e.g. that return self) where an
operator chain can be stopped at any point, unless it clearly doesn’t make
sense, in which case @discardableResult would not be advised. I am building
such a library. It has 200+ uses of @discardableResult and *I don’t have
a problem with it in it’s current form* (especially since it can go on
the line before the function). It’s an annotation for a specialized
purpose, hence the very specific nomenclature.

the very current form of @discardableResult as a function attribute leads
to these type of questions in the first place. if it was a type modifier -
there would be no doubt:

class A {
    func foo() -> Bool {
        ...
    }

    func bar() -> discardable Bool {
        ...
    }
}

class B: A {
    override func foo() -> discardable Bool { // ok, types compatible
       ...
    }

    override func bar() -> Bool { // error. types mismatch
        ...
    }
}

Mike

···

On 19 October 2017 at 05:04, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

d) Does a class that override a `@discardable` type inherit that
annotation? If not, they it's kind of a weird exception to the inheritance
thing, no? If so, then we'd need a @nondiscardable annotation to do
type-level overrides of @discardable.

FWIW, I’d be pretty opposed to making Void? implicitly discardable. In the case of a generic function that returns T? where T can sometimes be void, the optional still carries information: perhaps about failure of the operation or something else. The reason that void and Never default to being ignored is that they are carry no information. Void? carries one important bit.

-Chris

···

On Oct 18, 2017, at 8:04 PM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:

I am not sure this is entirely wise, for a few reasons.

a) I sure don't know why you'd want to return `Void?`, but if you do, it doesn't follow that it should be discardable simply because `Void` is discardable. It may well be so, or it may be (for some odd reason) that it's the return type of a pure function that certainly shouldn't be discardable.

True, and it was making the method signature too long. But at least I have the option to do that. If we move the annotation to just before the return type, then we have no choice.

David James

···

On Oct 12, 2017, at 1:40 PM, Mike Kluev <mike.kluev@gmail.com> wrote:

let me guess: you put it on a different line exactly because it is in it's current ugly form :slight_smile:

No, I'm talking about the implicit discardability proposed by Brent, such
as for all Optional<@discardable T>.

He proposes that the @discardable syntax has a strong motivating advantage
because it can be extended in a way to mark _types_ so that return values
of those types are always implicitly @discardable. That is:

@discardable class A { ... }
// any return value of type A is implicitly discardable
// what happens if A : Error and I throw A?

class B : A { ... }
// is any return value of type B also implicitly discardable?

···

On Thu, Oct 19, 2017 at 01:02 Mike Kluev <mike.kluev@gmail.com> wrote:

On 19 October 2017 at 05:04, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

d) Does a class that override a `@discardable` type inherit that
annotation? If not, they it's kind of a weird exception to the inheritance
thing, no? If so, then we'd need a @nondiscardable annotation to do
type-level overrides of @discardable.

the very current form of @discardableResult as a function attribute leads
to these type of questions in the first place. if it was a type modifier -
there would be no doubt:

class A {
    func foo() -> Bool {
        ...
    }

    func bar() -> discardable Bool {
        ...
    }
}

class B: A {
    override func foo() -> discardable Bool { // ok, types compatible
       ...
    }

    override func bar() -> Bool { // error. types mismatch
        ...
    }
}

Mike

"discardable" only apply to return types, similar to how "inout" only
applies to "parameter types"
(e.g. you can't make "func foo(x: Optional<inout Bool>)"

Mike

···

On 19 October 2017 at 08:52, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

No, I'm talking about the implicit discardability proposed by Brent, such
as for all Optional<@discardable T>.

He proposes that the @discardable syntax has a strong motivating advantage
because it can be extended in a way to mark _types_ so that return values
of those types are always implicitly @discardable. That is:

@discardable class A { ... }
// any return value of type A is implicitly discardable
// what happens if A : Error and I throw A?

class B : A { ... }
// is any return value of type B also implicitly discardable?

Very well said.

For that same reason “return void-expression” shall not be allowed (and not parsed as such in a multiline statement)?

override func viewDidLoad() {
    super.viewDidLoad()
    return

    someView = SomeView(frame: view.bounds)
    ....
}

Although it doesn’t fully solve the problem, as the two types may well be something other than void.

Mike

···

On 21 Oct 2017, at 17:06, Chris Lattner <clattner@nondot.org> wrote:

FWIW, I’d be pretty opposed to making Void? implicitly discardable. In the case of a generic function that returns T? where T can sometimes be void, the optional still carries information: perhaps about failure of the operation or something else. The reason that void and Never default to being ignored is that they are carry no information. Void? carries one important bit.

you can still put it on the next line along with the result :slight_smile:

imho, this shall not be a decision maker nowadays (20 years ago it would).

Mike

···

On 12 October 2017 at 14:14, David James <davidbjames1@gmail.com> wrote:

True, and it was making the method signature too long. But at least I have
the option to do that. If we move the annotation to just before the return
type, then we have no choice.

I don’t think this is a good idea to make discardable part of the function type.

What would fun(callback: () -> discardable Int) would means ?

And allowing it in signature but not in lambda would be confusing.

···

Le 12 oct. 2017 à 15:32, Mike Kluev via swift-evolution <swift-evolution@swift.org> a écrit :

On 12 October 2017 at 14:14, David James <davidbjames1@gmail.com <mailto:davidbjames1@gmail.com>> wrote:
True, and it was making the method signature too long. But at least I have the option to do that. If we move the annotation to just before the return type, then we have no choice.

you can still put it on the next line along with the result :slight_smile:

imho, this shall not be a decision maker nowadays (20 years ago it would).

Mike

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

Of course. That’s not the concern.

···

On Thu, Oct 19, 2017 at 08:59 Mike Kluev <mike.kluev@gmail.com> wrote:

On 19 October 2017 at 08:52, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

No, I'm talking about the implicit discardability proposed by Brent, such
as for all Optional<@discardable T>.

He proposes that the @discardable syntax has a strong motivating
advantage because it can be extended in a way to mark _types_ so that
return values of those types are always implicitly @discardable. That is:

@discardable class A { ... }
// any return value of type A is implicitly discardable
// what happens if A : Error and I throw A?

class B : A { ... }
// is any return value of type B also implicitly discardable?

"discardable" only apply to return types, similar to how "inout" only
applies to "parameter types"
(e.g. you can't make "func foo(x: Optional<inout Bool>)"

you mean this?

func foo(callback: () -> discardable Int) {
    ...
    let x = callback()
    ...
    callback() // no warning or error here
}

Mike

···

On 13 October 2017 at 21:15, Jean-Daniel <mailing@xenonium.com> wrote:

I don’t think this is a good idea to make discardable part of the function
type.

What would fun(callback: () -> discardable Int) would means ?

I mean:

func foo() -> Int { … }

func bar(callback: () -> discardable Int) { … }

bar(foo) // does it warns ?
bar({ 3 }) // does it warns ? If it does, how to avoid it ?

···

Le 13 oct. 2017 à 23:23, Mike Kluev via swift-evolution <swift-evolution@swift.org> a écrit :

On 13 October 2017 at 21:15, Jean-Daniel <mailing@xenonium.com <mailto:mailing@xenonium.com>> wrote:
I don’t think this is a good idea to make discardable part of the function type.

What would fun(callback: () -> discardable Int) would means ?

you mean this?

func foo(callback: () -> discardable Int) {
    ...
    let x = callback()
    ...
    callback() // no warning or error here
}

Mike