This seems pretty cool, from looking over the documentation. Two things I wish I could do that I don't see in the documentation:<p>- Replace an import with another import. This is used when forking a go package.<p>- Rename a package.<p>It's also pretty unclear from the documentation which operations are "UNIMPLEMENTED", since the label simply falls directly between two different operations. It would be nice if this were made more explicit.
I used to joke at work that the fastest, simplest way to get promoted to a staff engineering position was to finish a 1 yr refactor.<p>Getting existing codebases to do new things is hard, and most of enterprise software engineering is basically "rework this API (in the general sense, not web-API sense) for a new product use case".<p>This tool seems to borrow the philosophy of Go's keeping the language simple, with the tradeoff of a more complex (but fairly well supported) ecosystem to account for missing language features.<p>IME, Golang (some would say paradoxically due to a lack of generics) is one of the best languages to refactor because of:<p>- Forced error handling semantics so that unhappy paths are easily enumerated<p>- Tooling like `rdep` to quickly grok the impact of a package refactor<p>- String templates/codegen being a first-class "blessed" part of the ecosystem (i.e. you can find tooling by the Go team as a reference when writing your own)<p>Some would balk at things like codegen being how Go handles this, but for the iteration loops at most companies at scale (where a few tools to do codegen are written & maintained by one team and consumed by others) it works well. For paradigms where you want everyone to contribute to the tooling, it works slightly less well since the barrier of understanding the ecosystem is greater than just understanding the language. Nevertheless, it seems to be the right tradeoff for most enterprise use cases.
A similar concept named "Tactics" was explored in Haskell.
<a href="https://reasonablypolymorphic.com/blog/towards-tactics/" rel="nofollow">https://reasonablypolymorphic.com/blog/towards-tactics/</a>
HN Discussion: <a href="https://news.ycombinator.com/item?id=24759649" rel="nofollow">https://news.ycombinator.com/item?id=24759649</a>
I hope more refactoring tools come into existence in the future. Right now, writing transforms similar to this complexity using Clang would require a fairly large amount of boilerplate code, implementing at least some AST matching code and wrapping it into a frontend action. While having this for Go is good, I hope it grows and inspires others to do similar things in other languages, the same way gofmt once did.
I think this is cool but I wonder what the expected API surface for editor integrations (with mouse-click menu selection to apply a refactor) would work. Would editors code-generate this mini scripting language? Or will there be a more abstract way of providing the same intention to the tool? If editor integrations are expected to send the script-snippets, will there be facilities for programmatically generating valid script snippets?
I've always wanted a tool that finds duplicate code (with minor variable name differences) so I can factor it out. Often when prototyping I'll copy a function thinking it will change a lot or maybe just not knowing what will change. As the application matures I'll go back and clean these up but it shouldn't be too hard for a tool to identify.
A similar, but general purpose, tool to this is <a href="https://comby.dev/" rel="nofollow">https://comby.dev/</a>.<p>I've used it before locally for some structural code changes. The author is super helpful/responsive too.
I wonder if this is some sort of precursor work for the generics release? Feels like gofmt -r on steroids, and could be eventually used to do large scale transformations to the standard library?