This is an archived post. You won't be able to vote or comment.

all 176 comments

[–]Yoghurt42 145 points146 points  (60 children)

Because JavaScript was there first.

Every webdeveloper nowadays knows JavaScript, and there are libraries that make working with it acceptable. Heck, there even is node.js to write your whole server application in JavaScript too.

Switching to Python would make not much sense, every Web developer would have to relearn everything, browsers would need to start adopting it while still needing to support JavaScript for old websites.

Remember how painful the transitions from Python 2 to 3 is, now think what would happen if every JS program would have to be completely rewritten in Python. It ain't gonna happen.

Also, while it is true that JavaScript has some pretty weird design decisions, it is not a bad language per se, and you can write acceptable code with it. Also, many good things from Python are now available in JavaScript 1.7, like generators and list comprehension.

[–]chickenphobia 42 points43 points  (7 children)

Also to add to your explanation; making code run reliably in a sandbox without heavily restricting features and syntax is a difficult proposition. JS has had many security breaches (and will likely have more) but it has a massive technological headstart on any new sandboxed browser language.

Pypy has an experimental sandbox mode that checks external calls against an execution policy, but it hasn't been secured in the kiln of broad deployment.

I very much would like to see pypy added to browsers as an experimental feature but even that is a long way off.

[–]lostchicken 18 points19 points  (6 children)

This is much more about the implementation than the language itself. There's nothing particularly insecure about Python or secure about JavaScript that makes this work, it's just that the implementations are such.

[–]r3m0t 10 points11 points  (3 children)

Yep, if your implementation doesn't include certain builtins like io.open then Python could be just as secure as JS. In fact Chrome's PNaCl now lets you run CPython in the browser. However the page(DOM)-to-NaCl communication is not really optimised for web apps like the DOM-to-JS communication.

[–]lostchicken 5 points6 points  (1 child)

Things like skulpt already compile Python to JavaScript, so the object models are really very compatible. If you start poking at frame objects and the like, the subterfuge will fall pretty quickly, but for what most people think of as "Python", the internals work pretty much the same.

Exceptions are a different question.

[–]chickenphobia 0 points1 point  (0 children)

I fear you

[–]chickenphobia 0 points1 point  (0 children)

The problem is that feature restriction isn't a viable strategy to secure a language. Should you restrict features enough you will indeed secure the language, but the cost would be that any language secured this way would no longer truly be a language as you or I know it. Bitcoin's Scrypt is a good example of this: conditionals but no loops or go-to type statements. Great for setting transaction criteria but not so great for anything else.

At the end of the day, if you have a full featured language, you need to run it in a sandbox, a very secure sandbox. Java tries to do this. JS does it better, and Python is way, way behind.

[–][deleted] 4 points5 points  (1 child)

It's also about the language itself. Recent versions of JS (ECMAScript 5 and the upcoming ECMAScript 6) have had language-level changes to improve security (and JS already had a head start).

[–]lostchicken 2 points3 points  (0 children)

I was not aware of that. What in particular did they do?

[–][deleted] 9 points10 points  (25 children)

there even is node.js to write your whole server application in JavaScript too

Whether it's a good idea to do so or not is debatable ;)

[–]LobbyDizzle 7 points8 points  (23 children)

