I am tasked with learning PHP, but there are many things I don't understand. For example, the concept of "variable functions" is not one I've seen anywhere else. There are many other examples, but for brevity, I found PHPWTF, which has many examples of PHP's idiosyncrasies.
Most other languages I've used have either a formal specification (e.g., Haskell 2010) or at least a research paper on their formal semantics (e.g., this for Javascript). However, I can't find anything comparable for PHP.
There is an official "language reference". However, it is very informal, reads like a wiki, and is missing entire sections (e.g., the section on syntax doesn't define the syntax at all). Confirming what I suspected, this guy tells me that there is no official specification, nor even a defined syntax.
Wikipedia has an article on "PHP syntax and semantics", but it only touches on the syntax, and barely mentions semantics.
One paper I've found on PHP is this paper on its assignment semantics. This is a very small fragment of the language and probably not much use to me without some context. There is also this paper on 'SaferPHP', which presumably has to work with some definition of PHP, though I couldn't see any.
Interpreters/compilers provide a semantics, so I thought to look at these. However, the Zend source is intimidating (though it does provide useful test cases), and HipHop runs to 2.7 million LoC. (I find it amazing that people have poured enormous effort into writing compilers for a language without ever writing something like a specification.)
I thought of looking at type systems for PHP for guidance, much like TypeScript provides some guidance for JavaScript. I found these tantalising slides on Hack, an optional type system for PHP. However, it's just slides, and the project seems to be an internal one at Facebook at this time.
Does anyone know of anything better than these poor man's semantics? Or does everyone just "learn by example"?
It seems that you're not after an official standard (which might be useful, for example, to someone writing an independent conforming implementation), but for a presentation of the language that will allow you to make coherent sense of it. Unfortunately there cannot be such a thing, because PHP does not have a coherent formal model behind it. It has grown organically and is now saddled with inconsistencies, most notoriously in function and method naming but also in little details like what counts as true and false, and other similarly worrisome details.
The best one can do to approach PHP, in my opinion, is to get a good feel for the core features and libraries, for the "gotcha's" that you need to watch out for, and (in order to read existing code without distraction) for the anti-patterns that are all too common in real-world PHP scripts. My guess is that it's best to learn PHP under the tutelage of people who know how to work with it effectively, but I didn't have that luxury. (Regarding the documentation: It took me forever before I noticed that you can use square brackets to index into strings. The feature may be mentioned somewhere in the documentation, but not, back then at least, anyplace where it belongs.)
This article gives a nice tour of the kind of things that make a semantic model of the kind you want impossible. (You may want to skip the opening rant and go straight to the discussion of PHP features.) There are many, many other similar texts. Quote: "PHP was originally designed explicitly for non-programmers (and, reading between the lines, non-programs); it has not well escaped its roots."
Don't get me wrong: I work with PHP, and although it's not my favorite language, I wouldn't say I hate it. I would say that to work effectively with it, one must be aware of its nature and limitations. If you're coming to this from Haskell, you're in for quite a shock.
This answer comes a bit after your initial question, but now we finally have a formal semantics for PHP. Check it out: http://www.phpsemantics.org. A paper about it has been recently published in the ECOOP 2014 proceedings, if you are interested you can find the link in the webpage I linked. Regards.
Doesn't directly address your inquiry, but explains some of the magic behind PHP variables.
http://webandphp.com/how-php-manages-variables
Interesting question. I'd regard the manual as the official language reference; I appreciate it isn't quite "formal reference" in the sense you are seeking, but I don't know how much such a thing would be widely desired as something to learn from.
I'm not familiar with PHPWTF, but I'd guess it is in the same mould as the blog post Fractal Of Bad Design (linked by #alexis earlier). I can't peer into the mind of either author, but it seems to me that they are written from the perspective of wanting PHP to be bad. Religious wars frequently dominate on the internet and in programming — the browser you prefer, the IDE/editor you use, your operating system and your choice of framework have all had the same ferocious, partisan and unyielding treatment. Programming languages are, sadly, no different.
It is certainly true that PHP does have a number of design inconsistencies, in particular about how nulls are treated, and in the ordering of parameters in standard functions. However, it is also true that PHP has been hugely successful, despite all that. It spent a long time in the reliability doldrums in 5.0 and 5.1, 5.2 was stable but arguably not enterprise, and it's finally coming of age in 5.3 onwards.
Whilst this might be my biases emerging, I sense a consensus amongst users I read on Stack Overflow that all of the popular languages have their place. This is partly a response to the reality that the ones we dislike won't go away, and partly perhaps that learning .net, Java, Perl, Ruby, PHP, Python etc is pretty much always a good thing. Maybe we have also collectively tired of the flame-wars over each (Java is bloated, PHP is inconsistent, Microsoft is vendor lock-in, Rails is unstable, and so forth).
I've veered rather off-topic, but I tend to regard this particular viewpoint as worth reading, especially for those who would be traditionally minded to disagree with it in relation to PHP.
To address the purpose of your question, how should you learn? Well, learning by example is an excellent approach - one just needs to know which examples to learn. Searching for "PHP tutorial" and "PHP beginner" will — perhaps as is the case with any language — offer a mix of excellent and dreadful material. One might argue that PHP's low barriers to entry have given rise to a large stock of insecure and badly written "how to" articles, and I've certainly seen quite a few!
I think the solution is to look directly at code from well-engineered projects, and to learn from there. Such as:
Symfony2 (and Components)
Zend Framework
Guzzle
Propel
Doctrine
Ah, nearly forgot; this website is also a good place to start.
Post Script: they may be referred to by a different name in other languages, but I expect they all have variable functions. In JavaScript for example, it's object[myFunc]();, where myFunc is a string.
It's not exactly a formal semantics, but, after all these years, the HHVM project has produced a PHP specification!
Related
I'm a PHP developer. I like PHP! It is a really good language if you know how to use it, but I know it allows very bad design sometimes.
It reminds me of JavaScript which has good parts and bad parts. One particular project, CoffeeScript, tries to focus only on the good parts, forcing you to write good code.
I was thinking if something similar could be done with PHP... A new syntax that would be compiled only to good PHP code taking advatage of all the new and exciting stuff we can get with PHP 5.3.
So, getting ahead of some people, I'll ask: Why create a new language on top of PHP if you can just use Ruby or Python or something else?
PHP is easy to deploy anywhere
The language itself has a lot of good features and ideas
There are lots of good libraries written in PHP
...
So, my real questions here are...
Is this a stupid idea? Why would it be? Do you think CoffeeScript is stupid?
How do someone starts to create a new language on top of another? I know nothing about this, but I would like to learn. Where to start?
The idea is definitely not stupid, especially if executed well.
I like coffeescript a lot, but it has it's approach has downsides as well. Debugging a coffeescript script still requires you read the generated Javascript code, which can be tedious, since you haven't written it actually yourself.
I've understood that Jeremy Ashkenas, the creator of coffeescript has started to work on coffeescript after reading "Create your own freaking awesome programming language" by Marc-André Cournoyer.
Good luck!
The reason CoffeScript is a good idea is that if developers want to run code in a client browser they have to use javascript; so the only way to program in a different language is to allow that language to be convertible to javascript.
I'm not sure the same really applies to server side programming. If you've got issues with PHP and want to use a new language there is no real advantage to having that language generate PHP.
On the other hand, a language that was very similar to PHP, but fixed some of the flaws would be a great idea.
Heh, great idea. My thoughts, some contradictory...
There are precedents for civilizing bad languages by putting syntax preprocessors in front of them.
In the early days of Unix, Fortran was popular and about the only portable language because most machines had no C compiler. But the vanilla Fortran of the day didn't even have block structured if-then-else, just a goofy single-statement if or an if-goto. So, the Ratfor language was implemented as a preprocessor for Fortran-66.
I believe there were (are?) Cobol preprocessors that presumably dealt with the verbosity and limitations of early Cobol dialects.
To this day Unix-derived systems ship with a macro processor called m4.
Several CSS preprocessors are available today, most notably Sass and LESS.
But...
Just let it die, and the sooner the better
The problem isn't really in the syntax.
I don't see much of a JavaScript-PHP parallel. JavaScript is a great language. It's kind of the opposite of PHP.
I'm not sure why you say that PHP is a great language. It's one of the worst. Every decent feature is a patch or repatch in a recent version.
As you noted, there is a fixed-up version of PHP already: it's called Ruby and, as a language, it's near-perfect. There is another fixed-up version called Python. The world would be better off in the long run if we support the better systems.
It is here now. A new language which is to PHP what CoffeeScript is to Javascript. (I.e., awesome.)
SNOWSCRIPT
Snowscript code looks like this:
fn how_big_is_it(number)
if number < 100
<- "small"
else
<- "big"
PHP output looks like this:
function how_big_is_it($number) {
if ($number < 100) {
return "small";
} else {
return "big";
}
}
All it needs now, is you.
If it would be to PHP what something like sass is to CSS, I'd be interested. But what would exactly would you want to add? Or would you just want to weed out the bad?
And what would you consider to be the bad?
Writing a PHP syntax transformer would probably be a neat project.
However, don't forget that PHP's standard library is a huge mess. Cleaning that up, would be a far bigger task.
The more I am thinking about this, the more irrealistic it sounds. The reason is simple: There actually are such language proprocessors already. Two of them (though not using PHP as implementation, only as compilation target) can be found here. But simply nobody uses them.
Yes, if the compiler itself were written in PHP, probably more people would use it. But I really can't see a way how to get this popular enough to be worth the work.
Another big problem is, that people mostly are used to their awesome code-highlighting, code-completing, code-inspecting IDE. Without getting IDE support probably merely anybody will use it (and IDE support can only be obtained by having many people use it...)
Thoughts?
I can see writing compilers to JavaScript (because the web imposes it upon us), but this sounds like a waste of time.
Haxe already does this, although it's not specifically targeted at PHP (linked to the Wikipedia article instead of their website because I'm afraid I'm going to get exploited if I visit the real site...)
PHP is easy to deploy anywhere
...as are its vulnerabilities.
I know it allows very bad design sometimes.
That's a bit of an understatement, it doesn't even have a module system, has no encapsulation, and has tons of silly things such as dynamic name resolution.
PHP is slow enough as it is, do you really want something an order of a magnitude slower?
Java is much more easy to deploy anyways, and lets you drop down to the bytecode level if you want. Java also gives you access to moderately sane libraries.
This is something I have thought about already often. PHP just is messy at some points.
Actually, I already have a project PrePHP focusing on providing PHP 5.3 functionality to PHP 5.2. But it adds some minor language features, like func()[0]. I haven't developed this project for some time and it definitely isn't "clean", but it shows, that what you want is possible and actually even not that complicated.
If you are serious about this, I am perfectly willing to collaborate with you.
Very interesting idea and if it come to life i think that i wan't to be involved in :)
For start You may check and read this position http://www.amazon.com/Masterminds-Programming-Conversations-Creators-Languages/dp/0596515170 (iam reading it now). It makes clear how really complicated is to maintain own language.
I agree that PHP definitely could do with some improvement, right now it allows for too much fooling around.
Some things I'd like to see
Static Typing
Required indentation
Proper use of objects (using arrays as objects is just stupid)
Then again, maybe I should just drop PHP and start working with Ruby or Python.
I'm like 8 years too late, but I'll answer anyways for anyone else who stumbles upon this.
Hack is a language developed by Facebook to deal with some of the issues of PHP, since Facebook had a large PHP codebase. Hack adds some nice features on top of PHP such as gradual typing (what TypeScript has) and generics, among other features, and gets rid of some of the more dangerous PHP features. Hack was at one point a superset of PHP, but is no longer completely compatible after removing some of the worse PHP features.
This is slightly different from what you were asking, since at this point Hack has its own interpreter, written by Facebook, but this started out as "better language that compiles to PHP", so I thought it was worth mentioning here.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
The community reviewed whether to reopen this question 11 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I am setting out to do a side project that has the goal of translating code from one programming language to another. The languages I am starting with are PHP and Python (Python to PHP should be easier to start with), but ideally I would be able to add other languages with (relative) ease. The plan is:
This is geared towards web development. The original and target code will be be sitting on top of frameworks (which I will also have to write). These frameworks will embrace an MVC design pattern and follow strict coding conventions. This should make translation somewhat easier.
I am also looking at IOC and dependency injection, as they might make the translation process easier and less error prone.
I'll make use of Python's parser module, which lets me fiddle with the Abstract Syntax Tree. Apparently the closest I can get with PHP is token_get_all(), which is a start.
From then on I can build the AST, symbol tables and control flow.
Then I believe I can start outputting code. I don't need a perfect translation. I'll still have to review the generated code and fix problems. Ideally the translator should flag problematic translations.
Before you ask "What the hell is the point of this?" The answer is... It'll be an interesting learning experience. If you have any insights on how to make this less daunting, please let me know.
EDIT:
I am more interested in knowing what kinds of patterns I could enforce on the code to make it easier to translate (ie: IoC, SOA ?) the code than how to do the translation.
I've been building tools (DMS Software Reengineering Toolkit) to do general purpose program manipulation (with language translation being a special case) since 1995, supported by a strong team of computer scientists. DMS provides generic parsing, AST building, symbol tables, control and data flow analysis, application of translation rules, regeneration of source text with comments, etc., all parameterized by explicit definitions of computer languages.
The amount of machinery you need to do this well is vast (especially if you want to be able to do this for multiple languages in a general way), and then you need reliable parsers for languages with unreliable definitions (PHP is perfect example of this).
There's nothing wrong with you thinking about building a language-to-language translator or attempting it, but I think you'll find this a much bigger task for real languages than you expect. We have some 100 man-years invested in just DMS, and another 6-12 months in each "reliable" language definition (including the one we painfully built for PHP), much more for nasty languages such as C++. It will be a "hell of a learning experience"; it has been for us. (You might find the technical Papers section at the above website interesting to jump start that learning).
People often attempt to build some kind of generalized machinery by starting with some piece of technology with which they are familiar, that does a part of the job. (Python ASTs are great example). The good news, is that part of the job is done. The bad news is that machinery has a zillion assumptions built into it, most of which you won't discover until you try to wrestle it into doing something else. At that point you find out the machinery is wired to do what it originally does, and will really, really resist your attempt to make it do something else. (I suspect trying to get the Python AST to model PHP is going to be a lot of fun).
The reason I started to build DMS originally was to build foundations that had very few such assumptions built in. It has some that give us headaches. So far, no black holes. (The hardest part of my job over the last 15 years is to try to prevent such assumptions from creeping in).
Lots of folks also make the mistake of assuming that if they can parse (and perhaps get an AST), they are well on the way to doing something complicated. One of the hard lessons is that you need symbol tables and flow analysis to do good program analysis or transformation. ASTs are necessary but not sufficient. This is the reason that Aho&Ullman's compiler book doesn't stop at chapter 2. (The OP has this right in that he is planning to build additional machinery beyond the AST). For more on this topic, see Life After Parsing.
The remark about "I don't need a perfect translation" is troublesome. What weak translators do is convert the "easy" 80% of the code, leaving the hard 20% to do by hand. If the application you intend to convert are pretty small, and you only intend to convert it once well, then that 20% is OK. If you want to convert many applications (or even the same one with minor changes over time), this is not nice. If you attempt to convert 100K SLOC then 20% is 20,000 original lines of code that are hard to translate, understand and modify in the context of another 80,000 lines of translated program you already don't understand. That takes a huge amount of effort. At the million line level, this is simply impossible in practice. (Amazingly there are people that distrust automated tools and insist on translating million line systems by hand; that's even harder and they normally find out painfully with long time delays, high costs and often outright failure.)
What you have to shoot for to translate large-scale systems is high nineties percentage conversion rates, or it is likely that you can't complete the manual part of the translation activity.
Another key consideration is size of code to be translated. It takes a lot of energy to build a working, robust translator, even with good tools. While it seems sexy and cool to build a translator instead of simply doing a manual conversion, for small code bases (e.g., up to about 100K SLOC in our experience) the economics simply don't justify it. Nobody likes this answer, but if you really have to translate just 10K SLOC of code, you are probably better off just biting the bullet and doing it. And yes, that's painful.
I consider our tools to be extremely good (but then, I'm pretty biased). And it is still very hard to build a good translator; it takes us about 1.5-2 man-years and we know how to use our tools. The difference is that with this much machinery, we succeed considerably more often than we fail.
My answer will address the specific task of parsing Python in order to translate it to another language, and not the higher-level aspects which Ira addressed well in his answer.
In short: do not use the parser module, there's an easier way.
The ast module, available since Python 2.6 is much more suitable for your needs, since it gives you a ready-made AST to work with. I've written an article on this last year, but in short, use the parse method of ast to parse Python source code into an AST. The parser module will give you a parse tree, not an AST. Be wary of the difference.
Now, since Python's ASTs are quite detailed, given an AST the front-end job isn't terribly hard. I suppose you can have a simple prototype for some parts of the functionality ready quite quickly. However, getting to a complete solution will take more time, mainly because the semantics of the languages are different. A simple subset of the language (functions, basic types and so on) can be readily translated, but once you get into the more complex layers, you'll need heavy machinery to emulate one language's core in another. For example consider Python's generators and list comprehensions which don't exist in PHP (to my best knowledge, which is admittedly poor when PHP is involved).
To give you one final tip, consider the 2to3 tool created by the Python devs to translate Python 2 code to Python 3 code. Front-end-wise, it has most of the elements you need to translate Python to something. However, since the cores of Python 2 and 3 are similar, no emulation machinery is required there.
Writing a translator isn't impossible, especially considering that Joel's Intern did it over a summer.
If you want to do one language, it's easy. If you want to do more, it's a little more difficult, but not too much. The hardest part is that, while any turing complete language can do what another turing complete language does, built-in data types can change what a language does phenomenally.
For instance:
word = 'This is not a word'
print word[::-2]
takes a lot of C++ code to duplicate (ok, well you can do it fairly short with some looping constructs, but still).
That's a bit of an aside, I guess.
Have you ever written a tokenizer/parser based on a language grammar? You'll probably want to learn how to do that if you haven't, because that's the main part of this project. What I would do is come up with a basic Turing complete syntax - something fairly similar to Python bytecode. Then you create a lexer/parser that takes a language grammar (perhaps using BNF), and based on the grammar, compiles the language into your intermediate language. Then what you'll want to do is do the reverse - create a parser from your language into target languages based on the grammar.
The most obvious problem I see is that at first you'll probably create horribly inefficient code, especially in more powerful* languages like Python.
But if you do it this way then you'll probably be able to figure out ways to optimize the output as you go along. To summarize:
read provided grammar
compile program into intermediate (but also Turing complete) syntax
compile intermediate program into final language (based on provided grammar)
...?
Profit!(?)
*by powerful I mean that this takes 4 lines:
myinput = raw_input("Enter something: ")
print myinput.replace('a', 'A')
print sum(ord(c) for c in myinput)
print myinput[::-1]
Show me another language that can do something like that in 4 lines, and I'll show you a language that's as powerful as Python.
There are a couple answers telling you not to bother. Well, how helpful is that? You want to learn? You can learn. This is compilation. It just so happens that your target language isn't machine code, but another high-level language. This is done all the time.
There's a relatively easy way to get started. First, go get http://sourceforge.net/projects/lime-php/ (if you want to work in PHP) or some such and go through the example code. Next, you can write a lexical analyzer using a sequence of regular expressions and feed tokens to the parser you generate. Your semantic actions can either output code directly in another language or build up some data structure (think objects, man) that you can massage and traverse to generate output code.
You're lucky with PHP and Python because in many respects they are the same language as each other, but with different syntax. The hard part is getting over the semantic differences between the grammar forms and data structures. For example, Python has lists and dictionaries, while PHP only has assoc arrays.
The "learner" approach is to build something that works OK for a restricted subset of the language (such as only print statements, simple math, and variable assignment), and then progressively remove limitations. That's basically what the "big" guys in the field all did.
Oh, and since you don't have static types in Python, it might be best to write and rely on PHP functions like "python_add" which adds numbers, strings, or objects according to the way Python does it.
Obviously, this can get much bigger if you let it.
I will second #EliBendersky point of view regarding using ast.parse instead of parser (which I did not know about before). I also warmly recommend you to review his blog. I used ast.parse to do Python->JavaScript translator (#https://bitbucket.org/amirouche/pythonium). I've come up with Pythonium design by somewhat reviewing other implementations and trying them on my own. I forked Pythonium from https://github.com/PythonJS/PythonJS which I also started, It's actually a complete rewrite . The overall design is inspired from PyPy and http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-89-1.pdf paper.
Everything I tried, from beginning to the best solution, even if it looks like Pythonium marketing it really isn't (don't hesitate to tell me if something doesn't seem correct to the netiquette):
Implement Python semantic in Plain Old JavaScript using prototype inheritance: AFAIK it's impossible to implement Python multiple inheritance using JS prototype object system. I did try to do it using other tricks later (cf. getattribute). As far as I know there is no implementation of Python multiple inheritance in JavaScript, the best that exists is Single inhertance + mixins and I'm not sure they handle diamond inheritance. Kind of similar to Skulpt but without google clojure.
I tried with Google clojure, just like Skulpt (compiler) instead of actually reading Skulpt code #fail. Anyway because of JS prototype based object system still impossible. Creating binding was very very difficult, you need to write JavaScript and a lot of boilerplate code (cf. https://github.com/skulpt/skulpt/issues/50 where I am the ghost). At that time there was no clear way to integrate the binding in the build system. I think that Skulpt is a library and you just have to include your .py files in the html to be executed, no compilation phase required to be done by the developer.
Tried pyjaco (compiler) but creating bindings (calling Javascript code from Python code) was very difficult, there was too much boilerplate code to create every time. Now I think pyjaco is the one that more near Pythonium. pyjaco is written in Python (ast.parse too) but a lot is written in JavaScript and it use prototype inheritance.
I never actually succeed at running Pyjamas #fail and never tried to read the code #fail again. But in my mind PyJamas was doing API->API tranlation (or framework to framework) and not Python to JavaScript translation. The JavaScript framework consume data that is already in the page or data from the server. Python code is only "plumbing". After that I discovered that pyjamas was actually a real python->js translator.
Still I think it's possible to do API->API (or framework->framework) translation and that's basicly what I do in Pythonium but at lower level. Probably Pyjamas use the same algorithm as Pythonium...
Then I discovered brython fully written in Javascript like Skulpt, no need for compilation and lot of fluff... but written in JavaScript.
Since the initial line written in the course of this project, I knew about PyPy, even the JavaScript backend for PyPy. Yep, you can, if you find it, directly generate a Python interpreter in JavaScript from PyPy. People say, it was a disaster. I read no where why. But I think the reason is that the intermediate language they use to implement the interpreter, RPython, is a subset of Python tailored to be translated to C (and maybe asm). Ira Baxter says you always make assumptions when you build something and probably you fine tune it to be the best at what it's meant to do in the case of PyPy: Python->C translation. Those assumptions might not be relevant in another context worse they can infere overhead otherwise said direct translation will most likely always be better.
Having the interpreter written in Python sounded like a (very) good idea. But I was more interested in a compiler for performance reasons also it's actually more easy to compile Python to JavaScript than interpret it.
I started PythonJS with the idea of putting together a subset of Python that I could easily translate to JavaScript. At first I didn't even bother to implement OO system because of past experience. The subset of Python that I achieved to translate to JavaScript are:
function with full parameters semantic both in definition and calling. This is the part I am most proud of.
while/if/elif/else
Python types were converted to JavaScript types (there is no python types of any kind)
for could iterate over Javascript arrays only (for a in array)
Transparent access to JavaScript: if you write Array in the Python code it will be translated to Array in javascript. This is the biggest achievement in terms of usability over its competitors.
You can pass function defined in Python source to javascript functions. Default arguments will be taken into account.
It add has special function called new which is translated to JavaScript new e.g: new(Python)(1, 2, spam, "egg") is translated to "new Python(1, 2, spam, "egg").
"var" are automatically handled by the translator. (very nice finding from Brett (PythonJS contributor).
global keyword
closures
lambdas
list comprehensions
imports are supported via requirejs
single class inheritance + mixin via classyjs
This seems like a lot but actually very narrow compared to full blown semantic of Python. It's really JavaScript with a Python syntax.
The generated JS is perfect ie. there is no overhead, it can not be improved in terms of performance by further editing it. If you can improve the generated code, you can do it from the Python source file too. Also, the compiler did not rely on any JS tricks that you can find in .js written by http://superherojs.com/, so it's very readable.
The direct descendant of this part of PythonJS is the Pythonium Veloce mode. The full implementation can be found # https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/veloce/veloce.py?at=master 793 SLOC + around 100 SLOC of shared code with the other translator.
An adapted version of pystones.py can be translated in Veloce mode cf. https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pystone/?at=master
After having setup basic Python->JavaScript translation I choosed another path to translate full Python to JavaScript. The way of glib doing object oriented class based code except the target language is JS so you have access to arrays, map-like objects and many other tricks and all that part was written in Python. IIRC there is no javascript code written by in Pythonium translator. Getting single inheritance is not difficult here are the difficult parts making Pythonium fully compliant with Python:
spam.egg in Python is always translated to getattribute(spam, "egg") I did not profile this in particular but I think that where it loose a lot of time and I'm not sure I can improve upon it with asm.js or anything else.
method resolution order: even with the algorithm written in Python, translating it to Python Veloce compatible code was a big endeavour.
getattributre: the actual getattribute resolution algorithm is kind of tricky and it still doesn't support data descriptors
metaclass class based: I know where to plug the code, but still...
last bu not least: some_callable(...) is always transalted to "call(some_callable)". AFAIK the translator doesn't use inference at all, so every time you do a call you need to check which kind of object it is to call it they way it's meant to be called.
This part is factored in https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/compliant/runtime.py?at=master It's written in Python compatible with Python Veloce.
The actual compliant translator https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/compliant/compliant.py?at=master doesn't generate JavaScript code directly and most importantly doesn't do ast->ast transformation. I tried the ast->ast thing and ast even if nicer than cst is not nice to work with even with ast.NodeTransformer and more importantly I don't need to do ast->ast.
Doing python ast to python ast in my case at least would maybe be a performance improvement since I sometime inspect the content of a block before generating the code associated with it, for instance:
var/global: to be able to var something I must know what I need to and not to var. Instead of generating a block tracking which variable are created in a given block and inserting it on top of the generated function block I just look for revelant variable assignation when I enter the block before actually visiting the child node to generate the associated code.
yield, generators have, as of yet, a special syntax in JS, so I need to know which Python function is a generator when I want to write the "var my_generator = function"
So I don't really visit each node once for each phase of the translation.
The overall process can be described as:
Python source code -> Python ast -> Python source code compatible with Veloce mode -> Python ast -> JavaScript source code
Python builtins are written in Python code (!), IIRC there is a few restrictions related to bootstraping types, but you have access to everything that can translate Pythonium in compliant mode. Have a look at https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/compliant/builtins/?at=master
Reading JS code generated from pythonium compliant can be understood but source maps will greatly help.
The valuable advice I can give you in the light of this experience are kind old farts:
extensively review the subject both in literature and existing projects closed source or free. When I reviewed the different existing projects I should have given it way more time and motivation.
ask questions! If I knew beforehand that PyPy backend was useless because of the overhead due to C/Javascript semantic mismatch. I would maybe had Pythonium idea way before 6 month ago maybe 3 years ago.
know what you want to do, have a target. For this project I had different objectives: pratice a bit a javascript, learn more of Python and be able to write Python code that would run in the browser (more and that below).
failure is experience
a small step is a step
start small
dream big
do demos
iterate
With Python Veloce mode only, I'm very happy! But along the way I discovered that what I was really looking for was liberating me and others from Javascript but more importantly being able to create in a comfortable way. This lead me to Scheme, DSL, Models and eventually domain specific models (cf. http://dsmforum.org/).
About what Ira Baxter response:
The estimations are not helpful at all. I took me more or less 6 month of free time for both PythonJS and Pythonium. So I can expect more from full time 6 month. I think we all know what 100 man-year in an enterprise context can mean and not mean at all...
When someone says something is hard or more often impossible, I answer that "it only takes time to find a solution for a problem that is impossible" otherwise said nothing is impossible except if it's proven impossible in this case a math proof...
If it's not proven impossible then it leaves room for imagination:
finding a proof proving it's impossible
and
If it is impossible there may be an "inferior" problem that can have a solution.
or
if it's not impossible, finding a solution
It's not just optimistic thinking. When I started Python->Javascript everybody was saying it was impossible. PyPy impossible. Metaclasses too hard. etc... I think that the only revolution that brings PyPy over Scheme->C paper (which is 25 years old) is some automatic JIT generation (based hints written in the RPython interpreter I think).
Most people that say that a thing is "hard" or "impossible" don't provide the reasons. C++ is hard to parse? I know that, still they are (free) C++ parser. Evil is in the detail? I know that. Saying it's impossible alone is not helpful, It's even worse than "not helpful" it's discouraging, and some people mean to discourage others. I heard about this question via https://stackoverflow.com/questions/22621164/how-to-automatically-generate-a-parser-code-to-code-translator-from-a-corpus.
What would be perfection for you? That's how you define next goal and maybe reach the overall goal.
I am more interested in knowing what kinds of patterns I could enforce
on the code to make it easier to translate (ie: IoC, SOA ?) the code
than how to do the translation.
I see no patterns that can not be translated from one language to another language at least in a less than perfect way. Since language to language translation is possible, you'd better aim for this first. Since, I think according to http://en.wikipedia.org/wiki/Graph_isomorphism_problem, translation between two computer languages is a tree or DAG isomorphism. Even if we already know that they are both turing complete, so...
Framework->Framework which I better visualize as API->API translation might still be something that you might keep in mind as a way to improve the generated code. E.g: Prolog as very specific syntax but still you can do Prolog like computation by describing the same graph in Python... If I was to implement a Prolog to Python translator I wouldn't implement unification in Python but in a C library and come up with a "Python syntax" that is very readable for a Pythonist. In the end, syntax is only "painting" for which we give a meaning (that's why I started scheme). Evil is in the detail of the language and I'm not talking about the syntax. The concepts that are used in the language getattribute hook (you can live without it) but required VM features like tail-recursion optimisation can be difficult to deal with. You don't care if the initial program doesn't use tail recursion and even if there is no tail recursion in the target language you can emulate it using greenlets/event loop.
For target and source languages, look for:
Big and specific ideas
Tiny and common shared ideas
From this will emerge:
Things that are easy to translate
Things that are difficult to translate
You will also probably be able to know what will be translated to fast and slow code.
There is also the question of the stdlib or any library but there is no clear answer, it depends of your goals.
Idiomatic code or readable generated code have also solutions...
Targeting a platform like PHP is much more easy than targeting browsers since you can provide C-implementation of slow and/or critical path.
Given you first project is translating Python to PHP, at least for the PHP3 subset I know of, customising veloce.py is your best bet. If you can implement veloce.py for PHP then probably you will be able to run the compliant mode... Also if you can translate PHP to the subset of PHP you can generate with php_veloce.py it means that you can translate PHP to the subset of Python that veloce.py can consume which would mean that you can translate PHP to Javascript. Just saying...
You can also have a look at those libraries:
https://bitbucket.org/logilab/astroid
https://bitbucket.org/logilab/pylint-brain
Also you might be interested by this blog post (and comments): https://www.rfk.id.au/blog/entry/pypy-js-poc-jit/
This Google Tech Talk from Ira Baxter is interesting https://www.youtube.com/watch?v=C-_dw9iEzhA
You could take a look at the Vala compiler, which translates Vala (a C#-like language) into C.
Somebody said that when your PHP code and application use global variables then it must be spaghetti code (I assume this). I use WordPress a lot. As far as I know, it's the best thing near great PHP software. And it uses many global variables to interact between its components.
But forget about that, because frankly, that's the only thing I know. So it's completely biased ;D
So, I am just curious, What is the characteristic of spaghetti code?
PS: the only thing I know is WordPress. So, hopefully, maybe this will help somebody give a great answer for somebody who has little experience in developing a full web application on PHP (for example, the Stack Overflow website).
No modularity (everything in one file, class, module, namespace, package, or whatever your language uses to provide modularity),
Plenty of goto's,
Poor organization,
No clear separation of functionality and purpose. (That is, all-encompassing classes or functions)
Long functions.
Poor naming.
No consistent coding style throughout.
No clear interface contract between implementation and clients of code. (That is, no specification of what the inputs, outputs, pre- and post-conditions of functions are)
Over-reliance on internals of data structures with little abstraction.
Functions randomly permute/modify global state without any mention of it in documentation.
Lack of comments or documentation of non-trivial code.
Code that is more complicated than it needs to be.
Lack of reuse. (plenty of duplicated code, a.k.a. copypasta)
No verification or unit testing (it works on faith).
Magic numbers.
In essence, a lack of design and
forethought, and just a mishmash of
hacks slapped together. This applies to any language, not just PHP.
for somebody who has little experience in developing a full web application on PHP (for example, the Stack Overflow website)
Just FYI, but Stack Overflow was not developed with PHP.
Well, talking of comment you posted, the explanation is very simple.
Using global operator makes source of a variable is unknown, like other end of spaghetti noodle. It can be defined everywhere. So, when you call your function, you have no idea what value this variable has. Instead of it, direct passing a variable makes it plain and clear:
function hello_testing($conditional_random) {
if ($conditional_random)) {
echo "foo is inside";
}
}
P.S. http://en.wikipedia.org/wiki/Spaghetti_code
Spaghetti code has specific characteristics which distinguish it from plain poor code. Spaghetti is extremely complicated and unstructured, so it is hard to follow the flow of a process through the program. It is like trying to untangle the noodles in a bowl of bolognese.
This is why GOTO statements (dread word!) are often cited in this context: a GOTO statement transfers control to another arbitrarily defined location in the code base. Most programming languages have commands which can be abused to simulate goto style behaviour; for instance, using exceptions to implement regular business logic rather than handling errors.
Global variables contribute to spaghetti code because the values are assigned outside of the scope of the current program unit. This can make it difficult to determine where in the code base a variable is set to a given value (or indeed whether it is set to any value at all).
Spaghetti code can be functionally correct and performative. It's a problem because it's hard to understand, so we can't be sure it is bug free and the lack of structure makes it difficult to troubleshoot. For similar reasons spaghetti code is brittle and difficult to change; the risk of introducing a bug is high.
Incidentally, the use of goto statements does not mean a program is spaghetti. It is perfectly possible to write clear, well-structured code using goto, it is just requires a lot of self-discipline not to abuse its flexibility. Modern programming languages have made its use unnecessary, and undesirable.
WordPress is the biggest piece of spaghetti code PHP I have seen around. There is a shocking mix of PHP, HTML, JavaScript and all things in between all lumped in the same files. If you want another example of spaghetti code look at osCommerce or Zen Cart.
In fact I dare say a large majority of open source PHP applications are pretty shocking examples of how to program in PHP. If you want to look at a good structured example (that is, non-spaghetti) then look at Yii framework or Zend Framework. Frameworks like CodeIgniter and Kohana, although not spaghetti, are not very good examples of how to structure things in PHP 5 as they use many of the features used in PHP 4 simply because there was no better way of doing them until PHP 5 (for example, using path based inheritance instead of true object inheritance).
If you want a reasonbly good example of procedural programming done right look at Drupal. It might not be the best performing PHP application, because of the complexity, but it sure beats WordPress and you can do many of the same things with it.
I'm working with a PHP developer who is, shall we say, unhappy with .NET. His complaints include having to rebuild the web application solution for every test (though I pointed out that this is usually only necessary if a .cs file has been changed, not interface .aspx files), having to include every file in the solution that is required to be deployed, etc.
I've pointed out a number of advantages of the compiled model including RTTI (reflection), source code integrity (source isn't deployed to the server, keeping meddlesome IT people from modifying it on-the-fly), performance differences (though he insists that this isn't valid since PHP is now "compiled"), etc. What are some other advantages of .NET over PHP? This may incite a religious debate - please God, no - but I'm such a fan of .NET that some of these questions which I asked years ago seem so silly that I can't articulate a valid response.
There also seem to be significant differences in the way in which he goes about developing a page. For instance, declaring a class which represents part of a page - say, a particular column in a 3-column layout - rather than breaking up the code in a more logical fashion and relying on the .aspx to handle layout. It strikes me as odd that page layout would, in any way, be tied to class structure beyond that of the code-behind for a aspx page.
Comments?
UPDATE BTW, this is an old question, but I felt it necessary to update with a few points:
Optimization This is a big one. Compilation provides the opportunity to perform some optimizations that aren't practical to perform during the JIT.
The article that o.k.w referred to is so obviously biased and created by someone that hasn't worked a significant time in .NET that it's hardly worth reading, (though I did). It also makes points that are entirely incorrect.
It's damn near impossible to make Mac people realize that Windows has its place. On the other hand, most Windows guys I know think that Macs are great for a lot of things. Most even own one. We don't use them for developing websites or embedded systems for a reason. (And, yes, our business involves both, intimately.)
First loves gone bad... excellent analogy. This will probably come out of my mouth in a meeting sometime soon.
This debate is useless. I may as well try and convince the UK to drive on the correct side of the road. And Australia. And Hong Kong. And... you see where this is going.
Cheers.
I work with both languages daily, and both are great for development. It's hard to get into the "compiled vs. interpreted" debate without getting all flamey and zealous, so I don't think I'll say anything about that. However, here are some of things I prefer about .Net:
Visual Studio vs. Eclipse.
No #includes, and real namespaces. I want to know about my types all the time, and not rely on weird hacky autoloading routines.
API discoverability. PHP has horrible, inconsistent API naming.
Compile time checking and code analysis
Superior debuggers and profilers
This isn't really anything to do with the models they use though, it's just attributes of the tools themselves. I wouldn't suggest trying to change his mind or even arguing with him about it - he'll either see the advantages himself or he won't, but pushing them on him will probably just make it take longer ;)
From what I understand (not having worked much in PHP myself) PHP is both powerful and easy to use, and really shines on smaller, simpler projects, particularly where the business logic consists mostly of moving content between a database and a web page. ASP.NET lends itself better to larger, more business-logic-intensive applications, where the compile-time checks allow you to catch errors sooner. Catching an error at compile time versus run time can make an order of magnitude of difference in how much time it takes to fix.
Where I work, we use PHP to build mockups to show customers and get them to sign off on our ideas, and then we write the actual product in a compiled language like .NET or Java, since that's the code we'll need to maintain for the next decade or more.
The primary issue is that, almost any advantages you can come up with for .Net can be achieved with PHP if a framework exists for it. I believe there are PHP MVC frameworks.
However, I will say this about the compilation model for ASP.Net, it's extremely helpful to know that there are no syntactical errors in all your code behind code. PHP and ASP Classic didn't have this. In a site of 400+ pages it was difficult to know which ones were and weren't functional with a degree of certainty.
Why are so many people still writing crappy versions of things in standard libraries? Not to go after PHP developers, but guys go read the PHP SPL
Peer review can help catch that kind of thing. If you have another developer looking at the code, and they continually find implementations of standard library methods, it should fail the review unless there's a good reason for reinventing the wheel.
Young, ambitious programmers like to solve every problem on their own. They don't need no stinkin' libraries. Older, lazy programmers would rather search for existing solutions to the problem at hand.
So my advice: the next time you hire a programmer, choose the old guy who falls asleep in the reception area.
Just kidding, mostly. Peer review and education is the answer.
Better search techniques. and Domain Specific Familiarity
How does a developer check for a function they dont know the name of? Or perhaps there isnt an EXACT built in function to do what they want, but something they can use to save a lot of code. You need to be able to find the right terminology for the problem at hand, and from there you know what to search for. This is best achived by reading topics specific to your problem domain. Get away from coding specific resources and spend sometime in the field which you are coding for... wether it be retail, medical, insurance, etc.
Summary: Assumption is the mother of all FUBARs
I see this a lot from colleagues who are unfamiliar with the concept of frameworks (god how they complain about "two languages in one"), to wit: old C++ guys suddenly confronted with C# diving in head first to recreate hashtables from scratch...
Clearly a big part of this phenomenon from that angle is not stepping out of old mindsets and habits. If you're in a new environment you need to learn the new rules. The only way to deal with that from the outside looking in is to provide training, whether that's pair-programming for a while or something more formal.
Lack of familiarity with your tools breeds the contempt of others.
A simple coding style document might help by reminding the devs that there are libraries available (maybe list some preferred) and that they should be familiar with them.
Sometimes, you just have to remind people.
A peer review would help.
PHP is well documented if and only if, you know exactly what you're looking for. For example, you'd open Arrays and Array functions sections to see what you can do with arrays. And guess what, there is not even mention of SPL.
You should also encourage research before actually setting out on writing code. I usually approach problems by thinking about a way to do it, then I try to find anything in the standard library or any other libraries that will help me out. I'd say that an hour of research in some cases can be worth days of coding.
If people aren't doing this, it may be a good idea to have someone ask them questions about their general approach to the problem and what library functions/classes they are thinking about using. If they're missing something obvious, suggest it to them.
Two reasons pop to mind quickly. First, the Standard PHP Library isn't WELL known, and suffers from poor documentation. The php.net website is widely considered the language's best asset, but a lot of the newer built in classes (such as the SPL, reflection API, DomDocument, etc.) are little more than a list of methods without a lot of context.
More importantly though, it looks like the full SPL never shipped by default with any version of PHP prior to the (unreleased) 5.3. This is a killer as far as adoption goes. Usually people writing PHP code don't have control over what gets complied into their PHP binary. That's handled by their web-host and/or operations team, and web hosts and/or operations teams have different goals than a developer and aren't going to install every optional extension that comes along. This also means projects like Drupal, Joomla, Wordpress, etc. can't rely on the SPL being installed everywhere, so they don't use it.
Part of the reason PHP "won out" over perl was a single install had everything you ever needed. Optional extensions have never become widely adopted until they became part of the base install.
Very hard question to answer. Obviously peer review helps, but also proper documentation. Do your projects have technical specs, where you map out the classes and intefaces to be created?
If so, someone else on the team should review the specs and point out where existing code could be used...
Agree with training and peer review, but also enforcing unit testing and code documentation should help with the NIH syndrome :)