← Back to context

Comment by TeMPOraL

5 years ago

GP is asking for the opposite. They're asking for code unfolding.

That is, given a "clean code like":

  auto DoTheThing(Stuff stuff) -> Result {
    const auto foo = ProcessSth(stuff);
    const auto bar = ValidateSthElse(stuff);

    return DoSth(foo, bar);
  }

The tool would inline all the function calls. That is, for each of ProcessSth(), ValidateSthElse() and DoSth(), it would automatically perform the task of "copy the function body, paste it at the call site, and massage the caller to make it work". It's sometimes called the "inline function" refactoring - the inverse of "extract function"/"extract method" refactoring.

I'd really, really want such a tool. Particularly one where the changes were transient - not modifying the source code, just overlaying it with a read-only replacement. Also interactive. My example session is:

- Take the "clean code" function that just calls a bunch of other functions. With one key combination, inline all these functions.

- In the read-only inlined overlay, mark some other function calls and inline them too.

- Rinse, repeat, until I can read the overlay top-to-bottom and understand what the code is actually doing.

Signed up just to say that I've also really, really wanted such a tool since forever. While for example the Jetbrains IntelliJ family of editors has the automatic "inline function" refactoring, they do it by permanently modifying the source code, which is not quite what we want. Like you say, it should be transient!

So I recently made a quick&dirty interactive mock-up of how such an editor feature could look. The mockup is just a web page with javascript and html canvas, so it's easy to try here: https://emilprogviz.com/expand-calls/?inline,substitution (Not mobile friendly, best seen on desktop)

There are 2 different ways to show the inlining. You can choose between them if you click the cogwheel icon.

Then I learned that the Smalltalk editor Pharo already has a similar feature, demonstrated at https://youtu.be/baxtyeFVn3w?t=1803 I wish other editors would steal this idea. Microsoft, are you listening?

My mock-up also shows an idea to improve code folding. When folding / collapsing a large block of code, the editor could show a quick summary of the block. The summary could be similar to a function signature, with arguments and return values.

  • Thank you! I'm favoriting this comment. This is exactly what I was thinking about (+/- some polish)!

    In particular, the SieveOfErastothenes() call, which I can inline, and inside the overlay, I can inline the call to MarkMultiples(), and the top-level variable name `limit` is threaded all the way down.

    Please don't take that demo site down, or publish it somewhere persistent - I'd love to show it around to people as the demonstration of the tool I'm looking for.

    > When folding / collapsing a large block of code, the editor could show a quick summary of the block.

    I love how you did this! It hasn't even occurred to me, but now that I saw it, I want to have this too! I also like how you're trying to guess which branches in a conditional won't be taken, and diminish them visually.

    EDIT: Also, welcome to HN! :).

    • > Please don't take that demo site down, or publish it somewhere persistent

      Feel free to spread the URL around, I plan to keep it online for the rest of my life, or until the feature is available in popular editors - whichever comes first. And if someone wants to mirror the demo elsewhere, it should be easy to do so, since it's client-side only and MIT licensed.

      > Also, welcome to HN! :)

      Thanks! Been lurking here in read-only mode for years, but today I finally had something to contribute.

      3 replies →

I'm curious to understand your use-case, would be open to explaining more?

Do you actually want to overlay the code directly into the parent method or would a tooltip (similar to hyperlink previews) work? I wondering how expanding the real estate space would help with readability and how the userflow would work.

For example, code folding made a lot more sense because the window would have those little boxes to fold unfold (which is basically similar to the act of inline and un-inline).

  • Yes, I want to overlay the code directly into the parent method, preferably with appropriate syntax highlighting and whatever other goodies the IDE/editor provides normally. It would be read-only to indicate that it's just a transient overlay, and not an actual code change.

    So, if I have a code like:

      auto Foo(Bar b) {
        return b.knob();
      }
    
      auto Frob(Frobbable f) {
        auto q = Foo(f.thing());
        return q.quux(f.otherthing());
      }
    
      auto DoSth(Frobbable frobbie) {
        auto a = Frob(frobbie);
        return a.magic();
      }
    

    Then I want to mark the last function, and automatically turn it into:

      auto DoSth(Frobbable frobbie) {
        auto foo_1 = frobbie.thing();
        auto q_1 = foo_1.knob();
        auto frob_1 = frobbie.otherthing();
        auto a = q_1.quux(frob_1);
        return a.magic(); 
      }
    

    Or something equivalent, possibly with highlights/synthetic comments telling me which bits of code came from where. I want to be able to keep inlining function calls like this, until I hit a boundary layer like the standard library, or a third-party library. I might want to expand past that, but I don't think I'd do that much. I'd also like to be able to re-fold code I'm not interested in, to reduce noise.

    What such tool would do is automating the process I'm currently doing manually - jumping around the tiny functions calling other tiny functions, in order to reassemble the actual sequence of lower-level operations.

    I don't want this to be a tooltip, because I want to keep expanding past the first level, and have the overlay stay in place until I'm done with it.

    EDIT: languages in the Lisp family - like Common Lisp or Emacs Lisp - feature a tool called "macroexpander". Emacs/SLIME wraps it into an interactive "macrostepper" that behaves pretty much exactly like the tool I described in this discussion thread.

    EDIT2: See the excellent demo upthread by ' emilprogviz - https://news.ycombinator.com/item?id=27306118. That's the kind of tool I had in mind.

    • yes excellent mock, I see what you mean.

      How would you deal with multiple levels of nesting? :) Let's say you're at level 5 which is pretty reasonable.

      Oh and I also forgot about languages like Java that are heavy on interfaces and DI. That would be interesting to handle.