Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!weretis.net!feeder1.news.weretis.net!feeder.erje.net!newsfeed.xs4all.nl!newsfeed5.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.002 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'debug': 0.03; 'preferably': 0.03; 'operator': 0.04; 'cpython': 0.05; 'interpreter': 0.05; 'symbols': 0.07; 'context.': 0.09; 'etc).': 0.09; 'subject:method': 0.09; 'sure,': 0.09; 'def': 0.13; 'intermediate': 0.15; 'typing': 0.15; '"~"': 0.16; '(say': 0.16; 'len(x)': 0.16; 'operators,': 0.16; 'spec,': 0.16; 'subject:function': 0.16; 'subject:python.': 0.16; 'subject:release': 0.16; 'wrote:': 0.18; 'string,': 0.18; 'this?': 0.19; 'holds': 0.21; 'long,': 0.21; 'dec': 0.22; 'stuff': 0.22; "doesn't": 0.22; 'header:In-Reply-To:1': 0.22; 'versions': 0.23; 'breaks': 0.23; 'formatting': 0.23; 'int,': 0.23; 'code': 0.25; 'suggestion': 0.26; 'expect': 0.26; 'code,': 0.27; 'raise': 0.28; 'needed,': 0.28; "wasn't": 0.28; 'message-id:@mail.gmail.com': 0.28; 'expressions': 0.29; 'pm,': 0.29; 'class': 0.29; 'confused': 0.30; 'fewer': 0.30; 'for,': 0.30; 'parent': 0.30; 'str': 0.30; 'subject:support': 0.30; 'unicode,': 0.30; 'skip:( 20': 0.31; 'values': 0.32; 'cases': 0.32; 'error.': 0.32; 'tue,': 0.32; 'idea': 0.32; 'comment': 0.32; "can't": 0.32; "isn't": 0.33; 'there': 0.33; 'received:209.85.160': 0.33; 'to:addr:python-list': 0.34; 'character': 0.34; 'handled': 0.34; 'mostly': 0.34; 'anything': 0.34; 'function.': 0.34; 'operations': 0.35; 'something': 0.35; 'received:209.85.160.46': 0.35; 'received:mail- pw0-f46.google.com': 0.35; 'unless': 0.35; 'none': 0.37; 'instead,': 0.37; 'to:name:python-list': 0.37; 'skip:" 10': 0.37; 'but': 0.37; 'received:google.com': 0.37; 'think': 0.37; 'problems': 0.37; 'could': 0.37; 'using': 0.38; 'patch': 0.38; 'received:209.85': 0.38; 'couple': 0.38; 'created': 0.38; 'should': 0.39; 'why': 0.39; 'called': 0.40; 'subject: (': 0.40; "it's": 0.40; 'received:209': 0.40; 'to:addr:python.org': 0.40; '8bit%:8': 0.40; 'more': 0.61; 'type': 0.61; '2011': 0.61; 'your': 0.61; 'back': 0.62; 'you.': 0.63; 'ever': 0.65; 'special': 0.68; 'works,': 0.68; 'designed': 0.69; 'offer': 0.72; 'advantages': 0.80; '(see:': 0.84; 'deliberate': 0.84; 'nathan': 0.84; 'similar)': 0.84 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type:content-transfer-encoding; bh=HDBG8N9ijysOMF27VTxPBOyQNn9WXRnildEx1FwwXbA=; b=rcA5UQfdboyWTerzvDML2pyvmPLA+b6CNwlQfYRnHd6KWwTxn1YZ0yvNJFXnOgcoio HA3OrOb1bQPseFxa+uMOLQwVH0pieV5I4Mp5ftkwIQUaxsP1sdgLL33yl6kM1Qw9OoaT mePYVchoS4Otfh5kP5/bHW2a8kqVyimRoqiOs= MIME-Version: 1.0 In-Reply-To: References: Date: Wed, 21 Dec 2011 10:07:31 -0500 Subject: Re: Elementwise -//- first release -//- Element-wise (vectorized) function, method and operator support for iterables in python. From: Nathan Rice To: python-list Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 68 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1324480061 news.xs4all.nl 6976 [2001:888:2000:d::a6]:56651 X-Complaints-To: abuse@xs4all.nl Xref: x330-a1.tempe.blueboxinc.net comp.lang.python:17666 On Tue, Dec 20, 2011 at 8:37 PM, Joshua Landau wrote: > On 21 December 2011 00:24, Nathan Rice > wrote: >> efoo_res =3D ((efoo2.capitalize() + " little indian").split(" >> ").apply(reversed) * 2).apply("_".join) # note that you could do >> reversed(...) instead, I just like to read left to right >> efoo_res.parent.parent.parent # same as ((efoo2.capitalize() + " >> little indian").split(" ") in case you need to debug something and >> want to look at intermediate values > > How is any of this better than the elementwise operators ("~")? People > should be able to expect len(x) to always=A0return a number or raise an e= rror. > I know it's not part of the spec, but a lot breaks without these guarante= es. > When "str(x)" isn't a string, all the formatting code breaks*. And when t= he > other suggestion ("~str(x)" or "str~(x)" or something similar) has all th= e > benifits and none of the drawbacks, why should I use this? len() will always return a number or raise an error, just like the type functions (bool/int/etc) return that type or raise an error. The interpreter guarantees that for you. This has a couple of advantages over element-wise operators: 1. Because everything is handled in terms of generator chains, all operations on an ElementwiseProxy are evaluated lazily. With element-wise operator overloading you would need to perform each operation immediately. 2. As a result of #1, you can "undo" operations you perform on an ElementwiseProxy with the parent property. 3. This still works if the person who created the class you're working with doesn't add support for element-wise operators. Sure, you could monkey patch their code, but that can lead to other problems down the line. 4. There isn't an obvious/intuitive character for element-wise versions of operators, and fewer symbols is better than more IMHO (see: Perl). Also, if you use the ElementwiseProxyMixin, you can sprinkle element-wise stuff in neatly just by using "variable.each" where you would use "~" in your examples. > Upon this implementation I take back my comment on the whole typing thing= . > Your title just really confused me. > > * You can't just make functions non-elementwise unless called through > ".apply" either: > def str(x): return x.__str__() str is one of the special cases (along with repr, unicode, int, float, long, bool, etc). These can't ever be elementwise in CPython (I don't know that this holds in other interpreters). The idea is that you use ElementwiseProxy(x) or preferably x.each, work with your data in an element-wise capacity as needed, then list() or iter() back out. I think it should be a deliberate change of context. Interleaving the proxy (say via x.each) in mostly scalar expressions works, but wasn't the use case I designed it for, and in those circumstances it doesn't really offer anything above the map function. Nathan