Add support for literal tuples
This will be a bit of a change in user experience - folks will see e.g. Array(Integer, String) instead of just Array on foo = [1, "bar"].
I haven't experienced any shift in typechecking results from having more specific Array types hanging around - while I'm sure we'll want to add more logic in the future to be better on more explicitly handling Array() vs Array<>, at the moment Array(Foo, Bar) just gets treated as Array<Foo, Bar>, which seems perfectly fine. Glad we can get away with a small incremental change!
I'm a big fan of expanding support for tuples, but I'm a little hesitant to infer tuples from literal arrays. I have some cases in my own projects where an array that's intended to be mutable gets initialized with default elements. I'd prefer them to be inferred as Array<X> instead of Array(X, Y, Z). It might be less of a problem in practice than I think, but I'd like to spend more time trying it out.
This kinda makes me wish Ruby had some equivalent to Elixir's native tuple type :/
@castwide: In your case, would the types be varied? If not, I think I taught Chain::Array to create Array<X> instead of Array(X, X, X, X) or what have you for something like x = ["foo", "bar", "baz"]
If the types /are/ varied, https://github.com/apiology/solargraph/pull/4 has Array(X, Y, Z) treat Array<X, Y, Z> as its de-facto superclass, - so ideally it would degrade gracefully if you tried to mutate the array and still accept the operations. I could add some specs to explore that behavior and agree on what we want it to be and what it will take to get there.
I could perhaps even find the common superclass (e.g., Array(Integer, Float) could have a "superclass" of Array<Numeric>).
Another idea would be to treat this as a bit of a 'hidden' type - the LSP could show the Array<> types when the type is inferred, and the Array() version when the types are declared explicitly.
I'll dig in a little and find out what TypeScript and Mypy do in these situations (Steep and Sorbet as well if applicable)
I could perhaps even find the common superclass (e.g., Array(Integer, Float) could have a "superclass" of Array).
That was one of the use cases that occurred to me. I might want array = [String, Integer] to be inferred as Array<Class> instead of Array(Class<String>, Class<Integer>). As I mentioned, that might be less of a problem in practice than I expect. Maybe we can merge it as is and determine whether we need to refine it after seeing it in action.
That makes sense to me. I've been running with it for three weeks now and have been pretty happy with it, but I think we have options if folks want a more conservative approach too.
I think we're ready to merge the tuple features into 0.56.0. I might suggest a couple refinements as I see them in action, but the fundamentals look solid.
Thanks again for all your hard work on this! :+1: :shipit: