It sounds like many would agree that renaming some things could have many
benefits, but the cost seems to be higher than I imagined.

What if an easier way could be created to manage renaming that avoided many
of these problems?

Perhaps aliases of objects could be something worth baking into the
language itself. I don't mean having multiple names pointing to the same
object as we can do today, but something new entirely.

*THE FOLLOWING IS PROBABLY A CRACKPOT IDEA*, hear it out of you are in the
mood to humor me on this Saturday morning.

What if the __dict__ for modules and classes could be something like a
ChainMap, with multiple internal lookup mappings. The first level (by which
I mean, the first mapping consulted) would be the same as exists today, but
the second would contain a weak value dictionary with aliases pointing to
objects so that when you do json.load_str, it returns json.loads object
just like it would if you had added the alias in the way you would today.
But the dict is weak value so that if an object is garbage collected, its
alias entries are removed.

So the second mapping would be a so called "alias dictionary".

How could this be done to overcome some of the same objections raised?

*First, regarding discoverability: *

dir() would work identically to as it does today, but you could give an
argument to also provide aliases, something like:

>>> dir(json, alias=True)
['JSONDecodeError', 'JSONDecoder', 'JSONEncoder', '__all__', '__author__',
'__builtins__', '__cached__', '__doc__', '__file__', '__loader__',
'__name__', '__package__', '__path__', '__spec__', '__version__',
'_default_decoder', '_default_encoder', 'codecs', 'decoder',
'detect_encoding', 'dump', 'dumps [dump_str]', 'encoder', 'load', 'loads
[load_str]', 'scanner']

Note that when you tell dir() that alias=True, additional aliases for
objects are added to the output in the form of a string-ified list.

Also change the default object repr so that it says something like:

>>> json.loads
<function loads (alias: load_str) at 0x.... >

The help() could be modified to be something like:

>>> help(json.load_str)

Help on function loads in module json (alias: load_str): ...

*Second objection: "people are going to be confused because now they will
ask 'What is the difference between these TWO functions, or between these
TWO methods?'":*

There are no longer "two different functions/methods". Since aliases are
something baked into the language, both new and old folks would need to
learn to be GENERALLY aware that they exist, and there will need to be an
easy way to retrieve the aliases for an object. So there's a big new thing
to learn there.

But once that exists, it mostly becomes a single point of learning.

People would still periodically see the different names in code and ask the
question "what's the difference" of course, but the answer would change.
Instead of simply "oh it is the same function with a second name", the
answer would be "those are a thing called python aliases; here is a link to
the docs talking about how to find aliases". The docs for the object would
also list aliases (if there are any). However I dare say you'd probably get
this question less often because of the repl output I am suggesting above.

*Third objection: it polluts the namespace.*

It still would do this to a degree, but I think in a more tolerable way.

Most importantly, it seems like it would be preferred for * importing
everything from a module to import only the first level dictionary and not
all the aliases. Additionally, you can still add or monkeypatch new objects
into a namespace (they would go into the first level dictionary, therefore
overriding any aliases in the second level). Beyond that, since I'm talking
about something new baked into the language, the code writing tools would
be updated to know about aliases and provide useful auto complete
functionality that makes it clear this is an alias.

But yes, of course I knowledge there would definitely be the possibility of
bugs created by an accidental typo that happened to also be an alias.

*For convenient addition of aliases and discovering them for a specific
member:  *

There are likely all sorts of ways you could do this. Perhaps a dunder
alias combined with an alias decorator could be added (probably in
functools? not top level)?

You could add an alias like:

@functools.alias("load_str")
def loads(...): ...

assert loads.__alias__ == ["load_str"]

class MyClass:
    @functools.alias("prof")
    def process_file(self, ...): ...

assert MyClass.process_file.__alias__ == ["prof"]

I'm sure this is an extreme idea and likely nobody is going to be
interested. But I started writing it and couldn't stop.
_______________________________________________
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/O66RJ5X7IZPB3FUJGB7O2ZWK7ZQCZ5GG/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to