javascript to python
Bruno Desthuilliers
bruno.42.desthuilliers at websiteburo.invalid
Fri Oct 3 06:29:17 EDT 2008
lkcl a écrit :
> On Oct 2, 7:42 pm, Bruno Desthuilliers
> <bdesth.quelquech... at free.quelquepart.fr> wrote:
>> lkcl a écrit :
(snip)
>>> for fits and giggles, compile the above python using
>>> pyjs.py, the python-to-javascript compiler
>>> (seehttp://pyjamas.sf.net) and compare the
>>> resultant javascript to your original code-fragment.
>>> l.
>> I did. Here's the result:
>
> ok - these are the "important" bits. notice that the pyjamas
> compiler is doing a little bit more than your original code:
Not 'mine' - I'm not the OP. And as far as I'm concerned, the point is
exactly here : it's doing "a little bit more" than the original code.
This "little bit" requires 6 times the original code (cf below), and is
actually useless for the OP's use case (else the OP's code wouldn't use
litteral object notation but a full-blown prototype).
> it's
> overriding the "prototype" of dataListener, making it a true "class"
> object.
There's nothing like a notion of "class" in javascript - as you of
course already know.
> this is where there's a key departure from the original code and the
> translation to python: the original code isn't actually a class, at
> all
Indeed. Why would it need to be ?
> - it's more like a.... c struct that has function pointers in it.
It's an object. What's wrong with objects ?
> by declaring a python "class", the javascript equivalent is to add to
> "prototypes".
Indeed. But the point is that Python - while close to a prototype-based
language in many aspects - is still class-based. The closer Python
translation of the OP's javascript snippet is probably the one I gave
using a 'class singleton' - that is, using the class itself as an
object. But retranslating this to javascript using a
python-source-to-javascript-source tool like pyjamas won't give you back
the original javascript snippet (which is by no mean a criticism of
pyjamas - it would just be way too complicated to automatize such a
translation).
>
>> __dataListener.prototype.__init__ = function() {
>> var data = '';
>> };
>
> [ ... so for example here, now when you declare _any number_ of
> "dataListener"s,
What for ? In the original snippet, there's clearly only a need for a
single one - and that's a *very* common pattern in browser-side
javascript scripting. The original snippet is 12 lines, 29 words, 369
bytes long (according to wc). The pyjamas translation of the Python
translation of the original javascript snippet is 49 lines, 126 words,
2285 bytes long. That's 6 times more code (to download and parse) - for
an unneeded feature. Often, less is better.
> each and every one will have its __init__ function
> called. in your original example,
"my" ? I repeat : I'm *not* the OP.
> you're effectively making one and
> only one "dataListener".
s/you/the OP/
And yes, indeed, there's only one dataListener object. What makes you
think there's a need for more than one ?
> you're kinda... it's a bit like having a
> lambda-class (nameless class) and declaring one and only one instance
> of that python class... ]
It's like having an object. period. While most OOPLs are class-based,
classes are by no mean a requirement of OO.
> so - yeah, you can see that (apart from the .prototype, which is
> necessary to make a "class a la javascript") it's a pretty accurate
> translation back to the original javascript.
I don't mean it's not working. I mean that it's a lot of unnecessary
code for an unnecessary feature. Believe me, 6 times more code makes a
*huge* difference when it comes to browser-side scripting and
user-experience.
Also and IMHO, it's trying to forcefit alien idioms in javascript. Being
prototype-based is by design - it's not a shortcoming.
>
>> All this, and more, thanks to the strange idea that it would be better
>> to write javascript in Python instead of writing it in javascript !-)
>
> *lol* :) fortunately, pyjs.py does that translation for you ha
> ha. like they say on brainiac, "STOP! we do these experiments, so
> you don't have to".
"fortunately" is judgement call. As far as I'm concerned, and despite a
couple warts (but hey, no language is wart-free, and Python has it's own
share, isn't it ?), I like javascript as a language, and enjoy coding in
javascript almost as much as I enjoy coding in Python.
> yes - it's because in the translated python, dataListener was
> declared as a class, whereas in the original javascript, the
> corresponding concept (prototypes) are not made use of.
There's probably a reason why the OP didn't use a full blown prototype,
isn't it ?-)
> if you wanted to experiment, you could try this:
>
> def onStartRequest(this, request, context):
> pass
>
> def onStopRequest(this, request, context, status):
> instream.close()
> oustream.close()
> listener.finished(this.data)
>
> def onDataAvailable(this, request, context,
> inputStream, offset, count):
> this.data += instream.read(count)
>
> class dataListener:
> def __init__(self):
> self.data = ''
> self.onStartRequest = onStartRequest
> self.onStopRequest = onStopRequest
> self.onDataAvailable = onDataAvailable
>
> which you will find to be more accurately representative of the
> original javascript, conceptually.
Nope. You defined functions outside the object's scope, and you still
have to instanciate dataListener. Also, this above code just won't work
- unless you explicitely pass the dataListener instance to the
functions, ie:
d = dataListener()
d.onDataAvailable(d, ...)
If you want per-instance methods, you have to invoke the descriptor
protocol by yourself, ie:
class dataListener:
def __init__(self):
self.data = ''
self.onStartRequest = onStartRequest.__get__(self, type(self))
self.onStopRequest = onStopRequest.__get__(self, type(self))
self.onDataAvailable = onDataAvailable.__get__(self, type(self))
But that's still not close to the OP's javascript code, and it's not
pythonic no more.
> i.e taking into account that in
> the _original_ javascript, you don't have any "prototypes".
> but - i don't believe it to be what you actually want, even though
> it's "a slightly more accurate representation".
>
It seem you didn't read my other translation proprosal, so I repost it here:
class dataListener(object):
data = ''
@classmethod
def onStartRequest(this, request, context):
pass
@classmethod
def onStopRequest(this, request, context, status):
instream.close()
oustream.close()
listener.finished(this.data)
@classmethod
def onDataAvailable(this, request, context,
inputStream, offset, count):
this.data += instream.read(count)
This is probably the closest Python translation one can come with
(javascript's 'this' semantics set aside) - even if it's not idiomatic
Python.
As you may have guess by now, I'm more than a bit skeptical about
'language XXX to javascript source' translations[1] - the target is a
too hi-level language IMHO. I don't mean that everyone should learn and
love javascript, but I think that targeting VM specific byte-code is a
way better approach.
[1] which is not a criticism of pyjamas, pypy's python2js compiler etc
effort - only my very humble opinion.
My 2 cents...
More information about the Python-list
mailing list