`borrow` and `take` parameter ownership modifiers

Sorry, I am failing to make the larger point about the idea behind set parameters. Let's backup for a second and think about inout. In a language with value semantics, inout parameters allow us to express in-place mutation across function boundaries.

inout is a simple yet very powerful concept: value goes in and then it goes out. So it makes sense to apply the same principle to other features. For instance, when we revisited subscripts in Val, we thought that it made sense to use inout to represent _modify accessors. Value goes to the caller and then it goes back to the callee. Strictly speaking it still goes "in and out" if we consider inversion of control.

Now we can draw a parallel with what I'm trying to achieve with set parameters. I want to describe assignment across function boundaries as a language-level concept. A set parameter is like inout, except that no value needs to go in.

Assignment and initialization are closely related concepts. At a high-level, initialization is just assignment where there isn't a value yet (there's a catch with that reasoning, but I'll get to it). That is why I argue it makes sense to also use set parameters to represent initialization across function boundaries.

Again, we can generalize set parameters as a concept and see where else it can apply. It turns out that a set accessor in Swift is a good match, as the value to be set does only go in (again, considering inversion of control). That has an obvious advantage in terms of performance: we do not have to synthesize the value that goes out.

I concede that this whole reasoning is largely motivated by theory. While set accessors in subscripts will probably be very common, set parameters in functions will surely be less so That said, if there are use cases for placement new in C++, I believe there will be use cases for set parameters in Val. What's very interesting to me is that set parameters complete the calculus in a coherent way. They let us express assignment and initialization across function boundaries as a language-level concept, without having to know about the underlying implementation.

With that perspective in mind, let's get to your comments.

You are correct; my description was lacking. In a subscript, set parameters relate to assignment rather than initialization because self must necessarily be initialized before the subscript is called.

You put your finger on a point that I'm still trying to iron out in Val. When do set parameters relate to assignment rather than initialization? The answer is clear for subscripts as their value must already exist, as you pointed out, or be synthesizable. But what about functions?

A simple escape hatch is to say that the compiler outright rejects programs that attempt to pass initialized arguments to set parameters. But that takes an optimization opportunity away from us: what if we want to reuse part of the storage of the notional LHS of the assignment?

We have started exploring a way to handle that specific optimization. An assignment a = b is translated by the compiler as b.move(into: &a), where move(into:) is a customizable method of the LHS. I think it would be interested to generalize that translation so that it applies to set parameters too. But that's a Val design question. I don't want to pollute this thread.

I believe set parameters express at the language level what Swift does under the cover. I do not claim it is strictly necessary to surface the mechanism that initializes return values. It is a quite low-level feature with niche use cases. Another argument is that giving the compiler full control over initialization yields more opportunities for optimizations.

I expect both of these observations to hold in Val. We'll write let x = T() in 99% of the cases and we'll let the compiler implement x's initialization as it sees fit. But I think set parameters are valuable nonetheless from practical, educational, and theoretical point of views. I base that belief on the fact that there are use cases for placement new in C++, that set parameters provide an interesting way to understand the type of an initializer, and that they seem to fit very well in the calculus we have designed for Val.

1 Like