>> Apologies for my overly-fragmentary toy example.
well, better than my no example :-) -- but I wasn't referring to any particular example, I meant it generally -- again, this proposal is about using local variables to fill in function calls (or dict construction) with the same names, and I'm suggesting that if that is "data", then it probably shouldn't be in local variables anyway. And if it it came from JSON (or some such), then it took effort to put it in local variables ...
> Let’s say you have a function that makes an API request to some video site to get the local-language names of all movies of the user-chosen genre in the current year.
> If you’ve built an object model, it’ll look something like this:
query = api.Query(genre=genre, year=datetime.date.today().year)
response = api.query_movies(query)
result = [
movie.name[language] for movie in response.movies]
> If you’re treating the JSON as data instead, it’ll look something like this:
query = {'query': {'genre': genre, 'year': datetime.date.today().year}}
response = requests.post(api.query_movies_url, json=query).json
result = [movie['name'][language] for movie in response.movies]
well, the query params and the result are not really the same, on the data vs code continuum. But...
> Either way, the problem is in that first line, and it’s the same problem. (And the existence of ** unpacking and the dict() constructor
> from keywords means that solving either one very likely solves the other nearly for free.)
Agreed. I do think that if this is going to happen at all, it should be a dict display feature (which would help with both "data" and "code"), not a function calling feature.
> Here I’ve got one local, `genre`. (I also included one global representing a global setting, just to show that they _can_ be reasonable as well, although I think a lot less often than locals, so ignore that.) I think it’s pretty reasonable that the local variable has the same name as the selector key/keyword. If I ask “why do I have to repeat myself with genre=genre or 'genre': genre”, what’s the answer?
Sure, but treating the result as data does not mean you have to treat the query as data as well, and you may have a query_params class that holds all that anyway :-) -- and even if they are locals -- where did they come from? (read from a config file? gotten from user input?) if you were doing a full on JSON API, they may not have ever had to be in variables in the first place.
> If I have 38 locals for all 38 selectors in the API—or, worse, a dynamically-chosen subset of them—then “get rid of those locals” is almost surely the answer, but with just 1? Probably not. And maybe 3 or 4 is reasonable too—
right. but I don't think anyone is suggesting a language change for 1, or even 3-4 names (maybe 4...)
> And it’s clearly not an accident that the local and the selector have the same name. So, I think that case is real, and not dismissible.
I wasn't trying to dismiss it.
I'm not saying it never comes up in well designed code -- it sure does, but if there's a LOT of that, then maybe some refactoring is in order.
> Yes. And now that you point that out, thinking of how many people go to StackOverflow and python-list and so on looking for help with exactly that anti-pattern when they shouldn’t be doing it in the first place ...
Right. I think the data vs code distinction is a tough one in Python (maybe a tiny bit less than JS?) In more static languages, you can kind of decide based on what a pain it is to write the code -- if it's a serious pain, it's probably data :-)
> And if we go back a couple messages in this thread, I was suggesting that the anti-pattern was not using the same names in calling and function scope, but rather, using local names, when it really should be data: in a dict, or even a special object.
> there is definitely a risk that making this syntax easier could be an antipattern magnet. So, it’s not just whether the cases with 4 locals are important enough to overcome the cost of making Python syntax more complicated; the benefit has to _also_ overcome the cost of being a potential antipattern magnet. For me, this proposal is right on the border of being worth it (and I’m not sure which side it falls on), so that could be enough to change the answer,
Good point.
> But I don’t think it eliminates the rationale for the proposal, or even the rationale for using it with JSON-related stuff in particular.
Nor do I. However, as I think about it, where this may make the most sense might be for cases when you're making a complex call that has SOME arguments in the local namespace, with the some with other names, and some specified as literals. That's pretty common pattern in the call to setup() in setup.py files, for example.
-CHB