<h3>Background</h3>
<p>What I want is to make the behaviors of the following two pieces of code identical:</p>
<pre class="lang-js prettyprint-override"><code>specifier x = getX();
doSomething(x);
</code></pre>
<pre class="lang-js prettyprint-override"><code>function f(specifier x) {
    doSomething(x);
}
f(getX());
</code></pre>
<p>That is, to make the behavior of passing a parameter identical to initializing a variable. (The initialization looks like an assignment. The relationship between it and assignment is not discussed here. But the distinction is important in the C++ example.)</p>
<p>Beside the type, the specifier could also specify whether <code>x</code> is a new variable located in an independent address, or an alias of the thing assigned to it, that is, <strong>passing by value or by reference</strong>. And I may extend it to support more options like the two.</p>
<p>C++ has done it right. Specifically, references could be defined in context other than passing a parameter, to imitate passing a parameter:</p>
<pre class="lang-cpp prettyprint-override"><code>Type &amp;x = getX();
</code></pre>
<p>Or in C#:</p>
<pre class="lang-csharp prettyprint-override"><code>ref Type x = ref getX();
</code></pre>
<p>So there is nothing for me to invent. But while I was trying to build something else related to this distinction, I found a strange source of confusion, that some languages tries to make the opposite correspondence. An example is Pascal, where <code>var</code> means both creating variables in independent addresses, and making alias of the passed parameter:</p>
<pre class="lang-pascal prettyprint-override"><code>var x, y : T;
begin
    x := y;
    doSomething(x); // y is not modified
end.
</code></pre>
<pre class="lang-pascal prettyprint-override"><code>var y : T;
procedure f(var x : T);
begin
    doSomething(x); // y is modified
end;
begin
    f(y);
end.
</code></pre>
<h3>Question</h3>
<p>How does languages distinguish passing a parameter by value and reference? I'm especially interested in languages that are not like C++, that initializing a reference isn't so different from assignment, or doesn't have the concept of reference like in C++, so what works in C++ couldn't easily apply. I hope to see languages using the correspondence like in C++, but languages like Pascal or using other ways could also be helpful, as it may tell how the different ideas developed and how much it affects.</p>
<p>Beside the syntax, I'm also interested in how they are distinguished conceptually, in the specification or other materials such as textbooks. The problem of &quot;passing by value or by reference&quot; is it is too specific about parameters. It isn't easily understandable if I say creating a variable, or even creating a nameless <em>value</em> &quot;by value&quot;. Languages using keywords might be a bit more helpful than languages using symbols as they automatically provide readable names, but that might not cover the tagless option.</p>

<variables><references>
How does languages distinguish passing a parameter by value and reference, especially with non-parameter direct initializations in consideration?
<h1>Swift</h1>
<p>Swift doesn't let you generally create aliases the way <code>T&amp;</code> works in C++. To cause a parameter to be passed by reference, you mark it with <code>inout</code> in the function declaration and <code>&amp;</code> at the call site:</p>
<pre class="lang-swift prettyprint-override"><code>func increment(_ x: inout Int) {
  x += 1
}

var y = 1
increment(&amp;y)
print(y) // prints 2
</code></pre>
<p>Notably, the <code>&amp;</code> prefix is not necessary if the function is an operator.</p>
<pre class="lang-swift prettyprint-override"><code>struct Foo {
  static func += (lhs: inout Foo, rhs: Foo) {
  }
}

var x = Foo(), y = Foo()
x += y // passed inout with no &amp;
</code></pre>
<p>If you don't mark the parameter <code>inout</code>, not only can mutations not be seen by the caller, you can't even try to mutate it -- you don't get a copy to mutate like in C. If you need a copy to mutate for whatever reason, you have to explicitly copy it:</p>
<pre class="lang-swift prettyprint-override"><code>func illegal(x: Int) {
  x += 1 // won't compile
}

