On Feb 3, 2020, at 03:59, Richard Damon <rich...@damon-family.org> wrote:
> 
> On 2/3/20 12:02 AM, Bruce Leban wrote:
>> People keep mentioning refactoring. It's a red herring.
>> 
>> No refactoring tool needs a nameof operator added to the language in order 
>> to do its job. And certainly an operator that requires running the program 
>> in order to use it is not going to be helpful. Refactoring tools analyze the 
>> program; they don't run it.
>> 
>> And f-strings are another red herring. There is nothing magical about 
>> expressions inside f-strings compared to those outside.
>> 
>> Ignoring the red herrings, I see no utility in a nameof operator and no way 
>> for it to actually do anything useful.
>> 
>> --- Bruce
> 
> IF Python had a proper refactoring tool (see my other message where I 
> question the ability to do that) then the nameof operator would clearly help 
> keep logging/debug strings in line with the program definitions.
> 
> A statement like print("bar", foo.bar) would be very hard to notice that the 
> "bar" match the foo.bar, while
> 
> print(nameof(foo.bar), foo.bar) makes the connection explicit.
> 
> This is where such an operation could help with refactoring, having an actual 
> Python attribute reference that the refactoring operation could see, so it 
> knows that the string is based on that attribute and not something else.
> 
> As I mentioned elsewhere, the issue is that in Python, if we change the 
> attribute bar in class Foo, then we have the problem that we often can't tell 
> if in foo.bar if foo is of type Foo, so we should apply the change. This 
> isn't a problem is statically typed languages, as there we can determine the 
> type of foo, and see if the change applies (at least in most cases).

This is the same as Smalltalk, ObjC, Ruby, f-script, and all of the other 
languages that use the same dynamic type/data model as Python. And Smalltalk 
was the first language to have practical refactoring tools (although I don’t 
think they were called that until Ralph Johnson’s refactoring object browser in 
the early 90s).

One difference between Python and most of the other Smalltalk-model languages 
is that they use symbols or selectors or some other string-like type to name 
methods, while Python uses plain old strings. If you have print(:bar, foo.bar) 
obviously bar is the name of an attribute rather than normal text. Dropping 
selectors from the language turns out to cause a lot fewer problems than any 
Smalltalk devotee would have believed, just a few very small problems—like the 
one nameof is trying to fix.

Meanwhile, unlike Smalltalk and most other languages with the same model, 
Python has optional static typing. The other major Smalltalk-model language 
that added optional static types is ObjectiveC—and one of the reasons was to 
improve the navigation and refactoring tools. For example, if you have a 
function that takes a `foo: Any` param (spelled `id foo` in ObjC) and there are 
three unrelated types that all have a `bar` method, the tool will tell you that 
it’s ambiguous which one you meant by `nameof bar` (spelled `@sel(bar)`), and 
it can suggest that you either specify a type for `foo`, or create an implicit 
ABC (a `@protocol` in ObjC terms) to own the method. If you do the first, 
renaming Foo.bar to baz will change the selector; if you do the latter, it will 
warn you that Foo.bar makes Foo conform to the Barable protocol that you 
defined and there are selectors in your program that depend on it being 
Barable, so do you want to break that or do you want to rename Barable.bar and 
all of the classes that implement it instead? If you do neither, it doesn’t 
guess, it tells you that there are two ambiguous uses of the selectors and lets 
you see the two uses of the selector or the three classes that define it, so 
you can proceed manually.

Of course this means that an IDE, object browser, or standalone refactoring 
tool has to build a mapping from selector names to a list of implicit uses, 
explicit uses, and definitions (including knowing which definitions are 
inherited, and which are relied on by protocols)  for the whole program. But 
that’s exactly what they do. That’s why RJBrowser takes a while to start up, 
and why Xcode is constantly running clang on bits of your code in the 
background as you edit.

Couldn’t a Python tool just also keep track of every string and substring that 
has at least one match as a use or definition of an attribute? Yes. But I think 
it’s obvious why this is a lot more work and at least a little less useful. And 
that may be part of the reason Python has always had fewer refactoring tools 
available than Smalltalk, ObjC, etc., which is why nameof could be a useful 
addition.

_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/CKCJK7AYEM3UCFK6Q76GRNNUALLDLUQY/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to