I’d assume a self-rebinding feature would mostly be used to create DSL-ish APIs, and for those I think it would be better to have the rebinding in the closure type declaration, to have less syntax (in DSLs potentially repeated many times) at use point.

In Kotlin, you can declare what they call function type with receiver like this:

The latter is neat and such, however I once talked with @hartbit about such a functionality (without rebinding) and he quickly convinced me that this addition would be ambiguous if some other already existing init had a trailing closure.

The following idea is purely bikeshedding so please don’t interpret too much in it.

I would like to see a semi-automatic rebinding which would be part of the function parameter type like inout is. In that sense the function from way above would bind the inout T (not self!!) and provide a very nice usability:

So bind is completely optional in that sense and can only be used on function parameters. There could only be at most one parameter that can be bind. The AST printer should only print bind on closure parameters, other funtions and methods can still use this feature but exposing it from outside the module does not make sense.

While I see what you’re going for, my initial reaction is that it’s a bit too powerful for what’s meant to be a convenience feature. The idea of using anything more than self for implicit lookup seems potentially confusing to me, and if you really need to access self, you can just do so outside of the closure.

The ‘anonymous methods’ idea seems a much more direct solution to this problem with is meant to solve; it’s lightweight and much easier to reason about.

Other the other hand, the benefit of your solution is that it’s perfect for DSLs, and as your example shows, it can be used to create a with function/operator. If this is a problem we want to solve, it does make more sense to go in this direction, and turn with into a library feature.

I think that if rebinding the implicit method lookup target is desired, self should be able to be used as an identifier as discussed here, with the exception that the implicit method lookup is the current overload for the self identifier.
eg. in

Your example doesn’t match the way it is discussed in the other thread. They want to be able to make [weak self] strong when entering a closure. Being able to just override self by itself seems like a very bad idea; nowhere else do we allow type changes like this. With guard you can do some type changes but it doesn’t force variable occlusion like this does with old self.

I am fine with rebinding self but it should only be at the start of a new scope and only when explicitly requested.

I now agree with you that this is important, and that we should do the obvious thing here: just make self be a normal identifier which is implicitly injected into methods. This is your #1 option, which would allow rebinding with if/let, guard, shadowing and everything else.

Although, I see my example was indeed incorrect for my interpretation, which would indeed require the new overload for the identifier self to be in a new scope. (will edit it)
Additionally, my idea would be explicitly requested, by naming the new variable self.

In other words, the scope following the with keyword is a place where Self becomes implicit the way self is implicit in methods.

In practice, putting static properties under an case-less enum is the closest thing we have to a namespace in Swift. This addition will bring this use case closer to the ergonomic of an ML-style module syntax without introducing a whole new set of language features.

I mused about this a few months ago, and for this desire of mine, I’m against any introduction of with as anything short of a first-class keyword.

(side note: another thing I wish would one day exist is a shorthand to make everything in an declaration implicitly static, aka

If we had a bind annotation in closure parameter type lists, as @DevAndArtist suggested, we would come very close to this, and additionally could use it in a number of other ways.

Swift has precedent for making it possible to create language-style features in libraries (see @autoclosure, trailing closure syntax and custom operator support), which is, in my opinion, a good way to approach things.

Now if using could be declared as func using<T>(_ val: T.Type, do closure: (bind T.Type) -> Void), you could drop the $0, and we’re quite close to your example except for the .self (which is something we probably want to get rid of at some point).

I’m sorry, this may seem close to you, but using $0 is explicitly not what Xiaodi or I wanted. In fact, in my working environment, complex or multiple expressions with implicit closure arguments is banned in the style guide due to poor readability.

I think there’s merits to what you said and it’s great that we can simulate this style today without much change to the language. But I want to be clear that we are talking about very different things.

Exactly, this way it eliminates the burden with only allowing to bind self, and still allows you to use the parameter explicitly. bind on function parameter would be a complete convenience opt-in thing.

Ah, my apologies. You mentioned “this is possible today” followed by the code example and I made a conclusion. I should’ve read your entire post.

I still think we are talking about 2 agnostic features even tho they could have similar effects. At the moment I have no opinion about the bind proposal (also, should we discuss that in a separate thread?)

Feel free to open a new thread for this if there is no yet. The current thread feels exactly like the thread about Result becuase there is another feature that could be introduced first and would have an impact on the design of the current pitch.

Okay. How? Any idea where a starting point for this? Or for something more along the lines of a discardable-result function that operates on a value, allowing that to be treated as the instance for self and allowing you to omit the self reference in use?

Internally, self is already treated more or less like any other variable binding, which is part of why the guard self = self trick used to work by accident. We recently “fixed” this by making it so that self is a “special identifier” rather than a normal identifier. If we were going to support rebinding self officially, then we could parse the self token into this special identifier in contexts where we want to allow self-rebinding (if/guard conditions, closure arguments, maybe everywhere?). Unqualified name lookup might also have to change to do lookup based on the current self binding rather than assuming the self binding is a particular method argument as well.

// what is self here? Can I refer to "timeStyle" and have it know
// that's scoped to the dateFormatter and "foo" scoped to the
// `SomeType` instance, the way I'd expect in nested functions?

We can rephrase that question like this: Does what we’re talking about as “self-rebinding” (a) literally bind a new value to self and then you can use the existing ability to omit self., or does it (b) take the value and bind all it’s members into the current scope?

I’m currently thinking that (a) is simpler in terms of mental model, and is probably a less intrusive change implementation-wise as well (although I don’t know much about the compilers inner workings).