That's an idea that could be added to my thread "dialects of python" in
order to compile some fancy or specific syntax to regular python.

Le sam. 22 sept. 2018 à 13:53, Lee Braiden <leebr...@gmail.com> a écrit :

> Could I get some feedback on this?  I'd like to know if anyone thinks it
> might make it through the pep process before spending too much (more) time
> on it.  That said, it seems valuable to me, and I'm willing to put in the
> time, of course, IF it has a chance.
>
> ---------------------------
>
> Problem:
>
>     Due to (biggest python WTF) (Problem 1), which prevents actual default
> argument values being set in a function signature, many
>     functions look like:
>
>         > def teleport(from, to, passenger, hitchhiker=None,
> food_accessory=None, comfort_accessory=None):
>         >     if hitchhiker is None:
>         >         hitchhiker = Fly()
>         >
>         >     if food_accessory is None:
>         >         food_accessory = Cheeseburger()
>         >
>         >     if comfort_accessory is None:
>         >         comfort_accessory = Towel()
>         >
>         >     ...
>
>     This None checking and setting is unwieldy (Problem 2) boilerplate,
> which is responsible for many extra lines of code in python
>     (Problem 3), and tends to distract from the real code (Problem 4) in a
> function.
>
>     To reduce boilerplate, a ternary or binary expression can be used:
>
>         > def teleport(from, to, passenger, hitchhiker=None,
> accessories=[]):
>         >     hitchhiker = hitchhiker if hitchhiker or Fly()
>     # Existing Solution A
>
>         > def teleport(from, to, passenger, hitchhiker=None,
> accessories=[]):
>         >    hitchhiker = hitchhiker or Fly()
>     # Existing Solution B
>
>     These help, but are still quite repetitive:
>
>     * Existing Solution A is often avoided simply because many Pythonistas
> dislike tenery expressions (perhaps due to
>       readability or hidden code branch concerns), and can quickly become
> unwieldy when the new value (Fly()) is a more
>       complex expression, such as a list comprehension:
>
>         > def teleport(from, to, passenger, hitchhiker=None,
> accessories=[]):
>         >    hitchhiker = hitchhiker if hitchhiker or filter(lambda h: not
> h.already_hitching(), available_hitchhikers)[0]
>
>     * Existing Solution B is less unwieldy (solving Problem 2), yet still
> suffers from repetition (Problems 2, 3, and 4).
>
>     In a similar scenario, when we want to populate an empty list (say,
> accesories), we could write:
>
>         > accessories |= [Cheeseburger(), Towel()]
>      # Almost-Solution C
>
>     However, this is not actually a solution, because:
>
>         * The inplace-or (|=) operator is not provided for None in python:
>
>           > food_accessor = None
>           > food_accessory |= Cheeseburger()
>
>           Traceback (most recent call last):
>           File "<stdin>", line 1, in <module>
>           TypeError: unsupported operand type(s) for |=: 'NoneType' and
> 'Cheeseburger'
>
>           This could be added, but would not solve the issue, because:
>
>         * If an non-default (non-None) argument value WERE provided, we be
> would modifying
>           the argument unintentionally:
>
>             > class Larry:
>             >     def __ior__(self, other):
>             >         print("{} modified".format(self))
>             >
>             > teleport(..., hitchhiker=Larry(), ...)
>             <__main__.Larry object at 0x7f1ad9828be0> modified
>
>     And so Problems 1,2,3, and 4 are compounded.
>
> Proposal:
>
>     The addition of a ?= operator could provide an elegant solution:
>
>         > def teleport(from, to, hitchiker=None, food_accessory=None,
> comfort_accessory=None):
>         >     hitchhiker ?= Fly()
>         >     food_accessory ?= Cheeseburger()
>         >     comfort_accessory ?= Towel()
>
>     In these examples,
>
>         > a = None
>         > a ?= b
>
>         > c = [1, 2]
>         > c ?= d
>
>     Would be equivalent to (assuming ?= was called __ielse__):
>
>         > class ExtendedNone(NoneType)
>         >     def __ielse__(self, other):
>         >         return other
>         >
>         > class ielse_list(list):
>         >     def __ielse__(self, other):
>         >         return self
>         >
>         > None = ExtendedNone()
>         >
>         > a = None
>         > a = a.__ielse__(b)
>         >
>         > c = iff_list([1, 2])
>         > c = a.__ielse__(d)
>
>     Although explicitly provided for list above, this ielse operator could
> be defined
>     (again, as `return other` for NoneType only, but defaulted to `return
> self` for
>     all other values of `a`, requiring very little implementation effort
> or intrusion
>     into other types.
>
> Possible interaction with typing
>
>     It may be also possible to define a ? suffix on function arguments, so
> that:
>
>         > def func(a?):
>         >     a ?= [1,2]
>
>      greatly shorting the current verbose form:
>
>          > from typing import Optional
>          >
>          > def func(a = None : Optional[Any])):
>          >     a = [1,2] if a is None else a
>
>     and equivalent to:
>
>         > from typing import Optional
>         >
>         > def func(a: Optional[Any]):
>         >     a = a.__ielse__([1,2])
>
> Possible alternatives:
>
>     * The __ielse__ name is highly debatable.  Alternatives such as
> __iif__ (inplace if), __imaybe__, __isomeor__ (borrowing from Rusts's
> Some/None terminology, and reflecting the intended use as in relation to
> None types, DB nulls, and similar void-like values).
>
>     * The ? function argument suffix is not necessary to implement the
> core ?= proposal.
>
>     * If the ? function argument suffix  is implemented, implementation
> via typing.Optional is not necessary; it could also be simply implemented
> so that:
>
>         > def f(a?):
>         >     ...
>
>     is equivalent to:
>
>         > def f(a=None):
>         >     ...
>
>
> ---------------------------
>
> Feedback would be much appreciated.
>
> --
> Lee
>
> _______________________________________________
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to