chapel icon indicating copy to clipboard operation
chapel copied to clipboard

Should tertiary methods be imported using `module.type.*`?

Open bradcray opened this issue 1 year ago • 13 comments

Today, to get access to the tertiary methods defined in a module M on a type t, you write import M.t; and that will make those tertiary methods available. For example, the IO module defines a tertiary method on the type string, so you could gain access to that through an import using import IO.string;.

While I've been satisfied with this implementation, it was pointed out today that it could seem somewhat surprising since most import statements of the form import M.x; imply "OK, now I can refer to x!" Whereas if x is a type, it's really saying "now I can refer to tertiary methods on x." To that end, @e-kayrakli proposed that perhaps such cases should be written import M.x.*; (or import M.t.* or import IO.string.*; using the examples from the previous paragraph). This seemed like an interesting enough proposal to be worth capturing in an issue.

Specifically, it would give us the exact same behavior and capabilities we have today, but make it more syntactically evident what is being imported. Note that we are only talking about applying * after a type name as a means of gaining access to all of its tertiary methods (and, more specifically, presumably only for a type name not defined in the module in question), so would not support, for instance import M.*; to get access to all of M's symbols (for the same reasons we've historically given—to keep import a precise way of bringing in symbols, and not as prone to hijacking as use is today). If we went this route, I'd suggest we deprecate support for import M.t; when t is not defined within M to avoid confusion.

Moreover, longer-term, we could imagine selectively importing certain tertiary methods using, say, import IO.string.format;.

bradcray avatar Jul 18 '23 03:07 bradcray