On 13 October 2012 16:22, Mike Meyer <span dir="ltr"><<a href="mailto:mwm@mired.org" target="_blank">mwm@mired.org</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">



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


<div><br></div><div>The code is one <a href="http://codepad.org/TnuehfQH" target="_blank">Codepad</a> for brevity, and it lets you do things like this:</div><div><font face="courier new, monospace"><br></font></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">



<font face="courier new, monospace"> >>> (2 *dot* "__mul__" |mappedover| 10-to-25) >> tolist<br>[20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48]</font></blockquote><div><br></div><div>


Note that this is a contrived example equivalent to:</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">


<span style="font-family:'courier new',monospace"> >>> list(map((2).__mul__, range(10, 25)))<br></span><span style="font-family:'courier new',monospace">[20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48]</span></blockquote>


<div><br></div><div>and mixing the styles you can get a quite nice:</div><div><br></div><div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">


<span style="font-family:'courier new',monospace"> >>> map((2).__mul__, 10-to-25) >> tolist<br></span><span style="font-family:'courier new',monospace">[20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48]</span> </blockquote>


<div><br></div><div>which would actually look readable if it was considered mainstream.</div><div><br></div><div>Note that making an in-line function is as simple as:</div></div><div><br></div><div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">


<font face="courier new, monospace">>>> @Inline<br></font><font face="courier new, monospace">... def multiply(x, y): return x*y<br></font><font face="courier new, monospace">... <br></font><font face="courier new, monospace">>>> 3 ^multiply^ 3<br>


</font><font face="courier new, monospace">9</font></blockquote><div><br></div><div>and that you can use any surrounding operators (other than comparisons)  to chose your operator priority or what reads well:</div></div>

<div>
<div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><font face="courier new, monospace">>>> 1 |div| 3 |div| 3<br>


0.1111111111111111<br>>>> 1 |div| 3 *div* 3<br>1.0</font></blockquote></div><div><br></div><div>and finally you also get "coercion" to functions á la Haskell:</div><div><br></div><div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">


<font face="courier new, monospace">>>> 2 |(div|3)<br></font><font face="courier new, monospace">0.6666666666666666<br></font><font face="courier new, monospace">>>> (div|3)(2)<br></font><font face="courier new, monospace">0.6666666666666666</font></blockquote>


</div><div><br></div><div>but I wouldn't even hope of calling it stable code or low on WTFs (if the above wasn't enough):</div><div><br></div><div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">


<font face="courier new, monospace">>>> (div|(div|3))(3) # Go on, guess why!<br>1.0<br>>>> 2 + (div|3) # 'Cause you can, yo<br>0.6666666666666666</font></blockquote></div><div><div><br></div><div>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.</div>


<div><br></div><div>So enjoy. Or not. Preferably not. </div></div></div>