import {Component, render} from 'https://cdn.pika.dev/preact/v8';I disagree with you after there.
[0] https://addons.mozilla.org/en-US/android/addon/containers-on...
func make_numbers() -> Sequence<Any>
This should work as long as Sequence is covariant on Element. You could return any possible Sequence here, like Sequence<Int> or Sequence<Double>. The user of the function wouldn't know.You could also do something like
func make_numbers() -> Sequence<Comparable&PartialOrder>In Java, the following function definition compiles just fine:
IShape getShape() {
return new Rectangle(20, 40);
}
And, assuming that `IShape` has a `draw()` method, you can write: IShape shape = getShape();
shape.draw();
It works because there is dynamic dispatch occurring at runtime: the JVM will look for the implementation of `draw()` in the `Rectangle` class (not sure of the exact mechanism, but that's the idea), and call it. To find it, the value (here, shape) must holds a reference either to its class so the JVM can go and look for the implementation, or to a table of all methods it implements (I think it's the first). So the compiler code doesn't know the layout of the concrete type used, it just add instructions to go look for the implementation at runtime. But that's fine, because any Object in Java is in fact like that: a fat pointer, containing a pointer to the data, and a pointer to the implementations.I won't work in Swift because, as far as I know, there is no dynamic dispatch, at least by default. When you write the following:
func render<T: Shape>(_ shape: T, at point: Point) { … }
The compiler will know what is the concrete type of `T`, and so will use its implementation of the `draw()` method. It won't be found at runtime, it is known at compile time. What this means is that a protocol is not a type. This is the important part. An interface in Java is a type, because it doesn't dictate how the method is called, it allows the concrete type to live under the hood, and call the right method at runtime. A class in Swift is a type because you know how to call it, how to access it. But a protocol is just a set of constraints on a type, not a type by itself.That's why you need the `some` in return position. Well, you don't really need the syntax, but it helps understanding the difference with the "same" Java code. The `some` keyword says that the function will returns some type that will implements the `Shape` protocol. It will in fact return the concrete type, but this is not included in the type signature, so it can change, it can hide implementation details, without making a breaking change in the API. It also means that the following won't compile (I'm not sure here, but it works that way in Rust):
func union(_ leftShape: some Shape, _ rightShape: some Shape) -> some Shape {
if isEmptyShape(leftShape) {
return rightShape
} else if isEmptyShape(rightShape) {
return leftShape
}
return Union(leftShape, rightShape)
}
Because here, all code path don't return the same concrete type. If you want different concrete types, you'll need the other keyword, `any`. `any` is in fact a lot like the interfaces in Java, because it uses dynamic dispatch under the hood (if it works like it does in Rust). The compiler will know how to turn the concrete type into the dynamically dispatched one.Isn't it some kind of disguised tracking? I know it doesn't give as much info as the user agent of a browser, but still, you could track the OS, even the linux distribution, and surely more, while still being a reproducible build.