[Feature request] Introduce constant type
When I've recently opened PR to add signatures of the Parallel gem on the ruby/gem_rbs_collection repository, I encounter the following difficulty:
# Ruby code
items = [1, 2, 3]
Parallel.all?(-> { items.pop || Parallel::Stop }) { |item| item.size == 1 }
# RBS (short version)
module Parallel
Stop: Object
# `T | Stop` should be better than `T | untyped`.
def self.all?: [T] (Enumerable[T] | (^() -> T | untyped) array) { (T) -> boolish } -> bool
end
As you see above, we now cannot use Parallel::Stop as a type.
Supporting such a type signature might be useful, but what do you think?
This proposal is thanks to @pocke. Please refer to https://github.com/ruby/gem_rbs_collection/pull/21#discussion_r587286192 for details.
Yes, Parallel::Stop is not a type here. I don't think we can introduce a feature to use constants as types...
Do you know if some languages allow this?
Do you know if some languages allow this?
Umm..., I'm not sure, but TypeScript does not seem to support such a type at least:
https://www.typescriptlang.org/play?ssl=1&ssc=1&pln=7&pc=1#code/MYGwhgzhAEBiD29oG8BQ0PQgFzNglsNAEJgBO0AvNAIzqYBGYAXgBTkDmAXCeQJQ8AbvHwATFPUyYyAU2wBXMgDtJ0AL6oNQA
This programming pattern like Parallel::Stop might not be common... 🤔
One idea is to introduce new opaque type feature that allows writing:
module Parallel
type stop # No right hand side; defines new type that's not equivalent to anything else.
Stop: stop
def self.all?: [T] (Enumerable[T] | (^() -> T | stop) array) { (T) -> boolish } -> bool
end
@soutaro Introducing an Opaque Type sounds like an interesting idea!
Considering a type without assignment as an opaque type seems sufficient for this case (Parallel::Stop), but if we would introduce an opaque type, it seems to me that there are more things to consider.
For an example of Flow, the opaque keyword is used.
Also, for an example of Swift, the some keyword is used.
@ybiquitous I think the type syntax without equation is brought from signature declaration of OCaml.
- https://caml.inria.fr/pub/docs/manual-ocaml/moduleexamples.html#s%3Asignature
The problem is that if we can introduce the concept of internal <=> external. I don't think it makes much sense compared to the complexity required for it...
Oh, the syntax comes from OCaml. I understand. 🙆♂️
The problem is that if we can introduce the concept of internal <=> external. I don't think it makes much sense compared to the complexity required for it...
That's a hard trade-off. If such a pattern like Parallel::Stop is not common, it seems unreasonable to me to introduce a new syntax... 🤔
Just FYI TypeScript does allow this, you just have to tell to use the typeof that specific property (your syntax had it looking just for a global Bar property):
class Foo {
static Bar = 1
baz(arg: typeof Foo['Bar']): void {
return
}
}
https://www.typescriptlang.org/play?#code/MYGwhgzhAEBiD29oG8BQ0PQgFzNglsNAEJgBO0AvNAIzqYBGYAXgBTkDmAXNNgJ4AHAKbwAZnEQBtAOSky0gLoBKHgDd4+ACYp6mTGSHYArmQB2u6AF9U1oA
