While I am not at this point dropping the idea of @decorator(expression) targetnamea thought occurred to me yesterday after discussing targetname as a string in
assignments (and I appreciate the continued discussion in a new thread but
this is a new counter proposal so keeping it here).
There is at least one other place where python saves us from retyping the lhs
in an assignment statement: augmented assignment. It is not being used as a
string, true, and it's much more difficult to introduce a subtle bug by mis-typing
the name if one were to use the standard operator instead. But we still have
augmented assignment for all operators IMO because programmers are
productively lazy and came up with a way to not retype their variable.
What if, instead of adding a new magic symbol to the assignment
statement (statements? still not sure which ones are supported in the
counter proposal) we add a new assignment operator and corresponding
dunder method that would perform the real operation behind the syntactic
sugar.
For now I propose the operator "<==" and dunder "__assign__". Both
very bikeshedable, but allows us to draw some examples
RED <== str
would become
RED = str.__assign__("RED")
# or is this how it's actually done? don't remember
# RED = type(str).__assign__(str, "RED")
where str now has the method
def __assign__(cls, assignment_name):
return assignment_name
Following the example of augmented assignment, both of these would
be SyntaxErrors:
spam = eggs <== str
spam, eggs <== str
Although there is probably a way to make the second one work, that
can be experimented with in a reference implementation or saved for
a later PEP.
Some more of my original examples with the new operator:
Point <== namedtuple("x y z")
UUIDType: str <== NewType
Colors <== Enum("RED GREEN BLUE")
class Colors(Enum):
RED <== str
GREEN <== str
BLUE< == str
It would also be possible to reuse a factory, similar to the way a
decorator that takes arguments first creates a sort of closure and
is then that is passed the function object in a subsequent call.
SPAM_DB <== get_sql_db(pass=_secret, user=user)
TABLE1 <== SPAM_DB
TABLE2 <== SPAM_DB
would be the same as
SPAM_DB = get_sql_db(pass=_secret, user=user).__assign__("SPAM_DB")
TABLE1 = SPAM_DB.__assign__("TABLE1")
TABLE2 = SPAM_DB.__assign__("TABLE2")
Regards
~Jeremiah