Tips for refactoring code

Hi,

I wonder if there are any good ways to refactor julia code (or workflows which reduces the labour)?

I’m trying to do TDD but with my current setup I need to update at least three files even for a trivial thing like a name change: 1) The actual source code, 2) my module file with the exports 3) the test case file.

This is taking alot of fun out of it and I keep thinking I must be doing something wrong.

In case it matters I’m currently using juno and I kinda like it (except for the topic of this post).

I have searched for things like “julia refactoring” but I only found very specific things (like “how do I refactor this code into xxx”.

I usually put the exports at the top of the file that (first) defines a function.

Any decent editor should be able to search & replace in multiple files.

That said, renames are usually the cheapest when refactoring.

I believe you have to be a bit more specific about the refactoring. If it amounts to renaming, it is a trivial task, as @Tamas_Papp just mentioned. There are some small problems there as well related to the alignment of arguments etc.

A slightly more complicated refactor is related to splitting functionality in files, modules etc and there you have to be more specific.

I remember a very good talk on a Java developers conference (or a PyCon) a few years back where a guy what talking about coding for minimal future refactor work, you may try searching for it on youtube. Very similar to this

1 Like

I have this piece of code that does method extraction. It looks at the AST and try to figure out what variables are not assigned and will generate a function signature for it. Even though it’s a bit buggy I find it very useful, you can write code in the global scope and when you are happy with it just press ctrl-e and turn in into a function. It’s one of the thing I miss when using Juno.

That said I should try to rewrite it using MLStyle because it’s not pretty and sometimes just fails.

1 Like

If you’re asking “can I easily set up the canonical package structure?” the answer is PkgTemplates.

5 Likes

Thanks alot for all the answers.

Sorry about not being very specific. It is just a general feeling I’m doing something wrong as I constantly find myself realizing stuff like I forgot to export the new method name after spending some 30 seconds to parse a stacktrace from a failed testcase after a round of refactoring. Some of it is probably just about getting used to the language overall (I really like it so far!) though.

I guess I was secretly hoping there was a plugin I forgot to install that would give access to options similar to the ones in eclipse or IntelliJ :slight_smile:

Doing (regex) replace in multiple files is of course workable in some cases. What I remember from it before I was spoiled by IDEs was that one still needs to be a bit careful to not accidentally mess up other parts (especially comments and documentation).

I will take a look at that Refactoring module as and the refactoring talk as well.

I did find that excellend PkgTemplates package and found it very useful.

I agree! Coming from the Java/Scala world I really miss the automatic refactoring of IntelliJ and/or Eclipse. Any decent environment should include “rename”, “move”, “change signature”, “extract function”, “inline” etc. And it is not just search and replace-- “extract function” for example finds all the equivalent blocks of code, and replaces them with a call to a function. “Move” for Julia would move a function to a different module, and fix all the places that reference it. “Change signature” changes the arguments and fixes all the places that call that function. Such tools are the central to the “refactor mercilessly” strategy of maintaining clean code Refactor Mercilessly

3 Likes

I suspect this wasn’t the case when this question was asked, but the Julia extension for VS Code now provides great renaming functionality, very similar to how JetBrains products’ refactor->rename command works.

I thought is was worth reviving this topic, since this page seems to be in the top search results for people wondering how to get this kind of functionality from a Julia IDE.

Also, see the following link, it appears that the Julia devs are switching from Juno to VS Code, so VS Code is probably the best option for most users at this point: Bye-bye Juno, hello Julia for VS Code - IDE shifts form, reaches 1.0 • DEVCLASS

2 Likes

Thanks for the tip. I’m using VS code but I didn’t know about that option.

As a debrief about one year later, I pretty quickly found a good workflow in which the lack of refactoring tools was more than well made up for by the language itself being so easy to use.

It is hard to put a finger on it without writing a whole blogpost, but the combination of dynamic typing (and the awesome type system in general) and reliance on class based programming seem to make refactoring tools a lot less necessary.

I still use IntelliJ and eclipse quite a bit so it’s not like I have gotten used to not having refactoring tools either.

Hi,

I’m very new to julia and have just started migrating some code from java, within the scope of a private project to learn the basics and get started.

However I’m pretty astounded (and even genuinely shocked) by the (it seems) complete lack of decent tools or even an awareness of the need for such.

I totally agree with @peter.wolf: Coming from a java-ecosystem, I’m used to being able to rename variables, fields, methods, classes, files / changing the signatures of functions and any datastructures once, anywhere in my code and having an ide propagate those changes to every corner within the scope of my project (as defined by the project-setup in the ide): This includes files of different extensions (.java, .html, .xml, .json, .properties, …) and even extends to commented-out portions of those files (which is, when the ide would be polling me with the result of a search and ask for a decision to include those or not).
This has been common practice for the past 20 yrs. or so, within the java-world.

Please note, that merely using “find & replace” in a texteditor, without applying any semantic and syntactic knowledge is like falling back from using word on a laptop for textediting to using a mechanical typewriter - yes it works, but it could hardly be considered an acceptable alternative, once you had adopted word (or any other editor, back in the day).

(In the case of refactoring the signature of functions or datatypes in general, using “find & replace” doesn’t even work - it’s no use, finding all mentions of UInt64, when you want to change just the type of one parameter of one function to Int128 within a large project - just as one trivial example).

So all ranting aside: How do people tackle this (apart from the obvious: Be less verbose in your style, start thinking more about names, like we did before refactoring ever became feasible and be disciplined with your conventions from the start, etc, to reduce tedious overhead, later)?

Which tools seem to be most promising wrt. to these issues, atm?

I’m using vs code, which does recognize the option of refactoring (shows an entry in a contextmenu for it, when I select a variable, function, type, etc.), but then follows up with a no refactorings available, when I select that option. :grimacing:

1 Like

Addendum: I do recognize, it is not trivial, having (some of) these features for julia, in a way, that truely manages dynamic typing and multiple dispatch, but there has to be a way, to support some basic refactoring, at least for local names and static types, within a certain scope (project, package, module, function or whatever other unit of work).

It’s great that there’s any such code available, reminds me, while I should use an editor/VS Code IDE more/always, since this takes a string, is there any way to get code of functions back that you’ve just typed into the REPL (with comments, as is)? I know it’s in the edit history, and you can search it, just thinking if the code is only stored in (some) lowered form, or something like could be available:

@code_original my_func

I need to check it out, it’s just renaming, not extract method or more advanced I hear of for other languages, Java?

I found this very frustrating to begin with. However, as I adopted a standard package structure (like using PkgTemplates.jl) helps the language server in VS code know what symbols you are using which actually lets you do symbol refactoring across multiple files. I have found that having a separate environment to your package, such as in a test or scripts subdirectory and then deving your package lets the intellisense work properly. The only issue is that sometimes you need to restart the language server if your changes aren’t updated.

I’ve not really found a robust/standard workflow or tooling option that isn’t slightly frustrating, and it’s my least favourite part about using Julia.

[…] helps the language server in VS code know what symbols you are using which actually lets you do symbol refactoring across multiple files. I have found that having a separate environment to your package, such as in a test or scripts subdirectory and then dev ing your package lets the intellisense work properly […]

Hmmm, thx for this feedback!
Makes me reconsider, procrastinating to learn about proper package / project-setup.
As of now, vs-code doesn’t seem to be able to refactor anything in my setup (at least not anything beyond simple find-replace, purely based on lexicographic pattern-matching, that one could be doing in any basic text-editor).
But your post makes me question, whether that is “just” due to my own ignorant setup, or not…
I’ll be testing it, I guess! :thinking:

2 Likes