T O P I C R E V I E W |
jay.carlton |
Posted - Oct 31 2013 : 11:11:53 PM It would be neat to right-click on any type name appearing in a function body and convert the function into a templated function on that type.
So if I had
double ToTheThird(double x)
{
return x * x * x;
}
I could right-click on "double" in the parameter list (or in the return specification, or in the body) and say "Templatize ToTheThird on this type" and VA X would give me
template<typename T>
T ToTheThird(T x)
{
return x * x * x;
}
For functions that were already templated, I'd probably want to be able to right-click on another type and add it as a template parameter. Support for naming the parameter would be slick as well.
Same principle would work for classes I'd think.
Naturally there's a bit of risk, since in some cases I might want only 9 of 10 occurrences of the type to change. Some kind of preview might help there, but I wouldn't think it would be essential.
Thanks again, Jay |
10 L A T E S T R E P L I E S (Newest First) |
jay.carlton |
Posted - Nov 14 2013 : 8:27:17 PM That is good news. I'll have to try it. It sounds very close to what I was thinking of.
Thank you. |
accord |
Posted - Nov 14 2013 : 1:53:22 PM *ah* I see. I suspected something like this but wasn't sure. The good news is that we already have this feature.
1. Just select a text block you want to make VA snippet from. 2. Invoke: VAssistX -> Tools -> Create VA Snippet From Selection 3. You can edit the details (title, shortcut, description) and "identify which symbols or tokens to replace by snippet arguments or VA-defined snippet environment variables" since VA loads the selection to the snippet editor. 4. Press OK
Is this what you were looking for? |
jay.carlton |
Posted - Nov 14 2013 : 10:13:18 AM Sorry, kinda hijacked my own thread there. I was thinking of something to do what a Snippet does, but backwards. So if I've got a function or other piece of text that has an instance of a reusable pattern in it, I'd highlight it, invoke the Snippet from Text command, and identify which symbols or tokens to replace by snippet arguments or VA-defined snippet environment variables. Then I'd just give it a snippet name and shortcut and save with my existing list of VA Snippets.
-Jay |
accord |
Posted - Nov 13 2013 : 2:53:16 PM jay.carlton: yes, we can call it something else (e.g. code creation) instead of refactoring, problem solved
quote: Maybe Extract Snippet would be a more useful capability in the same vein as this one. Just have a window where I can click on individual symbols in a function (or other chunk of text) and replace them with a new snippet argument, saving a bit of find & replace.
I don't really understand that. You want to select multiple symbols / words in a function and replace it with something?
DusanDusan: yes, I had mentioned that in the feature request. It is a useful idea but what I meant is that this part cannot be done in an automated fashion. |
Dusan |
Posted - Nov 12 2013 : 04:41:45 AM quote: Originally posted by accord
Since VA can't know for sure what other changes to do, what doubles (in this case) to change to T"
If you look in my post, there is a list of actions for VA to make this refactoring interactive, particulary points: ... 2) invoke Rename command in method body for "double" to generated template argument. 3) user in Rename dialog unchecks instances to be preserved ... |
jay.carlton |
Posted - Nov 11 2013 : 3:12:09 PM Thanks.
I understand it has the power for misuse or error, but so do many IDE and VA X features.
I concur with the statement that it's not a real refactoring command; it's more of a function authoring command. In that sense it has more in common with snippets than refactorings. (There is a separate Template Method refactoring, which is a different concept entirely).
The original function can still be called by specializing the appropriate parameter to the original type or constant. Separate instantiations of a template aren't refactorings of each other: I agree Foo<dog>() is not functionally equivalent to Foo<cat>(). However, if I created the template using the proposed tool, I believe the specialization ToTheThird<double>() is a refactoring in the strict sense of the original ToTheThird(). ToTheThird<int>() and ToTheThird<matrix<int>>() are separate functions, regardless of whetehr I provide the specialization or let the compiler do it. And yes, it will probably take a human with some understanding of how those types will behave in the function body to catch the difference. (For user-defined types used in uniform ways throughout the function or class to be templatized, the risk of silent semantic change is perhaps lower than for builtin types. You'll get compiler errors if you try something completely unsupported, but I agree it's not a zero-risk proposition.)
So I guess it's more of an advanced editor productivity enhancement. It's not something that's especially common, true, or necessariliy made much faster or more accurate using this tool, and I understand if it's maybe not a priority. I personally think it's an interesting transformation to apply in order to reduce duplication and raise the abstraction level, but if no one would use it then I understand.
Maybe Extract Snippet would be a more useful capability in the same vein as this one. Just have a window where I can click on individual symbols in a function (or other chunk of text) and replace them with a new snippet argument, saving a bit of find & replace. |
accord |
Posted - Nov 11 2013 : 2:06:40 PM I have put in a feature request, but I have serious concerns about the practicability of this refactoring command. Since VA can't know for sure what other changes to do, what doubles (in this case) to change to T, so it can never be a "real" refactoring command. i.e. one that don't break the code. In other words (from Wikipedia) it won't be a "disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior"
http://en.wikipedia.org/wiki/Code_refactoring
case=78337 |
jay.carlton |
Posted - Nov 05 2013 : 10:16:41 AM Hi,
Sorry I missed your replies before.
I think I'd use this in cases where I have small functions or types that I realize could be made more generic if types or integer constants referenced were selected at compile time. Examples might include
- mathematical constructs like matrices, vectors, complex numbers, and quaternions
- decorator functions added to classes (or groups of classes) I don't have permission to change
- similar resource classes managed by RAII-style stack objects
- legacy code written in C or before the widespread use of templates in C++
I think template-friendliness has more to do with readability and a sense of reasonable semantics for all the types referenced than with anything else. At runtime, a function doesn't care (or know) if it's a template specialization, so it's mostly about doing things that make sense. I'd ideally refactor target functions or types to be template friendly before applying this kind of tool.
And maybe one of the reasons template functions are designed that way from the beginning is that nobody has a tool to do it the other way yet. Refactoring is a great way to make hindsight look like foresight.
For classes, yes, there's potential to do things that get you into trouble. I'm thinking mainly of a helper or wrapper class that feature anothers anotehr class prominently it its interface and implementation.
I like DusanDusan's use case of collapsing existing equivalent-except-for-type functions into a single template function, especially if VA X could detect candidates for this automatically. Likewise, functions that are equivalent except for parameter names should in many cases probably be coalesced somehow, but that's another story.
The other reason I think this would help is that it would remove another excuse for writing generic code, so templates might be something more people take advantage of. And it's a platform to add more capabilities in the future, like "specialize this template" or custom typedefs for full or partial specializations. If you specialize a type template and then typedef it to the original name of the type, then code consuming that type ideally wouldn't need to react at all.
Just my two cents, Jay |
Dusan |
Posted - Nov 05 2013 : 02:42:40 AM This is a great idea and could work also for C#. I have spent too much of time by writing such functions.
double ToTheThird(double x) { return x * x * x; }
VA should do: 1) identify type user clicked and create/insert a template argument 2) invoke Rename command in method body for "double" to generated template argument. 3) user in Rename dialog unchecks instances to be preserved 4) VA applies Rename command
template<typename T> T ToTheThird(T x) { return x * x * x; }
Also, imagine situation. You have many overloaded functions: double ToTheThird(double x) { return x * x * x; } int ToTheThird(int x) { return x * x * x; } float ToTheThird(float x) { return x * x * x; }
Then you could modify one to make it template and remove all other.
Idea is good, but usefulness is questionable. |
feline |
Posted - Nov 01 2013 : 11:01:59 PM This makes sense, and it is an interesting idea. Do you have many functions that you want to do this to? In my experience template functions have to be written as template functions, since a lot of functions end up doing things that are not going to be template friendly.
If you are thinking of having all of the members in the class updated when you make the class a template class, which I think is what you mean by your "9 out of 10" comment, then this just makes it worse, since are all of the functions going to be template friendly? |
|
|