Also instead of always replacing the text, it could also be an overlay, where the function call is temporarily expanded in your IDE while in some special mode.
I was surprised it wasn't combined with clangd.
let cell = self.cell_mut(pos);
Becomes: let cell = {
let ref mut this = self;
&mut this.board[usize::from(pos)]
};
Instead of: let cell = &mut self.board[usize::from(pos)];
It did manage to simplify the argument (maybe because it was the same name?) but had to rename `self`.currently my only tool is "jump to definition" & docstr tooltips, but if i could expand those definitions in place... i'd imagine i could grok the code much faster, because i could expand multiple functions and even nested functions, and read the code in one linear flow.
http://number-none.com/blow/john_carmack_on_inlined_code.htm...
> The real enemy addressed by inlining is unexpected dependency and mutation of state, which functional programming solves more directly and completely. However, if you are going to make a lot of state changes, having them all happen inline does have advantages; you should be made constantly aware of the full horror of what you are doing. When it gets to be too much to take, figure out how to factor blocks out into pure functions (and don.t let them slide back into impurity!).
Of course, just like rust-analyzer's "Expand macro recursively" command, this could be used as an analysis utility, even better if it works not only on functions but also C/C++ macros.
Yes. But there is no optimal, best single abstraction - the best abstraction is always for a specific purpose you're looking at the code in question. Same code, same programmer, two different tasks - each may command a code structure opposite of the other.
The core problem is that we insist on working with a single-source-of-truth, plaintext representation - and that is not even remotely sufficient to express everything, every cross-cutting concern, in a readable way, at the same time. Inlining is a perfect example, because "few big functions" vs. "lots of small functions" is one of those holy wars that will not end, because the actual answer is "whichever works best, for you, at this moment".
A bluntly-put corollary:
> Refactoring should be process that involves intellectual creativity, involves deeply understanding the intricacy of dependencies and references, not mechanically expanding functions and call it done.
The sad thing is, all that creativity and exertion of mind is wasted work. The more you refactor your code for your current purpose, the harder it will be for you (or someone else) to work with the code for for a different, cross-cutting purpose. Past some point, we're just overfitting the medium of single, flat, plaintext representation.
A tool like this `clang-expand` is an example of a small part of a solution - ideally, you should be able to trivially do those transformations whenever you need, on whatever code you need, mostly for reading but also for writing. As in, inline a bunch of functions, filter out noise, make your changes, and have those changes propagate to where they should in "canonical representation" - the raw source code, which you don't generally look at, any more than you look at object files your compiler produces today.
For me, such a tool, for other languages would have been useful many times as a way to make refactoring less tedious.
What about by-hand-inlining `std::find` makes the code better?
You can already expand macros at call site in any major C++ editor, so why not functions as well?
I would like this mainly just for making source exploration easier. Visual Studio and Clion have a "peek" feature that does something similar, but as a purely UI element, but Emacs' implementation of peek from LSP works much worse.
Moreover things like SFINAE, variadic functions, and macros can make some libraries really opaque. Stuff like loggers, pub-subs, SERDES code... there will be a lot of template complexity and other indirection where this tool would help dramatically in peeling back the layers and could be used in place of breakpoints or a traditional debugger. (And it can often be hard to set up a debug session for large systems).
Can also be useful when you want to take an existing function and customize it for the call site versus write a new helper. For example maybe you want std::find_if() but instead of writing a lambda predicate you want some other code embedded into the body of the loop.
The output seems nice enough it should be possible to integrate it with Emacs to show as overlay, vs. actually replacing code - though in practice, I'd probably want a mix of both.