jMar"s Blog DevSmash Developer Portal

Thursday, May 1, 2008

Why PHP and JavaScript IDE's Suck

Few things fire up an engineer faster than over generalizations, criticizing a favorite language, or attacking their favorite IDE. So I'm off to a good start. Oh ya, my mom hates that word too (sorry Mom)!

However, interestingly enough, this fact (just concede for now) is not the fault of the given language, or even the IDE developers. So who's fault is it? In truth, no ones. It's really more of a bi-product of these languages themselves (and as we'll see, many other languages (such as Perl) could be thrown into this bunch as well). In fact, the same IDE, such as Eclipse, can be outstanding with a language like Java, yet be rather disappointing when it comes to PHP.

So before we go any further, I need to lay out a tighter definition for "suck". I'll admit that it's too broad a stroke, albeit attention getting. If I had to pick one single feature that makes or breaks an IDE for me, it would be autocomplete (or Intellisense for you Visual Studio people). The frameworks and libraries that we use today are simply too big to try and remember every single class/object member, and it's just too slow to go sifting through the documentation every two minutes. Nothing speeds up my productivity like being able to press Ctrl + Space and voila - there are my options. Therefore, to me, and for the purposes of this discussion, any IDE that doesn't have autocomplete that's up to snuff, sucks.

Thus far, the languages that I've interacted with the most are Java, PHP, C#, C++, JavaScript, and I've dabbled with Object Pascal. I'd consider myself a jack-of-some, master-of-none. In the bizarre scenario where I had to put each of these languages into one of two buckets at gun point (me, not the buckets), I would divide them based on this single comparison: strongly-typed versus loosely-typed.

Interestingly enough, if I compared them based on their respective "IDE suckiness", they'd end up in the same buckets. Why is that? Well, as I've already implied, there's a strong correlation between how a language is typed, and how effectively an IDE can offer suggestions from a given context. In contrast to a loosely typed language, a strongly typed language can make some guarantees about what a variable holds.

For example, if I'm working on a Java application in Eclipse, I can use autocomplete to inspect the members of my current object, like this:

Eclipse Screenshot

Most conveniently, all of my autocomplete options are relevant to my Person object. Eclipse can do this because in Java, once I declare jMar as a Person, it now has a guarantee that jMar is and always will be a Person. This guarantee holds true for other strongly typed languages as well, which provides their respective IDE's with the same promise.

Now let's say I'm working on a PHP application in Dreamweaver. If I reproduce the equivilent Java code from above, my "autocomplete" options are really just a list of every function defined in the PHP5 documentation.

Dreamweaver Screenshot

Slightly more helpful than nothing, but it's far short of I had before - not to mention that this gives me no insight into the members of my Person class. But don't hate Dreamweaver - what else can it do? Remember - when you're coding in PHP, you're not making any guarantees as to what a variable holds.

Consider the following perfectly legal PHP code:

class FirstClass {
 ...
}

class SecondClass {
 ...
}

$foo = new FirstClass(); // $foo is now a FirstClass
$foo = new SecondClass(); // $foo is now a SecondClass
$foo = "bar"; // $foo is now a string
$foo = true; // $foo is now a boolean
$foo = 777; // $foo is now an int

No wonder the autocomplete isn't much help. And this is the exact same scenario for JavaScript, Perl, and other loosely typed languages.

I know I've personally been frustrated on numerous occasions with the apparent "lack of effort" being given to autocomplete with regards to these widely used languages; however, after pondering some of the fundamental obsticles that the IDE developers are facing, I can understand how the feature set is impacted by the target language. I suppose an article can only be so valuable without offering some sort of a solution, but just consider this a "state of affairs" on the IDE world, and thanks for reading!



23 comments:

leonsp said...

This isn't a hard problem to solve. One just needs to keep track of more information.

PHP Development Tools for Eclipse does a decent job, for instance.

Jeremy Martin said...

@leonsp
It's true that improvements can be made in some areas, but there is a hard fast wall that these IDE's run up against. For example, consider the following PHP snippet:

if($_SESSION['foo'] == bar) {
$x = false;
} else {
$x = new Person();
}

The data type of $x upon leaving this conditional can only be determined at runtime - even in this simplest of cases, the IDE only has a 50/50 chance of getting it right.

Paul said...

The new NetBeans support for javascript autocomplete is apparently pretty impressive.

http://blogs.sun.com/tor/entry/javascript_type_inference

Jeremy Martin said...

@Paul
Wow - that does look very promising. Unfortunately, though, it still relies on comments in the code. Try using that on a packed script!

GUEBRE GILDAS said...

i'm still using zend studio 5.2 ...
and the autocomplete can browse ur classes ...

Jeremy Martin said...

@Guebre
I assume you mean from a static context? If it can do this on instance variables, I would like to check it out...

Nick Aceves said...

I hate to nit-pick, but I think by loosely-typed you mean dynamic. Loose vs. strong typing is an argument that you don't want to touch with a ten foot pole, because those terms mean different things to different people. Static and dynamic are well-defined.

That said, I think there's quite a bit more that can be done to improve the quality of IDEs for dynamic languages. Take the following, for example:

if($_SESSION['foo'] == bar) {
$x = false;
/* here, the ide should be able to figure out that $x is a boolean */
} else {
$x = new Person();
/* here, the ide should be able to figure out that $x is a Person */
}
/* here, the ide should be able to figure out that $x is either a boolean or a Person, and can display options for both */

On-the-fly code analysis is really the only way to do this. This field still seems to be in its infancy (at least when it comes to implementing it within an IDE), but great progress is being made.

As dynamic languages gain more popularity, our IDEs will evolve. For certain problem classes, the benefits of using a dynamic language outweigh those of static languages, even though static languages currently make it easier to develop a good IDE.

Jeremy Martin said...

@Nick
Good to see you on here! I should know to be more careful with smarter people like you out there...

Anyway, I would have to agree with you that "dynamic" would be a better categorization, since that not only implies loose typing, but also the possibility of class augmentation and the like (which would also be relevant to this discussion).

However, I think you would be embarking on a computational nightmare in trying to parse out all the possible "types" for a instance variable at a given point. For example:

$foo = get_bar();

Now you have to go inspect get_bar(), and any methods that it calls. You could always just put a limit on the "depth of analysis", but that limit would have to be sufficiently deep to allow for some of the more complex frameworks out there with levels upon levels of abstraction.

And of course, going back to augmentation, you don't even have a guarantee that the runtime definition of a class matches the code time definition.

Anyway, I certainly agree that this field is in it's infancy, and it will be interesting to see how the IDE developers address it. I would be unforgivably naive to declare this as a hopeless cause...

Matt said...

i think there is a problem with your php example screenshot. '.' is the concatenation operator, so of course after a period it will try to show every function because it has nothing to base a suggestion on. try '->' instead.

alexbl said...

So, I'm going to take a stab at this one:

$foo = get_bar();

You raise the point that doing the inference here is a very expensive operation as the depth increases. I would suggest you consider statically typed languages like Haskell or O'Caml that use type inference to determine the type of a variable, usually some variation on Hendley-Milner (http://en.wikipedia.org/wiki/Type_inference).

This technique makes it possible to calculate the return type(s) of a function (in the case of a more dynamic language we'd want to deal with types) in a rather quick way. If we can assure the runtime consistency of a function we can even memoize that result.

Moving beyond these more static-typing methods (which still work for some instances of this case) one can also look at what Self did to speed up execution. You can read papers on many of the techniques the Self folks used at: http://research.sun.com/self/papers/papers.html , particularly in the Implementation and Type Inference sections. Self is much like Javascript in that it's a prototypical-OO language that is massively dynamic. The self folks realized, that though they had a high degree of dynamism, in many cases they could do some type inference and just ignore the more expensive code paths (usually involving lots of lookups and message sends). This same technique, of saying this is probably an X could work for type inference in an IDE. We can at least provide an ordering that puts the most likely completions at the top, if not assume that only a certain set of completions are possible.

This is even more powerful if we can attach a runtime environment to facilitate these guesses.

Ok, off my soap box. This is an area I'm really interested in. :)

Anonymous said...

You are just too noob to talk about PHP IDEs

Matt said...

"Type inference" for dynamic languages like Scheme, JavaScript, PHP, Smalltalk, etc. is actually called "higher-order [control] flow analysis."

Academics have developed a multitude of algorithms for solving this problem, including the k-CFA family (0CFA, 1CFA, CPA, poly/CFA), the unification-based techniques (Steensgard, Heinglein), and the demand-driven techniques (Spoon) to name a few.

Despite being around for nearly two decades, few outside of academic research in programming languages know of these algorithms, and none of these people are developing IDEs.

Lex Spoon's Ph.D. work on Chuck for Squeak Smalltalk is probably the only one to get integrated into a working IDE.

DrScheme has a MrFlow application that can do it for Scheme, but I've never tried it out.

Jeremy Martin said...

@First Matt
Ha - so that's a little embarrassing. To much bouncing between languages yesterday. Anyway, thanks for pointing that out - it's now updated. The update makes no difference on the autocomplete, btw.

@alexbl
I completely agree that these IDE's can make an educated guess (or even guarantee) in certain cases. For example, in the following snippet...

$foo = new Bar();
$foo-> ...

...the IDE can be certain that $foo is a Bar in the second line (although it can't be certain on the type definition of a Bar, since that can change at runtime). So I agree with you insomuch as there is a lot of room for improvement. Unfortunately, like you said, in many cases the best it can do is "probably" (although I'd say "possibly" is probably more accurate...). Good points though - I definitely want to check out some of those Self papers.

@Anonymous
[blank stare]

@Second Matt
Well after a very brief look at your dissertation, I know better than to argue! That's really interesting - I had never heard of most of these algorithms.

So I'm still ignorant on the approach that these algorithms take, but is it correct for me to assert that the best an IDE can do is narrow a variable's type down to a discrete subset of possible matches?

Raj said...

Try using Quanta Plus(Linux: I use ubuntu 7+), It does have such autocomplete features..

Even Not that is not so good!!

Nick said...

Well..you use dreamweaver in the first post and recently i have been using a few ide's.
PhpDesigner (seems promising although having to type everything to include such things as css files is rather annoying whereas in dreamweaver you can right click then include) And Eclipse + dreamweaver of course.I have just got into OOP in php and i was wondering.Dreamweaver 8 doesn't allow for completion of code such as "$foo->" and then it would give a function etc.But the main thing you have to be aware of is that no IDE can be perfect and if it was that would elimate the need for a human to actually write the code =/.
Peace.

Matt said...

@Jeremy

Yes, all of these algorithms give conservatively correct answers--in the sense that if it could be X or Y, the analysis might say it could be X or Y or Z.

To determine the answer exactly in all cases would require a solution to the halting problem, so researchers have explored trade-offs between making the analysis fast and making the analysis precise.

adormitu said...

you are using the wrong tool... a good ide does the job well... take a look for instance at phpdesigner -> http://img13.imageshack.us/my.php?image=phpdesigner.jpg

the same does Zend IDE... Dreamweaver is "jack-in-all master-in-none" :)... and it's not an IDE, just an editor. IDE's have debuggers :P

Dracos said...

Just came across this blog as I am in the search for a Javascript IDE. I will try some of the ones mentioned here.

However I have been in PHP for quite sometime and have felt the same pangs of frustration on poor IDE's for php. That is until I ran across Nusphere's PhpED. I have never been happier writing PHP code. Its autocomplete is not only very complete, it is fast. It also understands when you are in a PHP part of HTML code, and switches it's "intellisense" accordingly from PHP to HTML and back. I highly recommend it to any PHP developer. The only drawback is its lack of Javascript capability. They have plans to add it though.

Anonymous said...

I realize that this is a tad bit behind the schedule of this post's comments, but have you tried the Komodo IDE series from ActiveState? True, its not a freebie, but it's code intelligence for multiple dynamic languages is indeed quite good. (Perl, PHP and javascript as the the common ones I'm using it for)

hyponiq said...

@Dracos: I, too, have recently acquired my taste for PhpED. I tried it out several years ago when it was "young" and wasn't too pleased with it. Up until recently, I used Adobe (formerly Macromedia) Dreamweaver for all of my editing needs. However, its lack of support for several dynamic languages, including those mentioned, lead me to explore other alternatives. Hence, I found PhpED. Now, when you made your comment is about when I purchased PhpED. And, to that extend, at the time their JavaScript support was much more limited than it is now. However, they've updated PhpED 8 times since I bought it and the JavaScript support has grown immensely.

@Jeremy Martin: I already have/had experience with Visual Studio and used it quite freequently to program Windows applications as well ASP.NET, but never really fiddled with it much when it came to JavaScript because it didn't have good enough support for it. Now that the 2010 Beta 2 has been released, I've been testing it thoroughly with JavaScript. It is a rather great tool, however it still lacks two things: proper "IntelliSense" and code folding. One major pro of it, though, is that you can reference any JavaScript file inside another to include the (limited) IntelliSense for that document, such as the lovely and elegant jQuery library. One workaround is to "VS Doc" a JavaScript file so that Visual Studio can interpret the return types of functions or the values of variables. It does work a lot better, but from a developer's point of view - unless the library is already VS Doc'ed - that is a rather daunting and unnecessary task.

Proper code-completion for dynamic languages like PHP/JavaScript is a feature that most IDEs lack, although a vast majority of them do "read" project directories and create a cache of auto-completion libraries for JavaScript/PHP files in the project.

So, PhpED is still my choice of IDEs. It has rather extensive JavaScript support in that it does cache the project directories, has the ability to include outside directories into the project, run multiple projects in the same workspace, and, most importantly (for me), has great code-folding features. However, its code-completion, as with all other IDEs, is rather lacking. The most that it can do, for now, is return the function/method/variable/property list. The actual implementation and/or use of each function/method/variable/property is very lacking.

Again, as you said, an IDE would literally have to parse the entire JavaScript/PHP file and internally "run" it in order to figure out a dynamic variable's actual definition/type. That is a rather taxing and extensive procedure; an IDE that does this would most likely consume all available resources after so many hours of working through the same project (if not minutes).

hyponiq said...

I also forgot to mention that I have tried SEVERAL other popular IDEs, such as the Eclipse-based line (Aptana Studio, PDT, Eclipse, and Zend Studio), phpDesigner, ActiveState Komodo, HTML-Kit, and a few others.

All of them have their pros and cons. But, for the most part, I don't use them because they lack other program features that I desire (although they are tedios at best and do not seriously impact or hinder my abilities). For now, Visual Studio 2010 Beta 2 and PhpED 5.9.5921 do it for me.

Anonymous said...

Pfff what you need sir is to use a plain text editor once in a while :)

that is :D

PHP + Javascript is such a powerfull combo, the question is not how much the IDE can do for you... but how much can YOU do with the code.

In your context sssembly code might suck the most :P

clod said...

Codelobster PHP Edition works great for me!