-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make devices package importing explicit #3593
Make devices package importing explicit #3593
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a way to configure at what point a import ._
becomes preferable? I personally dislike long lists of imports.
I agree that long strings of imports look cluttered, and Scalafix does has a setting for coalescing imports. (https://scalacenter.github.io/scalafix/docs/rules/OrganizeImports.html#coalescetowildcardimportthreshold.) There's a few reasons it helps to be more explicit about our imports. For new people wanting to contribute to the project wildcard imports obfuscate the origins of imported definitions, and that makes it challenging to get a grip on the code base. With implicit type conversions there's also a lot of hidden functionality when you use wildcard imports vs explicit importing. This generally also helps with overall context when reading through all the implementation. This is also something that later versions of scala are trying to move away from. A lot of editors now have options for folding the import section, so we can both have the explicit information available to us, and also make the files appear more concise. My main aim right now is to lean into small, ergonomic improvements with the goal of helping onboard new contributors and generally helping us lower maintenance burdens. Both inside this project, and also for downstream consumers. |
Points all diplomacy imports in devices package to standalone diplomacy library
e37a89b
to
9455a8b
Compare
While I agree that discoverability is useful, and that implicit conversions are a dangerous pattern, I'm still reluctant to blow out all the imports. I view Perhaps in places, it would be preferable to prepend the package scope to the code, rather than the import list. Ex: For discoverability, I feel like better documented IDE and language-server support would do more to improve the situation. |
yeah, i totally acknowledge that this ask is somewhat out of line with other scala projects, and also that i should have brought this up as a proposal first (honestly wasn't thinking about how big a change it was, and that's on me). My main goal with the change is to simplify the amount of context you need to hold at once to understand the implementations. I think the biggest issue for me is the fact that these wildcards masked a bunch of implicits which made getting up to speed much more difficult. I'm still kinda in that process right now as well. I've been using scala metals and have LSP and hooks all set up, it's just not as effective at really delivering that context. It can sometimes take minutes to finish the install/compile steps, and there's times when the incremental compiles will just fail to update the LSP entirely. So it's been a pretty rough experience overall during this refactor. At the very least i think it'd be a good idea to prefer explicitly importing these implicits to de-obfuscate the type conversions that happen for things other then the chisel DSL library (i haven't done any digging to see what the impact of alternatives to wildcard importing that would be). There's a few other code maintenance benefits to moving away from wildcards project wide as well. Explicit imports at the top make understanding changes easier and additional feature usage more noticeable. And if dependent APIs change we'll have a lot easier time actually finding what broke and either changing the import, or modifying the code to use newer APIs. Maybe the ideal way forward is for anything that we end up using a lot of things from, we prefer namespaced useages (lazymodule.LazyModule for example). This is also related to deciding at what point the import list should be coalesced or moved to namespaced usages. i'll admit i don't have a preference here for what that limit is, since i generally don't mind large import blocks at the starts of files. I've done some other digging as well, and there's a scalafmt config that will let us compact the grouped imports more by allowing them to be either on a single line (tbh, i think this is less readable), or set some max number of columns to target before wrapping to a new line. I absolutely think it'd be useful to have a wider discussion on what scalafmt rules/config we'd like to use here as well, and i can open an issue to discuss that. Im going to go ahead and open an issue for discussing more about if and/or how we'd like to change code style things (including imports) so we can capture this conversation and have space to discuss more. |
Scalafix has a threshold for when it turns things into a wildcard import: https://scalacenter.github.io/scalafix/docs/rules/OrganizeImports.html#coalescetowildcardimportthreshold I think that's generally a good thing to use, Somewhere in the range of 5-15 seems to be a good value, YMMV. I would also note that while implicit conversions[1] are generally considered dangerous, extension methods[2] are not and the vast majority of these things are actually extension methods. While the names may suggest conversion ( No doubt extension methods have discoverability issues and I don't disagree with stylistic choices to import them by name (rather than by wildcard), I do want to ensure people understand that these are different than implicit conversions. A common pattern in the Scala community these days is to put extension methods in packages called
|
@jackkoenig Thanks for the additional info here, I'm also generally new to scala so im still working on getting my terminology correct. scala 2.x specifically is rather confusing, my understanding is the implicit class declarations operate by implicit type conversion, where in the new extension syntax in 3 is built on the type system a little differently. I think namespacing them is also a generally good idea, especially since it would let us ensure they're always the last import statements ensuring that there's less possibility of them getting overridden by other imports (and we can make this automatic with scalafix). If you've got the time/energy to contribute to the discussion in #3597 it'd be great to capture context around what y'all are doing in chisel, that way this project will feel structurally similar and hopefully reduce barrier of entry for anyone coming from the chisel side. |
Here is my two cents: neither do I like import I'm proposing an alignment for rocket-chip that: we can add And for implicit conversions in rocket-chip. I suggest removing them or upstream them to chisel. I do not think RocketChip is proper place for them to live: if they are good patterns, they should live in chisel; if they are from prehistory, we should purge them and forbid downstream using them. |
I agree |
That seems reasonable to me, and for diplomacy we'll probably want diplomacy.(submodule)._ There's not a ton of things that provide extension methods, im down to dig into chisel and open a PR with those changes. a quick grep shows that there's not a ton of implicit classes, so it shouldn't be hard to clear.
|
closing in favor of #3602 |
Type of change: other enhancement
Impact: no functional change
Development Phase: implementation
Release Notes
Points all diplomacy imports in devices package to standalone diplomacy library