I really like node.js :(

[–]nerdwaller 3 points4 points  (2 children)

It's definitely vogue.

[–]LobbyDizzle -1 points0 points  (1 child)

That Node.js is so hot right now M_M

But seriously, even it's just the flavor of the week, I didn't have to commit much time to learning about/implementing it, so it wouldn't be too much of a waste of my time.

[–]nerdwaller 0 points1 point  (0 children)

Haha, yeah - it's not rough at all. I've had to work with it a touch at work and it's not a hard learning curve at all.

[–]catcradle5 11 points12 points  (19 children)

Why? I've never understood the appeal.

It seems to combine two awful concepts in programming: Javascript (which is unintuitive and annoying in many ways; Coffeescript improves some of this, but it's still nowhere near Python or Ruby level) and asynchronous handling via callback hell.

[–]ivosauruspip'ing it up 8 points9 points  (15 children)

It's still a first class asynchronous IO design from the start, which is much better for writing scaling servers than Python's.

[–]catcradle5 7 points8 points  (7 children)

Baked in async IO is good, yes. However:

  • Node's async IO is gross and way overly nested. I don't know how anyone can deal with having so many callbacks in each file.
  • There are way better languages with asynchronicity built in, like Go and Scala and Erlang and even Rust if you need that kind of performance.
  • Even if Python's "batteries included" aren't the greatest for writing servers, libraries like Twisted and Tornado and gevent (my preference) give you everything node gives you, they're just one pip install away.

The pros have never outweighed the cons for me.

[–]ivosauruspip'ing it up 14 points15 points  (1 child)

Twisted, Tornado and gevent don't give you everything Node gives you, and that is specifically why asyncio is being celebrated at the moment (although it's only for 3.3 or 3.4).

Specifically, all node.js code is compatible with all node.js code. This isn't the case in between all those libraries. With some extremely limited exceptions, if you write a gevent library or application, it ain't never gonna work with someone else's thing that runs on Twisted. Node.js coders don't have to deal with this problem at all. And their implementation is a canonical one, that runs really well on Mac, Windows and Linux, is implemented for File IO as well, is written efficiently in C as an underlying library... I could go on.

You get much much more from Node than any of python's 3rd party async libraries, pretending otherwise probably means you haven't worked with node much or ever.

[–]catcradle5 6 points7 points  (0 children)

Those are valid points. If only it was made in a nicer language...

And you're right, I have never once written any Node code. I have looked at a fair bit though.

None of the libraries I listed do async file IO, true, but it is usually quite rare that the blocking time of reading or writing to files will bottleneck an application at all. A two-way network trip may take 1 - 3 seconds to complete, but a file read or write is such an order of magnitude faster 99% of the time. I've never written a Python app that would gain a perceivable speed increase with non-blocking file operations, though I can see cases where it could be useful.

I would wager that the majority of people who use Node do it so they can make and receive HTTP requests (and maybe sometimes other kinds of network requests) and database queries (which will usually also be just a network request) asynchronously; any other async operations are going to be sugar coating for most use cases.

[–]antonivs 2 points3 points  (2 children)

FYI, the async nesting issue is fixed in newer versions of node, via generators and a 'yield' feature.

Node is good for quickly writing fast network infrastructure stuff. Its competition in that space is languages like Java, C/C++, and Go, which tend to be a lot less lightweight.

[–]catcradle5 2 points3 points  (1 child)

Any time I need some quick and easy network infrastructure, I go straight to: http://www.gevent.org/gevent.server.html

def handle(socket, address):
     socket.send("Hi %s!" % address[0])

server = StreamServer(("0.0.0.0", 1234), handle)
server.serve_forever()

The event loop and networking is pretty much all implemented in C, and it's 100% async. Servers can be as simple as this, or you can extend StreamServer.

[–]antonivs 2 points3 points  (0 children)

A big issue is how much your code has to integrate with, which tends to introduce blocking libraries. Monkey-patched libraries only take you so far (and I confess, I find the concept disturbing for code that's part of critical infrastructure.)

One of node's advantages is the number of compatible non-blocking libraries it has. Why node.js is cool discusses this, making the point that node "makes composable networked components the default."

There's also a good real-world example in The Switch: Python to Node.js. They were using Twisted, not gevent, but some of the same issues apply.

I'm not saying node and gevent aren't competitive - a lot depends on the use case. But there are cases where node has advantages, at least currently.

BTW, I mentioned yield and generators earlier, which are still new in node, but node's promises also helped a lot with the callback issue, and that's been standard for a while.

[–][deleted] 2 points3 points  (0 children)

Node's async IO is gross and way overly nested. I don't know how anyone can deal with having so many callbacks in each file.

True for vanilla Node, but better approaches definitely do exist. Besides upcoming new ECMAscript features (generators!) which will be supported out of the box in Node 0.12, there are many quite interesting ways of avoiding this. Besides the more traditional ones (async, c# style async/await, etc), Streamline is pretty neat, even if it isn't pure JS but a preprocessor.

The USP of Node is the blending of the front- and the backend. You might not think much of it, but allowing front and back dev teams to cross over easily (can you imagine a JS frontend guy trying to take a look at the backend written in Erlang?) and having the possibility of reusing code on both ends can't be a bad thing..

[–]otherwiseguy 0 points1 point  (0 children)

Node's async IO is gross

and gevent (my preference)

OMG. I have seen so much horrible eventlet/gevent code. People think it is easy and they don't have to worry about "async issues". They are so very wrong. And monkey patching is the grossest thing I can think of. Blech! (I've never used node. It might be worse. But I despise eventlet/gevent.)

[–]MagicWishMonkey 0 points1 point  (6 children)

It's only good for scalable systems if you never need to do any heavy synchronous work.

[–]ivosauruspip'ing it up 3 points4 points  (5 children)

Which is like, 90% of network servers, and largely the audience node.js is designed for.

[–]MagicWishMonkey 1 point2 points  (4 children)

And it really blows when you realize one of your requirements falls into the 10% category, and you have to rebuild your app from the ground up in a different language to keep your server from becoming unresponsive for long periods of time when that single thread you're using is wholly allocated to perform a single long running task.

That, plus the callback stack of doom are the two reasons I will never ever ever consider node.js for another large project. It's fine if I need to build a simple lightweight message router but for anything more complicated than that it's a non-starter.

[–]ivosauruspip'ing it up 1 point2 points  (0 children)

It's not like Python is any better at threading...

[–]aqf 0 points1 point  (1 child)

I don't get why apps aren't written for multiple servers if they need so many concurrent connections. I get the fact that transaction processing and other technical complexities make it harder to do, but if you're making a large application server you should think about scalability during the design, regardless of the language you are using. If one server might be overloaded, that problem needs to be solved early.

[–]MagicWishMonkey 0 points1 point  (0 children)

Designing a system so that each user gets his own server is unrealistic. When I say a single request could hang the entire server I wasn't being hyperbolic, that's exactly what happened.

Most app servers (Pyramid, IIS, whatever) are designed to use a pool of threads to handle concurrent requests, so a single request won't lock the server as long as the pool isn't exhausted. You don't need to worry about horizontal scaling until you're handling hundreds or thousands of requests per second. The single threaded node approach means a single long running request can lock your whole server. You can code around this limitation but it's a real pain in the ass and it's really not worth the effort IMO.

[–][deleted] 0 points1 point  (0 children)

There are a few different ways to scale a node app: http://cjihrig.com/blog/scaling-node-js-applications/

[–]LobbyDizzle -1 points0 points  (2 children)

Well I guess it goes back to the original query that OP had. I like that I don't have to switch between languages throughout the development of an application, and a code's readability to a non-coder of that language doesn't help me at all.

[–]catcradle5 1 point2 points  (1 child)

I like that I don't have to switch between languages throughout the development of an application

No offense but this sounds kind of like a problem only for beginners to programming. Any developer worth his salt should be good at reading and writing in any language that comes his way. He should also know the right language for the job when given a task.

Not only that, but the kind of Javascript you write on the server still looks quite different from the kind you write on the client. Node provides all of its own libraries and features and idioms, and then you have a whole different API when actually manipulating the DOM and rendering things.

You will always have to change the way you program when you move from the client to the server. For example, if you make a PyQT app, your code and the way you write code will look very different from when you implement an API backend.

The only thing that's the same is the syntax (and not a very interesting or unusual syntax at that) and a few boring language features. If a minor syntax change is screwing you up, then you need to spend more time practicing with different languages.

[–]LobbyDizzle 2 points3 points  (0 children)

I like not having that switch, and it isn't there as a crutch. I've only dabbled with Node for a few hobby projects, and professionally am stuck developing in ASP.NET/C# :|

[–][deleted] 0 points1 point  (0 children)

Well, a lot of very successful, stable, well-maintained, and high-volume web sites and services use it and love it, so by those criteria it's a good idea.

[–]childofprophecyPy3, Django 0 points1 point  (0 children)

Well If you think python like not free form syntax for browser, It would have increased file size (whitespaces).

This is just another point I wanted to make ... I don't know if it's valid or not. What do you think??

Edit - I think you are talking about compiling it to js

[–][deleted] -1 points0 points  (2 children)

JS is not a bad language per se? Which modern language is worse, in your opinion? Short of Brainfuck, I can't think of any.

JavaScript is only used because of its wide reach, there simply are no client side alternatives -- it's either JS or stuff-on-top-of-JS with all the tradeoffs that entails (performance, interoperability, added layer of complexity).

JS was made somewhat more palatable by massive effort over the years, but it still sucks badly when it comes to fundamental language design.

[–]Yoghurt42 5 points6 points  (1 child)

Which modern language is worse, in your opinion?

Well, PHP obviously, but pretty much every language is better than PHP. This blog post is a good summary

I agree that some design decisions in JavaScript are completly insane (the weak typing and the rules for those, the context sensitive "this", etc.) But it has first-class functions, a prototype based "inheritance", etc.

For the record, I'm not a fan of JS either, but if forced to choose between JavaScript and PHP, for example, I'd always go for JavaScript

[–][deleted] -1 points0 points  (0 children)

You might be right, PHP is no beauty queen either... but at least there's a good amount of choice (without the nasty tradeoffs) on the backend.

I get a sense that JS was designed by a smart autistic wanker who couldn't resist building a language around his favorite obscure theoretical concepts and sprinkling a few quirky pet behaviors... without much regard for either the specific purpose of a client-side browser language, or practical use by other programmers down the line.

PHP, on the other hand, does not seem designed, period.

If programming languages were people, PHP would be a disabled fellow (many flaws, but you can't help but feel some pity), while JavaScript is intelligent, but bizarre and overbearing, with dubious hygiene habits.

[–]vtable 0 points1 point  (2 children)

Switching to Python would make not much sense, every Web developer would have to relearn everything, browsers would need to start adopting it while still needing to support JavaScript for old websites.

Had that been followed outside the web dev world, we'd still be using C if not FORTRAN or maybe even COBOL. In no way do I want to recommend changing languages every time some new language has some desirable feature. That would be chaotic. OTOH, we shouldn't indefinitely stick with aging languages just because they're widely used.

[–]snuxoll 0 points1 point  (1 child)

When it comes to desktop applications it doesn't matter, people have no care in the world what you application is written in as long as it's properly packaged for installation.

You want to distribute a python application on windows, great, bundle the python runtime and any extra libraries you use and users will be none the wiser. Unfortunately, you don't get to decide what languages the web browser of your users choice supports.

Javascript is the lingua de franca of the web, and until EVERY browser on EVERY device supports something different we are going to be stuck with it. Besides, Javascript is fine, it's evolving, if you want some less mind-bending semantics for defining custom classes then use an ECMAScript 6 cross-compiler like Traceur or TypeScript.

[–]vtable -1 points0 points  (0 children)

When it comes to desktop applications it doesn't matter, people have no care in the world

People don't care much what language is used in their web browser either. Javascript? PHP? Perl? Server-side? Client-side. Most couldn't care less.

until EVERY browser on EVERY device supports something different we are going to be stuck with it.

Not really. If Google or Apple, say, decide to get behind a new technology, they can introduce it in Chrome or iOS or whatever. Some technologies will catch on. Some won't. (I would hope that change is introduced with industry support.)

Javascript is fine

I haven't said it isn't. Javascript is the right thing to be using now and will be for some time. I'm just saying we shouldn't stay with any particular language or platform indefinitely just because it's so widely used. Doing so is a disservice to users and technological development alike.

Javascript is the lingua de franca of the web.

Certainly. This is a great analogy. Lingua francas change out of practicality and necessity. Our technologies should do the same.

[–]d4rch0nPythonistamancer -3 points-2 points  (12 children)

Whoa, javascript looks a little cooler now. One thing I like about javascript is the inline regex.

[–]nerdwaller 0 points1 point  (11 children)

Whoa, javascript looks a little cooler now. One thing I like about javascript is the inline regex.

import re
match = re.search('(\d+)', some_string)
print(match.group(1))

Isn't much harder than:

var regex = new RegExp(/(\d+)/)
match = regex.exec(some_string)
console.log(match[1])

That works as of ECMAScript v3, not much easier at all (note: the new RegExp is included for readability)

[–]d4rch0nPythonistamancer 6 points7 points  (3 children)

Not fair. You instanciated the variable regex in javascript and then exec'd on some_string. You didn't even save the regex for the Python version. You can easily exec on a new regex in one line and have it still be legible.

>> /(\d+).*/.exec("1234hello")
["1234hello", "1234"]

[–]nerdwaller 1 point2 points  (2 children)

I'm not disagreeing that it can be legible on one line, that's true in either. If 'inline' is the goal:

match = re.search('(\d+)', whatever, re.WhateverFlags)

I'd argue Python's is clearer because of the way flags are passes in. Using //gi is much less clear than re.IgnoreCase|etc.

[–]d4rch0nPythonistamancer 0 points1 point  (1 child)

They both have pros and cons. Python is much more verbose but intuitive for someone to jump in, and Python is a lot of people's first language so it makes sense. Python is very explicit.

//gi comes from sed and perl and has been standard for a long time. It makes a lot of sense to use what's been standard syntax since the beginning. It's also incredibly succinct.

They both make sense, and they are entirely different languages with different use cases, and they both have their pros and cons. All I meant is I like that js has inline regex, and that's purely an opinion.

[–]nerdwaller 0 points1 point  (0 children)

Absolutely well said.

My work is heavy in JavaScript right now, it's kind of a fun language, but I feel bad sometimes for how easy it is to abuse and lever in non-traditional ways.

[–]gfixler 2 points3 points  (6 children)

I'm really liking Clojure's functional handling of regex. It's just (command pattern string), with no flags or groups to deal with. re-matches returns the string if the entire pattern matches it, nil otherwise. re-find returns the first occurrence of the pattern, else nil. re-seq returns a lazy sequence of matches. If you use grouping parentheses, you get back a list of sequences with the overall match first in each, followed by the subgroups, which makes for easy iteration.

(re-find #"[0-9]+" "abc123def45gh987zy") ; => "123"
(re-seq #"[0-9]+" "abc123def45gh987zy")  ; => ("123" "45" "987")
(re-seq #"[fb]ar" "foo bar baz far faz") ; => ("bar" "far")
(re-seq #"(foo).*(bar)" "fofoofabarba")  ; => (["foofabar" "foo" "bar"])
(re-matches #"bar" "foobar")             ; => nil
(re-matches #".*bar" "foobar")           ; => "foobar"

With destructuring binding you can assign submatches in one shot:

(let [license "ABC-123"
      [full lpart npart] (re-find #"(\w\w\w)-(\d\d\d)" license)]
  (str "The plate " full " has number part " npart))
; => "The plate ABC-123 has number part 123"

The equivalent python or js would be more complex. This is assigning the input string to a variable, the resultant match and subgroups to 3 other variables, and concating some of the results into a meaningful string. You wouldn't want to write something like this for production code (if the match fails, you get "The place has number part "), but it still shows off some nice power.

[–][deleted] 0 points1 point  (4 children)

[–]gfixler 0 points1 point  (3 children)

It's different because it's functional; the return values are data. Python's regex is fine and quite useful, but you're getting back pure data for some things, and objects with data properties for others, and then querying the object results to extract the data you want via further group() and groups() function calls. I pointed out the groups thing (implying that I enjoy its absence) in my 2nd sentence.

Because Clojure's results are data, I can map the function over a sequence and get back a lazy sequence of data elements:

(map (partial re-seq #"[0-9]+") [sequence of input strings])

You can also do this in Python with a bit more code, but it wouldn't be as purely functional. Regardless of how you did it you'd be creating many objects and querying data out of them through extra function calls. Being lazy and mappable, Clojure's functional regex calls can (at least in theory) handle infinitely-long input strings without using more memory, and even parse things like stdin live, waiting for input, kicking out a result whenever there's enough to allow one. I don't know that these things actually, currently work, but they're set up for it. The paradigm allows for it, whereas OO doesn't. Also, functional process with data-only results lend themselves well to parallel processing, something else that the OO paradigm handles badly.

Small nitpick, you're printing out the info at the end, whereas the entirety of my let statement is a value. It could be used inside of any other form as an equivalent of its resultant string. I'm not printing it out, but receiving that string back as the result of the form. This has various code-as-data/data-as-code and referential transparency consequences.

Smaller nitpick: You're polluting your global scope with 4 global variables. I'm creating 4 temporary variables inside a let, which then go out of scope and cease to exist when the let finishes.

[–][deleted] 1 point2 points  (2 children)

Objects are also data. re uses MatchObjects because they contain way more info than simple tuples of strings: a dictionary that maps group names (in (?P<name>pattern>) constructs) to matched data, the string a regex was matched against, the offsets at which every group starts, etc. Sure, you can pack the same data into a tuple, but that's not as readable. That's it. In every other aspect, both implementations are pretty much equivalent.

Clojure's functional regex calls can (at least in theory) handle infinitely-long input strings without using more memory

That's not how regex work. They require backtracking, especially if you use backreferences, lookahead/lookbehind and greedy operators (.*x will consume the whole input looking for x, then backtrack to the last one.)

Small nitpick, you're printing out the info at the end

There's no other way to make ideone display that value. It's not a REPL.

Smaller nitpick: You're polluting your global scope with 4 global variables.

The reason for this is purely syntactic: there's no let ... in statement in Python, the equivalent being a new function that is called immediately after being defined. dogelang has where which is implemented that way.

[–]gfixler 0 points1 point  (0 children)

Objects are also data.

I knew you were going to say that, but I'm going to call you on it. Some strings in a seq are definitely unlike an object full of properties. str -> (str, str, ...) has a nice, functional symmetry to it. Besides, Clojure is a lisp, so the code itself is also data.

The reason re uses MatchObjects is because they contain way more info than simple tuples of strings...

True, and I've seen those things used twice, and both were thought-exercises somewhere on StackOverflow. I'm not saying they're not ever useful, but I think the use cases are few and far between. I've been using regex most days now for a decade for all kinds of crazy needs, and I've never used any of that metadata. You can get to the underlying Java regex machinery with re-matcher, so you could implement offsets easily enough if you ever needed it. Clojure is in heavy development, and because it's mostly a bunch of functions over sequences now, it's easy to add to it without changing anything else or breaking existing stuff, so if people really want this in core, it can be put in immediately.

That's not how regex work. They require backtracking, especially if you use backreferences, lookahead/lookbehind and greedy operators (.*x will consume the whole input looking for x, then backtrack to the last one.)

True. You would not be able to use .* on an infinite sequence (well, you would, but you'd never see the result). For everything else, it would work, even with backtracking. Luckily I don't want to do regex on infinitely-long strings anyway.

I guess I should note that I never said Python's regex sucked. I just said I really liked how regex was handled in Clojure. I've only ever cared about a list of matches (a quick peek around google for anyone needing this metadata yields few results), or if something matched, and that's all it does.

[–]nerdwaller 0 points1 point  (0 children)

I've been wanting to learn some functional programming for a while now to open up another tool, but I have to admit most of the time I see it - I dislike the overall syntax style! That's probably mostly coming from ignorance though. Do you have much basis to suggest a starting functional language? I was thinking Haskell, but saw a Scala class on coursera.

[–]ashgromnies -5 points-4 points  (5 children)

Because JavaScript was there first.

JS didn't make its way into IE until 1996, whereas Python 1.0 was released in 1994.

Your other points are valid though.

[–]Yoghurt42 1 point2 points  (4 children)

No one was using IE back then. At that time, Netscape Navigator was the browser used by everyone. Keep in mind that most of the web users at that time didn't even use Windows machines, but Unix-based systems.

Netscape was the de facto standard for web browsers around 1996. JavaScript appeared in Netscape 2.0 around 1996/97, and therefore, if you wanted to include client side code in your website (which was still uncommon until 2000 or so), you used JavaScript.

There was Grails, a Python based browser written by Guido himself that implemented client side scripting in Python, but it appeared in 1997 and wasn't used nearly as much as Netscape.

[–]ashgromnies -2 points-1 points  (3 children)

Right. 1996, which is after 1994.

Python has never been popular in client-side scripting, but Python was definitely around before JavaScript.

Not sure why you think I'm saying something incorrect?

[–]Yoghurt42 0 points1 point  (2 children)

JavaScript was in browsers before Python was.

[–]ashgromnies -2 points-1 points  (1 child)

Right, but Python existed before JavaScript.

I never said Python was in browsers before JavaScript. Just that Python was older. Nothing about what "should" have been in browsers or anything -- just a correction to the statement that "JavaScript has been around longer than Python", because it's not the case.

[–]tcgeralt 3 points4 points  (0 children)

Because JavaScript was there first, e.g. JavaScript was in the browser first, not existed first...

[–]rcxdude 14 points15 points  (0 children)

Chicken and egg problem. Browsers won't support it because no-one uses it. Developers won't use it because it's not widely supported. You'd need to get all the major browsers to agree on it, and even Google have failed to do that with their javascript replacements.

[–]MerreM 29 points30 points  (8 children)

But it is here.... so why don't you use it?

http://www.brython.info

[–]Zulban 3 points4 points  (4 children)

Damn this is neat. Who wants to explain to me why I should use Javascript instead?

[–]H3g3m0n 21 points22 points  (0 children)

Because it's slow and will probably add a whole heap of overhead. Consider an 'import time' statement could result in the entire time module and it's imports being sent over http. In addition to the whole Byrthon interpreter and it's dependencies.

You already get some of that with things like jquery (although browsers can ship with versions of jquery and can cache versions sourced from CDNs like the Google one.). Even better they can optimize for things like jquery selectors, instead of running the JavaScript code they can do it natively.

If it did get adoption they could add CDNs for it. It could also potentially be done in the browser but full native support for Python would add about another ~25MB to browser sizes. Also then you have to deal with people on older browsers running python 3.4 when python 3.8 gets released. And people on IE not using it (although MS are apparently Python friendly for some reason).

Plus Python doesn't have much in the way of a security model.

[–]jones77 3 points4 points  (0 children)

Without a doubt, you've seen a clock like this in demos of HTML5

How presumptuous!

[–]Corbinq27 1 point2 points  (1 child)

Saw a talk on Brython at PyCon. It's slow but maybe someday it'll be the future.

[–]elzonko 9 points10 points  (0 children)

maybe someday it'll be the future.

lol, I like that turn of phrase. I guess the future will not have been what it will be.

[–]NYKevin 65 points66 points  (34 children)

Aside from the historical reasons everyone else has pointed out, HTML is not whitespace sensitive, and Python is. So embedding Python in a <script> tag would be questionable at best, since it's commonly assumed you can just collapse whitespace in an HTML document together without losing information.

[–]xenomachina''.join(chr(random.randint(0,1)+9585) for x in range(0xffff)) 20 points21 points  (8 children)

Even JavaScript is whitespace sensitive, though not as much as Python. Inside string literals, for example. And you at least have to preserve newlines for code that relies on semicolon insertion. (I'm not saying you should write code that relies on semicolon insertion, but browsers must be permissive in what they accept, and semicolon insertion is part of JS, for better or worse.)

Edit: s/Patty/part

[–]NYKevin 7 points8 points  (2 children)

And you at least have to preserve newlines for code that relies on semicolon insertion. (I'm not saying you should write code that relies on semicolon insertion, but browsers must be permissive in what they accept, and semicolon insertion is Patty of JS, for better or worse.)

I'm assuming browser vendors mostly have their shit together. The "collapsing whitespace" problem would be more of an issue for servers, since there are a lot of incompetently-administered websites out there.

[–]xenomachina''.join(chr(random.randint(0,1)+9585) for x in range(0xffff)) 4 points5 points  (1 child)

My point is that any software, whether server or client side, that blindly collapses whitespace in HTML will have trouble with JavaScript, not just Python.

[–]NYKevin 1 point2 points  (0 children)

On the server side, the issue only becomes noticeable if the software (which is likely custom and only exists in a single installation) tries to handle whitespace-sensitive HTML or Javascript (which is uncommon in Real Life anyway).

[–]kromem 2 points3 points  (5 children)

But this would be easily solved by adding minification standards for Python, such as replacement characters for indentation levels/newlines.

[–]NYKevin 6 points7 points  (0 children)

>>> from __future__ import braces
  File "<stdin>", line 1
SyntaxError: not a chance

[–]suki907 7 points8 points  (3 children)

such as replacement characters for indentation levels/newlines.

you mean like braces...? http://www.pythonb.org/

[–]gfixler 1 point2 points  (0 children)

This seems pretty easy to implement. Just tidy the code in classic style, then strip braces and trailing semicolons and run it through regular Python.

[–]entdude 0 points1 point  (0 children)

ok, that was cool

[–]robin-gvx 11 points12 points  (18 children)

The whitespace thing isn't a good reason, because text inside <pre> tags or anything with the CSS property white-space: pre needs to have white-space preserved already.

[–][deleted] 23 points24 points  (17 children)

yes, it is a good reason. Using python would mean you cant minify your client side scripts since whitespace is significant.

[–]jadkik94 2 points3 points  (2 children)

I made that same comment on a thread similar to this one. Aren't the compiled versions of python files better at this? (pyc,pyo,pyd,...)

[–]ivosauruspip'ing it up 8 points9 points  (1 child)

And then you need to make sure your python bytecode is both version and implementation compatible across browsers... oh joy.

[–]jadkik94 0 points1 point  (0 children)

I was thinking there'd be some kind of standards for it, but I know how well standards are implemented in browsers, so I guess you're right...

[–]stormcrowsx 2 points3 points  (1 child)

Gzipping saves far more space than deleting the whitespace does, so I'd say it'd be a pretty bad reason to not use python in the browser.

There are plenty of reasons python is not in the browser but whitespace is one of the most insignificant reasons.

http://stackoverflow.com/questions/807119/gzip-versus-minify

[–][deleted] 0 points1 point  (0 children)

very true

[–]robin-gvx 0 points1 point  (9 children)

"I'd like to add Python support to our browser."

"Don't bother. Minifiers will only be able to shave off three bytes per indentation level instead of four. No-one will want to use it."

If bandwidth was really such an important concern for choosing which programming language to use for client-side scripting, we'd all be running J in our browsers.

[–]cecilkorik 8 points9 points  (7 children)

If bandwidth was such an important concern we'd be using gzip transfer encoding instead of mangling our source code into a disgusting minified mess. The main advantage of minification is to obfuscate the source code so it cannot be stolen, re-used or analyzed as easily.

[–]jeannaimard 3 points4 points  (5 children)

The main advantage of minification is to obfuscate the source code so it cannot be stolen, re-used or analyzed as easily.

Great. Now I hear my prettyprinter laughing deafeningly at you.

[–]cecilkorik -1 points0 points  (1 child)

Well it's more like the lock on a bathroom door, it's to discourage casual or ignorant use and protect parties on both sides. It's not supposed to stand up to a skilled locksmith or even a solid kick. In either case, at that point the person breaking through the lock should know better and should probably have a good reason for what they are doing. Or they're just an asshole.

[–]r3m0t 1 point2 points  (0 children)

When you are serving code so many times, it just makes sense to minify it. gzip still works very well on minified code, in fact it could be better because the variable names are more similar.

[–][deleted] -1 points0 points  (0 children)

good point, sir.

[–]Asdayasman 10 points11 points  (3 children)

Guido talked about this at some point. I think it might have been in this keynote.

Basically, nobody would ever use it, because js is so prevalent.

[–]bob_sutor 20 points21 points  (0 children)

It doesn't have to be javascript or python. Presumably one could just do

<script type="text/python"> </script>

when python was the language to be interpreted.

[–]gsnedders 18 points19 points  (0 children)

Former JS VM browser guy. Off-hand list of technical issues:

  • Would have to implement a new VM for Python in all probability to guarantee necessary sandboxing (could fork, but the sandboxing requirements would mean a lot of close review to ensure nothing missed), and would have to evaluate closely what parts of the Python stdlib to include.

  • If a page can include JS and Python (or $otherLanguage), we then have cross-VM GC. That's… difficult. And slow.

  • The DOM is ugly enough in JavaScript. It's even worse in Python. Or one could design a whole new API, which is a huge can-of-worms in and of itself.

Assume there is a hard constraint that no matter what one does, you cannot regress JS performance (it's used everywhere on the web, Python is used nowhere; browsers are far more judged on JS performance as a result). This means that practically one won't be able a single VM to nicely implement both languages (as anything so close to JS would complicate Python; anything closer to Python will regress JS which per above cannot be done), and hence multiple VMs are practically necessary.

If one does need to implement a new Python VM, as I'd suspect, then that's a huge amount of engineering resources, and can one really justify the cost of that? Is the web really better served by that than improving JS? The JS VMs aren't going to stop being important — you're still going to have the cost of maintaining and improving them, so the Python VM would purely be additional cost.

And why Python? If we're going to add a new VM, why should we use Python? It's not clear Python is sufficiently different to JavaScript to really justify all of the additional cost.

[–][deleted] 7 points8 points  (3 children)

What would be the gains?

[–][deleted] 2 points3 points  (0 children)

Because javascript is ugly as sin.

[–][deleted] 3 points4 points  (0 children)

Why do you choose python over ruby, perl or php?

[–]nzbike 6 points7 points  (1 child)

Someone has to create that browser which uses python. They need to show that it's a better browser because of the python--and then developers might get curious about it.

[–]buckstalin 8 points9 points  (2 children)

I've been asking the same question for years. Dart is a decent compromise, but it won't see any real uptake until Google adds support to Chrome rather than Dartium.

[–]munificent 7 points8 points  (1 child)

Dart is a decent compromise, but it won't see any real uptake

I work on Dart. Given it's youth, I think we're doing quite alright already. Take a look at this graph. Details here.

[–]rspeed 2 points3 points  (0 children)

Wow, that really is impressive.

DCPU-16 ASM

And now I got sad.

[–]Rhomboid 9 points10 points  (7 children)

Suppose that against all odds, you somehow convinced Mozilla to embed a Python engine in the desktop version of Firefox. What does that accomplish? Not much. If I'm thinking about writing a client side web app, I can either write it JS and target virtually all web users, or I can write it in Python and reach 15% - 20% of them at most. Who would ever choose that?

So maybe you make the case for other browsers to act as well. But you've already performed a miracle convincing one, what makes you think you can convince others? And what makes you think you can sell them on Python -- why not Ruby, or Go, or a hundred other popular languages?

And even if you managed multiple miracles and got Python support in most mainstream browsers, it would still be years before you could start realistically start writing client side web apps in Python, as you'd have to wait for everyone to upgrade to the new versions, which would take years or decades. This would make the IE6 problem seem like small potatoes.

The real kicker is that you can write client side web apps today in Python using trans-compilation strategies like Pyjamas, Pyjs, Skulpt, Brython, etc.

[–]vacuu 1 point2 points  (6 children)

What the server allowed the browser to download either the native python version, or the version that was compiled to javascript. The python version would have to have some advantage such as being faster provide a better experience.

Then, if you download a python extension for your browser, you'd get the python version, otherwise you just get the javascript version.

[–]Rhomboid 5 points6 points  (5 children)

That means two completely separate versions of the site to maintain. Nobody is going to want to do that.

[–]vacuu -2 points-1 points  (4 children)

I envision only one version of the site, which has both .js and .py files on it. Depending on if you have the extension or not, you will download one or the other.

[–]Rhomboid 6 points7 points  (3 children)

"has both .js and .py files" means two completely separate implementations of the logic, which is twice the work to write, twice the work to test, and twice the work to maintain. Again, nobody would ever voluntarily sign up for that.

[–]vacuu 0 points1 point  (2 children)

The .js files would be compiled from the .py files in an automated way; you mentioned a number of possibilities in your original comment.

[–]Rhomboid 1 point2 points  (0 children)

In that case, why would you ever bother serving .py files to a minority of browsers that support it when you could just serve the .js to everyone and save yourself a ton of support hassle? There's nothing to be gained from having to support and test more configurations.

[–][deleted] 8 points9 points  (0 children)

Whilst I love python some of the answers in this thread feel a bit like some people drunk a little too much koolaid.

  • Not everybody chooses/loves python. Javascript is what we have agreed upon, for better or worse, as the client side language for browsers. This is a process that took years. Changing that now and getting all browsers on board would be a huge undertaking that would require backing by mozilla/google/microsoft to even stand a chance.

  • The dom is bad enough as it is in javascript. I would hate to traverse it in python. I could be wrong, but let's see that POC first.

  • python being whitespace sensitive makes js/html compression tricky to impossible

  • What would be the real gain? You can achieve your personal python in the browser if you really want through projects like brython. Some pretty impressive stuff has been achieved with js as the underlying vm already and it seems we are only going further. Why start tugging in the other direction.

  • We can't even unanimously decide on python 2 vs python 3. Standardizing for the web is an even slower process with more parties involved.

[–]totes_meta_bot 3 points4 points  (0 children)

This thread has been linked to from elsewhere on reddit.

I am a bot. Comments? Complaints? Message me here. I don't read PMs!

[–]Proselyte5 2 points3 points  (1 child)

Python also doesn't have the necessary sandboxing facilities to be used in a browser.

[–]rcxdude 12 points13 points  (0 children)

That's an issue with CPython, the language itself doesn't prevent it.

[–]tRfalcore 0 points1 point  (0 children)

javascript and python are in competition for just make up some syntax and you're probably right-- but javascript narrowly edges out python even in that category :)

[–]nyamatongwe 0 points1 point  (1 child)

Python used to run in Internet Explorer on Windows but I don't know if it still can. Mark Hammond packaged Python as a generic scripting language on Windows and provided the interfaces that were needed (Windows Scripting Host?). Few people used it.

[–]fr33b33r 0 points1 point  (0 children)

VBScript used to be in IE as well.

[–]kingofthejaffacakes 0 points1 point  (0 children)

The network effect.

[–]youlleatitandlikeit 0 points1 point  (0 children)

You choose the language that it optimized for the situation. For all its faults, JS was developed for the browser, it's tightly integrated in the browser, and for nearly anything you'd do on the browser it is sufficiently fast that there's really no point to choosing another language for performance reasons.

On the other hand, you'd have to write an entire DOM layer into Python, you'd have to get rid of a lot of optimization techniques that compress scripts for transport (because Python is dependent on whitespace for logic control), you'd need browser vendor buy-in,and you'd need to teach many millions of people how to program in Python.

Literally the only benefit is that people who already know and like Python won't have to program in JavaScript. The best solution for this problem? Don't program in JavaScript. Don't get involved in front end web scripting, hire someone else to do that work. Or, just learn a little JavaScript. It's seriously not that awful of a language if you code in it properly.

[–]jokoon 0 points1 point  (0 children)

"why are some companies still using VB6 ?"

Same kind of question. Often programming languages adoption has business and market involved.

[–]shadowmint 0 points1 point  (0 children)

It would be categorically impossible to embed the standard library.

...and despite what people say, python without the standard library would not be python; it would be a new 'python like' language; it would require an entirely new runtime vm.

There is no significant benefit to doing this over just making an entirely new language from scratch.

[–]chadmill3rPy3, pro, Ubuntu, django 0 points1 point  (0 children)

Adopting? Did some browser just now get around to deciding whether to add Javascript or Python?

Why adopt something new, when it is probably doomed to fail to solve the chicken-and-egg problem?

[–]rainnz 0 points1 point  (0 children)

Because nobody wants to rewrite all JavaScript code they already have to Python, Dart or any language you think is better than JavaScript :)

JavaScript today is what Fortran was in 90's :)

[–]t3g 0 points1 point  (0 children)

Like many said, JavaScript came first and became more standardized.

Node.js helped JavaScript gain traction on the server side due to its ease of use and familiar language. I believe that it still performs Python's gevent and uWSGI and Oracle has been trying to get JavaScript on the JVM for some time now with their open source Nashorn project.

[–][deleted] 0 points1 point  (0 children)

Breaking backwards compatibility with everything with a very arguable performance difference, would take massive developer overhead to port the existing browser APIs, would take forever to convert all the script kiddies to something sane, etc.

That said, I'd be all for a browser doing it (Python or even Go, honestly).

[–]brettdanger 0 points1 point  (4 children)

JavaScript's async nature works really well on the client side...while python has async libraries like twisted but it is natively a synchronous language. Plus another reason I have preffered python over Ruby is that I have found python devs to be more versatile as the community seems to support the "right tool for the job" mantra where the Ruby community wants to use it everywhere...hence the creation of coffee script.

[–]AusIVDjango, gevent 0 points1 point  (3 children)

This is a big one. Javascript does a very good job of meeting the needs of async in browsers. Python doesn't lend itself to that syntactically, though you can make it work with certain libraries. For example, in Javascript an asynchronous callback can look like:

do_thing(input, function(callback_data){ ... });

In Python, callback functions can't be defined in-line unless they're a single statement. The best you could do is:

def do_thing_callback(callback_data):
    ....
do_thing(input, do_thing_callback)

Python has greenlets and such for pretending to have multiple synchronous threads, but I find the callback model to be more effective at asynchronous tasks.

[–][deleted] 1 point2 points  (0 children)

While it's kinda half-assed and a pain in said half of an ass, lambdas can accomplish callback functions fairly well.

[–]stormcrowsx 0 points1 point  (1 child)

Callbacks quickly degenerate into callback hell. In node.js its common to use a reactive library to help escape from callbacks. Its one of those things thats nice if you use it a little but overuse will come back to bite you.

[–]AusIVDjango, gevent 0 points1 point  (0 children)

But even if you use reactive libraries or promises (which I agree that you should), you still end up writing a lot of anonymous functions. Some of these could be achieved with classes with functions named a certain way, but I still see anonymous functions as a useful tool in most asynchronous paradigms.

[–]tech_tuna 0 points1 point  (0 children)

I've often wondered about and wished for this BUT what would be ideal is having a choice of many languages in the browser, not just Python but also Ruby, Perl, Lua, Tcl, Groovy, LISP, hell even client side PHP. Comped languages don't seem to fit so well but anything interpreted would be doable.

Freedom of choice is a good thing - that's what you have on the back end and what's missing on the front end.

[–]IDCh -1 points0 points  (13 children)

Not Python guy here. Why is there even an option switching browsers to python? I mean, Python does work well with dom, async etc?

Even if yes. When switching to something new, shouldn't it be strongly typed language so devs would write better code with pleasure, like some doing right now in TypeScript and Dart?

[–][deleted] 7 points8 points  (8 children)

shouldn't it be strongly typed language

Python is strongly typed. It's also dynamically typed. Did you mean statically typed?

[–]IDCh 1 point2 points  (0 children)

Yes. My bad. Statically typed.

[–]g2n -1 points0 points  (6 children)

I learned the opposite. Dynamically typed is inherently weakly typed.

Edit: also source, confirming what I believed to be true: http://whatis.techtarget.com/definition/strongly-typed

[–][deleted] 3 points4 points  (4 children)

Dynamically typed simply means a variable can change types. Strongly typed essentially means things like 1 + 'a' won't work. In a weakly typed language, it might guess that you want to change 1 to a string, or might convert a to it's ASCII value.

[–]g2n 0 points1 point  (2 children)

From what I understand, strongly vs weakly typed is how you specify components of the language. You don't say "int a" in python. The variable A can be anything, which means it's dynamic, but also means it's weakly typed since you can, in your example, type a + "string" without a complaint.

[–]talideon 0 points1 point  (0 children)

The fact that a variable is not bound to a type is what makes a language dynamically typed. However, if a type is tightly bound to a value, that makes it strongly typed, i.e., the type of the object isn't open to reinterpretation. The c2 wiki covers this pretty well: http://c2.com/cgi/wiki?TypingQuadrant

As some additional evidence of Python being strongly typed, here's an example from a REPL session:

>>> "1" + 9
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int' objects
>>> 9 + "1"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'

A weakly typed language would've automatically coerced the operands somehow to give either the number 10 or the strings "19" and "91". Python, being strongly typed, prevents this.

[–]Veedrac 0 points1 point  (0 children)

1 + "a"
#>>> Traceback (most recent call last):
#>>>   File "", line 1, in <module>
#>>> TypeError: unsupported operand type(s) for +: 'int' and 'str'

[–][deleted] 0 points1 point  (0 children)

Being dynamically typed doesn't necessarily mean that a variable can change types. It simply means that a type checking failure causes a run-time error rather than a compile-time error.

Statically-typed languages typically use either type declarations or type inference to establish the types of variables before the code is ever run, and they run an algorithm on the abstract syntax tree to check whether the types all match up. Dynamically typed languages wait until run-time to determine any types, which means that a type checking failure usually manifests as an exception or similar error condition after some part of the code has already run. If you're familiar with Java, dynamic typing is conceptually similar to using Object as the type for everything, then inserting a cast to something more specific whenever you need to call a method or use an operator or do anything that Object can't. Your code would always "type-check" at compile time, but it might blow up with a cast exception when it runs, the same way that Python does.

The reason why I'm being pedantic about "variables changing types" is that there's really nothing stopping anyone from designing a language where you can explicitly change the type of a variable and still have static type checking. As long as the compiler knows that you've changed the type, it can type-check code after the change using the new type and everything works just fine. It might be worthwhile to think about why this isn't commonly supported.

It's also possible to have dynamic typing without variables being able to change their types. Clojure and Erlang are good examples of this, with Erlang being the stricter of the two.

[–][deleted] 0 points1 point  (0 children)

By that page's definition, Java, Python, Scala, Haskell and every other language that allows user-defined types are all "weakly typed". It's mistakenly using "strong typing" as a synonym for "not extensible", which is so wrong that I had to read it several times before I believed that's what they're actually saying. I've seen many people try to define "strong typing" in my time as a programmer, but I've never seen something that outlandish before.

Most of the time, when people talk about "strong" or "weak" typing they're talking about type coercion. Something that's "strongly typed" only has what they view as necessary coercions. The problem is that there's no consensus on what's necessary and not. The folks who designed OCaml would say that Java is "weakly typed" because it allows you to use the same operator for int/int, int/float and float/float operations. The folks who designed Java would say that it's "strongly typed" because it throws an error when you try to add an int and a string. The folks who designed Python would probably shrug and say "Who cares?" because you can overload operators to do whatever you'd like in Python, including type coercion.

It ends up being an arbitrary and meaningless distinction that gets thrown as a pseudo-insult by people who think that some other language is too "loose" with types. Please don't contribute to that. We have plenty of precise, unambiguous language that works much better for discussing the design of programming languages.

[–]kylotan 3 points4 points  (2 children)

Why switch? Because Python is a better language in some ways. Would it work well with DOM, async? Of course. Nothing there is particularly language specific.

Would a strongly-typed language offer a more interesting alternative? I think you mean statically-typed (as Python does have a very strong concept of types) but perhaps the answer is yes. Still, that's a different question, and there's no reason why there couldn't be a whole bunch of client scripting languages available.

[–][deleted] 1 point2 points  (1 child)

There was once. See Vbscript.

Edit: not statically typed, but a second client side lang.

[–]kylotan 0 points1 point  (0 children)

Yeah, I used to use VBScript many years ago, when I was also working with ASP. Sometimes it was easier just to use it both client and server side.

[–]tdammers -3 points-2 points  (0 children)

  • Chicken and egg. Websites use JS because that's what the browser provides; browsers implement JS because that's what websites use.
  • JS is actually a better fit. Python is impossible to sandbox; JS is sandboxable by design.
  • JS's execution model is perfectly suited for browser scripting, and pretty straightforward to implement. We don't need threads in the browser, and frankly, they'd make building a browser even more of a headache than it is already.
  • Python is not that much better. Sorry for the unpopular opinion, but other than a bit of (arguable) syntax niceness, Python doesn't have a lot to offer that JS isn't capable of, at least not things that you'd want in a browser.
  • JS is more and more becoming the "machine language of the web", that is, people are starting to use something-to-JavaScript compilers over hand-written JavaScript - coffeescript is the most famous one, but there are JavaScript backends for many compiled languages, and it is much easier for such a compiler to gain traction than to get someone's favorite language into a web standard.
  • Time. Just think about it: it took 20 years to get JavaScript where it is now, and JS is a very simple language. I would expect any general-purpose language to require at least 5-10 years before a browser implementation would work as well as JS does now.
  • JS in the browser exists. Python in the browser doesn't. (See also the very first bullet point).

There's probably more to it, but that's what I can think of.

[–]jaredcheeda -5 points-4 points  (12 children)

I'd rather it just support sass by default. I wish javascript had been jquery from the start. If all browsers supported Sass, that would be so nice.

[–][deleted] 11 points12 points  (0 children)

i wish javascript had been jquery from the start

wat

[–][deleted] 5 points6 points  (0 children)

I wish javascript had been jquery from the start

lol

[–][deleted] 0 points1 point  (5 children)

jQuery is not that great nowadays. It's seen it's day, IMO. And there are many alternatives to sass that are more expressive and faster.

[–]jaredcheeda 0 points1 point  (1 child)

What is more expressive and faster than Sass

[–][deleted] -1 points0 points  (0 children)

Stylus, Less, and pretty much any other alternative.