A More Readable (Pythonic) Javascript Syntax?
While I’ve come to love Javascript, I miss the syntactic beauty of Python. The stark modern minimalism of the language causes the meaning of code to float on the syntax like a feather on water. There are no extra braces, brackets, or parenthesis to saturate your visual bandwidth. In comparison, Javascript’s syntax is like the cluttered boudoir of a Victorian house: elaborate, ornate, and unnecessary. You can be left with half a dozen trailing braces and parenthesis, with no clear owner; their balance in an unstable equilibrium.
Note that I am not arguing that Javascript isn’t a beautiful or powerful language, just that its syntax is a vestigial meme left over from a time when we didn’t know better.
I’ve often wanted to bring Javascript and modern minimalism together: to strip the language of parens, braces, and semicolons. So that’s what I’ve done. I wrote a little parser for a slight modification of Javascript. I call it Pyscript.
Here’s what it looks like:
// Example One function triangle(a,b): function sqroot(x): return Math.pow(x,.5) return sqroot( a*a + b*b )
// Example Two
for var i=0; i<5; i++:
var el = document.getElementById("el"+i)
if count % 2 == 0:
el.innerHTML = "Hello"
else:
el.innerHTML = "World"
Comparison
When you put normal Javascript and Pyscript side-by-side, you can see the large difference in readability the addition of Python-style syntax makes.
// Pyscript
function triangle(a,b):
if a > 0 && b > 0:
function sqroot(x):
if x > 0:
return Math.pow(x,.5)
else:
return 0
return sqroot( a*a + b*b )
else:
return 0
// Javascript
function triangle(a,b){
if(a > 0 && b > 0 ){
function sqroot(x){
if( x > 0 ){
return Math.pow(x,.5);
}
else {
return 0;
}
}
return sqroot( a*a + b*b );
}
else {
return 0;
}
}
Pyscript is just a syntactic beautification of Javascript, where indents have meaning and braces are unnecessary. I’ve even shown it to Brendan Eich and he gave his nod of approval.
How Do I Get It?
Download it here or check out the demo page. Pyscript runs in all modern browsers. All you have to do is:
- Add
<script src="pyscript.js"/>to your<head>tag - Put your pyscript code in a
<script type="text/pyscript">tag.
Help!
Pyscript is really just a proof of concept. It has a set of unit tests, and as you can see not all functionality is completed yet. Anonymous inline functions do not work, there is no robust handling of indentation, and a number of features (like switch) do not work. But, the whole thing is open source so you can get involved.
What other ways can we make Javascript syntax prettier and more readable?
RT @azaaza A More Readable (Pythonic) Javascript Syntax? | Follow @azaaza on Twitter | All blog posts
Ed Spencer
I used to think this about JavaScript when I first switched to if from Ruby, but I’ve grown to like the old girl and now it’s Ruby that looks unpleasant to my eyes.
I guess there’s no accounting for taste!
[ICR]
Well yah, if you inconsistently format the javascript of course pyscript will come out better.
Stuart Ballard
I think this is a great idea – but personally my pet JS syntax peeve isn’t braces (my native language is C#, I like braces) but the fact that the syntax for typing a lambda is so verbose and involves typing an 8-character word each time plus parentheses.
I’d love it if you could get “function () { xyz }” down to something smaller. C#’s “() => xyz” might be tricky to pull off, but there’s got to be something that could be done.
Gozala
// Javascript
function triangle(a,b) {
if(a > 0 && b > 0 ) {
function sqroot(x) {
return (x > 0) ? Math.pow(x,.5) : 0;
}
return sqroot( a*a + b*b );
} else return 0;
}
// mozilla specific
function triangle(a,b) {
if(a > 0 && b > 0 ) {
function sqroot(x) (x > 0) ? Math.pow(x,.5) : 0;
return sqroot( a*a + b*b );
} else return 0;
}
// or even better
// Javascript
function triangle(a,b) {
if (a < 0 || b 0) ? Math.pow(x,.5) : 0;
return sqroot( a*a + b*b );
}
Gozala
or some reason last example got broken
function triangle(a,b) {
if (a < 0 || b 0) ? Math.pow(x,.5) : 0;
return sqroot( a*a + b*b );
}
Gozala
well it broked my comment again here is the gist anyway
http://gist.github.com/277650
Dan
Wouldn’t text/x-pyscript be better?
Paul O’Shannessy
I’m going to guess you’ve seen CoffeeScript (since I know you read Reddit), but just in case…
It has a similar sort of goal – making the JavaScript syntax more beautiful. It’s not trying to imitate Python syntax (that I’m aware of), but could give you some interesting ideas. I don’t think it’s as easy as you’re making this, but still cool.
Dave
I’ve never understood this weird bias against braces and semicolons like somehow explicitly defining things in an whitespace neutral way is a bad thing.
I am no fan of quite a few things in JavaScript, but braces, parens, and semicolons is not the bad part. It does, however, have a tendency to get bad if you misuse it like in your straw man example.
// Javascript without useless braces
function triangle(a,b) {
function sqroot(x) {
if ( x > 0 )
return Math.pow(x,.5);
else
return 0;
}
if (a > 0 && b > 0 )
return sqroot( a*a + b*b );
else
return 0;
}
// Javascript without redundant usage of ‘return’
function triangle(a,b) {
function sqroot(x) { return x > 0 ? Math.pow(x,.5) : 0 ; }
return (a > 0 && b > 0 ) ? sqroot( a*a + b*b ) : 0 ;
}
Learning a new language, be it verbal or programing, requires not just learning the parts but thinking in a new way. If you’re thinking the way another language is set up, yes, using another will be annoying. I, coming from the opposite world of using JS, have issue with reading the Python-style version. Beauty is in the eye of the beholder, I guess. My advice: don’t try to make one language into another.
G
Some of the syntax improvements already exist! Version 1.7 of JavaScript is available today, in some modern browsers, and the changes thru 1.8.1 are worth reviewing.
https://developer.mozilla.org/en/New_in_JavaScript_1.6
https://developer.mozilla.org/en/New_in_JavaScript_1.7
https://developer.mozilla.org/en/New_in_JavaScript_1.8
https://developer.mozilla.org/En/New_in_JavaScript_1.8.1
Martin
js.io uses syntax very similar to python to do synchronous imports directly into the current scope. We don’t actually rewrite the javascript though: the parsing is done by interpreting a string, e.g. jsio(“from util import base64″).
Andrew
How do anonymous functions work in this syntax? Pythonizing javascript is an excellent idea but one of the big differences at least in python proper is the lack of multiline anonymous functions which I use quite frequently in javascript.
For example:
doIt(function (thingeroo) {
/* do something complicated and
interesting here */
});
Can not be done in python unless you name the function which can be useful but then it creates a sort of visual break in the flow of the code that can look awkward.
mattly
I’ll second the recommendation to check out coffee-script; while I’m primarily a rubyist, coffee-script reminds me heavily of python, yet with javascript’s support for first-class functions and closures. It’s quickly becoming my favorite “language”, even if it just compiles to javascript.
David Hammond
I’ve always found Python’s whitespace-based block formatting to be a shortcoming of the language.
With curly braces, you can easily count the closing braces to see how many levels you’ve just closed.
Whitespace indentation levels are much more difficult to visually count, unless you move your caret around and count the steps that way. You could set your text editor to show markers for each indentation, but then your screen becomes more cluttered with symbols than it is with JavaScript.
Overall, I’m a fan of JavaScript’s syntax. There are some problems, such as semicolon inference (which can eventually be disabled using the new “strict” feature in ECMAScript 5), but it’s mostly a very nice syntax to work with.
My main complaint about JavaScript is the rather poor standard library. Compared with something like PHP, which comes standard with hundreds of useful functions for working with basic data types (strings, arrays, dates/times, etc.), JavaScript’s offer feels very incomplete. No native base64 encoding/decoding, no equivalent of htmlspecialchars or htmlentities, no native support for sorting an array numerically or in natural language order (PHP’s natsort), and on and on. I know these features can be implemented through custom JavaScript code or external libraries, but that shouldn’t be necessary for this kind of basic stuff.
At any rate, I supposed the syntax thing is a largely subjective issue. I think your JavaScript example is more readable than the PyScript example (although your inline whitespace usage was inconsistent in both examples). But, arguing meaningful indentation vs. visual delimiters is like arguing spaces vs. tabs for indentation: Tabs are better, and no one can tell me otherwise. ;)
MV
Great! I’ve been doing this using http://blog.brush.co.nz/2007/09/nobraces/ but this hack makes it much easier.
– MV
Kevin Dangoor
Neat bit of work, Aza.
That said, if you figure out a workable syntax for anonymous functions, you might finally be able to convince Guido. People have been trying for a while to figure out how to anonymous functions work right in Python.
Simon
@David Hammond – I don’t buy that argument as to Python indenting. If you’re having to resort to counting (indents or braces) to keep track of blocks in your code, you’re already in trouble. Personally, I find that harder in C-like languages, where poorly-formatted code may be misleading.
Elijah Grey
You should preserve any extra flags in the “pyscript” type in your `evalPyscript` function.
The relavent code would be the following. You would only want to replace the first pyscript so a string is going to be more appropriate than a regexp.
s.type = scripts[i].type.replace(“pyscript”, “javascript”)
For example, this will allow you to use “application/x-pyscript;version=1.8″ to use JavaScript 1.8 and higher features.
Also, JavaScript 1.8 has similar implicit brackets but also implicit return statements for functions so you can do the following:
function foo (bar, baz) bar + baz
YES
Down with extraneous punctuation! Up with mandatory consistent whitespace!
Christian
I personally think the pyscript should be converted to javascript using a command line tool.
That way, you wouldn’t have to parse the code every time you run it.
zam3858
i wonder what happens when i try this with extjs. always had problem looking at the amount of braces i have in my code.
thanks!
jashkenas
Aza — please do take a peek at CoffeeScript when you get a chance. It’s a stab at trying to answer the questions that you raise here, and includes function literals that clear out the clutter. To square a number:
x => x * x
Passing a function into a function call:
elements.each(el => el.show())
Or, using block-style syntax:
numbers.reduce(0) sum, num =>
sum + num
Finally, the empty function:
=>
The most interesting thing about it is that all JavaScript statements are transformed into expressions (via closures, when necessary), so you can add up assignments, pass try/catch or if/else as an argument, and assign to the result of an if statement.
PyScript is nice and short and sweet right now, but I’m sure there’s plenty of room for it to grow — we should all be cross-pollinating as much as possible…
Karl
> What other ways can we make Javascript syntax prettier and more readable?
Put the braces back in using Ruby’s block syntax for lambdas.
Dave Hulbert
Would this be just for development, or would files be served to the browser like this too? Or would they be “compiled” back to JS?
JavaScript is an interesting language, because the code is both seen by the programmer and sent to the user.
How well would this minify? Removing {} saves some bandwidth, but there’d be lots of whitespace.
Would there ever be issues with servers using different line endings (\r\n)? Would JSON work ok?
Iain
I don’t even see the code anymore, all I see now is blonde, brunette, redhead.
Henry
That pointless “else: return 0″ instead of just “return 0″ at the end is just there to make the old style look bad, right?
Philipp von Weitershausen
Nice work, Aza! It’s impressive how little code Pyscript needs to work.
That said, I think curly braces, indention, anonymous functions etc. are just distractions. For me the big issue is the whole object/method/inheritance definition syntax. Except there isn’t just one syntax but many, all of which aren’t truly great ones. If we’d fix that, JavaScript would be much more pleasant already. And after that, I think the next big thing should be decent namespaces.
Anyway I’ve posted a detailed comment on my blog: http://philikon.wordpress.com/2010/01/15/javascript-curly-braces-are-not-the-problem/
Jay
Yeah, Aza, seems you’ve been in Python too long, you can’t write concise javascript anymore.
Alternatively, you’re deliberately writing excessively verbose JavaScript to make PyScript seem better in comparison. Can’t be that, right?
Also, readable and pythonic are not synonymous.
Gerv
Interesting :-)
If you haven’t registered the MIME type, it’s much more polite to use an x-. And I believe application/javascript is the official type for JS, rather than text/javascript. Which suggests what you actually want is:
application/x-pyscript
Would you like a patch? :-)
Gerv
Neil Rashbrook
My eyes! The goggles do nothing!
Joe
I love this idea. It’s something we were thinking about all the time. It’s very frustrating to search for a bug caused by a missing semicolon or brace. This syntax adds absolutely no value to your code. It’s a bug source, nothing more.
Another bug source is that JS by default defines global variables. How stupid is that? In 99% of all cases you want a local variable, so that should be the default.
What’s really sad is that so many developers religiously believe that a syntax that adds unnecessary clutter is better.
[ICR]
I love python’s syntax, but at the same time I think your example does brackets and braces a disservice.
Here’s an example with much better formatting consistency (pastebined because it seems this blog will chew up the formatting): http://pastie.org/779716
Once you add more consistent formatting, and follow the guard pattern, the code looks much cleaner and more comparable.
Personally, with braces I can take or leave it. I like that they’re not needed in Python, but I don’t find them terribly egregious when they are.
I do, however, actually like the brackets around conditions. It’s probably just familiarity, but for some reason I find it much easier to read a condition when it is in brackets — to see where it begins and ends. I know logically that is weird and is likely not the same for other people, but it still feels awkward to read python without the brackets.
Sander Aarts
Sure, your Pyscript examples are shorter than their JavaScript versions, but the JavaScript examples can still be minified.
@Stuart Ballard: Do you really prefer a notation with “=>” in it? This syntax of (ASCII style) arrows, like => and ->, is what always hurts my eyes whenever I look at PHP. At least ‘function’ has a clear meaning as a word, but using 2 characters to create something that resembles an arrow… brrr, horrible.
JavaScript
This can’t possibly be any good for JavaScript performance. Instead of obfuscating JavaScript, why not just learn JavaScript and stick to it? It’s much easier for everyone involved. I seriously hope that nobody tries to start a serious web development project using Pyscript. Pyscript is only dithering the usefulness and ubiquity of JavaScript.
شات الشله
This can’t possibly be any good for JavaScript performance. Instead of obfuscating JavaScript, why not just learn JavaScript and stick to it? It’s much easier for everyone involved. I seriously hope that nobody tries to start a serious web development project using Pyscript. Pyscript is only dithering the usefulness and ubiquity of JavaScript
Mook
Personally, I find that the braces force less visual complexity per line, since they typically force mostly-blank lines. Of course, I also like spaces after parens in function declarations, and spaces after commas – just more spaces in general. I also wish JS had mandatory semicolons, instead of this crazy guessing that is mostly, but not always, right…
It is interesting to note that your pythonic javascript would fail horrendously in your blog comments due to indents being stripped completely.
Your examples look almost like valid python, with s/function/def/ and removing the various variable declarations. Perhaps what you _actually_ want is to build on ActiveState’s pyxpcom/pydom work and use Real Python in the browser instead?
nintendo dsi r4
I would rather like a language with C# syntax, because the worst problem with JS is OOP. I have written some LIBs using OOP for my Website but it always comes down to more code than necessary. Having typified variables at least in the first stage (before translating into JS) could enable the compiler to at least find some errors.
Lennart Regebro
“While I’ve come to love Javascript”
Well, THERE’s yaahr prahblem. :)
Javascript with slightly more Pythonic syntax? Why? The only benefit Javascript has over Python is that it doesn’t rely on indentation and therefore can be compacted. You just removed Javascripts only benefit as a browser language. If you want indentation (and I do) then why not just go full out to Python?
gimme abreak
“What other ways can we make Javascript syntax prettier and more readable?”
by eliding the input from pytards? i mean, really….uhm, the only way to make “javascript” (note, a different language) “prettier and more readable” (implied, is to make it like python) seriously? is that actually your question?
there are a many issues with javascript but, “prettier and more readable” are so far down the list that they are not even on the radar…
this article, is less than helpful – every language has its pros and cons. attempting to “make” one like your favorite is just silly.
SMiGL
really such scripts will not be able to reduce in volume:). This is the loss advantage of this approach!
Catherine Devlin
Where has pyscript been all my life?
Thank you, Aza. You’ve made JavaScript more usable to me.
Really?
Really? I think this makes it worse as far as readability. Can’t tell who’s nested where. Just use a text editor with syntax highlighting and code-collapse and JS is easily readable.
buy 8gb micro m2
It only takes a complete trouncing and embarrassment to get Obama to DO something – I mean, in baby steps. The thing is, I don’t think he believes in this. This is brand new, another tactic. He believed (so we were told) in health care, and up until yesterday, banks were merely the places from which he hired his cabinet.
Matthew Raymond
Doesn’t that triangle function just boil down to the Javascript below?
function triangle(a, b) {
return Math.min(a, b) <= 0 ? Math.pow(a * a + b * b, 0.5) : 0;
}
Not having any experience with Python, I can’t really tell where code blocks begin and end in your examples. For instance, take your second example:
// Example Two
for var i=0; i<5; i++:
var el = document.getElementById(“el”+i)
if count % 2 == 0:
el.innerHTML = “Hello”
else:
el.innerHTML = “World”
How do I know the if…else block is inside the loop? Of course, I can guess based on the scope of “el”, but that reasoning is not based in any way on the syntax.
Honestly, it would be easier to read VBScript:
For i = 0 to 4
Dim el = document.getElementById(“el” + i)
If count Mod 2 = 0 Then
el.innerHTML = “Hello”
Else
el.innerHTML = “World”
End If
Next i
Marat
I think, it’s problem of coding style
Compare original code:
function triangle(a,b){
if(a > 0 && b > 0 ){
function sqroot(x){
if( x > 0 ){
return Math.pow(x,.5);
}
else {
return 0;
}
}
return sqroot( a*a + b*b );
}
else {
return 0;
}
}
and code what reminded by me:
function triangle(a, b)
{
if(a > 0 && b > 0 )
{
var x = a*a + b*b;
return x > 0 ? Math.pow(x, 0.5) : 0;
}
return 0;
}
auscompgeek
Er, has anyone done a Google for Pyscript lately? There seems to be another project called Pyscript. Let’s all get confused.
frogola
Why not eliminate the letter ‘e’ while you’re at it?
Dentist Downey
Hello. Thank you for sharing your post. I’m sure your readers who are web enthusiasts as well will be very interested in this. Looking forward to reading more of your posts. All the best.
Matthias Schirm
> What other ways can we make Javascript syntax prettier and more readable?
A programming language don’t need written keywords like ‘function’ and so on. Look at your examples where those tokens are colour-highlighted, If the colour encodes functionality why is the duplication of this information though special keywords needed as the colour alone hold all necessary information ?
Example language: colorforth.
Tim
I don’t think I’ve come across a blog without any timestamps (or at least dates) before. Frustrating, to say the least.
I do love the idea of this though! I just can’t tell if it’s been around long enough for me to have missed it when I looked around a few months ago ;)
jay
Hey do you mind if I use some of this content on http://www.basicwebdesign.co.cc in exchange for a link back to your site? Thanks
jay
Hello, would you mind if I use some of your sites content on http:/basicwebdesign.co.cc ? I’ll be sure to keep the credit to you, along with a link back to your site. Thanks.
jhuni
Since when did forcing the user to be sensitive to whitespace automatically make better code? Aza has clearly been in the Python world for far too long, personally I find the braces to be helpful if you have a good editor, because editors can line them up and they can give them their own color with syntax highlighting, so ultimately what you need is a good editor, not some script that changes JavaScript’s syntax.
What JavaScript needs to make that “triangle()” function readable is a decent exponentation operator, not white-space sensitivity.
sub triangle($a, $b) {
($a ** 2 + $b ** 2) ** 0.5
}
For the second one the ternary operator and a loop statement that doesn’t suck will suffice:
for 0..5 -> $i {
document.getElementById(“#el” ~ i).innerHTML = ($count % 2) ?? “World” !! “Hello”
}
The JavaScript ternary operator is flawed and that makes it hard to read, the (? :) syntax is confusing, however, if you put (?? !!) its pretty easy to understand because (?) is always associated with true booleans and (!) is always associated with false ones.
web tasarımı
Tebrikler vallahi dua edeceksiniz bana.
CapsiPlex
Thanks for share, weldone.
termal jel
My eyes! The goggles do nothing.
Thomas Holloway
Is there a reason this wasn’t made into a compile time execution so pythonic scripts were compiled into native javascript. Sass is a great example of this usage of creating css from the generative tools (I of course use compass watch to monitor changes to my sass files).
It would be nice to leverage this from the command line.
Zayıflama Lida Fx15 Ve Biber Hapı Zlfvbh
I used to think this about JavaScript when I first switched to if from Ruby, but I’ve grown to like the old girl and now it’s Ruby that looks unpleasant to my eyes.
I guess there’s no accounting for taste!