5 ms·
Interesting project, and I wish them luck. But Python is really not suitable as a compiled language. Its ability to change what any object is, on the fly, reall
by bcl 16y ago
Interesting project, and I wish them luck. But Python is really not suitable as a compiled language. Its ability to change what any object is, on the fly, really throws a wrench into things. I think efforts like PyPy are much more likely to produce improvements in execution speed.
- riobard 16y ago"Its ability to change what any object is, on the fly" No, it doesn't. It changes the reference. If things are referred in the right way, it is possible to statistically compile them. PyPy relies on this info too, but JIT compiling.
- haberman 16y agoclass Dog: def speak(self): print "Woof!" class Cat: def speak(self): print "Meow!" obj = Dog() obj.speak() obj.__class__ = Cat obj.speak() Prints: Woof! Meow! Seems to validate what the OP was saying. EDIT: I don't understand the downvotes. The OP spoke of Python's "ability to change what any object is, on the fly," but was refuted and downvoted. Doesn't the above code sample illustrate exactly that? The object's class can be changed on the fly, therefore changing what the object is.
- ohyes 16y agoObj when constructed contains a reference to the Dog class. Assignment updates the reference to be the Cat class. None of this has relevance to the ability to compile to machine code. It does however, have implications for the efficiency of said code. (Object has to dereference the speak function for its class, and then call it, rather than being able to call the class's speak function directly, as you might in Java. It is also harder to eliminate type checks with such a scheme).
- haberman 16y ago> None of this has relevance to the ability to compile to machine code. It does however, have implications for the efficiency of said code. This is a tautology. You can always "compile" a script to machine code by just making all the generated code call back into the interpreter. The only point of compiling to machine code is if it can be more efficient than interpreting the code. > Object has to dereference the speak function for its class, and then call it That's exactly what the interpreter would have to do. So what are you gaining by ahead-of-time compiling to machine code, again?
- ohyes 16y agoA tautology is when I say something that asserts its own truth. I don't believe that to be a tautology. I don't think I said anything about calling back to the interpreter. I merely meant to imply that the efficiency might not be as good as that of a statically compiled language. There is a large implementation difference between an interpreter and a compiler. It goes far beyond 'efficiency.' In an interpreter, generally, you are interpreting a data-structure and dispatching based on the symbols in that data-structure to do various things. The advantage of the interpreter is that you don't have to compile (you just have to tokenize/parse). Every function call and value dereference requires interpretation of this parsed structure. This means that for every function call you have to do some sort of lookup, and your flow control constructs (like if) are done by manipulating your position in the data-structure. In a compiler, you are operating at a much lower level, having already interpreted the data-structure, and transformed what you would have interpreted as a data-structure into a machine code representation of itself. Instead of manipulating a position in a data-structure to interpret the code, you use the program counter (machine code jmp instructions). In certain situations, you can prove things about the code that is being compiled, leading to more efficient code (similar to what one might do with a static compiler). In the example above, the interpreter might look up the proper function by finding the correct class object in a hash table, and then finding the pointer to the function. In a compiler, it might dynamically recompile a dispatch function (when you add an object that implements that method), and then simply dispatch based on a case statement of 'object type' (something more sophisticated is likely possible as well). The second way of handling it would likely be much more efficient, even in the face of dynamically changing classes. If you allow type hints in your compiler, you can prove even more things about various pieces of your program, meaning that, for example, you might be able to do straight up integer math in machine code (add, imul, sub, ash, etc) rather than having to go through a 'generic math' dispatch. There is a lot of interesting 1980s-early 1990s literature on efficient implementation of dynamically compiled languages. There are number of smalltalk, scheme, and common lisp compilers that are good examples of this technique (and proof of my claims!) It is a fascinating subject and I highly recommend reading about it. (The Henry Baker archives might be a good start).
- rayiner 16y agoCommon Lisp supports that --- it doesn't really much with compilation too much.
- sedachv 16y agoNot only that, there is already a Python implementation that compiles to Common Lisp (http://common-lisp.net/project/clpython/ http://common-lisp.net/project/clpython/), so you can get native code compilation for Python by running CLPython on any of the Common Lisp compilers that produce native code. IMO, I don't see the point of working on static compilers for languages with simple meta-circular semantics at this point in time. LuaJIT has proven beyond doubt that tracing JIT compilation is the way to go.