[Python-ideas] Is there a good reason to use * for multiplication?

Joshua Landau joshua.landau.ws at gmail.com
Sat Oct 13 18:10:08 CEST 2012


On 13 October 2012 16:22, Mike Meyer <mwm at mired.org> wrote:

> On Sat, 13 Oct 2012 19:18:12 +1100
> Steven D'Aprano <steve at pearwood.info> wrote:
>
> > On 13/10/12 19:05, Yuval Greenfield wrote:
> > I believe that Haskell treats operators as if they were function objects,
> > so you could do something like:
>
> For the record, Haskell allows operators to be used as functions by
> quoting them in ()'s (to provide the functionality of operator) and to
> turn functions into operators by quoting them in ``'s.
>
> > negative_values = map(-, values)
> >
> > but I think that puts the emphasis on the wrong thing. If (and that's a
> big
> > if) we did something like this, it should be a pair of methods __op__ and
> > the right-hand version __rop__ which get called on the *operands*, not
> the
> > operator/function object:
> >
> > def __op__(self, other, symbol)
>
> Yeah, but then your function has to dispatch for *all*
> operators. Depending on how we handle backwards compatibility with
> __add__ et. al.
>
> I'd rather slice it the other way (leveraging $ being unsused):
>
> def __$<op>__(self, other, right):
>
> so it only has to dispatch on left/right invocation.
>
> <op> must match a new grammer symbol "operator_symbol", with limits on
> it to for readability reasons: say at most three characters, all
> coming from an appropriate unicode class or classes (you want to catch
> the current operators and dollar sign).
>
> Both of these leave both operator precedence and backwards
> compatibility to be dealt with.
>

If anyone is taking this as more than a bit of fun, *stop it*.

How'er, for all you wanting something a bit more concrete to play with,
I've got something that simulates infix based off something I'd found on
the netz sometime who's author I do not remember.

The code is one Codepad <http://codepad.org/TnuehfQH> for brevity, and it
lets you do things like this:

 >>> (2 *dot* "__mul__" |mappedover| 10-to-25) >> tolist
> [20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48]


Note that this is a contrived example equivalent to:

 >>> list(map((2).__mul__, range(10, 25)))
> [20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48]


and mixing the styles you can get a quite nice:

 >>> map((2).__mul__, 10-to-25) >> tolist
> [20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48]


which would actually look readable if it was considered mainstream.

Note that making an in-line function is as simple as:

>>> @Inline
> ... def multiply(x, y): return x*y
> ...
> >>> 3 ^multiply^ 3
> 9


and that you can use any surrounding operators (other than comparisons)  to
chose your operator priority or what reads well:

>>> 1 |div| 3 |div| 3
> 0.1111111111111111
> >>> 1 |div| 3 *div* 3
> 1.0


and finally you also get "coercion" to functions á la Haskell:

>>> 2 |(div|3)
> 0.6666666666666666
> >>> (div|3)(2)
> 0.6666666666666666


but I wouldn't even hope of calling it stable code or low on WTFs (if the
above wasn't enough):

>>> (div|(div|3))(3) # Go on, guess why!
> 1.0
> >>> 2 + (div|3) # 'Cause you can, yo
> 0.6666666666666666


These could both be "fixed" by making an infix require the same operator on
both sides, which would make these both errors, but that wouldn't catch
cases like (or*(div|3))(3) anyway.

So enjoy. Or not. Preferably not.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20121013/c178f78c/attachment.html>


More information about the Python-ideas mailing list