Ya know, it’s funny. I like Python. We like it enough to actually use it in embedded products. It has its limits, and we use other tools where it doesn’t fit. Python in a browser seems like a keen idea.
But JavaScript vs Python isn’t really the key thing for me on the web. It’s the uncanny pile of other software one uses to build a man-machine connection that flummoxes me. It’s the CSS, the DOM, the events, the browser API, the ever churning massive pile of complexity that interactive software has become with the voluminous W3C specs, expressed in near BNF form and full of edge cases and backwards compatibility, all so every thing my user does can be observed by myself a few megacorps. I honestly wouldn’t care if I could write it in Fortran. It’s such a minor wart of the whole mess.
Caring about which actual language you can use in all the script tags of a jacked up text format feels like caring which font is being used in your favorite hot piece of government legislation.
In some ways I prefer javascript for lots of tasks. Easier to write functional style using filter and maps and lambdas, than python's weird itertools and list comprehensions.
Same, python is my goto language so its (minor-ish) deficiencies annoy me a lot.
- Annotating nested JSON objects is a pain in the ass. You need a bazillion intermediary classes.
- Sometimes you need a 3ish line lambda, because you have an beefy if-condition or a try-catch. Too bad multi-line lambdas aren't a thing.
- Function hoisting in JS is actually really nice, not just for the previous scenario. You can define utility functions at the bottom of a function and they'll be available to anything before that definition
- I wish python had a more succinct way to destructure dicts / objects like JS does, outside the new switch statements. (ie doesnt require imports, doesn't require typing the object name over and over.)
- Code completion doesn't work for list comprehensions because the for x in xs comes last :(
Agreed with @richiebful1, multiliners are better as standlone funcs, and I'd say (personal opinion) that they'd be better here. I like functional a lot but I don't lambda up unless it's more or less a one-liner or a kind of control structure, where they can get large but that's the point.
I've had to deal with too much shit code where lambdas within lambdas are considered hot.
Added bonus, the names are useful (naming is hard because if you do it right you are adding valuable information).
I'm sure there are cases where doing it your way are better, but I can't think of them.
If `apply` is your own code, you could refactor it to
@apply(lst)
def naming_is_hard():
...
I came to python after working in JS fulltime for years, and used to complain about the exact same thing. After I started using decorators, I stopped complaining about the single-line lambdas.
For any non-python devs looking at my example, it's equivalent to
Problem with list comprehensions are that it's often not easy to see what you're trying to do. Like, I have some objects I want to group by a property, and then make a map containing the sum of some other property of those groups but only if it's value is above 5.
result = {
key: sum(el["myValue"] for el in elements)
for key, elements in groupby(
sorted([el for el in my_list if el["myValue"] > 5], key=lambda el: el["myKey"]),
key=lambda el: el["myKey"],
)
}
to me that's incomprehensible. You have to read it the wrong way, and it's not really clear what the intention behind each step is. Like, the filter is in the middle!
keyOf = itemgetter("myKey")
valueOf = itemgetter("myValue")
filtered = (item for item in myList if valueOf(item) > 5)
grouped = groupby(sorted(filtered, key=keyOf), keyOf)
result = {key: sum(valueOf(item) for item in group) for key, group in grouped}
OP wrote the code as if the list items were dictionaries, so I just made that pythonic. If they are objects whose attributes we care about then we can get rid of the two getters altogether which are mostly there to make the code more legible but also remove duplication. You could also switch them to attrgetters.
Yeah that Python would not pass my code review. Rule of thumb is don’t nest list comprehensions, and if you have to try to keep it to two. Checkpoint the results info a variable. You aren’t supposed to chain like that in Python.
> You might have noticed that methods like insert, remove or sort that only modify the list have no return value printed – they return the default None. [1] This is a design principle for all mutable data structures in Python.
> Footnotes
> [1] Other languages may return the mutated object, which allows method chaining, such as d->insert("a")->remove("b")->sort();.
Yeah ... In that case I would write a function to return this result dict in a more imperative way in python -- but perhaps that's cuz i am not that great of an engineer/python dev. But what I can see is that the syntax of Kotlin (which I've never written) you've provided is a lot cleaner.
Python also has filters maps and lambdas, and lots of third-party support for other functional ideas (e.g. the Toolz library).
Though personally I really like itertools and list comprehensions. (And list comprehensions are pretty functional as well, they were inspired by haskell I blieve.)
I’m primarily a Python dev but I’ve been recently working on a React codebase. One of the things that’s been driving me insane is how the default way to import things is without a namespace, aka:
`import {foo} from ‘bar’;`
This makes reading code really really hard as I can’t tell where some symbol is coming from.
There also seems to be a general aversion against using classes to model types. Instead we have a host of functions that manipulate JSON/dataclasses, which means business logic is scattered around 10 different places!
Yeah there's a lot of weird design choices in JS code. I'm not sure all of them really make sense given the modern state of the language but old habits die hard.
> This makes reading code really really hard as I can’t tell where some symbol is coming from.
That's why you use Typescript then you can just hover something or ctrl-click it.
Anyway Python is exactly the same in my experience. Sometimes people `import numpy as np` or whatever but most of the time they `from foo import X, y, z`.
I don't like more the default exports / imports. In this case one can import using completely different name and then it is even harder. Also it won't be changed while renaming utill the developer will go in all other places and do it manually
My problem is that I find TypeScript written by another person entirely unreadable. Python written by another person? Relatively intuitive, even if it's written badly.
I love JavaScript (yes, I'm one of THOSE people) and like what TypeScript brings to the table but it quickly becomes hard to read as the code becomes more complex.
Python has always had a readability advantage... up to the point where people start doing code golf and nesting multiple comprehensions together.
Python beat Perl in the 90s-2010 era thanks to its readability which was always advertised as a supreme advantage. Of-course Python 3.x is more complex, but even as an occasional Python user who doesn't like Python that much, I can still dive into an OSS python project and understand what its doing with little prep or Googling needed.
Can't really say that for most programming languages with the exception of Go.
What would you say it is about TypeScript that makes the code harder to read as it becomes more complex? Just the additional type annotation syntax, extra concepts like generics and/or the accompanying more exotic features of TS, the type definitions physically adding many lines of extra code, something about TypeScript that encourages code to be written in a certain way that is different and more complex?
Would this be in a different way to the equivalent JavaScript code? Or do you just mean like physically, the layout of the code with the additional TypeScript syntax makes it appear more nested/indented and more difficult to parse?
Ah, this is a facepalm moment in that I had completely misread the initial comment not as being a comparison of JS/TS to python, but of JS to TS then a further comparison to python. Now it makes much more sense!
I agree here, Typescript is actually quite a nice language to write in, but the complexity of setting up a project and your own compiling pipeline and everything causes my head to spin.
I get it. As an Old, I have watched the web evolve, threw out my HTML 2.0 book not too long ago. Netscape floppies and Trumpet Winsock. CSS being invented by people who, I don't know, did they ever hear the four principles of Contrast, Repetition, Alignment, and Proximity? I feel like they heard one of them. A programming language for it that had a ten day deadline. Tables abused like Russian nesting dolls shellacked into layers just to serve as doorstops. Dead-end evolution that thrashed around in the tar pits for a long time, screaming before its expiration: Flash.
And yet the network effect would keep this going even if you had a team of a thousand brilliant people design a rational replacements for all of this ad-hoc cruft that has traditioned its way into being something like a standard.
The article describes what is possible with Python in a browser, but misses an important detail: how much memory it consumes and how much CPU it uses.
Python is not a fast language. For example, consider a simple loop:
for i in range(10):
pass
In Python, this will be compiled into: a call to range(), heap allocation of an Iterable, calling getIterator() on an Iterable (which might also do allocation), calling next() on an Iterator while catching for StopIteration exception (and calls are often slow in interpreted languages). While in C we could just have a loop without any calls.
I remember how I had to use a Dart-based web application (compiled to JS) in one of Google's advertising products. The script weighed around several megabytes and everything was so slow. Furthermore, there also was a small and useless "what's new" applet, and it probably was shipped with a separate copy of Dart runtime because it weighed several megabytes too. Obviously this was a product intended to be used only on latest MacBooks, not on a Windows XP laptop.
It is totally fine to write such application for youself, or maybe for internal use, but if you are a corporation with millions of users, I think you should pay a little attention to performance and choose a better technology. Or, if you are of a Google scale, find a way to optimize the code.
The incumbent is not C, it is JavaScript. Initially JavaScript was also simply run on an interpreter. And it wasn't particularly fast until it got considerable attention by Google & Co, and browsers competing for "who can run this silly JavaScript benchmark the fastest".
Then complaining about how more abstract languages like Python are inefficient compared to C is not fair. These calls to range and Exception handlers are there on purpose, to help the developer avoid writing boilerplate code for the millionth time, and focusing on the problem itself, writing cool things.
C would be a terrible language for the Web I would argue. Web "development" was never a thing for the greybeards and "I dream in assembler"-types (not that I want to exclude anyone, I mean it didn't attract that crowd and another instead).
Any challenger for JavaScript must be approachable, easy to understand, easy to write and read. Easy to fix and modify (most "Web Apps" are already obsolete the moment they hit deployment).
Heck, why not go full x86 instructions? Hm, then there are millions of iPhones and Androids on the Web that are not x86... Write our own Assembler?! Let's call it WebAssembly!
I didn't write that you need to program your website in C. Obviously it is more convenient to use high-level languages. Everybody wants to write less code. I use Python myself, although not for work. But it would be a good idea to design high-level languages so that it would be easy to compile and optimize them.
For example, JS has no classes and uses prototype inheritance, and you can even change prototype at runtime. This is absolutely useless, inconvenient feature and it makes optimization (like JIT compilation) much more difficult (for example, before calling a method you must ensure that the prototype didn't change, the method was not replaced and so on).
In 95% (arbitrary number) of cases you just need classes with a fixed set of fields and methods known at compile time, which is very optimizer-friendly.
On the opposite: not only it isn't unfair, it's absolutely necessary. Over the years we witnessed the birth of so many languages, and each of them promised to be more safe than C while keeping performance "close to C". Now we have a cornucopia of programming languages, many of them are definitely "safer" than C (in the sense that it is more difficult or impossible to create some types of errors like buffer overflows), but in terms of performance there still seems to be a considerable gap. Having bad performance is bad for the users, bad for the environment (in terms of direct energy consumption and more power-hungry hardware needed), and bad for software companies (who are limited in what they can do).
I believe Hacker News’s backend is written on a Lisp (or, more precisely, Arc). In this context, JavaScript, Python and C are being debated for a role of client-side language handling DOM events.
Also, C and Lisp are different breeds. It’s wrong to put them in one bucket of “greybeard” languages. Some Lisps gained traction in the front end space (see ClojureScript).
Hacker News does have a bit of frontend, written in JavaScript. You can see some here https://news.ycombinator.com/hn.js, I'm unaware if it's everything or just a part.
You can transpile this to a more efficient systems language using py2many or another transpiler and all these problems go away if you're willing to sacrifice some of the dynamic features of the language and embrace static types.
The difference is just scale of commercial investment.
JS got fast because Google and friends started an arms race on it, since the adoption scale justified pouring resources into optimizing efforts.
Python has a large amount of developers' mindshare, which makes its use in the browser potentially worthwhile for large interests invested in the ecosystem (e.g. Anaconda). However, the problem is so big that the cost/benefit ratio for any given group that would want to tackle it, is still fundamentally unattractive. Python developers are legion, but still not a patch on JS users.
This is where WASM is a potential game-changer: by effectively dividing the problem in two and sharing the load for the first half with a lot of other ecosystems, the cost/benefit calculation improves significantly enough that commercial interests seem more willing to invest. CPython speeds, after the temporary v3 setback, get better and better every year; likewise WASM speeds. If their coupling becomes normal, enough effort will go into it that this consideration will just go away.
WASM won't change anything. Python is compiled into bytecode and slowly interpreted. Any optimizations at WASM level won't change the bytecode. For example, they won't turn range()-based loop into a loop with a counter.
Also, it is unlikely that compiling to WASM will be more effective than to native code because browser cannot afford spending as much time on optimization as a native compiler. Therefore WASM will always be slower than a native code.
If you want to benefit from amazing optimizations that were done for JS, then it is better to transpile your Python code directly into JS.
> Any optimizations at WASM level won't change the bytecode.
No, but the bytecode gets better and more efficient with new releases. The point at which it becomes acceptable depends on the use case, of course.
> it is unlikely that compiling to WASM will be more effective than to native code
It doesn't have to be more effective, it only has to reach a point where the penalty is worth paying. After all, JS is slower than C, but you accept that as a part of larger trade-offs on manpower, ease of deployment, etc. Once the trade-off becomes acceptable for the use case, absolute benchmarks stop being relevant.
> If you want to benefit from amazing optimizations that were done for JS, then it is better to transpile your Python code directly into JS.
Why stop there? At that point you might as well use JS, since you get the best speeds and chances are you'll have to deal with it anyway at some point. There are already solutions like that out there, and they are not popular precisely for that reason. The beauty of using WASM is that you'll probably never have to touch JS.
> Also, it is unlikely that compiling to WASM will be more effective than to native code because browser cannot afford spending as much time on optimization as a native compiler.
No reason whatever compiles the code to wasm can’t perform all the expensive optimizations and the wasm execution environment just runs it.
In fact, I would be very disappointed in a tool that didn’t run optimization passes over the code while it still had the language specific information to inform the optimizer.
Then you just pass the multi-megabyte wasm payload over to the browser to render your static content — all’s still good in the webdev world.
How long have there been any serious official investments to make Python faster though? Python just recently touched interpreter level optimization from 3.10 and AFAIK they haven't begun JIT works yet. I'm not saying that Python will ever become as fast as JS, but neither JS was not designed to be fast; it was V8 that made it fast.
Python (and JS) is not optimizer-friendly and it is very difficult to write a JIT for it (you can read a description of JIT in WebKit dev blog to get an idea what it takes to write it).
Not "official" as in "officially sponsored by PSF" but the PSF is undersupported and doesn't have extra resources for something like that. There are many longstanding projects that attempt to make Python faster by reimplementing it (or parts of it), and CPython itself has become incrementally substantially more efficient over the last few releases.
Ironically Dart was built for the web [1] (as a Dart VM for Chrome, then later on compiled to JS). One would expect something like that to do well on the web.
But if your loop is busy doing stuff that’s hundreds of bytecode ops long, is worrying about the few extra bytecode ops that a for loop takes worth it?
How else would they feel superior to someone else, if not by comparing Python/JS to C's speed all the while talking about applications where C is never going to be used?
Indeed, taken to the extreme a Pyodide-based jupyter is available[1] which uses the same underpinnings as pyscript. It might not be perfectly efficient but it's totally usable, especially considering it moves the compute from a server to the client.
At this point the main issue I've seen is the slow load time (not a problem for jupyterlite but is for pyscript). Hopefully this can improve with time and regardless I think there are a lot of cases for pyscript to remove the need for server-side code and the associated maintaince.
We added support for PyScript using Collagraph, which allows you to define single file components with a Vue-like syntax.
Excerpt from the project README:
Write your Python interfaces in a declarative manner with plain render functions, component classes or even single-file components using Vue-like syntax, but with Python!
- Reactivity (made possible by leveraging observ)
- Function components
- Class components with local state and life-cycle methods/hooks
-Single-file components with Vue-like syntax (.cgx files)
- Custom renderers (PySide, pygfx and now PyScript)
Developer time is still more expensive than 'runtime'
Talking about optimizing a range(10) loop was valid in the 90's, not today
Yes, CPython could be better, but there's Pypy. And still, CPython runs circles around the optimized Dart example you gave.
"pay a little attention to performance" cool, are we going to take all the crap out of JS that makes it inefficient?
"pay a little attention to performance" sounds to me like you're a fan of those C compilers that break code on purpose because the developer forgot some arcane detail. To what I call BS
Obviously, one loop in Python won't hurt performance. But reality is that people will try to build SPA on this technology. They will port Redux, that uses immutable objects and recreates whole graph of objects on every event. They will try to move SQLAlchemy and Django into the browser. Isn't it cool (for inexperienced developer), you just import a script from CDN and can write Django code? And this will run on a 10-megabytes interpreter in WASM.
Of course if you are writing an internal app and can provide M2 MacBook to every employee, then it is totally fine. But if you are writing applications for wide audience, it is a different thing.
I remember that one of early users of Vkontakte (a Russian clone of Facebook) was impressed that the site was loading fast on his old computer. As I remember, its JS code was written in vanilla JS without libraries like jQuery. Today the hardware is better, but if you will run SQLAlchemy in a browser to save development cost, your site's loading time won't impress users.
There is absolutely no requirement or indication that Python UI framework will have to follow the same principles as JS ones.
> your site's loading time won't impress users.
Anybody who used client-server apps in the 80s and 90s is not impressed by browser-based apps either. Those expectations can be managed in so many ways.
> They will try to move SQLAlchemy and Django into the browser.
Yes that will be a complete non starter!
I'm all for fighting inefficiencies and slow code, but fixing things like this, or Redux etc go much further than a simple for i in range() loop in Python
True, but there are limits. It’s surprising how many apps and webpages I use that are just straight up slow - things that should load instantly instead take a second or two. The web is a good application for this to some extent since there are other latencies that make this less noticeable, but they still exist.
Anything written to be performant is immediately noticeable - things just happen when you click a button. Dev time > runtime, but I’d argue some runtimes are so slow they begin to eat into user time too.
I notice this too. If I open a SPA there almost always will be a spinning circle and I have to wait like 3 or more seconds before I can see the content. In theory one can write a SPA that would load instantly, but in reality it will be a spinning circle.
I can only imagine how many people will just close the tab and move to next search result.
> But there is another aspect of the language that makes it so desirable from his standpoint: it can be extended with binary extensions that use an API that is written in C, but can be accessed from other languages. He likens Python to "a Honda Civic with mounting bolts for a warp drive". So the language can be picked up by kids who can then pop open the trunk "and bolt on warp nacelles" that allows the code to run faster than C or C++ in some cases, Wang said.
>
> That aspect is sometimes overlooked, but it means that Python can be used in ways that other, similar languages cannot. "It's not just like Node, it's not just an alternative to Ruby".
Both node and Ruby have a comprehensive C API, this is a very common language feature since binding to native libraries is unavoidable. Is there actually anything different about python here?
If you’re just calling C functions or wrapping some C++ classes CPython isn’t very hard — unpack the arguments, call the function, pack up the return value(s).
Iterator support is a little trickier but not too bad once you have it figured out. Same with overloaded functions. Array access is a bit annoying because there’s two ways to do it and you have to guess the right one if you want slices and other craziness.
Memory management can be a pain but I’d imagine it is like that whenever you’re combining two languages.
I’ve done some pretty complex wrappers and have yet to find something that just isn’t possible (within the limitations of python). I usually get the boilerplate generated from pybindgen and then start on the serious hacking.
Actually… I did find something that wasn’t possible and that was because someone thought it was a good idea to commit the raw buffer interface (whatever it’s called) before it was finished and I wasted a whole lot of time on that before I dug into the python source to figure out why it wasn’t working.
have you tried pybind11? if you accept going from C to C++, all the dirty job is done for you, exposing a C++ function is one line and can use numpy arrays directly in the function.
I've contributed to extensions that are written against pybind11, but never written my own. It was pretty nice, and it does indeed cover some of my grievances (at the expense of making me write C++?).
That's literally the opposite feedback of the rest of the world. There is a reason the scientific community standardized on Python, and bindings for all sorts of things from Blender to KDE were more successful on Python than other languages.
My understanding of the "why" for Python in the scientific community is that it's twofold: it's very easy to get started in (and slowly build up expertise in), and (2) that a key set of packages (pandas, numpy) were created early and obtained critical mass.
But neither of these implies that the CPython API is exceptionally good: (1) can be an overriding factor during the implementation of (2), and (2) means that the average scientific Python user doesn't actually need to touch the CPython APIs that much (all the work is already done!).
So I don't think my feedback ("Ruby extensions are easier to write than CPython extensions") is actually incongruous with the rest of the world; the rest of the world picked Python because it's a better language in the ways that matter.
Maybe, and maybe there was also a timing issue - in the sense that at the time it mattered, which was about 10-15 years ago, the Python api was better than most alternatives.
Ruby and Python are incredibly similar in raw functionality, but extremely different in culture. e.g. Both languages allow monkey-patching, while one community thinks it is a great productivity boost making it easy to build cool language tricks, while the other considers it an absolute last resort to be avoided in almost every situation.
I think the key point here is that Python prioritized making native add-ons easy, and so it actually developed an ecosystem. The very second sentence on Ruby's C API that is linked above says "the API is huge and largely undocumented."
I can't say I'm as familiar with ruby bindings, I have dabbled with node bindings....
JS could sort of probably do most things Python can, except for there not being a huge effort for JS things to be native binary (compiling an exe wrapper that executes a VM is not the same thing, e.g. electron). I know there are various C++ injected JS dependencies on node...
Python has a distinct advantage of being a bit closer to the metal, though. Yeah the default python intepreter yadayada - but that's the honda civic bit. You can compile python to c code, compile it, and _call random python modules from within your c code_ all automatically. Or generate a binary c module, or create or a fully compiled exe, or create a python app with an embedded vm, or run the whole thing in a JIT....there's a lot of flexibility.
"Oh but with package XYZ I can cobble together something similar in JS" - yeah, you probably can, but normally you have to contend with a browser, or modules written for a browser, or a DOM, or a transpiler/webmaplicabroominator (don't ask, there's some real nonsense in the JS space) - its all non-standard, plus most of it has only existed for <5 years, python land has had this for...decades now?
JS is what you get when you build a language around a DOM, don't get me wrong, it can do some nifty things. Python is what you get when you mostly don't care about fancy UI...
I suspect Ruby is in a closer boat to Python than JS, but, python has been a more perlesque language insofar as its use as a glue language, Ruby is/was definitely focused on being a fantastic web rendering language (with a bit of JS UI glue). This is evident where python is often used - you can normally get a python binding, even if you don't have a JS or ruby binding.
Again, not the world - as far as type safety there are much better alternatives than any of these, for systems or reliability I would not depend on python (alone).
It had it a lot earlier, and built up a significant library and ecosystem of C modules fast enough to reach critical mass first. This matters because a bigger ecosystem and community creates a feedback loop that generates further resources and adoption. It's the ecosystem that's the game changer.
I'm not a C developer, so for me if the question is, can I call out to a C module that implements capability X, the answer to that is much more likely to be yes for Python than it is for Ruby.
I think he's referring to Python's ctypes, which is part of the standard distribution. Ruby and node can't dynamically load C libraries using just the core distro (though it's a little silly of a point to make, given that Ruby's FFI gem works fine, even if it's not part of the standard distribution).
> Ruby and node can't dynamically load C libraries using just the core distro
Ruby has had Fiddle[1] (a libffi binding) in stdlib for a while now. I don't know when exactly they added it, but it's been at least a couple of years.
Edit: I gave a talk on obfuscation in Ruby that used Fiddle back in 2017, so at least 5 years now.
Edit: But I also don't think that's what the speaker meant. "Binary extensions" are a semi-standard concept in Python, and generally refer to code (modules or packages) that gets compiled against the Python C APIs.
> Ruby has had Fiddle[1] (a libffi binding) in stdlib for a while now. I don’t know when exactly they added it
In ruby 1.9.2 [0], released in 2010.
> But I also don’t think that’s what the speaker meant. “Binary extensions” are a semi-standard concept in Python, and generally refer to code (modules or packages) that gets compiled against the Python C APIs.
Ruby has the same thing.
[0] Based on when it first appears in the standard library documentation on the web; 1.9.1 doesn’t have it, 1.9.2 does.
Wow, I don't know how I entirely missed that. Thanks for the heads up. I've even written a few libraries with C ABI and wrote gems around them with the Ruby FFI gem because I didn't know about Fiddle. I wish the name were better; I might have found it earlier.
Re edit 2: I've made those sorts of binary extensions before, but his wording is "extended with binary extensions that use an API that is written in C, but can be accessed from other languages", implying it's actually just about loading libraries with C ABI and not ordinary binary modules, at least by my interpretation.
I would love to see Python in browsers more than Javascript. But since this works through WASM, I'd probably stick with Rust in that case.
If I'm going to be bound by the limitations of how immature WebAssembly is right now, I'd at least use its more mature ecosystem for development, which is Rust. And actually, I recently began doing so in my free time with a framework named Yew[1].
I know that it's unrealistic to expect Python to be a first-class citizen in browsers as JS is, but at some point we'll grow tired of reading "X language is now available for browsers" when it's more like "X can do WASM now".
edit: Anyway, I don't want to come off as under-appreciative of PyScript. I'm sure a lot of people will love it and make it grow a lot. I'd probably give it a try someday too. Props to the developers!
To me, the groundbreaking thing about this is the idea of embedding Python in its own custom script tag instead of compiling it to WASM. Maybe other languages have done that before, but I haven't seen it.
That you have to ship the entire interpreter isn't great, but what it means for development is that there is no compilation step. You don't have to deal with the WASM toolchain directly. You write your Python code, refresh the tab, and see the results. That's a huge step up from trying to use Rust and WASM for the majority of people who aren't yet Rust developers.
Obviously it's super immature at this stage, but the future possibilities are exciting.
Doing it inside <script type="text/python">…</script>, and having the library scan for such elements, has been a standard technique in such situations for over two decades (and for stylesheet languages, like <style type="text/less">…</style>).
Doing it inside a custom element like <py-script>…</py-script> has been done occasionally, but doesn’t work well because (a) the code is now visible in the document by default and only hidden by stylesheets, and (b) < and & now need to be escaped as < and &.
Great for Python developers, not so great for everyone else.
This is something I find common in the Python ecosystem. There seem to be a lot of choices made more for the benefit of the developers than the end users. Even getting a Python app with some idiosyncratic build system to run can be a challenge sometimes.
I have a vague recollection of Microsoft and/or ActiveState enabling Perl as a browser language. For a time there was an ActiveX interface for a bunch of script languages like Perl and Tcl.
It’s a great feature. Funnily enough this was a feature of the Grail web browser which actually came out a few months before the first version of Netscape with JavaScript (livescript) support
Eeem... i have used Brython, maybe you will like it just as much as I do, i am not that sure how is it in performance yet to do minimal updates on text fields, handling butons and the like (as 99% of the web) it does just fine, you can even have animations. Finally front end code looks "clean" instead of looking like a project for computer science 101 as ... well 99% of the web hahaha
I tried brython but it fell at the first hurdle (I can't remember if it was xpath searches on the DOM or some XML manipulation in python), so I gave up. I'm sure it's better now, but the whole concept of binding Python abstractions to JS objects underneath felt a but clunky and it leaked a lot. WASM is definitely cleaner, if obviously slower.
Speaking of front-end, I really like Brython's site showcasing what they're doing. Just right-click > view source and you can immediately figure it out. On PyScript's site they use JS for the typing animation rather the framework they're making.
PyScript seems interesting, but must we have infomercial-level hyperbole at the adversity of the status quo to sell it?
> For example, you cannot write iOS apps with Python. You cannot create an application for Windows—the most popular corporate desktop—with a user interface
You can, in fact, do both of those things with Python. Heck, the latter you can do with the standard library alone.
It’s a bit ironic that you hyperbolicly accused him of hyperbole. He never says that you can’t do those things, he just says you can’t do them very easily.
I used some tech from the 200 B.C. yesterday when I used scissors to cut some cardboard. I really don't see why a technology's age has anything to do with how good or bad it is to use.
Interestingly this detail may be wrong, but the status quo is much worse. Packaging Python applications is enormously painful, and they often fail to install (or worse, a runtime error) if you’re not on a mainstream distro. And then there is the performance…
This is the general issue of distributing dynamically linked binaries on Linux and not really due to Python itself.
On Windows you can generate a folder with a bunch of files in it along an .exe that starts your app pretty easily and that'll work in most places just fine and is not excessively large, either.
Pipx might be the easiest way to get your application running on any platform that can run Python without caring about distro/OS specific packaging. And if you don't want to push your package to pypi, you can install with pipx directly from a git repo.
I'm really enthusiastic about what's happening with PyScript as the opportunities for the right use cases are enormous.
That said, it has really brought out the knee-jerked clichéd responses:
- X is way better than Y
- X is the Y killer / no it isn't
- Did you know Python is really slow?
- Sure you can, but why do this? (implication: don't do this)
To add to the fun, it attracts huge interest, and amongst those interested are a weird set of people who seem to know little about Python, little about JavaScript and seem unable to read before they try something impossible and then post a query about why their almost certainly never-going-to-work attempt hasn't worked! It needs plenty of patience pointing them to the huge pile of matching queries! I'm sure something will be done to give those types a friendly nudge in the right direction.
I can see there are other tags (py-env, etc.) that provide some yaml to fetch additional assets, but again, nothing significant that warrants the hype.
And if you want types then Typescript is a lot nicer than using Python's typing stuff.
I used to love Python's list comprehensions etc, but since JS got .map, .filter, and all the other new things I really don't miss them. My impression of async is that it's much nicer in JS than in Python.
In the new version of my employer's web app we are moving from JS front-end with Python (Flask) backend to using as much Typescript as possible, and only using Python where we need data-sciency / ML libraries. We'll call out to it from our Typecript backend as-needed, but will do as little in Python (and especially in Pandas) as possible.
Same - I still like Python for scripting, and Scala is still the language I have most fun coding in, but … JavaScript got decent, and TypeScript got really good. I used to want Python in the browser, but no longer see the need.
TypeScript is just a terrific choice for basically any web SPA. My current company is full stack TS (React/TS/MobX on the web, React Native/TS/MobX on mobile, RESTful Express/TS/Postgres/Redis services), and it’s the most productive, straightforward stack I’ve ever used. Perfectly decent performance too. A single language that is legitimately a great choice for most use cases on the web, mobile and backend, hard to compete with that.
Yeah, I think even when engineers are fully ramped up, a well written TS backend is a bit more productive than a well written Scala one. They’re actually decently similar languages, both are expressive languages with expressive type systems and an OOP/FP mix, but I’d say TS has a bit less boilerplate/overhead, the libraries tend to be simpler to learn/use, and it compiles faster.
The biggest efficiency gains, though, are:
- Much faster training/ramp up time for new devs with TS vs Scala
- You can use the same language on the FE and BE, makes it easier for individual devs to do full stack work
The main downsides of TS vs Scala are:
- Scala is faster and more efficient, performance wise. Have to spend more on TS services to serve the same amount of traffic, and if you have heavy computation that’s parallelizeable, Scala is wayyyyy better at that
- As you get into more niche use cases, you just can’t beat the JVM library ecosystem, there are high quality libraries for EVERYTHING. The Node ecosystem is very good too, but not as good as the JVM ecosystem
- TS/Node stack traces are useless compared to Scala/JVM stack traces
Overall, I’ve got ~7 years of professional Scala experience, love the language, but if I was starting a startup today, I’d go full stack TypeScript.
It appears to be a pretty fantastic time for full-stack development and solo founders.
For me, the context switch between client and server was always difficult using a Scala/TypeScript setup (startup).
As you said, unless you rely on some niche technology only available on the JVM, it‘s probably more productive to go full stack TypeScript. For perf-heavy workloads I would probably pick Rust instead of Scala.
I can't compare to Scala, but unless you know you need an API for a web frontend then I would take a look at tRPC or other "zero API" systems (Blitz is another one, but I'm a little unclear on where they are in their pivot).
It's a little hard to describe how magical it feels to actually use. It completely removes needing to think about an API. You don't think about endpoints, about (de)serialization, about the mechanics of fetching, or how arguments are passed. You just call you functions by name from the front-end. All your types are preserved so that if you change the signature of your backend function Typescript will catch it everywhere on front-end. If you use react-hook-form then you can export the zod validators that you wrote for the backend and import them to the frontend, and now your client-side code is using the exact same validator as your backend does. Change your server side validation and now your client-side form won't compile and you'll know exactly why.
Honestly it feels like the missing link in fullstack dev to me. Typescript brought the types and the compiler, and tRPC makes it feel like your entire back and front-end are one system.
Very interesting, I didn‘t know about tRPC yet. I remember in the early days of ScalaJS there were similar ambitions, but I believe it never really caught on.
I prefer Python over Javascript in almost every way. But python's async is a dumpster fire. It's quite natural in Javascript.
Unfortunately Javascript makes you do almost everything async, no choices. Which makes you think that way. Which is awkward to start with and can lead to a lot of strange corner cases. In python unless you're really trying to squeeze performance out of a system you almost never need async.
It doesn't help that it feels like pythons async ecosystem doesn't really know how it works. There is all sorts of blocking code in python async libraries and no one seems bothered by it.
I guess it could be that they just don't care about this type of thing to begin with and have no idea why they are using async other than they heard "it is faster". Meanwhile I am pulling my hair out trying to squeeze a more reqs/s out of an on premise server.
I want to love async. But it’s a nightmare to debug. To this day I still cannot debug tortoise ORM. I dont understand why I can await so easily in my browsers JS console but not in pdb.
python's async mostly works as long as you're using async-native libraries. if you can await it, it's okay. it only gets disastrous when you have to start mangling callback code into promises.
although i really do love javascript's ability to await synchronous functions without it causing any errors. i'm sure it's less performant, but sometimes i just don't care.
I want to use Python more often but having to care about significant white space is a much bigger downer for me than the async being a "dumpster fire" and I also don't think async in Python is so bad.
I'm saying this as someone who has been programming in many languages since more than 20 years.
What kind of editor do you use for writing code? If you need to "care" about significant white space, it might be that you're simply using the wrong tool for the job. Working with Python since 2.4 (among tens of other languages) I honestly don't remember a single situation where I had to care...
I was using Vim for a few years and later switched to Emacs. Both provide commands for handling indentation of lines and blocks of code. You just paste and select/mark a block, then indent or unindent until the first line of the block is aligned with the preceding line in a place where you pasted the code. It's true that you can't auto-indent on paste, though. Still, it never slowed me down noticeably. It's a trade-off, to be sure: you need to align indents manually, but then you don't ever have to deal with things like this:
Yeah, the thing is, if you do forget to align things, which is a thing if your eyes are not the sharpest, weird things can happen, especially when you are writing scripts as if there's no tomorrow. Those experiments usually end up being written for the node.js runtime because I really, really hate aligning lines when I'm writing one-off scripts.
Well, Python is in general not the greatest language for one-off scripts, so it's not strange to use something else for this use case. I definitely never felt your pain, though. I think I'd have to see you edit a Python file live to understand what makes it problematic for you (for example: what width of an indent do you use? wouldn't increasing the width help you notice misalignment? and if it's about seeing/noticing, can't you make your editor display whitespace?).
In my experience, there's no syntax that would be free of gotchas and pain points - I tend to accept them, and if I'm going to work with a particular syntax more than once, I write a bit Elisp to make working around them as seamless as possible.
I totally have this problem with yaml. I wish vim had a line-these-things-up button, kinda like how % lets you bounce around in parenthesis - something like that for leading-whitespace alignment.
I think this thread misses the point. The motivation for pyscript is the accessibility of Python, because it can be adopted even by persons without years of programming experience. I see it regularly in my company with youngsters.
This alone makes it deserve its existence and further pursuit (“for the other 99%”).
Imagine a world where only mechanics could drive cars, because the way they worked “would be fine with him or her” but for everyone else there would be a steep learning curve to overcome initially - which most won’t embark on because there are other goals in life too.
Keeping with the analogy, normal cars are still not suited for Grand Prix racing or other heavy use cases. But this is not needed for the 99%.
Its the same with Python, its limitations, and the better suitability of other languages for a mix of specialised and performance use cases.
Creating an application is more like building your own car, not merely driving it.
I think it would be great if more people would be able to create web applications, but there should be better technologies than shipping a ten-megabytes interpreter with every HTML page.
Also Python is not easy for non-developers. It might be easy for middle school level tasks like replacing a word in a string. However if you want to use a database, you have to learn about object-oriented programming, property descriptors, ORM and decorators, all of these are difficult topics and libraries like SQLAlchemy are not for beginners (just look at its documentation. It doesn't even explain what ORM means).
I don't agree that python is more easily adopted by people learning. Perhaps the older versions of python sure, with contrived "hello world" examples where there is not much going on. But with modern python it is a fucking disaster with pip and anaconda and easy_install and 2.x vs 3.x still lingering (Macs) and type hints or not and list comprehensions being incomprehensible etc and the use of indentation for scoping leading to frequent errors from people learning (I never understood why indentation was cited as a good thing for learners - please go run a "teach kids to code" class one day and you'll spend 50% of your time fixing indentation errors in their code!)
Javascript is everywhere on every device with a browser - if you can load a web page, you can start coding in javascript right away. No install needed - you have a REPL right in your browser.
Granted, NPM is a mess but that is not mandatory and it is still perfectly possible to write & ship modern production JS code without NPM or build-steps being involved. Modern JS is very powerful, and if you can stomach a build-step TS makes it even better.
That sounds frustrating, however easy_install hasn't been relevant for years, and obviously 2.x is EoL. Anaconda is generally better for beginners since it manages basically everything for you. Hardly a disaster.
You basically need NPM if you want to work with any kind of libraries, and I'd say the Anaconda system comes with way more ergonomics out of the box, so that's more or less a wash.
Isn't JavaScript also easy to learn? There are many people who have learned to use it for web development in a coding bootcamp or something and don't know much else about programming.
Similar opinion here. But another reason is now I tend to write my own code rather than depend on third party libraries and that removes one argument for making a choice.
15 requests.
21.65 MB / 7.66 MB transferred.
Finish: 8.19 s.
DOMContentLoaded: 707 ms.
load: 2.95 s.
no, stop. I'm super confused about the obsession of clonking specifically the reference implementation when other implementations exist, like micropython for example. Sure, less compatible, but you are already not getting native modules so shrug?
The funny part is that I can see many of these people that want to use python in the browser to complain about modern SPAs being too heavy when it's literally nothing in comparison.
If Cpython is transferred as a separate artifact, probably for a CDN, it will be cached super efficiently. I'm not sure whether it's that much of a problem.
IIUC, the TLDR is that they're experimenting with loading a bunch of popular scripts (e.g. top `N` scripts from CDNs) on all browsers, so the response is immediate, but they can't use the timing for fingerprinting because it's immediate for everyone.
Of course it's a problem, that cache is not shared across domains, so it will be the initial experience of your users. Perhaps they can do some kind of lazy loading magic to hide it eventually
The good thing though is: because it's a WASM problem, not a Python problem, it will likely get better with time, and the benefits will automatically percolate to Python too.
Yeah, it's cpython because you are getting at least some native modules, numpy, pandas, scikit-learn, etc. It's a matter of compiling the c modules to WASM...
This is also sandboxed FWIW. It means users could write plugins in Python and have them run securely, much like browsers running JavaScript, and games that have Lua scripting.
Deno also touts its permission system. It will be interesting to see if both get interesting use.
micropip is impressive. A lot of JavaScript dev still depends heavily on Node, to the point that only one browser-based build tool exists that can handle most projects and they're keeping it proprietary: https://blog.stackblitz.com/posts/introducing-webcontainers/
This is a laudable effort, but I'm not a fan of shipping the entire interpreter. I looked around a few weeks ago and found https://transcrypt.org, which compiles your Python script to JS, so size is minimal.
It's great for shipping small, internal tools/apps, I love how maintainable they are by all the Python devs, plus they're very fast to load and execute.
I agree. I've been using Transcrypt to create React applications using Python. It allows you to take advantage of existing JS libraries and bundlers but still code in Python. I have to say, it has been really nice not having to switch languages between front-end and back-end on a fullstack application.
I imagine compiling Python to JS instead of Wasm is a very leaky abstraction. Probably fine for simple stuff, but more complex Python code might not behave exactly as expected
Finally!!! The only other comment I've seen mentioning brython, heck I have even written WebComponents using the thing, how comes almost no one has cross paths with it... I guess in part JS won the web battle because (in resignation) most people just accepted (as some others have said in their comments that) it was the only choice... of course brython transpiles to JS yet it has exactly that spirit of "lets make things fun again"
I have done a lot of experimenting with Brython and like you, I would expect it to be more popular. Pierre (the author and primary maintainer) is amazing but something holds it back from large scale adoption. I can only list my reasons for not adopting it into my for-work projects:
* Slow start up times (a second or half a second) for anything that includes the python standard library.
* Avoiding the standard library means writing javascript helper functions so you end up needing to know and write javascript anyway. In some ways Brython feels like "Python for javascript programmers"
* Integration with browser for error messages isn't as convenient as for javascript where I can "click into" the js file in dev tools.
* Pierre is brilliant but it is clear that it is a labor of love. He doesn't want corporate sponsorship or anything that would make it a job for him. He works tirelessly on Brython, the man is a machine, but it really is just him having fun. What happens when its not fun any more? There is no obvious succession. The lack of corporate sponsorship/marketing means that the community is small, there's no "virtuous cycle" of adoption.
I hope the above doesn't mis-represent Pierre, this is my perception only.
Lastly, in recent years many people came to python for the scientific/ML libraries which don't work with Brython. To these people, a python without numpy is no python at all?
Site says this is based on Pyodide which is CPython compiled to WASM (similarly is Coldbrew). Brython (similarly is Skulpt but which lacks DOM manipulation) is a new implementation with parser & built-in objects written in JS and standard library is Python's converted to JS. There's also Transcrypt that opts for integration with JS libraries instead. I expect PyScript to be more compatible (which includes libraries written not in Python, such as numpy, pandas, etc), Brython be more flexible (but cannot support anything not in Python), and Transcrypt should've the best performance (when one wants something be used like JS).
Transpiling to JS is actually a good idea because one could benefit from JIT (as long as your variable types are not too dynamic).
UPD: I looked at the compiled code and currently it is unlikely to be optimized. Also this page [1] shows that the code run in browser can be up to 1000 times slower than in a native Python interpreter.
The figures in this page are relative to base 100 for CPython. Sometimes Brython is faster (value < 100), sometimes slower (value > 100). The worst value is 12 times slower.
While I love the tech behind this (as well as the good article and fun demo video), I'm very skeptical that this will be a good approach for most web apps. I hope it doesn't turn into Python programmers suddenly pulling in 7MB of WASM code/data just to render their websites (along with a 5s startup time), adding yet another layer of complexity and virtualization between their code and the browser. I think the interest in the tool is overall a good thing, but I think we need to be very careful about what kinds of projects we use this for.
I will also point out that there is some fairly low hanging fruit in this PyScript project, if they will attempt to be more "web native". Take this example: https://pyscript.net/examples/panel_kmeans.html
It loads a bunch of large `.whl` files, and they're served up without any apparent compression, which raised my eyebrows immediately. Upon closer inspection, this is a zip file under the hood, so they probably figured that compressing a zip file over the wire was a waste of resources, and they're not really wrong... but, does it need to be a zip file? That means they're shipping a library to handle decompressing and manipulating zip files.
If we unpack the zip file and make an uncompressed tarball out of it, we can feed that through brotli and get a much smaller file:
18M bokeh.whl
9M bokeh.tar.br
The network transfer is now twice as fast, and the browser will do a phenomenal job at decompressing this resource before handing it to the application. The browser will (presumably?) decompress these resources in parallel instead of the (likely) sequential process currently being used, the browser should be faster at decompression anyways, and not handling decompression means less code that PyScript has to ship. Even better, subsequent page loads wouldn't have to keep decompressing the same bundle over and over... it'll just be a cached resource. You'd still need to handle the tar format, but that shouldn't be too terrible.
Basically all browsers support Brotli[0], and you could always have a slow fallback for the... checks notes... IE 11 users out there.
This kind of low hanging fruit won't magically fix all the problems with PyScript, but it could go some distance towards making it more palatable for the purpose of bundling up a lightly modified Python application for use over the web.
I agree that the bundle size is a big concern. Another aspect that I am worried about is Python’s performance. JavaScript is not a fast language, and Python is an order of magnitude slower. What makes Python shine today rely on packages with native code. I don’t know how many of them can be run flawlessly in the browser without modification.
The virtualization that WASM does is actually cleaner than what other similar attempts do. In a field where implementations typically end up being a thin veneer over JS objects (which means you typically end up having to get your hands dirty and work with JS bits here and there), WASM should clear the slate clean enough for most uses, so if you write Python and target WASM, you'll not have to write a single line in JS (well, maybe a standard cookie-cutter loader while the thing downloads the first time, but that's it).
The difference is that required a local install, and this doesn't. In practice, browser plugins are dead, because of corporate security policies and the fact that desktop-environment knowledge is slowly disappearing from the population at large (people don't know how to safely install things, and don't want to know, they prefer the walled-garden one-click model).
The python version is much much slower loading at least on my browser. I counted 7 seconds to having it render the graph.
I kinda wish they spent the time thinking about Dom manipulation from a pythonic point of view rather than just providing the python to js interface and calling it a day.
Yeah I'm not so sure. Browsers need to ship python natively, and then we can just drop wasm and run python directly with a pythonic interface on the DOM.
Not sure that will happen given Python's resistance to incorporating a JIT. The only reason Javascript has acceptable performance is because there's been an absolutely insane amount of work on v8.
Python (the spec) is not against a JIT. Only CPython (the interpreter) is, which is a reference implementation. Other implementations such as PyPy use JIT. I guess Jython can also use the JIT features of the underlying JVM.
There are some important differences in approach. Java was never designed to be downloaded over a network, and didn't have a module format or JARs back then. This is part of what made it so slow. In contrast, efforts to make the encoding of modules as compact as possible started the moment WASM began. [1] It was based on past research in compactly encoding IRs, and the modules are often processed in parallel.
The IR is also a lot less opinionated than other VMs. It started out being similar to a stripped-down JavaScript in capability, but broadened. At the same time it remained easy for browser engines to process into native code. Compared to optimizing applets, it has a simpler task to solve. This does have the disadvantage that modules need to come with their own runtimes. Compilers for languages like C have to deal with the fact that their host languages expect to be running on a fully-featured OS instead of a browser.
Even though it is a binary blob downloaded over the web, browsers come with disassemblers that allow you to see what is actually running. This is a step up over applets, but this is one part of WASM I find particularly underwhelming. The messy development of the VM affected the text format the most, so it's more confusing than it really needs to be. Some docs expect you to write it like a Lisp, even though there's no parse tree encoded in WASM.
WASM has quite a few problems, but they're at least different problems than the ones applets had.
There’s a crucial difference though. Applets required you to download and install the JVM, and it was never part of web standards. Wasm is a w3c standard and built into browsers.
But I see the similarity in terms of compiling your software down to another (supposedly universal, we’ll see) intermediate instruction set.
Not really, via Java Web Start and Java kernel projects it was possible to have a similar Flash like experience, naturally the Web site had to adopt them.
An alternative, which doesn't require insane loading times, is to use any of the many great Python libraries that allow you to write web apps in Python, which get converted to JS web apps.
For example, I'm one of developers of Gradio [0], which lets you write your web app in Python, which gets rendered using Svelte-based components:
> An alternative, which doesn't require insane loading times, is to use any of the many great Python libraries that allow you to write web apps in Python
Sure, there are lots of things that do that.
They don't let you build apps using the Python scientific stack that live entirely in the browser, because they tend to be transpilers plus implementations of a subset of the stdlib plus some browser-specific libraries, whereas PyScript bundles WASM-compiled versions of important Python ecosystem libraries.
We migrated from React to Svelte because of two reasons: (1) speed: Svelte does a lot of work during the compile-time, which led to much faster and more responsive web apps (2) developer learning curve: as we expanded our team, we found that front-end engineers found Svelte much more intuitive and faster to learn
They say that Python has good bindings to C extensions, but for C libraries compiled to WebAssembly, someone will probably write some nice JavaScript bindings, so you might as well use JavaScript.
Meanwhile, JavaScript has been extended with so many language features that it's hard to see another scripting language giving people good reasons to switch. In the early days, JavaScript programming was very limiting and alternatives had a chance, but those days are pretty much over and I'd recommend just learning JavaScript.
(I say this as someone who spent more time exploring alternative languages than writing JavaScript by hand. Nowadays it's hard to come up with a good reason to bother.)
Related, I work on Nitro[1], which already offers a polished set of widgets, and a very simple way to author web apps using Python. I'll be releasing Pyodide support this week.
I also contribute to Wave[2], which provides a wide variety of widgets that can be snapped together quickly to build realtime dashboards/apps.
Both help non-front-end folks build web apps, and require no knowledge of HTML/JS/CSS.
No, this is not a project to replace javascript in the browser, this is a project to give Python apps an html-rendered frontend. And yes, you should expect this to be packaged in electron apps.
Maybe it is sad, but it’s definitely the shortest path to brining modern frontend dev to Python.
At https://hal9.com, we built components for data science in native JavaScript to avoid the waiting times and download overhead if Pyodide. We found out the best tools for doing data science in the browser are a combination of Arquero and D3 and TensorFlow.js. At least for now.
I’m curious what are the primitives for the scientific computing stack? I’m vaguely aware that libfortran or gdpr tran or something live at the bottom, but I’m not sure if there are other base libraries or what immediately depends on them. Also, did you need to reimplement these in native JS? How does the performance compare?
We are not using libfortran not gdpr, we are basically using whatever libraries are available for the web. Since most data scientists don't want to use JS per se, you can build the apps as blocks in the Hal9 site or using a soon-to-be-released Python/R package, see https://notebooks.hal9.com
Feel free to check out our repo as well, all the "primitives" / blocks code is in the scripts folder: https://github.com/hal9ai/hal9ai
From like 2003 to 2010 I loved Python. I was happy to code in it. Found it much better than Perl, my previous no-manual-compile-link-step language. I was mostly a C++ developer but wrote several large tools in python.
I slowly started making more JavaScript stuff and used Selenium (python IIRC).
Then I started learning node. Liked npm's default to local project installs vs python's default to system installs. Eventually I started writing the command line tools that I'd have written in python previously in node. node had some sync I/O so it wasn't hard. Then promise/async/await arrived and I was fully in. I haven't written much python in probably 9 years now.
When I do look at python, I don't feel it's better. I'm not saying it's worse nor am I saying it's not better, rather I'm saying it doesn't *feel* better. Basically I've learned JS inside and out and I'm super comfortable there.
I find it easier to get node installed on multiple platforms and installing it locally without root/admin privileges is trivial via nvm. I'm sure that's possible with python but it's certainly not the default. And of course the browser is everywhere so it's just way more accessible/sharable in JS
I'm using the underlying project, Pyodide, to launch a worker that can execute code and provide autocompletions (via jedi) to a codemirror editor. I'm not super crazy about the startup times, but I'm hoping that there will be more work to help optimize it further.
I don't see much point in going from one dynamic untyped language to another. Javascript and Python offer much of the same advantages and disadvantages, but having to deal with the overhead of running python code seems to just saddle it with tradeoffs for no real benefit. Learning one or the other is fairly easy too.
May as well write Javascript directly, as NPM is not short on packages if that's what you need. I see more value in going from higher level languages like ReScript, Purescript, Melange (Reasonml + Rescript compiler) to Javascript. You have to deal with things like code interop, strictness, overhead of compilation, but you at least gain in safety and succinctness.
The advantage is obvious. People who know and/or enjoy Python can get into web dev without having to fuss with a new language. It’s really that simple.
> The advantage is obvious. People who know and/or enjoy Python can get into web dev without having to fuss with a new language. It’s really that simple.
All web API docs are written for Javascript. Knowledge and practice of Javascript is mandatory for front end development at first place.
If that’s what you are doing then most of how you write python can be done in javascript. The languages are not too different except for superficial syntax stuff. You also inherit the problems that come with compiling and also in general the lack of web-oriented packages that javascript offers.
Np! The particle sim part of the code is actually super fast, the only reason it might not run with full framerate is that it’s software rendering all the pixels in python and dumping out the images to the screen in real time. that’s the expensive part!
I just love LWN for how impartial and informative it is. It's a bit clunky with 20x"he said", but it sure does a good job of giving me a balanced idea of what this is all about! Happy to be a subscriber.
Wow. The article means using pandas in the in-browser demo.
How do they do it? The whole point of numpy and pandas stuff is that they are Fortran and C code that does numeric operations very quickly, while the Python part gives a nice and ergonomic interface on top of them.
So they are showing a WASM port of NumPy / Pandas now, with the Python interface finally surfacing in the browser. It should be a very fair bit slower than native code, though.
Are we seeing the Atwood Law stumbling? That is, things are still migrating into the browser, but to WASM instead of JS now?
What I really hate about this is the absolutely disastrous API. From the <py-script> tag that could easily have been more standard-ish <script type="text/python">, to <py-config> and <py-env> that embed YAML for some reason, to weird custom components like <py-inputbox> that don't integrate with existing ecosystem at all. Brython, albeit still clunky, got it a lot better.
Wasm is far from browser-bound; there are many standalone runtimes and they're used for lots of different things, one of the big ones being edge-workers. Here's a collection of runtimes: https://github.com/appcypher/awesome-wasm-runtimes
let's be real, this has no chance of seeing any real adoption, except as a novelty or for technical demos, because the runtime takes multiple seconds to download, which is insane. reading that document without anything addressing this felt like I was taking crazy pills
I really, REALLY hate the idea of fracturing the frontend ecosystem further with another scripting language option when there is already an absolutely insane overabundance of tools and frameworks for JS alone
It should at this point be enshrined as an official binding standard that browser UAs must support JS and must NOT support any other scripting languages
While we're at it, should we also enshrine into OSs that nothing but C shall be used for systems programming and maybe also forbid anything but one gui toolkit....
That ship has long sailed. As soon as you have JS, you have the ability to transpile to JS from any language with the appropriate tooling, to say nothing of WASM.
Ya know, it’s funny. I like Python. We like it enough to actually use it in embedded products. It has its limits, and we use other tools where it doesn’t fit. Python in a browser seems like a keen idea.
But JavaScript vs Python isn’t really the key thing for me on the web. It’s the uncanny pile of other software one uses to build a man-machine connection that flummoxes me. It’s the CSS, the DOM, the events, the browser API, the ever churning massive pile of complexity that interactive software has become with the voluminous W3C specs, expressed in near BNF form and full of edge cases and backwards compatibility, all so every thing my user does can be observed by myself a few megacorps. I honestly wouldn’t care if I could write it in Fortran. It’s such a minor wart of the whole mess.
Caring about which actual language you can use in all the script tags of a jacked up text format feels like caring which font is being used in your favorite hot piece of government legislation.
JavaScript the language isn't even that awful anymore and TypeScript makes it actually pretty good.
In some ways I prefer javascript for lots of tasks. Easier to write functional style using filter and maps and lambdas, than python's weird itertools and list comprehensions.
Same, python is my goto language so its (minor-ish) deficiencies annoy me a lot.
- Annotating nested JSON objects is a pain in the ass. You need a bazillion intermediary classes.
- Sometimes you need a 3ish line lambda, because you have an beefy if-condition or a try-catch. Too bad multi-line lambdas aren't a thing.
- Function hoisting in JS is actually really nice, not just for the previous scenario. You can define utility functions at the bottom of a function and they'll be available to anything before that definition
- I wish python had a more succinct way to destructure dicts / objects like JS does, outside the new switch statements. (ie doesnt require imports, doesn't require typing the object name over and over.)
- Code completion doesn't work for list comprehensions because the for x in xs comes last :(
Honest question: why not name a function instead of using a multi-line lambda? I've never used a language where multi-line lambdas are common though.
Just readability for me. It's easier to read if the function is defined where it's used rather than before.
instead ofAgreed with @richiebful1, multiliners are better as standlone funcs, and I'd say (personal opinion) that they'd be better here. I like functional a lot but I don't lambda up unless it's more or less a one-liner or a kind of control structure, where they can get large but that's the point.
I've had to deal with too much shit code where lambdas within lambdas are considered hot.
Added bonus, the names are useful (naming is hard because if you do it right you are adding valuable information).
I'm sure there are cases where doing it your way are better, but I can't think of them.
If `apply` is your own code, you could refactor it to
I came to python after working in JS fulltime for years, and used to complain about the exact same thing. After I started using decorators, I stopped complaining about the single-line lambdas.For any non-python devs looking at my example, it's equivalent to
It's a nice way to pass functions into other functions, much like how you'd do with a lambda.edit: s/list/lst/g because autocorrect "fixed" the variable name.
Kotlin JavaScript typescript anonymous functions in golang
List comprehensions are one of the best features! How dare you sully the great name of the list comprehensions!
In all seriousness I do like them a lot. But like all things one can abuse them and make code unreadable.
Problem with list comprehensions are that it's often not easy to see what you're trying to do. Like, I have some objects I want to group by a property, and then make a map containing the sum of some other property of those groups but only if it's value is above 5.
Take Kotlin:
In python: to me that's incomprehensible. You have to read it the wrong way, and it's not really clear what the intention behind each step is. Like, the filter is in the middle!Use intermediate steps:
Could you save a line by replacing valueOf(item) with item.value?
OP wrote the code as if the list items were dictionaries, so I just made that pythonic. If they are objects whose attributes we care about then we can get rid of the two getters altogether which are mostly there to make the code more legible but also remove duplication. You could also switch them to attrgetters.
Ooh I like this. That’s about what I would do as well.
Yeah that Python would not pass my code review. Rule of thumb is don’t nest list comprehensions, and if you have to try to keep it to two. Checkpoint the results info a variable. You aren’t supposed to chain like that in Python.
From https://docs.python.org/3/tutorial/datastructures.html#id2
> You might have noticed that methods like insert, remove or sort that only modify the list have no return value printed – they return the default None. [1] This is a design principle for all mutable data structures in Python.
> Footnotes > [1] Other languages may return the mutated object, which allows method chaining, such as d->insert("a")->remove("b")->sort();.
True that. That's why I prefer R, and its built-in pipes, when I'm working with relatively clean data.
Yeah ... In that case I would write a function to return this result dict in a more imperative way in python -- but perhaps that's cuz i am not that great of an engineer/python dev. But what I can see is that the syntax of Kotlin (which I've never written) you've provided is a lot cleaner.
Python also has filters maps and lambdas, and lots of third-party support for other functional ideas (e.g. the Toolz library).
Though personally I really like itertools and list comprehensions. (And list comprehensions are pretty functional as well, they were inspired by haskell I blieve.)
In my experience lambdas are a lot easier to write with strong types and related tooling.
I’m primarily a Python dev but I’ve been recently working on a React codebase. One of the things that’s been driving me insane is how the default way to import things is without a namespace, aka:
`import {foo} from ‘bar’;`
This makes reading code really really hard as I can’t tell where some symbol is coming from.
There also seems to be a general aversion against using classes to model types. Instead we have a host of functions that manipulate JSON/dataclasses, which means business logic is scattered around 10 different places!
Yeah there's a lot of weird design choices in JS code. I'm not sure all of them really make sense given the modern state of the language but old habits die hard.
> This makes reading code really really hard as I can’t tell where some symbol is coming from.
That's why you use Typescript then you can just hover something or ctrl-click it.
Anyway Python is exactly the same in my experience. Sometimes people `import numpy as np` or whatever but most of the time they `from foo import X, y, z`.
I don't like more the default exports / imports. In this case one can import using completely different name and then it is even harder. Also it won't be changed while renaming utill the developer will go in all other places and do it manually
My problem is that I find TypeScript written by another person entirely unreadable. Python written by another person? Relatively intuitive, even if it's written badly.
I agree 100%.
I love JavaScript (yes, I'm one of THOSE people) and like what TypeScript brings to the table but it quickly becomes hard to read as the code becomes more complex.
Python has always had a readability advantage... up to the point where people start doing code golf and nesting multiple comprehensions together.
Python beat Perl in the 90s-2010 era thanks to its readability which was always advertised as a supreme advantage. Of-course Python 3.x is more complex, but even as an occasional Python user who doesn't like Python that much, I can still dive into an OSS python project and understand what its doing with little prep or Googling needed.
Can't really say that for most programming languages with the exception of Go.
Really interested in your experience with this.
What would you say it is about TypeScript that makes the code harder to read as it becomes more complex? Just the additional type annotation syntax, extra concepts like generics and/or the accompanying more exotic features of TS, the type definitions physically adding many lines of extra code, something about TypeScript that encourages code to be written in a certain way that is different and more complex?
As I remember, the biggest thing is the tendency of TypeScript to result in deeply nested code, which is very hard to read/unwind.
Note that I haven't touched TS in about two years now, so my memory is a little fuzzy.
Would this be in a different way to the equivalent JavaScript code? Or do you just mean like physically, the layout of the code with the additional TypeScript syntax makes it appear more nested/indented and more difficult to parse?
TS doesn't really do any worse than JS in this respect; the key here is the difference between either of them and Python.
Ah, this is a facepalm moment in that I had completely misread the initial comment not as being a comparison of JS/TS to python, but of JS to TS then a further comparison to python. Now it makes much more sense!
For me it is other way around, untill it is something very simple
And this is actually a hugely important consideration in determining whether a language becomes successful, it turns out.
JavaScript has a clearly superior model to support any:{custom:"data"}
I agree here, Typescript is actually quite a nice language to write in, but the complexity of setting up a project and your own compiling pipeline and everything causes my head to spin.
I get it. As an Old, I have watched the web evolve, threw out my HTML 2.0 book not too long ago. Netscape floppies and Trumpet Winsock. CSS being invented by people who, I don't know, did they ever hear the four principles of Contrast, Repetition, Alignment, and Proximity? I feel like they heard one of them. A programming language for it that had a ten day deadline. Tables abused like Russian nesting dolls shellacked into layers just to serve as doorstops. Dead-end evolution that thrashed around in the tar pits for a long time, screaming before its expiration: Flash.
And yet the network effect would keep this going even if you had a team of a thousand brilliant people design a rational replacements for all of this ad-hoc cruft that has traditioned its way into being something like a standard.
I used to read BNF forms on LCD displays.
The article describes what is possible with Python in a browser, but misses an important detail: how much memory it consumes and how much CPU it uses.
Python is not a fast language. For example, consider a simple loop:
In Python, this will be compiled into: a call to range(), heap allocation of an Iterable, calling getIterator() on an Iterable (which might also do allocation), calling next() on an Iterator while catching for StopIteration exception (and calls are often slow in interpreted languages). While in C we could just have a loop without any calls.I remember how I had to use a Dart-based web application (compiled to JS) in one of Google's advertising products. The script weighed around several megabytes and everything was so slow. Furthermore, there also was a small and useless "what's new" applet, and it probably was shipped with a separate copy of Dart runtime because it weighed several megabytes too. Obviously this was a product intended to be used only on latest MacBooks, not on a Windows XP laptop.
It is totally fine to write such application for youself, or maybe for internal use, but if you are a corporation with millions of users, I think you should pay a little attention to performance and choose a better technology. Or, if you are of a Google scale, find a way to optimize the code.
I think comparing it to C isn't fair.
The incumbent is not C, it is JavaScript. Initially JavaScript was also simply run on an interpreter. And it wasn't particularly fast until it got considerable attention by Google & Co, and browsers competing for "who can run this silly JavaScript benchmark the fastest".
Then complaining about how more abstract languages like Python are inefficient compared to C is not fair. These calls to range and Exception handlers are there on purpose, to help the developer avoid writing boilerplate code for the millionth time, and focusing on the problem itself, writing cool things.
C would be a terrible language for the Web I would argue. Web "development" was never a thing for the greybeards and "I dream in assembler"-types (not that I want to exclude anyone, I mean it didn't attract that crowd and another instead). Any challenger for JavaScript must be approachable, easy to understand, easy to write and read. Easy to fix and modify (most "Web Apps" are already obsolete the moment they hit deployment).
Heck, why not go full x86 instructions? Hm, then there are millions of iPhones and Androids on the Web that are not x86... Write our own Assembler?! Let's call it WebAssembly!
Oh, wait.
I didn't write that you need to program your website in C. Obviously it is more convenient to use high-level languages. Everybody wants to write less code. I use Python myself, although not for work. But it would be a good idea to design high-level languages so that it would be easy to compile and optimize them.
For example, JS has no classes and uses prototype inheritance, and you can even change prototype at runtime. This is absolutely useless, inconvenient feature and it makes optimization (like JIT compilation) much more difficult (for example, before calling a method you must ensure that the prototype didn't change, the method was not replaced and so on).
In 95% (arbitrary number) of cases you just need classes with a fixed set of fields and methods known at compile time, which is very optimizer-friendly.
> I think comparing it to C isn't fair.
On the opposite: not only it isn't unfair, it's absolutely necessary. Over the years we witnessed the birth of so many languages, and each of them promised to be more safe than C while keeping performance "close to C". Now we have a cornucopia of programming languages, many of them are definitely "safer" than C (in the sense that it is more difficult or impossible to create some types of errors like buffer overflows), but in terms of performance there still seems to be a considerable gap. Having bad performance is bad for the users, bad for the environment (in terms of direct energy consumption and more power-hungry hardware needed), and bad for software companies (who are limited in what they can do).
> Web "development" was never a thing for the greybeards
Hacker News is written in some Lisp, and I spend more time here than on any bloated SPA.
Reddit with the old UI is a close second.
I believe Hacker News’s backend is written on a Lisp (or, more precisely, Arc). In this context, JavaScript, Python and C are being debated for a role of client-side language handling DOM events.
Also, C and Lisp are different breeds. It’s wrong to put them in one bucket of “greybeard” languages. Some Lisps gained traction in the front end space (see ClojureScript).
Hacker News does have a bit of frontend, written in JavaScript. You can see some here https://news.ycombinator.com/hn.js, I'm unaware if it's everything or just a part.
You can transpile this to a more efficient systems language using py2many or another transpiler and all these problems go away if you're willing to sacrifice some of the dynamic features of the language and embrace static types.
The difference is just scale of commercial investment.
JS got fast because Google and friends started an arms race on it, since the adoption scale justified pouring resources into optimizing efforts.
Python has a large amount of developers' mindshare, which makes its use in the browser potentially worthwhile for large interests invested in the ecosystem (e.g. Anaconda). However, the problem is so big that the cost/benefit ratio for any given group that would want to tackle it, is still fundamentally unattractive. Python developers are legion, but still not a patch on JS users.
This is where WASM is a potential game-changer: by effectively dividing the problem in two and sharing the load for the first half with a lot of other ecosystems, the cost/benefit calculation improves significantly enough that commercial interests seem more willing to invest. CPython speeds, after the temporary v3 setback, get better and better every year; likewise WASM speeds. If their coupling becomes normal, enough effort will go into it that this consideration will just go away.
WASM won't change anything. Python is compiled into bytecode and slowly interpreted. Any optimizations at WASM level won't change the bytecode. For example, they won't turn range()-based loop into a loop with a counter.
Also, it is unlikely that compiling to WASM will be more effective than to native code because browser cannot afford spending as much time on optimization as a native compiler. Therefore WASM will always be slower than a native code.
If you want to benefit from amazing optimizations that were done for JS, then it is better to transpile your Python code directly into JS.
> Any optimizations at WASM level won't change the bytecode.
No, but the bytecode gets better and more efficient with new releases. The point at which it becomes acceptable depends on the use case, of course.
> it is unlikely that compiling to WASM will be more effective than to native code
It doesn't have to be more effective, it only has to reach a point where the penalty is worth paying. After all, JS is slower than C, but you accept that as a part of larger trade-offs on manpower, ease of deployment, etc. Once the trade-off becomes acceptable for the use case, absolute benchmarks stop being relevant.
> If you want to benefit from amazing optimizations that were done for JS, then it is better to transpile your Python code directly into JS.
Why stop there? At that point you might as well use JS, since you get the best speeds and chances are you'll have to deal with it anyway at some point. There are already solutions like that out there, and they are not popular precisely for that reason. The beauty of using WASM is that you'll probably never have to touch JS.
> Also, it is unlikely that compiling to WASM will be more effective than to native code because browser cannot afford spending as much time on optimization as a native compiler.
No reason whatever compiles the code to wasm can’t perform all the expensive optimizations and the wasm execution environment just runs it.
In fact, I would be very disappointed in a tool that didn’t run optimization passes over the code while it still had the language specific information to inform the optimizer.
Then you just pass the multi-megabyte wasm payload over to the browser to render your static content — all’s still good in the webdev world.
How long have there been any serious official investments to make Python faster though? Python just recently touched interpreter level optimization from 3.10 and AFAIK they haven't begun JIT works yet. I'm not saying that Python will ever become as fast as JS, but neither JS was not designed to be fast; it was V8 that made it fast.
Python (and JS) is not optimizer-friendly and it is very difficult to write a JIT for it (you can read a description of JIT in WebKit dev blog to get an idea what it takes to write it).
Not "official" as in "officially sponsored by PSF" but the PSF is undersupported and doesn't have extra resources for something like that. There are many longstanding projects that attempt to make Python faster by reimplementing it (or parts of it), and CPython itself has become incrementally substantially more efficient over the last few releases.
Ironically Dart was built for the web [1] (as a Dart VM for Chrome, then later on compiled to JS). One would expect something like that to do well on the web.
[1] https://en.wikipedia.org/wiki/Dart_(programming_language)#Hi...
Flutter web is a thing now; not sure how popular it is, but Flutter in general is doing pretty well.
In C, this loop would get unrolled to a no-op in a release environment. Source: https://godbolt.org/z/1sb5Tb3xv
I used an empty loop just to simplify an example. Obviousy in real code the loop would do domething useful and wouldn't be optimized out.
But if your loop is busy doing stuff that’s hundreds of bytecode ops long, is worrying about the few extra bytecode ops that a for loop takes worth it?
How else would they feel superior to someone else, if not by comparing Python/JS to C's speed all the while talking about applications where C is never going to be used?
It's not like those hundreds of bytecode ops aren't slow as molasses too, for similar reasons.
As I understand, C extensions are used for CPU heavy work e.g., numpy is likely ported to WebAssembly.
Indeed, taken to the extreme a Pyodide-based jupyter is available[1] which uses the same underpinnings as pyscript. It might not be perfectly efficient but it's totally usable, especially considering it moves the compute from a server to the client.
At this point the main issue I've seen is the slow load time (not a problem for jupyterlite but is for pyscript). Hopefully this can improve with time and regardless I think there are a lot of cases for pyscript to remove the need for server-side code and the associated maintaince.
[1] https://jupyterlite.readthedocs.io/en/latest/
No. People won't write C extensions. They will write something heavy like Redux (which recreates full object graph on every event) in Python.
You'll like what we've done during my Hackathon https://github.com/fork-tongue/collagraph/pull/66
We added support for PyScript using Collagraph, which allows you to define single file components with a Vue-like syntax.
Excerpt from the project README:
Write your Python interfaces in a declarative manner with plain render functions, component classes or even single-file components using Vue-like syntax, but with Python!
- Reactivity (made possible by leveraging observ)
- Function components
- Class components with local state and life-cycle methods/hooks
-Single-file components with Vue-like syntax (.cgx files)
- Custom renderers (PySide, pygfx and now PyScript)
Developer time is still more expensive than 'runtime'
Talking about optimizing a range(10) loop was valid in the 90's, not today
Yes, CPython could be better, but there's Pypy. And still, CPython runs circles around the optimized Dart example you gave.
"pay a little attention to performance" cool, are we going to take all the crap out of JS that makes it inefficient?
"pay a little attention to performance" sounds to me like you're a fan of those C compilers that break code on purpose because the developer forgot some arcane detail. To what I call BS
Obviously, one loop in Python won't hurt performance. But reality is that people will try to build SPA on this technology. They will port Redux, that uses immutable objects and recreates whole graph of objects on every event. They will try to move SQLAlchemy and Django into the browser. Isn't it cool (for inexperienced developer), you just import a script from CDN and can write Django code? And this will run on a 10-megabytes interpreter in WASM.
Of course if you are writing an internal app and can provide M2 MacBook to every employee, then it is totally fine. But if you are writing applications for wide audience, it is a different thing.
I remember that one of early users of Vkontakte (a Russian clone of Facebook) was impressed that the site was loading fast on his old computer. As I remember, its JS code was written in vanilla JS without libraries like jQuery. Today the hardware is better, but if you will run SQLAlchemy in a browser to save development cost, your site's loading time won't impress users.
There is absolutely no requirement or indication that Python UI framework will have to follow the same principles as JS ones.
> your site's loading time won't impress users.
Anybody who used client-server apps in the 80s and 90s is not impressed by browser-based apps either. Those expectations can be managed in so many ways.
> They will try to move SQLAlchemy and Django into the browser.
Yes that will be a complete non starter!
I'm all for fighting inefficiencies and slow code, but fixing things like this, or Redux etc go much further than a simple for i in range() loop in Python
True, but there are limits. It’s surprising how many apps and webpages I use that are just straight up slow - things that should load instantly instead take a second or two. The web is a good application for this to some extent since there are other latencies that make this less noticeable, but they still exist.
Anything written to be performant is immediately noticeable - things just happen when you click a button. Dev time > runtime, but I’d argue some runtimes are so slow they begin to eat into user time too.
I notice this too. If I open a SPA there almost always will be a spinning circle and I have to wait like 3 or more seconds before I can see the content. In theory one can write a SPA that would load instantly, but in reality it will be a spinning circle.
I can only imagine how many people will just close the tab and move to next search result.
https://nodejs.org/api/n-api.html https://silverhammermba.github.io/emberb/c/
> Is there actually anything different about python here?
I say this as a big fan of Python: I think the main difference is that the CPython C APIs are much more of a pain to use :-)
I don't know about Node's C APIs, but I've written both Python and Ruby extensions and find the MRI APIs much nicer than the CPython ones.
If you’re just calling C functions or wrapping some C++ classes CPython isn’t very hard — unpack the arguments, call the function, pack up the return value(s).
Iterator support is a little trickier but not too bad once you have it figured out. Same with overloaded functions. Array access is a bit annoying because there’s two ways to do it and you have to guess the right one if you want slices and other craziness.
Memory management can be a pain but I’d imagine it is like that whenever you’re combining two languages.
I’ve done some pretty complex wrappers and have yet to find something that just isn’t possible (within the limitations of python). I usually get the boilerplate generated from pybindgen and then start on the serious hacking.
Actually… I did find something that wasn’t possible and that was because someone thought it was a good idea to commit the raw buffer interface (whatever it’s called) before it was finished and I wasted a whole lot of time on that before I dug into the python source to figure out why it wasn’t working.
have you tried pybind11? if you accept going from C to C++, all the dirty job is done for you, exposing a C++ function is one line and can use numpy arrays directly in the function.
I've contributed to extensions that are written against pybind11, but never written my own. It was pretty nice, and it does indeed cover some of my grievances (at the expense of making me write C++?).
That's literally the opposite feedback of the rest of the world. There is a reason the scientific community standardized on Python, and bindings for all sorts of things from Blender to KDE were more successful on Python than other languages.
My understanding of the "why" for Python in the scientific community is that it's twofold: it's very easy to get started in (and slowly build up expertise in), and (2) that a key set of packages (pandas, numpy) were created early and obtained critical mass.
But neither of these implies that the CPython API is exceptionally good: (1) can be an overriding factor during the implementation of (2), and (2) means that the average scientific Python user doesn't actually need to touch the CPython APIs that much (all the work is already done!).
So I don't think my feedback ("Ruby extensions are easier to write than CPython extensions") is actually incongruous with the rest of the world; the rest of the world picked Python because it's a better language in the ways that matter.
Maybe, and maybe there was also a timing issue - in the sense that at the time it mattered, which was about 10-15 years ago, the Python api was better than most alternatives.
Sure, that seems likely to me as well!
Edit: Well, maybe 20 years ago -- 10 years ago, Ruby's C API was about the same and still (IMO) better.
Ruby and Python are incredibly similar in raw functionality, but extremely different in culture. e.g. Both languages allow monkey-patching, while one community thinks it is a great productivity boost making it easy to build cool language tricks, while the other considers it an absolute last resort to be avoided in almost every situation.
I think the key point here is that Python prioritized making native add-ons easy, and so it actually developed an ecosystem. The very second sentence on Ruby's C API that is linked above says "the API is huge and largely undocumented."
I can't say I'm as familiar with ruby bindings, I have dabbled with node bindings....
JS could sort of probably do most things Python can, except for there not being a huge effort for JS things to be native binary (compiling an exe wrapper that executes a VM is not the same thing, e.g. electron). I know there are various C++ injected JS dependencies on node...
Python has a distinct advantage of being a bit closer to the metal, though. Yeah the default python intepreter yadayada - but that's the honda civic bit. You can compile python to c code, compile it, and _call random python modules from within your c code_ all automatically. Or generate a binary c module, or create or a fully compiled exe, or create a python app with an embedded vm, or run the whole thing in a JIT....there's a lot of flexibility.
"Oh but with package XYZ I can cobble together something similar in JS" - yeah, you probably can, but normally you have to contend with a browser, or modules written for a browser, or a DOM, or a transpiler/webmaplicabroominator (don't ask, there's some real nonsense in the JS space) - its all non-standard, plus most of it has only existed for <5 years, python land has had this for...decades now?
JS is what you get when you build a language around a DOM, don't get me wrong, it can do some nifty things. Python is what you get when you mostly don't care about fancy UI...
I suspect Ruby is in a closer boat to Python than JS, but, python has been a more perlesque language insofar as its use as a glue language, Ruby is/was definitely focused on being a fantastic web rendering language (with a bit of JS UI glue). This is evident where python is often used - you can normally get a python binding, even if you don't have a JS or ruby binding.
Again, not the world - as far as type safety there are much better alternatives than any of these, for systems or reliability I would not depend on python (alone).
It had it a lot earlier, and built up a significant library and ecosystem of C modules fast enough to reach critical mass first. This matters because a bigger ecosystem and community creates a feedback loop that generates further resources and adoption. It's the ecosystem that's the game changer.
I'm not a C developer, so for me if the question is, can I call out to a C module that implements capability X, the answer to that is much more likely to be yes for Python than it is for Ruby.
I think he's referring to Python's ctypes, which is part of the standard distribution. Ruby and node can't dynamically load C libraries using just the core distro (though it's a little silly of a point to make, given that Ruby's FFI gem works fine, even if it's not part of the standard distribution).
> Ruby and node can't dynamically load C libraries using just the core distro
Ruby has had Fiddle[1] (a libffi binding) in stdlib for a while now. I don't know when exactly they added it, but it's been at least a couple of years.
Edit: I gave a talk on obfuscation in Ruby that used Fiddle back in 2017, so at least 5 years now.
Edit: But I also don't think that's what the speaker meant. "Binary extensions" are a semi-standard concept in Python, and generally refer to code (modules or packages) that gets compiled against the Python C APIs.
[1]: https://ruby-doc.org/stdlib-3.1.2/libdoc/fiddle/rdoc/Fiddle....
> Ruby has had Fiddle[1] (a libffi binding) in stdlib for a while now. I don’t know when exactly they added it
In ruby 1.9.2 [0], released in 2010.
> But I also don’t think that’s what the speaker meant. “Binary extensions” are a semi-standard concept in Python, and generally refer to code (modules or packages) that gets compiled against the Python C APIs.
Ruby has the same thing.
[0] Based on when it first appears in the standard library documentation on the web; 1.9.1 doesn’t have it, 1.9.2 does.
Wow, I don't know how I entirely missed that. Thanks for the heads up. I've even written a few libraries with C ABI and wrote gems around them with the Ruby FFI gem because I didn't know about Fiddle. I wish the name were better; I might have found it earlier.
Re edit 2: I've made those sorts of binary extensions before, but his wording is "extended with binary extensions that use an API that is written in C, but can be accessed from other languages", implying it's actually just about loading libraries with C ABI and not ordinary binary modules, at least by my interpretation.
I would love to see Python in browsers more than Javascript. But since this works through WASM, I'd probably stick with Rust in that case.
If I'm going to be bound by the limitations of how immature WebAssembly is right now, I'd at least use its more mature ecosystem for development, which is Rust. And actually, I recently began doing so in my free time with a framework named Yew[1].
I know that it's unrealistic to expect Python to be a first-class citizen in browsers as JS is, but at some point we'll grow tired of reading "X language is now available for browsers" when it's more like "X can do WASM now".
edit: Anyway, I don't want to come off as under-appreciative of PyScript. I'm sure a lot of people will love it and make it grow a lot. I'd probably give it a try someday too. Props to the developers!
1 : https://github.com/yewstack/yew
To me, the groundbreaking thing about this is the idea of embedding Python in its own custom script tag instead of compiling it to WASM. Maybe other languages have done that before, but I haven't seen it.
That you have to ship the entire interpreter isn't great, but what it means for development is that there is no compilation step. You don't have to deal with the WASM toolchain directly. You write your Python code, refresh the tab, and see the results. That's a huge step up from trying to use Rust and WASM for the majority of people who aren't yet Rust developers.
Obviously it's super immature at this stage, but the future possibilities are exciting.
Doing it inside <script type="text/python">…</script>, and having the library scan for such elements, has been a standard technique in such situations for over two decades (and for stylesheet languages, like <style type="text/less">…</style>).
Doing it inside a custom element like <py-script>…</py-script> has been done occasionally, but doesn’t work well because (a) the code is now visible in the document by default and only hidden by stylesheets, and (b) < and & now need to be escaped as < and &.
Great for Python developers, not so great for everyone else.
This is something I find common in the Python ecosystem. There seem to be a lot of choices made more for the benefit of the developers than the end users. Even getting a Python app with some idiosyncratic build system to run can be a challenge sometimes.
If you have to use a build system, you're not a user.
I have a vague recollection of Microsoft and/or ActiveState enabling Perl as a browser language. For a time there was an ActiveX interface for a bunch of script languages like Perl and Tcl.
It’s a great feature. Funnily enough this was a feature of the Grail web browser which actually came out a few months before the first version of Netscape with JavaScript (livescript) support
Damn, that's really cool. Too bad hype won out in the end...
Other languages have done that :)
Lua in the browser: https://fengari.io/
And then you can use that to run Fennel, a Lisp that compiles to Lua https://fennel-lang.org/
I think TypeScript also has a script you can include that lets you put your TS code in a special script tag, and it gets compiled in-browser.
Eeem... i have used Brython, maybe you will like it just as much as I do, i am not that sure how is it in performance yet to do minimal updates on text fields, handling butons and the like (as 99% of the web) it does just fine, you can even have animations. Finally front end code looks "clean" instead of looking like a project for computer science 101 as ... well 99% of the web hahaha
https://www.brython.info/
I tried brython but it fell at the first hurdle (I can't remember if it was xpath searches on the DOM or some XML manipulation in python), so I gave up. I'm sure it's better now, but the whole concept of binding Python abstractions to JS objects underneath felt a but clunky and it leaked a lot. WASM is definitely cleaner, if obviously slower.
Speaking of front-end, I really like Brython's site showcasing what they're doing. Just right-click > view source and you can immediately figure it out. On PyScript's site they use JS for the typing animation rather the framework they're making.
PyScript seems interesting, but must we have infomercial-level hyperbole at the adversity of the status quo to sell it?
> For example, you cannot write iOS apps with Python. You cannot create an application for Windows—the most popular corporate desktop—with a user interface
You can, in fact, do both of those things with Python. Heck, the latter you can do with the standard library alone.
It’s a bit ironic that you hyperbolicly accused him of hyperbole. He never says that you can’t do those things, he just says you can’t do them very easily.
What’s hard about tkinter exactly?
Stomaching the feeling of using ’90s-era technology.
I used some tech from the 200 B.C. yesterday when I used scissors to cut some cardboard. I really don't see why a technology's age has anything to do with how good or bad it is to use.
In a world where PyQt is a thing, Tkinter is not even worth learning.
The problem is that packaging a PyQt project is too difficult.
PyQt is GPL/commercial. That’s one big honking reason it can’t be used for a lot of projects.
PySide is more permissive though (LGPL).
You can, and I've done it, but it's an uphill battle.
Interestingly this detail may be wrong, but the status quo is much worse. Packaging Python applications is enormously painful, and they often fail to install (or worse, a runtime error) if you’re not on a mainstream distro. And then there is the performance…
This is the general issue of distributing dynamically linked binaries on Linux and not really due to Python itself.
On Windows you can generate a folder with a bunch of files in it along an .exe that starts your app pretty easily and that'll work in most places just fine and is not excessively large, either.
Pipx might be the easiest way to get your application running on any platform that can run Python without caring about distro/OS specific packaging. And if you don't want to push your package to pypi, you can install with pipx directly from a git repo.
I'm really enthusiastic about what's happening with PyScript as the opportunities for the right use cases are enormous.
That said, it has really brought out the knee-jerked clichéd responses:
- X is way better than Y
- X is the Y killer / no it isn't
- Did you know Python is really slow?
- Sure you can, but why do this? (implication: don't do this)
To add to the fun, it attracts huge interest, and amongst those interested are a weird set of people who seem to know little about Python, little about JavaScript and seem unable to read before they try something impossible and then post a query about why their almost certainly never-going-to-work attempt hasn't worked! It needs plenty of patience pointing them to the huge pile of matching queries! I'm sure something will be done to give those types a friendly nudge in the right direction.
Does PyScript offer anything of significance over and above what Pyodide already offers, other than several py-* tags?
In my experience, it's trivial accomplish this with Pyodide.
Here's a web worker that hosts Pyodide and loads packages, PyPI wheels, external modules, etc. and launches type=text/python script tags in-browser:
https://github.com/h2oai/nitro/blob/main/web/public/nitride....
About ~100 lines of code.
Maybe what it offers is abstraction. Boilerplate not required for immediate results, just a pyscript tag.
I understand that, but it's not much of an abstraction:
I can see there are other tags (py-env, etc.) that provide some yaml to fetch additional assets, but again, nothing significant that warrants the hype.Maybe I'm missing something?
I use to want this. Then I learned JavaScript, and decided it's a much better language for the browser than Python is.
And if you want types then Typescript is a lot nicer than using Python's typing stuff.
I used to love Python's list comprehensions etc, but since JS got .map, .filter, and all the other new things I really don't miss them. My impression of async is that it's much nicer in JS than in Python.
In the new version of my employer's web app we are moving from JS front-end with Python (Flask) backend to using as much Typescript as possible, and only using Python where we need data-sciency / ML libraries. We'll call out to it from our Typecript backend as-needed, but will do as little in Python (and especially in Pandas) as possible.
Same - I still like Python for scripting, and Scala is still the language I have most fun coding in, but … JavaScript got decent, and TypeScript got really good. I used to want Python in the browser, but no longer see the need.
TypeScript is just a terrific choice for basically any web SPA. My current company is full stack TS (React/TS/MobX on the web, React Native/TS/MobX on mobile, RESTful Express/TS/Postgres/Redis services), and it’s the most productive, straightforward stack I’ve ever used. Perfectly decent performance too. A single language that is legitimately a great choice for most use cases on the web, mobile and backend, hard to compete with that.
I have a similar language preference. Do you think a RESTful TypeScript backend is more productive than a Scala alternative?
Yeah, I think even when engineers are fully ramped up, a well written TS backend is a bit more productive than a well written Scala one. They’re actually decently similar languages, both are expressive languages with expressive type systems and an OOP/FP mix, but I’d say TS has a bit less boilerplate/overhead, the libraries tend to be simpler to learn/use, and it compiles faster.
The biggest efficiency gains, though, are:
- Much faster training/ramp up time for new devs with TS vs Scala
- You can use the same language on the FE and BE, makes it easier for individual devs to do full stack work
The main downsides of TS vs Scala are:
- Scala is faster and more efficient, performance wise. Have to spend more on TS services to serve the same amount of traffic, and if you have heavy computation that’s parallelizeable, Scala is wayyyyy better at that
- As you get into more niche use cases, you just can’t beat the JVM library ecosystem, there are high quality libraries for EVERYTHING. The Node ecosystem is very good too, but not as good as the JVM ecosystem
- TS/Node stack traces are useless compared to Scala/JVM stack traces
Overall, I’ve got ~7 years of professional Scala experience, love the language, but if I was starting a startup today, I’d go full stack TypeScript.
It appears to be a pretty fantastic time for full-stack development and solo founders.
For me, the context switch between client and server was always difficult using a Scala/TypeScript setup (startup).
As you said, unless you rely on some niche technology only available on the JVM, it‘s probably more productive to go full stack TypeScript. For perf-heavy workloads I would probably pick Rust instead of Scala.
I can't compare to Scala, but unless you know you need an API for a web frontend then I would take a look at tRPC or other "zero API" systems (Blitz is another one, but I'm a little unclear on where they are in their pivot).
It's a little hard to describe how magical it feels to actually use. It completely removes needing to think about an API. You don't think about endpoints, about (de)serialization, about the mechanics of fetching, or how arguments are passed. You just call you functions by name from the front-end. All your types are preserved so that if you change the signature of your backend function Typescript will catch it everywhere on front-end. If you use react-hook-form then you can export the zod validators that you wrote for the backend and import them to the frontend, and now your client-side code is using the exact same validator as your backend does. Change your server side validation and now your client-side form won't compile and you'll know exactly why.
Honestly it feels like the missing link in fullstack dev to me. Typescript brought the types and the compiler, and tRPC makes it feel like your entire back and front-end are one system.
Very interesting, I didn‘t know about tRPC yet. I remember in the early days of ScalaJS there were similar ambitions, but I believe it never really caught on.
I will definitely give it a go, thanks.
I prefer Python over Javascript in almost every way. But python's async is a dumpster fire. It's quite natural in Javascript.
Unfortunately Javascript makes you do almost everything async, no choices. Which makes you think that way. Which is awkward to start with and can lead to a lot of strange corner cases. In python unless you're really trying to squeeze performance out of a system you almost never need async.
It doesn't help that it feels like pythons async ecosystem doesn't really know how it works. There is all sorts of blocking code in python async libraries and no one seems bothered by it.
I guess it could be that they just don't care about this type of thing to begin with and have no idea why they are using async other than they heard "it is faster". Meanwhile I am pulling my hair out trying to squeeze a more reqs/s out of an on premise server.
I want to love async. But it’s a nightmare to debug. To this day I still cannot debug tortoise ORM. I dont understand why I can await so easily in my browsers JS console but not in pdb.
python's async mostly works as long as you're using async-native libraries. if you can await it, it's okay. it only gets disastrous when you have to start mangling callback code into promises.
although i really do love javascript's ability to await synchronous functions without it causing any errors. i'm sure it's less performant, but sometimes i just don't care.
I want to use Python more often but having to care about significant white space is a much bigger downer for me than the async being a "dumpster fire" and I also don't think async in Python is so bad.
I'm saying this as someone who has been programming in many languages since more than 20 years.
What kind of editor do you use for writing code? If you need to "care" about significant white space, it might be that you're simply using the wrong tool for the job. Working with Python since 2.4 (among tens of other languages) I honestly don't remember a single situation where I had to care...
It depends, I like using vim on a remote computer and use IntelliJ locally. It usually breaks when I'm trying to refactor, copying and pasting etc.
I was using Vim for a few years and later switched to Emacs. Both provide commands for handling indentation of lines and blocks of code. You just paste and select/mark a block, then indent or unindent until the first line of the block is aligned with the preceding line in a place where you pasted the code. It's true that you can't auto-indent on paste, though. Still, it never slowed me down noticeably. It's a trade-off, to be sure: you need to align indents manually, but then you don't ever have to deal with things like this:
Yeah, the thing is, if you do forget to align things, which is a thing if your eyes are not the sharpest, weird things can happen, especially when you are writing scripts as if there's no tomorrow. Those experiments usually end up being written for the node.js runtime because I really, really hate aligning lines when I'm writing one-off scripts.
Well, Python is in general not the greatest language for one-off scripts, so it's not strange to use something else for this use case. I definitely never felt your pain, though. I think I'd have to see you edit a Python file live to understand what makes it problematic for you (for example: what width of an indent do you use? wouldn't increasing the width help you notice misalignment? and if it's about seeing/noticing, can't you make your editor display whitespace?).
In my experience, there's no syntax that would be free of gotchas and pain points - I tend to accept them, and if I'm going to work with a particular syntax more than once, I write a bit Elisp to make working around them as seamless as possible.
I totally have this problem with yaml. I wish vim had a line-these-things-up button, kinda like how % lets you bounce around in parenthesis - something like that for leading-whitespace alignment.
I think this thread misses the point. The motivation for pyscript is the accessibility of Python, because it can be adopted even by persons without years of programming experience. I see it regularly in my company with youngsters.
This alone makes it deserve its existence and further pursuit (“for the other 99%”).
Imagine a world where only mechanics could drive cars, because the way they worked “would be fine with him or her” but for everyone else there would be a steep learning curve to overcome initially - which most won’t embark on because there are other goals in life too.
Keeping with the analogy, normal cars are still not suited for Grand Prix racing or other heavy use cases. But this is not needed for the 99%.
Its the same with Python, its limitations, and the better suitability of other languages for a mix of specialised and performance use cases.
Creating an application is more like building your own car, not merely driving it.
I think it would be great if more people would be able to create web applications, but there should be better technologies than shipping a ten-megabytes interpreter with every HTML page.
Also Python is not easy for non-developers. It might be easy for middle school level tasks like replacing a word in a string. However if you want to use a database, you have to learn about object-oriented programming, property descriptors, ORM and decorators, all of these are difficult topics and libraries like SQLAlchemy are not for beginners (just look at its documentation. It doesn't even explain what ORM means).
I don't agree that python is more easily adopted by people learning. Perhaps the older versions of python sure, with contrived "hello world" examples where there is not much going on. But with modern python it is a fucking disaster with pip and anaconda and easy_install and 2.x vs 3.x still lingering (Macs) and type hints or not and list comprehensions being incomprehensible etc and the use of indentation for scoping leading to frequent errors from people learning (I never understood why indentation was cited as a good thing for learners - please go run a "teach kids to code" class one day and you'll spend 50% of your time fixing indentation errors in their code!)
Javascript is everywhere on every device with a browser - if you can load a web page, you can start coding in javascript right away. No install needed - you have a REPL right in your browser.
Granted, NPM is a mess but that is not mandatory and it is still perfectly possible to write & ship modern production JS code without NPM or build-steps being involved. Modern JS is very powerful, and if you can stomach a build-step TS makes it even better.
That sounds frustrating, however easy_install hasn't been relevant for years, and obviously 2.x is EoL. Anaconda is generally better for beginners since it manages basically everything for you. Hardly a disaster.
You basically need NPM if you want to work with any kind of libraries, and I'd say the Anaconda system comes with way more ergonomics out of the box, so that's more or less a wash.
Isn't JavaScript also easy to learn? There are many people who have learned to use it for web development in a coding bootcamp or something and don't know much else about programming.
> Imagine a world where only mechanics could drive cars
A closer metaphor is: imagine a world where everybody builds their own car. That would be a bit of a mess.
Similar opinion here. But another reason is now I tend to write my own code rather than depend on third party libraries and that removes one argument for making a choice.
Hello World example:
15 requests. 21.65 MB / 7.66 MB transferred. Finish: 8.19 s. DOMContentLoaded: 707 ms. load: 2.95 s.
no, stop. I'm super confused about the obsession of clonking specifically the reference implementation when other implementations exist, like micropython for example. Sure, less compatible, but you are already not getting native modules so shrug?
The funny part is that I can see many of these people that want to use python in the browser to complain about modern SPAs being too heavy when it's literally nothing in comparison.
Part of the complaint is really from developers who hate dealing with the vagaries of JS build tools. Python on WASM would wipe all of that.
I too laugh at the kinds of things I imagine straw men saying. Darndest things come out of their mouths!
If Cpython is transferred as a separate artifact, probably for a CDN, it will be cached super efficiently. I'm not sure whether it's that much of a problem.
Browsers do not share cache hits to CDNs anymore. The cache is sharded (not shared) across origins.
As of quite recently that may be changing in Chromium (early experiment): https://groups.google.com/a/chromium.org/g/blink-dev/c/9xWJK...
IIUC, the TLDR is that they're experimenting with loading a bunch of popular scripts (e.g. top `N` scripts from CDNs) on all browsers, so the response is immediate, but they can't use the timing for fingerprinting because it's immediate for everyone.
Of course it's a problem, that cache is not shared across domains, so it will be the initial experience of your users. Perhaps they can do some kind of lazy loading magic to hide it eventually
uncached, 8 seconds, cached, 6.5 seconds
Loading the entire wasm, touching all the things that need to be touched, etc, takes up the majority of the time
The good thing though is: because it's a WASM problem, not a Python problem, it will likely get better with time, and the benefits will automatically percolate to Python too.
Yeah, it's cpython because you are getting at least some native modules, numpy, pandas, scikit-learn, etc. It's a matter of compiling the c modules to WASM...
reference implementation can probably be de-cluttered and modularized a lot.
Unfortunately https://www.npmjs.com/package/micropython is three years unmaintained.
Runtime offset of Hello World matters a lot less if you do real python stuff: physics, neural networks etc
That's a random unofficial build of micropython, MP is still in active development (the specific build target got touched 3 days ago)
This is also sandboxed FWIW. It means users could write plugins in Python and have them run securely, much like browsers running JavaScript, and games that have Lua scripting.
https://webassembly.org/docs/security/ https://www.reddit.com/r/WebAssembly/comments/ryz2zz/are_was...
Deno also touts its permission system. It will be interesting to see if both get interesting use.
micropip is impressive. A lot of JavaScript dev still depends heavily on Node, to the point that only one browser-based build tool exists that can handle most projects and they're keeping it proprietary: https://blog.stackblitz.com/posts/introducing-webcontainers/
This is a laudable effort, but I'm not a fan of shipping the entire interpreter. I looked around a few weeks ago and found https://transcrypt.org, which compiles your Python script to JS, so size is minimal.
It's great for shipping small, internal tools/apps, I love how maintainable they are by all the Python devs, plus they're very fast to load and execute.
I agree. I've been using Transcrypt to create React applications using Python. It allows you to take advantage of existing JS libraries and bundlers but still code in Python. I have to say, it has been really nice not having to switch languages between front-end and back-end on a fullstack application.
I did a writeup with a basic how-to a while back: https://dev.to/jennasys/creating-react-applications-with-pyt...
I imagine compiling Python to JS instead of Wasm is a very leaky abstraction. Probably fine for simple stuff, but more complex Python code might not behave exactly as expected
Yeah, certainly, but I wouldn't really advise using Python in the browser for more complex code yet.
Also check out "rapydscript-ng", by the author of Calibre e-book reader:
https://github.com/kovidgoyal/rapydscript-ng
How does that work for numpy or scipy? A main point of using python is the ecosystem.
I am amazed I am apparently the only one mentioning Brython over here
https://www.brython.info/
The video of this presentation is here: https://youtu.be/qKfkCY7cmBQ
How does this compare to Brython? [0]
Brython uses:
[0] https://brython.info/Finally!!! The only other comment I've seen mentioning brython, heck I have even written WebComponents using the thing, how comes almost no one has cross paths with it... I guess in part JS won the web battle because (in resignation) most people just accepted (as some others have said in their comments that) it was the only choice... of course brython transpiles to JS yet it has exactly that spirit of "lets make things fun again"
I have done a lot of experimenting with Brython and like you, I would expect it to be more popular. Pierre (the author and primary maintainer) is amazing but something holds it back from large scale adoption. I can only list my reasons for not adopting it into my for-work projects:
* Slow start up times (a second or half a second) for anything that includes the python standard library.
* Avoiding the standard library means writing javascript helper functions so you end up needing to know and write javascript anyway. In some ways Brython feels like "Python for javascript programmers"
* Integration with browser for error messages isn't as convenient as for javascript where I can "click into" the js file in dev tools.
* Pierre is brilliant but it is clear that it is a labor of love. He doesn't want corporate sponsorship or anything that would make it a job for him. He works tirelessly on Brython, the man is a machine, but it really is just him having fun. What happens when its not fun any more? There is no obvious succession. The lack of corporate sponsorship/marketing means that the community is small, there's no "virtuous cycle" of adoption.
I hope the above doesn't mis-represent Pierre, this is my perception only.
Lastly, in recent years many people came to python for the scientific/ML libraries which don't work with Brython. To these people, a python without numpy is no python at all?
Site says this is based on Pyodide which is CPython compiled to WASM (similarly is Coldbrew). Brython (similarly is Skulpt but which lacks DOM manipulation) is a new implementation with parser & built-in objects written in JS and standard library is Python's converted to JS. There's also Transcrypt that opts for integration with JS libraries instead. I expect PyScript to be more compatible (which includes libraries written not in Python, such as numpy, pandas, etc), Brython be more flexible (but cannot support anything not in Python), and Transcrypt should've the best performance (when one wants something be used like JS).
Transpiling to JS is actually a good idea because one could benefit from JIT (as long as your variable types are not too dynamic).
UPD: I looked at the compiled code and currently it is unlikely to be optimized. Also this page [1] shows that the code run in browser can be up to 1000 times slower than in a native Python interpreter.
[1] https://brython.info/speed_results.html
The figures in this page are relative to base 100 for CPython. Sometimes Brython is faster (value < 100), sometimes slower (value > 100). The worst value is 12 times slower.
While I love the tech behind this (as well as the good article and fun demo video), I'm very skeptical that this will be a good approach for most web apps. I hope it doesn't turn into Python programmers suddenly pulling in 7MB of WASM code/data just to render their websites (along with a 5s startup time), adding yet another layer of complexity and virtualization between their code and the browser. I think the interest in the tool is overall a good thing, but I think we need to be very careful about what kinds of projects we use this for.
I agree with everything you said there.
I will also point out that there is some fairly low hanging fruit in this PyScript project, if they will attempt to be more "web native". Take this example: https://pyscript.net/examples/panel_kmeans.html
It loads a bunch of large `.whl` files, and they're served up without any apparent compression, which raised my eyebrows immediately. Upon closer inspection, this is a zip file under the hood, so they probably figured that compressing a zip file over the wire was a waste of resources, and they're not really wrong... but, does it need to be a zip file? That means they're shipping a library to handle decompressing and manipulating zip files.
If we unpack the zip file and make an uncompressed tarball out of it, we can feed that through brotli and get a much smaller file:
The network transfer is now twice as fast, and the browser will do a phenomenal job at decompressing this resource before handing it to the application. The browser will (presumably?) decompress these resources in parallel instead of the (likely) sequential process currently being used, the browser should be faster at decompression anyways, and not handling decompression means less code that PyScript has to ship. Even better, subsequent page loads wouldn't have to keep decompressing the same bundle over and over... it'll just be a cached resource. You'd still need to handle the tar format, but that shouldn't be too terrible.Basically all browsers support Brotli[0], and you could always have a slow fallback for the... checks notes... IE 11 users out there.
This kind of low hanging fruit won't magically fix all the problems with PyScript, but it could go some distance towards making it more palatable for the purpose of bundling up a lightly modified Python application for use over the web.
[0]: https://caniuse.com/brotli
I agree that the bundle size is a big concern. Another aspect that I am worried about is Python’s performance. JavaScript is not a fast language, and Python is an order of magnitude slower. What makes Python shine today rely on packages with native code. I don’t know how many of them can be run flawlessly in the browser without modification.
A lot of the work porting these libs to wasm has already been done. But you can’t expect every Python program to just run.
Don't forget the 30 CPU minutes to solve the conda/mamba package requirements for the web app's dependencies.
The virtualization that WASM does is actually cleaner than what other similar attempts do. In a field where implementations typically end up being a thin veneer over JS objects (which means you typically end up having to get your hands dirty and work with JS bits here and there), WASM should clear the slate clean enough for most uses, so if you write Python and target WASM, you'll not have to write a single line in JS (well, maybe a standard cookie-cutter loader while the thing downloads the first time, but that's it).
Did Microsoft psyop Python into promoting the shipping of terrible web apps through Universal Windows Platform?
Still waiting for Windows Platform to become Universal.
What is new is old again.
ActivePython was available via the <object /> tag for Internet Explorer back in the early 2000's.
https://www.componentsource.com/product/activepython/about
The difference is that required a local install, and this doesn't. In practice, browser plugins are dead, because of corporate security policies and the fact that desktop-environment knowledge is slowly disappearing from the population at large (people don't know how to safely install things, and don't want to know, they prefer the walled-garden one-click model).
I was looking at PyScript and I was disappointed when I saw this code.
https://pyscript.net/examples/d3.html
The python version is much much slower loading at least on my browser. I counted 7 seconds to having it render the graph.
I kinda wish they spent the time thinking about Dom manipulation from a pythonic point of view rather than just providing the python to js interface and calling it a day.
2 seconds on my phone. This is new tech, I'm sure it'll get optimized. JS engines have thousands of man-hours into them.
Yeah I'm not so sure. Browsers need to ship python natively, and then we can just drop wasm and run python directly with a pythonic interface on the DOM.
Not sure that will happen given Python's resistance to incorporating a JIT. The only reason Javascript has acceptable performance is because there's been an absolutely insane amount of work on v8.
> Python's resistance to incorporating a JIT
Python (the spec) is not against a JIT. Only CPython (the interpreter) is, which is a reference implementation. Other implementations such as PyPy use JIT. I guess Jython can also use the JIT features of the underlying JVM.
Right, but other implementations are missing a lot of key libraries which rely on the CPython->C bridge.
Graalpython would be fast enough especially when C extensions aren't involved in the browser. Though I'm sure that comes with it's own complexities.
Wait a few years. This is an in-progress announcement, not an its-complete announcement.
It took less than a second on my basic af macbook lol.
Does anyone else remember the Java <applet /> days? It seems like we've come full circle after twenty years.
Except now we have to drag an entire JVM worth of code across the network just to say hello world!
There are some important differences in approach. Java was never designed to be downloaded over a network, and didn't have a module format or JARs back then. This is part of what made it so slow. In contrast, efforts to make the encoding of modules as compact as possible started the moment WASM began. [1] It was based on past research in compactly encoding IRs, and the modules are often processed in parallel.
The IR is also a lot less opinionated than other VMs. It started out being similar to a stripped-down JavaScript in capability, but broadened. At the same time it remained easy for browser engines to process into native code. Compared to optimizing applets, it has a simpler task to solve. This does have the disadvantage that modules need to come with their own runtimes. Compilers for languages like C have to deal with the fact that their host languages expect to be running on a fully-featured OS instead of a browser.
Even though it is a binary blob downloaded over the web, browsers come with disassemblers that allow you to see what is actually running. This is a step up over applets, but this is one part of WASM I find particularly underwhelming. The messy development of the VM affected the text format the most, so it's more confusing than it really needs to be. Some docs expect you to write it like a Lisp, even though there's no parse tree encoded in WASM.
WASM has quite a few problems, but they're at least different problems than the ones applets had.
1. https://github.com/WebAssembly/design/blob/a19e4ccf9c250cc73...
I am quite confident that jars were a thing already in 2000.
There’s a crucial difference though. Applets required you to download and install the JVM, and it was never part of web standards. Wasm is a w3c standard and built into browsers.
But I see the similarity in terms of compiling your software down to another (supposedly universal, we’ll see) intermediate instruction set.
Not really, via Java Web Start and Java kernel projects it was possible to have a similar Flash like experience, naturally the Web site had to adopt them.
An alternative, which doesn't require insane loading times, is to use any of the many great Python libraries that allow you to write web apps in Python, which get converted to JS web apps.
For example, I'm one of developers of Gradio [0], which lets you write your web app in Python, which gets rendered using Svelte-based components:
[0] https://www.gradio.dev
> An alternative, which doesn't require insane loading times, is to use any of the many great Python libraries that allow you to write web apps in Python
Sure, there are lots of things that do that.
They don't let you build apps using the Python scientific stack that live entirely in the browser, because they tend to be transpilers plus implementations of a subset of the stdlib plus some browser-specific libraries, whereas PyScript bundles WASM-compiled versions of important Python ecosystem libraries.
They have different strengths.
That's interesting. I played with Svelte a couple of times and I like it.
But since it's kind of niche among the rest of JS frameworks, I'm wondering, what made you chose it over the alternatives?
We migrated from React to Svelte because of two reasons: (1) speed: Svelte does a lot of work during the compile-time, which led to much faster and more responsive web apps (2) developer learning curve: as we expanded our team, we found that front-end engineers found Svelte much more intuitive and faster to learn
The trade off is flexibility, right? I mean, with something like gradio, can you add e.g. an event listener to a specific DOM element?
You can, if that that specific DOM element is a Gradio component (e.g. a button, image, textbox, etc). Here's a very simple example: https://github.com/gradio-app/gradio/blob/main/demo/blocks_h...
They say that Python has good bindings to C extensions, but for C libraries compiled to WebAssembly, someone will probably write some nice JavaScript bindings, so you might as well use JavaScript.
Meanwhile, JavaScript has been extended with so many language features that it's hard to see another scripting language giving people good reasons to switch. In the early days, JavaScript programming was very limiting and alternatives had a chance, but those days are pretty much over and I'd recommend just learning JavaScript.
(I say this as someone who spent more time exploring alternative languages than writing JavaScript by hand. Nowadays it's hard to come up with a good reason to bother.)
Related, I work on Nitro[1], which already offers a polished set of widgets, and a very simple way to author web apps using Python. I'll be releasing Pyodide support this week.
I also contribute to Wave[2], which provides a wide variety of widgets that can be snapped together quickly to build realtime dashboards/apps.
Both help non-front-end folks build web apps, and require no knowledge of HTML/JS/CSS.
[1] https://github.com/h2oai/nitro
[2] https://github.com/h2oai/wave
Article reports the guy as saying you can't use Python to do a GUI Windows app. Actually there are lots of ways to do this -
* Panda3D's main language is Python
* Godot has Python bindings
* So does raylib
...
Or TkInter and PyQt, which exist since 2 decades ago if not more.
More. TCL/Tk exists since 1991; TkInter was most likely created not long after that.
No, this is not a project to replace javascript in the browser, this is a project to give Python apps an html-rendered frontend. And yes, you should expect this to be packaged in electron apps.
Maybe it is sad, but it’s definitely the shortest path to brining modern frontend dev to Python.
At https://hal9.com, we built components for data science in native JavaScript to avoid the waiting times and download overhead if Pyodide. We found out the best tools for doing data science in the browser are a combination of Arquero and D3 and TensorFlow.js. At least for now.
We wrote our findings of this and many other libraries here: https://news.hal9.com/posts/data-science-with-javascript
I’m curious what are the primitives for the scientific computing stack? I’m vaguely aware that libfortran or gdpr tran or something live at the bottom, but I’m not sure if there are other base libraries or what immediately depends on them. Also, did you need to reimplement these in native JS? How does the performance compare?
We are not using libfortran not gdpr, we are basically using whatever libraries are available for the web. Since most data scientists don't want to use JS per se, you can build the apps as blocks in the Hal9 site or using a soon-to-be-released Python/R package, see https://notebooks.hal9.com
Feel free to check out our repo as well, all the "primitives" / blocks code is in the scripts folder: https://github.com/hal9ai/hal9ai
From like 2003 to 2010 I loved Python. I was happy to code in it. Found it much better than Perl, my previous no-manual-compile-link-step language. I was mostly a C++ developer but wrote several large tools in python.
I slowly started making more JavaScript stuff and used Selenium (python IIRC).
Then I started learning node. Liked npm's default to local project installs vs python's default to system installs. Eventually I started writing the command line tools that I'd have written in python previously in node. node had some sync I/O so it wasn't hard. Then promise/async/await arrived and I was fully in. I haven't written much python in probably 9 years now.
When I do look at python, I don't feel it's better. I'm not saying it's worse nor am I saying it's not better, rather I'm saying it doesn't *feel* better. Basically I've learned JS inside and out and I'm super comfortable there.
I find it easier to get node installed on multiple platforms and installing it locally without root/admin privileges is trivial via nvm. I'm sure that's possible with python but it's certainly not the default. And of course the browser is everywhere so it's just way more accessible/sharable in JS
I'm using the underlying project, Pyodide, to launch a worker that can execute code and provide autocompletions (via jedi) to a codemirror editor. I'm not super crazy about the startup times, but I'm hoping that there will be more work to help optimize it further.
I don't see much point in going from one dynamic untyped language to another. Javascript and Python offer much of the same advantages and disadvantages, but having to deal with the overhead of running python code seems to just saddle it with tradeoffs for no real benefit. Learning one or the other is fairly easy too.
May as well write Javascript directly, as NPM is not short on packages if that's what you need. I see more value in going from higher level languages like ReScript, Purescript, Melange (Reasonml + Rescript compiler) to Javascript. You have to deal with things like code interop, strictness, overhead of compilation, but you at least gain in safety and succinctness.
> May as well write Javascript directly, as NPM is not short on packages if that's what you need.
I haven't heard of an equivalent of the Python scientific stack for JS, and that seems to be one of the key selling points here.
That’s a good use case, but the theme seemed to be “Python all the things!” It came across as a bit fanatical.
The advantage is obvious. People who know and/or enjoy Python can get into web dev without having to fuss with a new language. It’s really that simple.
> The advantage is obvious. People who know and/or enjoy Python can get into web dev without having to fuss with a new language. It’s really that simple.
All web API docs are written for Javascript. Knowledge and practice of Javascript is mandatory for front end development at first place.
Agreed. Even with the higher level languages that compile to JS you still need to know JS, but you also get the benefit of the stricter languages.
If that’s what you are doing then most of how you write python can be done in javascript. The languages are not too different except for superficial syntax stuff. You also inherit the problems that come with compiling and also in general the lack of web-oriented packages that javascript offers.
My first impressions using pyscript:
https://pwhiddy.github.io/more-writing/2022/05/05/Pyscript-T...
That seems reasonably fast on my machine. Thanks for the demo (and the bonus for those interested in that kind of stuff).
Np! The particle sim part of the code is actually super fast, the only reason it might not run with full framerate is that it’s software rendering all the pixels in python and dumping out the images to the screen in real time. that’s the expensive part!
I just love LWN for how impartial and informative it is. It's a bit clunky with 20x"he said", but it sure does a good job of giving me a balanced idea of what this is all about! Happy to be a subscriber.
Wow. The article means using pandas in the in-browser demo.
How do they do it? The whole point of numpy and pandas stuff is that they are Fortran and C code that does numeric operations very quickly, while the Python part gives a nice and ergonomic interface on top of them.
So they are showing a WASM port of NumPy / Pandas now, with the Python interface finally surfacing in the browser. It should be a very fair bit slower than native code, though.
Are we seeing the Atwood Law stumbling? That is, things are still migrating into the browser, but to WASM instead of JS now?
What I really hate about this is the absolutely disastrous API. From the <py-script> tag that could easily have been more standard-ish <script type="text/python">, to <py-config> and <py-env> that embed YAML for some reason, to weird custom components like <py-inputbox> that don't integrate with existing ecosystem at all. Brython, albeit still clunky, got it a lot better.
[Brython]: https://www.brython.info/
Does WASM end up succeeding generally where Parrot[1] seems to have done otherwise? Right now WASM is browser-bound, but that did not stop Node.
[1] https://en.wikipedia.org/wiki/Parrot_virtual_machine
Wasm is far from browser-bound; there are many standalone runtimes and they're used for lots of different things, one of the big ones being edge-workers. Here's a collection of runtimes: https://github.com/appcypher/awesome-wasm-runtimes
Will PyScript honour the same naming tradition as JavaScript (which has nothing to do with Java) and thus have nothing to do with Python?
Isn't this the same idea as GWT (which is Java in the browser)? That one turned out to be impractical, e.g. for debugging.
Browsers definitely need an alternative to JavaScript but this doesn't look like the native integration I was hoping for.
let's be real, this has no chance of seeing any real adoption, except as a novelty or for technical demos, because the runtime takes multiple seconds to download, which is insane. reading that document without anything addressing this felt like I was taking crazy pills
[dead]
Nice! Fans of the two most awful languages fighting each other. I'm just gonna grab some popcorn!
>Nice! Fans of the two most awful languages fighting each other.
What? No one mentioned Rust or Go.
(slowly heads for the exit)
Hehe, yeah, I like that show too!
I really, REALLY hate the idea of fracturing the frontend ecosystem further with another scripting language option when there is already an absolutely insane overabundance of tools and frameworks for JS alone
It should at this point be enshrined as an official binding standard that browser UAs must support JS and must NOT support any other scripting languages
While we're at it, should we also enshrine into OSs that nothing but C shall be used for systems programming and maybe also forbid anything but one gui toolkit....
That ship has long sailed. As soon as you have JS, you have the ability to transpile to JS from any language with the appropriate tooling, to say nothing of WASM.
Any language can be the target of transpiling. JS just happens to be a popular target because we are forced to use it even if we have better options.