func okay(x: Int) {
  var x = x // explicit copy -- it's supposed to look weird
  x += 1 // okay, but the caller doesn't see this!
}
</code></pre>
<p>Besides <code>inout</code>, there are two other specifiers available as of Swift 5.9: <code>borrowing</code> (the default for most things) and <code>consuming</code> (the default for arguments to <code>init</code>s). For primitives like <code>Int</code> they don't mean anything; for classes and CoW structs they change where the refcounting operations happen; and for non-copyable types they control ownership: <code>borrowing</code> lets the new function access the value but not consume it (like <code>&amp;T</code> in Rust), while <code>consuming</code> transfers ownership and makes the value inaccessible to the caller (like plain <code>T</code> in Rust).</p>
<p>Default values are not available for <code>inout</code> parameters -- unlike C++ with <code>T&amp;&amp;</code>, you can't take a reference to an rvalue -- leading to overload pairs like this:</p>
<pre class="lang-swift prettyprint-override"><code>extension Int {
  static func random&lt;T: RandomNumberGenerator&gt;(in range: Range&lt;Int&gt;, using generator: inout T) -&gt; Int {
    // ...
  }

  static func random(in range: Range&lt;Int&gt;) -&gt; Int {
    var g = SystemRandomNumberGenerator()
    return random(in: range, using: &amp;g)
  }
}
</code></pre>
<p>Finally, there's a subtle but important rule known as the Law of Exclusivity: when a variable is passed <code>inout</code>, that can be the only concurrent access to that variable. If the same variable is mutated in one way and accessed in another at the same time, the Swift runtime panics.</p>
<pre class="lang-swift prettyprint-override"><code>var global = 1

func addGlobal(to x: inout Int) {
  x += global
}

addGlobal(to: &amp;global) // crashes due to exclusivity violation
</code></pre>
<p>By extension, you can't pass the same variable <code>inout</code> twice: <code>foo(&amp;bar, &amp;bar)</code> is always ill-formed.</p>
<p>On the ABI level: public functions take <code>inout</code> values as pointers. If there is no pointer available (such as for computed properties),  creates a temporary and passes pointer to that, then assigns the temporary back to the original after the callee returns. Private functions can use a nonstandard calling convention anyways -- sometimes the compiler passes only the properties you need rather than the whole struct, for example -- so ABI guarantees don't apply to them.</p>

CC BY-SA 4.0
2023-11-05T16:11:36.440Z
2023-11-05T16:11:36.440Z
Bbrk24
CC BY-SA 4.0
2023-11-05T16:46:33.193Z
If `inout` parameters are pointers does that mean changes inside the function to the local variable will be immediately visible from within the function, via other aliases? E.g. if an `inout` parameter points to an object field, will a local change to the parameter be visible in the object field before the function returns? This wouldn't be the case for "copy in, copy out" semantics.
kaya3
CC BY-SA 4.0
2023-11-05T19:45:29.330Z
@kaya3: For many tasks, best performance could be achieved by allowing a compiler to, at its convenience, use either a reference to the original object or a temporary object which is copied on entry and written back on exit.
supercat
CC BY-SA 4.0
2023-11-06T05:38:53.163Z
@kaya3 I’d have to do some experimenting to verify how different statements in the same function work but I think that might be an exclusivity violation? It’s late now (and I’ve been having internet problems all weekend) but I’ll get back to you when I can, probably tomorrow.
Bbrk24
CC BY-SA 4.0
2023-11-06T13:56:54.873Z
@kaya3 [Confirmed](https://swiftfiddle.com/ayum7zak4jdgtmkviasazlxgtu), it's an exclusivity violation to try to even read them both in different statements in the same function.
Bbrk24
# How does languages distinguish passing a parameter by value and reference, especially with non-parameter direct initializations in consideration?
Posted by: username_0 on 2023-11-04
Background
What I want is to make the behaviors of the following two pieces of code identical:
specifier x = getX();
doSomething(x);

function f(specifier x) {
    doSomething(x);
}
f(getX());

That is, to make the behavior of passing a parameter identical to initializing a variable. (The initialization looks like an assignment. The relationship between it and assignment is not discussed here. But the distinction is important in the C++ example.)
Beside the type, the specifier could also specify whether x is a new variable located in an independent address, or an alias of the thing assigned to it, that is, passing by value or by reference. And I may extend it to support more options like the two.
C++ has done it right. Specifically, references could be defined in context other than passing a parameter, to imitate passing a parameter:
Type &x = getX();

Or in C#:
ref Type x = ref getX();

So there is nothing for me to invent. But while I was trying to build something else related to this distinction, I found a strange source of confusion, that some languages tries to make the opposite correspondence. An example is Pascal, where var means both creating variables in independent addresses, and making alias of the passed parameter:
var x, y : T;
begin
    x := y;
    doSomething(x); // y is not modified
end.

var y : T;
procedure f(var x : T);
begin
    doSomething(x); // y is modified
end;
begin
    f(y);
end.

Question
How does languages distinguish passing a parameter by value and reference? I'm especially interested in languages that are not like C++, that initializing a reference isn't so different from assignment, or doesn't have the concept of reference like in C++, so what works in C++ couldn't easily apply. I hope to see languages using the correspondence like in C++, but languages like Pascal or using other ways could also be helpful, as it may tell how the different ideas developed and how much it affects.
Beside the syntax, I'm also interested in how they are distinguished conceptually, in the specification or other materials such as textbooks. The problem of "passing by value or by reference" is it is too specific about parameters. It isn't easily understandable if I say creating a variable, or even creating a nameless value "by value". Languages using keywords might be a bit more helpful than languages using symbols as they automatically provide readable names, but that might not cover the tagless option.
**Tags:** variables references
---
## 1 answers
### Answer by username_1 on 2023-11-05. Score: 1
Swift
Swift doesn't let you generally create aliases the way T& works in C++. To cause a parameter to be passed by reference, you mark it with inout in the function declaration and & at the call site:
func increment(_ x: inout Int) {
  x += 1
}

var y = 1
increment(&y)
print(y) // prints 2

Notably, the & prefix is not necessary if the function is an operator.
struct Foo {
  static func += (lhs: inout Foo, rhs: Foo) {
  }
}

var x = Foo(), y = Foo()
x += y // passed inout with no &

If you don't mark the parameter inout, not only can mutations not be seen by the caller, you can't even try to mutate it -- you don't get a copy to mutate like in C. If you need a copy to mutate for whatever reason, you have to explicitly copy it:
func illegal(x: Int) {
  x += 1 // won't compile
}

func okay(x: Int) {
  var x = x // explicit copy -- it's supposed to look weird
  x += 1 // okay, but the caller doesn't see this!
}

Besides inout, there are two other specifiers available as of Swift 5.9: borrowing (the default for most things) and consuming (the default for arguments to inits). For primitives like Int they don't mean anything; for classes and CoW structs they change where the refcounting operations happen; and for non-copyable types they control ownership: borrowing lets the new function access the value but not consume it (like &T in Rust), while consuming transfers ownership and makes the value inaccessible to the caller (like plain T in Rust).
Default values are not available for inout parameters -- unlike C++ with T&&, you can't take a reference to an rvalue -- leading to overload pairs like this:
extension Int {
  static func random(in range: Range, using generator: inout T) -> Int {
    // ...
  }

  static func random(in range: Range) -> Int {
    var g = SystemRandomNumberGenerator()
    return random(in: range, using: &g)
  }
}

Finally, there's a subtle but important rule known as the Law of Exclusivity: when a variable is passed inout, that can be the only concurrent access to that variable. If the same variable is mutated in one way and accessed in another at the same time, the Swift runtime panics.
var global = 1

func addGlobal(to x: inout Int) {
  x += global
}

addGlobal(to: &global) // crashes due to exclusivity violation

By extension, you can't pass the same variable inout twice: foo(&bar, &bar) is always ill-formed.
On the ABI level: public functions take inout values as pointers. If there is no pointer available (such as for computed properties),  creates a temporary and passes pointer to that, then assigns the temporary back to the original after the callee returns. Private functions can use a nonstandard calling convention anyways -- sometimes the compiler passes only the properties you need rather than the whole struct, for example -- so ABI guarantees don't apply to them.
> **Comments:**
> **username_2** (2023-11-05): If `inout` parameters are pointers does that mean changes inside the function to the local variable will be immediately visible from within the function, via other aliases? E.g. if an `inout` parameter points to an object field, will a local change to the parameter be visible in the object field before the function returns? This wouldn't be the case for "copy in, copy out" semantics.  
> **username_3** (2023-11-05): @kaya3: For many tasks, best performance could be achieved by allowing a compiler to, at its convenience, use either a reference to the original object or a temporary object which is copied on entry and written back on exit.  
> **username_1** (2023-11-06): @kaya3 I’d have to do some experimenting to verify how different statements in the same function work but I think that might be an exclusivity violation? It’s late now (and I’ve been having internet problems all weekend) but I’ll get back to you when I can, probably tomorrow.  
> **username_1** (2023-11-06): @kaya3 [Confirmed](https://swiftfiddle.com/ayum7zak4jdgtmkviasazlxgtu), it's an exclusivity violation to try to even read them both in different statements in the same function.  
---
