<p>Swift allows protocols (called &quot;interfaces&quot; or &quot;traits&quot; in other languages) to require initializers and static members. This allows things like this:</p>
<pre class="lang-swift prettyprint-override"><code>func canAddWithoutOverflow&lt;T: FixedWidthInteger&gt;(_ x: T, _ y: T) -&gt; Bool {
  precondition(x &gt;= 0)
  let roomToAdd = T.max - x // Notice the static member &quot;T.max&quot; here, from FixedWidthInteger
                            // https://developer.apple.com/documentation/swift/fixedwidthinteger/max
  return y &lt;= roomToAdd
}
</code></pre>
<p>Other languages, like C# and Java, don't do this. What are some advantages and disadvantages to having this?</p>

<language-design><types>
What are some disadvantages to allowing interfaces to require static members?
CC BY-SA 4.0
2023-08-28T18:53:23.353Z
I find this use of the word "static" amusing, since it means that invocations of such methods through the interface aren't statically bound after all.
kaya3
<h3>Advantage: Dynamic instantiation</h3>
<p>In functions without static methods on interfaces, it is impossible to construct an instance of a class without naming each individual class. However, if you allow static methods you can re-use instantiation logic for all implementers of a class.</p>
<pre class="lang-rs prettyprint-override"><code>trait K{fn new(u32)-&gt;K};

fn createFactory&lt;T: K&gt;()-&gt;Box&lt;dyn Fn(u32)-&gt;Box&lt;dyn K&gt;&gt;{
    |x|T::new(x)
}
</code></pre>
<p>This is especially useful if you want to eg. instantiate an array of many values of a specific class with similar logic for many different classes.</p>


CC BY-SA 4.0
2023-05-17T07:35:58.143Z
2023-08-28T17:35:03.903Z
2023-08-28T17:35:03.903Z
mousetail 'he-him'
<p>Tyr actually has both, classical static members that are associated with the type and, thus, not inherited and members associated with the class itself. The latter ones behave like the static members in the question. In essence, they are instance members that use the runtime type information as the underlying object.</p>
<p>Both serve different use cases. Static members are mostly stateless functions and constants associated with the surrounding type. There is no reason not to allow this for interfaces.</p>
<p>Class members are used to group properties that an instance of a type has but that does not depend on the instance. Something like a human-readable type name or widget name (field) or a constructor with a certain set of arguments (function).</p>
<p>The factory functions are an advantage over an implicit default constructor logic that most languages resort to.</p>
<p>The class fields are in many ways cheaper than using a function with a constant result as one would in Java.</p>
<p>A downside of class members over type members is that accessing them is more expensive. In the current Tyr implementation, a type member uses direct access that works well with optimization. A class member from a class uses a virtual member access which is barely optimized and a class member from an interface uses an imember access which I never saw to get optimized out in realistic code.
Also, in Tyr, class members require storage in each class inheriting them even if they inherit an unmodified copy from the parent class.</p>
<p>A downside of having, both, class and type members is that it makes the language more complex, harder to learn and harder to implement. One would think that the three kind of members (object, class, type) share a lot of implementation logic, but this is in fact not the case in most phases of the compiler.</p>

CC BY-SA 4.0
2023-08-28T18:53:59.040Z
2023-08-28T18:53:59.040Z
feldentm
# What are some disadvantages to allowing interfaces to require static members?
Posted by: username_0 on 2023-05-16
Swift allows protocols (called "interfaces" or "traits" in other languages) to require initializers and static members. This allows things like this:
func canAddWithoutOverflow(_ x: T, _ y: T) -> Bool {
  precondition(x >= 0)
  let roomToAdd = T.max - x // Notice the static member "T.max" here, from FixedWidthInteger
                            // https://developer.apple.com/documentation/swift/fixedwidthinteger/max
  return y <= roomToAdd
}

Other languages, like C# and Java, don't do this. What are some advantages and disadvantages to having this?
**Tags:** language-design types
> **Comments:**
> **username_1**: I find this use of the word "static" amusing, since it means that invocations of such methods through the interface aren't statically bound after all.  
---
## 2 answers
### Answer by username_2 on 2023-05-17. Score: 8
Advantage: Dynamic instantiation
In functions without static methods on interfaces, it is impossible to construct an instance of a class without naming each individual class. However, if you allow static methods you can re-use instantiation logic for all implementers of a class.
trait K{fn new(u32)->K};

fn createFactory()->BoxBox>{
    |x|T::new(x)
}

This is especially useful if you want to eg. instantiate an array of many values of a specific class with similar logic for many different classes.
---
### Answer by username_3 on 2023-08-28. Score: 2
Tyr actually has both, classical static members that are associated with the type and, thus, not inherited and members associated with the class itself. The latter ones behave like the static members in the question. In essence, they are instance members that use the runtime type information as the underlying object.

Both serve different use cases. Static members are mostly stateless functions and constants associated with the surrounding type. There is no reason not to allow this for interfaces.

Class members are used to group properties that an instance of a type has but that does not depend on the instance. Something like a human-readable type name or widget name (field) or a constructor with a certain set of arguments (function).

The factory functions are an advantage over an implicit default constructor logic that most languages resort to.

The class fields are in many ways cheaper than using a function with a constant result as one would in Java.

A downside of class members over type members is that accessing them is more expensive. In the current Tyr implementation, a type member uses direct access that works well with optimization. A class member from a class uses a virtual member access which is barely optimized and a class member from an interface uses an imember access which I never saw to get optimized out in realistic code.
Also, in Tyr, class members require storage in each class inheriting them even if they inherit an unmodified copy from the parent class.

A downside of having, both, class and type members is that it makes the language more complex, harder to learn and harder to implement. One would think that the three kind of members (object, class, type) share a lot of implementation logic, but this is in fact not the case in most phases of the compiler.
---
