Javascript came a long way and despite its legacy quirks is actually quite enjoyable with ES6. We also added tons of good tooling (like TypeScript, React or Vue) to improve the web development experience.
While I still think, it would be nice to use a language that doesn't need 3 equal signs for sane comparisons, I wonder if Python with its strong whitespace to code-block correlation is actually a good choice for transmission and remote execution?
It definitely increases the size of transmitted code (tho probably by not so much because I think files are usually transmitted gzip compressed to modern browsers).
Are there other issues anyone can think of? It somehow gives me an uneasy feeling even tho technically a semicolon or repeated 0x20 don't make a difference except size.
I (professional Python developer) tried writing some ES6 over the weekend. I acknowledge I'm out of the loop/practice, but I can handle ===. I do, however, struggle with 1) the lack of a reasonable standard library and 2) the lack of a well defined object model. In general, the fact that objects and mappings are the same thing, and that keys have to be strings, is tough for me to understand.
> In general, the fact that objects and mappings are the same thing,
What do you mean? What would you like to see in an object? ES6 has classes (syntactic sugar over prototypes, but does it really matter?) if that's what you are after.
> and that keys have to be strings
ES6 has a Map constructor[0] that can have any type of value as key. Usually, though, having keys as strings is quite sufficient.
"Any type of value as key" is quite misleading since anything other than primitive types (number, bool, string) is compared by reference. Observe:
> const m = new Map();
undefined
> m.set([1], "one");
Map(1) {Array(1) => "one"}
>m.get([1])
undefined
C++ and Rust don't stand for this nonsense. You can't even define a custom hashing function, which means if you want a useful map for anything other than numbers and strings you have to write a wrapper around `Map` that hashes the objects to numbers or strings, and then you're more or less back to raw objects.
It's definitely better than raw objects because it doesn't mix up data and methods, but it's not much better.
To clarify, I miss having an object model that allows customisation of hashing, equality etc
> ES6 has a Map
Thanks for this; I'll check it out. One simple example of a key that is hard to use strings with is a composite key of 2 strings. OK, you could concatenate them using a character you know won't be used in either string, but what if it's user input? The code is then littered with in/out concatenation/splitting my this extra character etc. (And that's the simple case without other types etc.) It's much easier to have a clear way to customise the hash function IMHO.
Most programming languages have a nice delineation between a dictionary and an object but they are one and the same in JS and that'll throw plenty of traditional programmers for a loop.
To be fair Python has the concept of "everything is a dictionary" running pretty deep in its DNA. To a certain extent everything in Python is syntactic sugar over dictionaries.
I’m a professional Python developer as well and JS objects are one of the things I envy. Python objects are still opaque to me after more than a decade. I couldn’t tell you all of the magic methods nor could I describe the functions of those that I do know. Many of the things that Python objects support, such as inheritance, strike me as overtly undesirable (it would be much better to use composition in all cases, IMO), and the meta type system seems far more complicated than it needs to be (partly because inheritance confounds things)—although I was relieved to discover that you can call type() to generate new types instead of using the meta type class syntax.
On the other hand, as far as I am aware, JS objects are just bags of attributes with relatively few special magic attributes. There also seems to be less of an obsession with inheritance in JS, probably because the syntax makes a functional style more ergonomic although perhaps also because prototype inheritance is relatively cumbersome.
In general, JS’s object system feels more transparent to me, although I wish they would go further and preclude the special syntaxes for creating types. There’s nothing wrong with a function that returns types (which are either objects or closures depending on your religion). But I suppose I’m well on my way to reinventing lisp at that point.
White I agree with you about modern JS, using Python in the browser has a few advantages:
- it can be the same language as the backend, that's a huge advantage (no need to change context, you can more easily have the team for backend and frontend)
- if you use Python elsewhere (like it's my case for multi-frontends XMPP client), you can factorize the code
- it's a really popular language, notably among scientists
- I have no numbers, but I suspect that once the initial download is done and cached, Python code should be smaller than JS equivalent
- there is a huge ecosystem (of course JS is even bigger, but the neat thing is that you can use both)
And probably other things I'm not thinking of right now.
> you get much bigger collection of ready to use opensource libraries,
bigger number, but that's because there is no (useful) standard library in JS. Datetime for example, there are loads of libs for that in JS, some of which are complete.
In python you just use the built in one. You bust out to a non standard lib when you want something fancy.
> bigger number, but that's because there is no (useful) standard library in JS.
I was thinking more about higher level libraries like frameworks.
> Datetime for example, there are loads of libs for that in JS, some of which are complete.
Ahm, and if you need to work with Timezones(not much fancy IMO) you still need an external library.
Important footnote: the creator of Node.js is also the creator of Deno. One of his key reasons for "starting over" with Deno is that the lack of a standard library in Node.js is one of it's biggest pitfalls. That is also one of Denos biggest features (among many other awesome things). Unfortunately there is still a long way to go for Deno to "catch up" to node.js.
As an experienced JS/TS and Python developer, I can confidently say that the Node.js / npm / yarn ecosystem sucks compared to what you get with Python and PyPi.
>the lack of a standard library in Node.js is one of it's biggest pitfalls
>npm / yarn ecosystem sucks compared to what you get with Python and PyPi
So you claim Python has a better standard library AND a better package ecosystem? That's bold. Care to expand on why you feel this?
I ask because of this. From the perspective of a JS dev who helps Python devs at work, pip seems pretty weak, its publishing story even weaker, and then both languages seem to have all their strength in their package ecosystems (Python: tf, django, dataframes, etc; JS: react, typescript, etc). So now to see you say "npm ecosystem sucks compared to pip" has me wondering what I'm missing.
As someone who's done a lot of python and a fair bit of JavaScript, I'll agree with the preference for the python ecosystem. I guess my perception of the difference is a quantity vs quality thing. My experience has been that python packages tend to be more stable, better documented, and frankly more reasonable in scope. There's less framework churn (Django has been around for what feels like forever, as have lighter solutions like Flask) and libraries tend to include enough functionality to seem with adding a dependency for; the number of transitive dependencies on a typical JS project is alarming. Also much less of the ecosystem feels like it's just trying to make up for an absent standard library. You don't see stuff like underscore in python land.
Both languages suffer from patchwork build infrastructure; interpreted languages are great when you have one file and no dependencies, but as soon as you grow a bit beyond that rules about where to find modules make things complicated. Both languages have developed tooling around this that suffers from being an afterthought, and I'm not sure which is worse.
I guess this might not strictly belong to "the package ecosystem", but I strongly disagree that you can compare the npm packaging story to the pip packaging story. Publishing to npm, hosting your own npm instance, configuring npm to look behind proxies for certain packages, an opinionated `package.json` with real functionality beyond dependencies, a unified entrypoint, wow it actually boggles my mind to hear Python people say pip is even in the same room as npm.
Definitely let's be clear - babel & webpack and the associated ecosystem are a pain, but those are mostly borne of necessity to transpile HTML/CSS/JS from frameworks, and not because node.js itself isn't a decent language.
Finally, I don't really follow all this business about the lack of standard library. Can you explain to me what you mean? What parts of the Python standard library are a part of your everyday toolkit? I've built a lot of web apps over the years and the only time I've ever used lodash is for throttle and debounce.
An npm publish requires you to run `npm publish`, assuming your `package.json` points to the entrypoint of your code. Remember: `package.json` is pre-populated when you start your project with `npm init`.
Also, I was able to run my own NPM instance with a zero-config tool, I expect Python has parity there.
Anyways, pip... Just the other day, I went to use a Python project I had been regularly using, and without any changes to Python, my OS, pip, or the project, it completely started failing. Some errors that the `ssl` module wasn't available. How can a module not be available? There was no easy solution, all to something triggered by nothing. This install was literally done thru a source-controlled script too. It's a pretty awful situaton.
Anyways, NPM has never so wholly failed me, and in the worst cases where it fails it usually has helpful messages directing the user what to do.
That plus tools `npx` make it pretty clear to me, Python is literally version and dependency hell. NPM has had this all on lock for years now
> As an experienced JS/TS and Python developer, I can confidently say that the Node.js / npm / yarn ecosystem sucks compared to what you get with Python and PyPi.
I can say the same. As an experienced Python and TS/JS developer, I confidently state that Python ecosystem sucks compared to what you get with typescript and npm.
And if we take only type systems TS is on another level compared to Python.
Although Javascript has a bigger collection, Python is often the go-to for Data Science, ML and AI, and Web dev backends. It's nice to reduce the complexity of the stack I'm using by being able to use Python for both.
Yet, in the same survey it is on par with Typescript.
Also for me always the question is loved by who. Of course junior/beginner level people will prefer simplistic language like Python, because that's the main target audience for Python as a language.
Yes it is on par but isn't Typescript an attempt to address the shortcomings of Javascript? I'm not saying Typescript is bad but it's a strange example to reach for when arguing for Javascript.
> - loved by who
Python is used by a huge number of professional developers for commercial applications, it is not targeted specifically towards beginners. Also, I don't see how it being a go-to language for a lot of beginners is a bad thing. A language being more complicated doesn't inherently make it better.
At the end of the day there are use cases for Javascript just as there are Python. The people using Brython will have their own reasons, just like you have yours for using Javascript for your applications.
It's a small advantage, practically. There's a limited set of circumstances where this is leveraged in the rare cases that client/server languages are matching (usually the ability to directly copy specific algorithmic implementations). The "advantage" always feels overstated...especially on the web where the frameworks are disparate because the underlying data models are different, ie the DOM.
I'd say the advantage is less on the architectural side and more on the team efficiency side – you could possibly have a full-stack team that only needs to do most of their work in 1 language. The benefits of easing task-switching could make it worthwhile as a stack choice.
The thing is that for anything more complex than simple CRUD either side (frontend and backend) is such an inherently different problem domain that I don't see that the programming language is the relevant factor.
Because frontend and backend need a very different skillsets and both need a lot of knowledge and training to become good, there are very few true fullstack engineers. And I would bet that most if not all of those can handle work in multiple different programming languages.
It would be nice to use the same BBCode parser on the server and client to give the client accurate previews. Why not just compile that one little module into Javascript and sent it over the wire?
> - it can be the same language as the backend, that's a huge advantage (no need to change context, you can more easily have the team for backend and frontend)
Having used TypeScript for both frontend and backend for several projects, I say this isn't as necessary as you might imagine.
The real context is whether you're coding for your frontend or your backend and that context will happen even if the languages are the same.
You can use same set of libraries but usually they don't really overlap either.
> I have no numbers, but I suspect that once the initial download is done and cached, Python code should be smaller than JS equivalent
You have to download 750 kB of Python interpreter. No way the terseness of Python can make up for that unless you have so much code you definitely shouldn't be using Python. Plus how do you minify Python? All those spaces...
Q: why use the operator <= to build the tree of DOM elements? This is not pythonic!
A: Python has no built-in structure to manipulate trees, ie to add "child" or "sibling" nodes to a tree node. For these operations, functions can be used; the syntax proposed by Brython is to use operators: this is easier to type (no parenthesis) and more readable
To add a sibling node, the operator + is used.
To add a child, the operator <= was chosen for these reasons:
* it has the shape of a left arrow; note that Python function annotations use a new operator -> that was chosen for its arrow shape
* it looks like an augmented assignment because of the equal sign
* it can't be confused with "lesser or equal" because a line with document <= elt would be a no-op if it was "lesser or equal", which is always used in a condition or as the return value of a function
* we are so used to interpret the 2 signs < and = as "lesser or equal" that we forget that they are a convention for programming languages, to replace the real sign ≤
* in Python, <= is used as an operator for sets with a different meaning than "lesser or equal"
* the sign < is often used in computer science to mean something else than "lesser than": in Python and many other languages, << means left shift; in HTML tags are enclosed with < and >
* Python uses the same operator % for very different operations: modulo and string formatting
I'll try to explain why I strongly disagree with the FAQ:
> this is easier to type (no parenthesis) and more readable
When 99% of the open-source codebase uses "<=" as lesser-than-equal, no it is not more readable to change that.
> It has the shape of a left arrow
Then, why not `child >> tree` ? or `tree << child`
> it looks like an augmented assignment because of the equal sign
No, it looks like a comparison. This is totally subjective.
> it can't be confused with "lesser or equal" because [...] would be a no-op
Wrong, the value of _ variable contains the result of the last expression. What value can i expect here?
> we are so used to interpret the 2 signs < and = as "lesser or equal" that we forget that they are a convention for programming languages
I agree, and trying to be subversive won't change that convention.
> in Python, <= is used as an operator for sets with a different meaning
The implementation is different, but the math are the same. The "<", "<=", "==", "!=", ">=", ">" operators are comparison operators.
"setA < setB" has the same meaning as "numberA < numberB", aka: a comparison between two object in an ordered space.
> the sign < is often used in computer science to mean something else than "lesser than", [...], << means left shift; in HTML tags are enclosed with < and >
You are talking about a character not an operator.
> Python uses the same operator % for very different operations: modulo and string formatting
Not at all a Python user, but I don’t get how this is a valid argument at all:
> Python has no built-in structure to manipulate trees
What’s wrong with an API like appendChild etc? I know you’re just quoting the FAQ but if anyone has an answer I am legitimately curious. I have worked with Ruby for many years and loath cute DSLs but I always thought it was just the Ruby community that went overboard on that shit haha
Verbosity vs. fluency, given the application domain, I expect is the concern. I'd rather have fluent DSL separate from the basic language runtime, though, so that adopting it is a separate decision from using the runtime.
I will never understand python API developers obsession with overloading the operator magic methods.
Apache Beam is one of the worst offenders to me. The recommended method is to connect your functional transforms when building your pipeline as if it were a series Bash commands piped together (overloading bitwise OR). Who thought “oh, you know what language and API is synonymous with ‘write a large complicated amount of business logic in me’, Bash.”
This is because it started out as a Google project.
There is an internal time-series framework there called Monarch that does the same thing for composing operations.
It's still python; you can overload operators and give them side-effects in any conforming implementation.
It may not be "pythonic", but there's an established tradition of operator methods and there's no requirement that python code conform to any particular tradition.
Overloading comparison operators like this is a particularly bad idea in Python, because of the "smart" behavior they have baked in. Overloading >> is comparatively safe.
Unless you implement __ge__, `'Hello!' >= document` will also call __le__, which may or may not be what you want. And `'Hello!' >= document <= 10` is equivalent to `'Hello!' >= document and document <= 10`, which can lead to confusing surprises.
(Brython does implement all of those pitfalls faithfully)
Sorry, what I meant was: Is it the Python you want in your browser?
So, this is just another implementation with its tradeoffs, just like when using Jython to have Python (without its ecosystem) and the JVM. Here you have Python with another semantic to learn.
I see this happening in a lot of Python libraries. It's still Python - or *ython maybe we can call it. The idiom of cutesy operator overloaded spread in from other languages; I'm personally not a fan.
I'm not interested in Brython, mainly because the data model is from Javascript, not from Python.
In my opinion there are two "right" ways for Python in the browser: One would be a bytecode interpreter in Javascript (like the discontinued Batavia project), the other is porting CPython or PyPy to WASM (Pyodide).
Both gives you the full Python experience and potentially even full performance.
'pansa2 already linked this upthread, but a colleague of mine wrote an in-depth comparison of six popular Python-in-the-browser implementations, and their trade-offs (with sample code). It's a writeup from a PyCon UK talk: https://anvil.works/blog/python-in-the-browser-talk
Brython feels like a Python interpreter (it's actually transpiling to javascript with a thin compatibility layer, cf. https://github.com/brython-dev/brython/wiki/How%20Brython%20...), you can use Python live in the browser, while Transcrypt transpile Python (or nearly Python, depending on what features you activate) to Javascript ahead of time (this can be achieved with Brython CLI too).
Brython has a better compatibility, but Transcrypt being pure javascript on the browser should be faster (I didn't made the comparison myself though). Both projects are complementary.
PyJS is a hostile fork (or I should say "hijack", but that's a long story) of Pyjamas, a Python 2 to Javascript compiler. I'm not sure where they are now, but at the time Pyjamas was Python 2 only and there was no plan to move it to Python 3 as this would mean a full rewrite of the transpiler.
It's pretty similar to Transcrypt except that it comes with a library which is a rewrite of GWT for Python. With that you end up writing web application in a similar way as you would do for desktop application. I've been using Pyjamas for years, it was working quite well (but you had to get used to some bugs/incompatibilities with Python, and I have not experienced that with Brython so far). About the library, while it seemed like a neat idea at the beginning, at the end it was an experience too distant from web developing, and meanwhile HTML and CSS improved a lot so it doesn't really makes sense anymore.
So from my experience :
- you want real Python 3 and being able to use it dynamically (in a live console for instance) ==> Brython
- you want something as fast as javascript with clean syntax of Python ==> Transcrypt
Both work well with JS libraries, Brython in addition re-implement most of Python standard API (but it's long to import, so it's often better to use JS libraries or native methods).
In addition, and really subjectively, I find the Brython community really nice, the main developer is reactive and kind.
Brython gives you real Python traceback, and you can even run pdb inside the browser (which will block your scripts) or an Inspector (a non blocking Python console) allowing to transfer objects between Python and Javascript for inspection in dev tools.
edit: corrected the initial statement, Brython feels like an interpreter, but it's actually transpiling, so you don't have such a big performance impact.
edit2: added that Brython can be compiled AOT from CLI too + precisions that I didn't compared with Transcrypt myself
I've been using Transcrypt for the last few months and am impressed at how well it integrates with JS libraries. But then that was done with intention in the design. I've been writing React+MaterialUI apps in Python and the resulting code actually still looks like the Python I know and love. I did get pulled into the NPM/Parcel world for JS package management & minification, but the build step is relatively painless and Transcrypt has a Parcel bundler plug-in so there's no extra work involved to use it.
The fact that Transcrypt hasn't implemented the full standard library yet hasn't been much of an issue for me so far either. In the very few cases where I was missing something, I just pulled in a JS library in it's place (i.e. deepcopy).
While using Transcrypt this way requires you to understand the APIs of the JS libraries that you use, the code you actually write is 99% pure Python.
just a correction for my comment above, I should have written "Brython feels like a Python interpreter", but it's transpiling to JS too, the difference is that it's done directly in the browser (it's also possible ahead of time from CLI), and then the JS is stored in indexecDB (this can probably be compared to .pyc from CPython).
I hadn't heard of Transcrypt, looks neat. Can it be used server-side? Leveraging a JavaScript JIT seems like a good way of 'passing the buck' for getting high performance out of a dynamically typed language.
Statically compiling dynamically-typed Python to statically-typed WebAssembly would be similar to how Nuitka [0] compiles Python to C. This compiled code may be a little faster than interpreted Python, but it's still going to be quite slow - much slower in a browser than JIT-compiled JavaScript.
AFAIK the ideal way to maximize the performance of Python in the browser would be to JIT-compile Python code to WebAssembly. Does anyone know whether WebAssembly implementations are able to support that?
Seems super interesting, but I'm afraid at how much of a performance impact this might have. Any benchmarks on that? I can't imagine interpreting Python in JS to be cheap.
There is a hit, but it doesn't seem too outrageous. Might be usable in simple webpages for people coming from Python that don't wish to learn an entire new language.
Question: What operations are being done on the client side that requires that much speed? Why is speed even a concern in this case? With modern hardware and the type of applications I am familiar with (rendering tens of thousands of financial data points), I could 50x lower the speed of execution and the client wouldnt even feel it. So I´m geniunly curious what people are working on that requires that much speed/performance?
This assumption is how you end up with Slack and Discord eating 100% cpu any time there's an animated gif. Something they probably don't notice on their powerful developer workstations.
You should spend more time using/working on heavy clients from a slow device since it tends to quickly answer the question. You aren't just using Brython for your one $('box').hide(). Rather, you're using it presumably because you are writing a lot of client code.
Curiously, I would say that if a frontend technology is fast then that's already improved the user-experience. If your user can click around quickly and if making a mistake isn't a huge setback in terms of time to navigate through loading screens etc.
It also gives developers a good starting point - no need to optimise if the language is just natively snappy.
But, as is usually the case, your mileage may vary depending on your use case!
I've just finished rewriting a standalone python application into a JS browser application, and runtime went from 20 minutes to 1.5s. The most important factor is that the original programmer didn't know what convolution is and that it's a linear operation, but in those 1.5s, V8 manages to run thousands of times through a 250k pixel array, convolve it, and draw it; changing the color mapping takes a mere 4ms, so it can be done with responsive controls. Python just can't do that.
Edit: this thing transpiles to JS, apparently, so it might perform.
no 50x. If you design your applications correctly with the right data structures, you rarely need all the computational power today´s machines have. In some cases, yea probably. but in most cases, hardware is already too good!
Well it seems like the clock example they have can't even hit 60 FPS without consuming 100% cpu (of one core). So yeah you probably don't want to actually use Python in the browser (via a JS interpreter).
> people coming from Python that don't wish to learn an entire new language
I see this argument all the time but I just don't get it. Python and Javascript are remarkably similar, they have different syntax and the metaprogramming side of things is quite different but aside from that, it's really not a big jump.
Syntax makes a big difference! I am more familiar with Javascript, and while can program Python, I find myself looking up Python’s syntax for things frequently while writing it. It a frustrating experience.
I, for one would prefer to just use Python, but Javascript is a necessity for web programming, obviously.
If I recall, Brython doesn’t behave exactly like CPython but more as a thin Python-like wrapper around JS. There’s not as much emulation as a result and the performance is more on par with JS than something like Skulpt.
The documentation could use some work - I have scoured the website and FAQ but still don't understand how this works. Does it compile into javascript, or it is a Python interpreter for the browser? What subset of python does it support? What about libraries?
I recently encountered Pyodide[1], which compiles to wasm. This seems more interesting/useful, because one can imagine running scientific computations (for which Python is a good choice) in the browser without much of a performance hit.
For the love of DOM, why replace one dynamic language that is at least optimized for by the browser by another foreign one with an intermediate layer in between ?
Yeah. I keep meaning to dig into Blazor but it seems overwhelming at first (especially because I'm mainly a C# dev due to Unity and a lot of the .NET jargon is foreign to me).
There seems to be more lightweight "c# to web-assembly" routes than might be worth investigating.
Just out of curiosity, what kind of a moderately-complex codebase can be migrated to a browser setting from one that C# is currently running on without considerable refactoring or adaptations ?
It generates and manipulates 3d geometries. I currently render it in Unity but it would be nice to have a lightweight WebGL native library that could be used by three.js, A-Frame etc.
There is: "This place is standardized on X" (what is way more common than it should be.)
And: "X-developers are cheaper" (and then, developers stay stuck there because it's a large market, but shouldn't.)
And there's the real reason why one should want to use the same language everywhere, that is to provide greater integration between frontend and backend on a framework (but then, currently it's mostly React that tries to do that and it doesn't get good results out of it - so much that developers refuse to use that feature).
In-browser programming is 5% about js as a language and 95% about DOM, html, various browser apis etc. - all the examples for the above are in js anyway so at the very least one needs to become proficient reading js to do anything useufl.
I've looked into Brython and other "Python in the browser" implementations (transcrypt.org, pypyjs.org). It's fun! At a high level, the approaches are:
* Create a Python interpreter that is able to run Python code directly in the browser (PyPy.js, Brython)
* Transpile Python code into JavaScript and send that to the browser (Transcrypt, which also does a lot of tree shaking to keep the transpiled code efficient).
Here are the benefits, IMHO:
* Share helper code and class definitions across environments
* Most of the std lib, and a handful of popular 3rd party libs, are supported
* In the rare happy path, only have to think about one programming language.
The downsides are:
* Slow. For the "send an interpreter" approach (Brython, PyPy.js), the browser has to compile a whole compiler before moving on to running your code.
* Incompatibilities. For Brython and Transcrypt, C parts of the standard lib have to be re-written in Python for compatibility. So when you're importing something from the itertools package, it's actually a custom implementation like this: https://github.com/brython-dev/brython/blob/master/www/src/L.... The custom code will not always be exactly compatible with the CPython implementation.
* Incompleteness. Some std libs aren't implemented, or are only partially implemented. 3rd party libs that rely on these will not work. Popular 3rd party libs like sklearn which get their power by wrapping C/Fortran libraries need custom wrappers that don't exist (AFAIK) yet.
* You still gotta JavaScript. Even in the best transpilation scenarios, things break and you have to figure out what the generated or interpreted code is doing. This is especially tough for Python in the browser tools, which aren't widely used, so have both undiscovered bugs and a lack of community support. In my experience, working in a transpiled codebase doesn't mean you have to learn one thing, but three: the source language, the target language, and the frankenstein monster of the logic/compromises bridging the two.
* Tooling. The ecosystem hasn't reached a critical mass to support tooling. It's unclear if there's enough excitement in the Python community to get it there.
With all that said, unless you're a true believer or just want to have a little fun (again, it is fun!), I wouldn't recommend this.
I always think these kinds of thing are cool in theory, but I feel like "the right tool for the job" is always more appropriate, and (for better or worse - right now) JavaScript is the right tool for the job.
I can only imagine (and shudder) starting to write a front-end app in Brython, coming up against an error and then not knowing where to turn. At least JS gives you the confidence of being able to Google / StackOverflow answers.
Is it though? The fact that there are thousands of tools like this and whole web-assembly movement just might mean that Javascript really sucks at what it supposed to do.
I implemented some scale scale webapp with it. At some point, it becomes way too slow.
It's a very cool project, which is only enabled by fast js engines, but the reality comes back hard: it's an interpreter, running on an interpreted language. I was never going to be fast.
I'm really forward to skilled people providing python though WASM. And not pyodide, which is more than just python.
Why not inline WASM for deployment but host human readable Python source in a URI? Accept liberal input languages but be conservative in the browser output.
I can throw out a couple of ideas. First, learning one language really well versus learning two languages really well -- that's an easy sell. Second, code reuse. If you think on it some, I am sure more ideas will come to you.
> So now we can write web apps in one of most inappropriate languages for frontend development.
Implying that javascript was ever appropriate.
> White space significant, good luck minifying it.
Just gzip it. Minifying is highly overrated to begin with.
> No anonymous functions, yes you need to have name for that callback, even though it's simply disabling a button.
Lambdas are supported, what do you mean?
> Webpack does a great job of handling assets by simply importing/require them in the code. Python import system, can't support that kind of importing.
Can we please stop doing the 4chan-esque snarky >implying ? It's not discussion in good faith.
> Minifying is highly overrated to begin with
Compression is not magic and minifying has real world performance gains in JS projects at least - I don't see how Python would be different here.
> Lambdas are supported
If you want to write your event handlers - which in UI programming is a lot of your code - in a point-free style, then I think you'll be letting yourself in for a lot of hassle.
> Webpack... What does this even mean?
I don't know Python too well, but I assume this is about the ability of Webpack to overload import semantics with non-code dependencies (e.g. importing stylesheets, icons, bits of JSON). Presumably Brython does not support this.
You seem quite bullish about the strengths of this project. Exactly what problems do you feel it solves? Assuming that we already have tooling like Webpack and are able to write in either ES2020 or TypeScript, what do you think we gain from writing our UI code in Python?
>Compression is not magic and minifying has real world performance gains in JS projects at least - I don't see how Python would be different here.
How much are the gains with minifying (factoring out compression) anyways? I'm sure they're somewhat faster, but enough to justify the step/obfuscation (assuming obfuscation isn't a goal)
If a function is so long it requires multiple statements, is it really so bad to give it a name and a separate line of code from its use? Personally I'd find that clearer, even if the language didn't enforce it.
Edit: Just in case anyone isn't aware, in Python, nested named functions have precisely the same capture rules as lambdas, so it's never a problem to replace a Python lambda with a normal function (except personal preference about code style). This is particularly in contrast to JavaScript where arrow functions are so popular partly because of their different relationship with `this` to other functions. And normal nested functions defined with `def foo():` have a benefit: they have their name attached to the object, so a traceback involving it will be clearer, which isn't true for `foo = lambda ...` or `bar(fn=lambda...)`.
In practice? Yeah. It sucks. In Javascript, I'd simply add curly braces and be done with it.
Code is meant to be clear. And often times with Python lambdas, there's no reason to give the function a name. It's a callback. What would you name it? "Callback"? You're adding extra complexity for no gain.
But, whatever. It is what it is. Javascript has its own pile of limitations. I was just saying that Python isn't a flawless butterfly.
Yes just call it "callback" if necessary. In the situations I'm imagining, that would still make the code clearer than using one statement to cram in both the definition of the multi-statement function and the use of it in another function.
But maybe we're imagining different situations, and maybe that's the real reason we don't share the same point of view.
100% this. When I write Javascript or Scala, I do this anyway just because it’s a better way to structure code.
Nested anonymous functions that contain complex bodies and rely on scope closure of args or local variables inside the complex bodies of exterior anonymous functions needs to stop being a thing, in any language, anywhere. It’s a massive antipattern.
Same for using functional programming constructs like map or filter or reduce with complex multi-statement nested anonymous functions. “Inlining” your anonymous function when it’s not just a simple statement is simply a terrible idea across the board.
It’s like living in crazy town to see that style defended as reasonable or treated like it’s valuable for a use case, etc.
Functional programming constructs helps you write simple code faster, and clarify the algorithm.
It is easier to rearrange, to test and to reason about, but it is harder to read.
Once your fast-written code works, you obviously need to optimize it where it's needed. And if you map/filter/reduce is your bottleneck, just get rid of it obviously.
But I highly doubt it will be your bottleneck.
Nested anonymous function that rely on scope closure is THE way to truly encapsulate your data, example: https://pastebin.com/JrAP6yGP
IMHO, the factory pattern is a clearer/easier pattern than Javascript's classes/prototypes.
I've been writing Python professionally for a while now, and the one thing I always want to reach for are multi-line anonymous functions. However, I do appreciate how Python prevents some of the callback hell one can encounter in JavaScript codebases.
There is a difference between abusing anonymous functions, and situations where anonymous functions might be called for, where it just so happens that those functions require more than one line of code.
>If a function is so long it requires multiple statements, is it really so bad to give it a name and a separate line of code from its use? Personally I'd find that clearer, even if the language didn't enforce it.
Sometimes this is the case. But let's take for example filtering an array. Do you really want to give names for the callback that will filter? Also I find it more readable if the logic doing the filtering is right there where the filter call is, and not somewhere above.
It sort of is a pain point because you need to move the code out of wherever the lambda was into its own block elsewhere. Breaks up the flow and is awkward. I'd love to see some kind of block lambda syntax in Python. The one drawback of whitespace syntax...
"Whitespace syntax" is not the problem. It is that Guido thinks that the anonymous callback style is harder to read and therefore something to avoid most of the time. I tend to agree.
It's the problem inasmuch as the way you'd spell an anonymous block is non-obvious considering that it would have to work as an argument to a function or element of a literal and in both of those cases indentation is freeform.
The only thing with 'just gzip it' is that actually minification+gzip does seem to give slightly better results than just gzipping it. This is partly going to be because there are some things that gzip doesn't know it can remove that a minifier does - e.g. comments. Presumably this difference is exacerbated if your codebase uses long/descriptive names and many long comments. Not that this is a particular problem for Python on the web of course because minifiers do exist for it.
Lambdas are not functions. You can't have statements in them, only expressions. So no, they don't cut it as anonymous functions.
>> Webpack does a great job of handling assets by simply importing/require them in the code. Python import system, can't support that kind of importing.
>What does this even mean?
It means that in JS you can do "require('./image.png')" and webpack will automatically handle the image for you. Python doesn't have any way to import anything that is not .py file.
This is some pretty intense negativity. What's wrong with doing something just for the hell of it? People will choose naturally whichever may be the most efficient methods.
There is no reason to shit on someone's work just because you think it was a bad idea. It's already done, and it can coexist in the universe with you.
> There is no reason to shit on someone's work just because you think it was a bad idea. It's already done, and it can coexist in the universe with you.
If zaro is wrong (and people pounce on him for being technically wrong), Brython will indirectly be vindicated. If he's right, it's the perfect opportunity for break down just how right he is; e.x, if future client-side languages will be shaped by their suitability for minification or if content compression obviates this.
I think even for new projects, this is good. Nobody arrogates themselves to the belief their project will be as influential as the most well known projects started just for fun (n.b "Just For Fun, Torvalds (2002)") and no critical commenter should pretend they are with replies that hide hostility behind concern for our future... but by the time news of it's development has reached us here, the sliver of chance that Brython will join their ranks is no longer microscopic. I'm reminded of early CoffeeScript (and even Javascript itself), which could have avoided numerous pitfalls with early constructive(!) criticism from cantankerous commentators.
No matter what, the armchair quarterbacks will be taken down a notch if they're wrong and are worth your time otherwise. Those early complaints help decide if your future is filled with a junkyard of half-baked software or manages to harness our collective wisdom (with a healthy dose of individual discretion) to refine itself into something elegant and powerful.
It's not that hard to see Brython doing just that either; you don't need to be Nostradamus to foretell a prophecy of an easy-to-use, "just works" implementation of Python3 in the browser profoundly altering the current landscape, shaping our future toolbox and even what software is thought possible.
He could have presented less snarky, but the comment is appropriate and helpful. The comments are the low effort way to get a feel for the technical viability of the tech featured in the main post.
You know, this idea that removing whitespace is the best way to reduce code size for delivery can be debunked by any student that takes a compiler class. That technique + gzip is a shortcut that we have taken as a defacto “right way” of delivering web code (of course taking out the whole conversation of WebAssembly). Perhaps something good can come up out of this - just like people pissed all over the idea of js on the server when node.js came out, perhaps this has the potential of doing the reverse on the client side. Stay open minded.
I'm not sure if any of the points you raise would be a deal breaker when set against the potential advantages for some people.
For example: "I have code that already exists in Python that I want to reuse in a browser" or "I am fluent and very productive in Python and I just need to get shit done".
I don't think anyone expects this to replace javascripts for normal public-facing web development. Do they?
> White space significant, good luck minifying it.
While I cant vouche for this implementation if you want to minify Python you compile it to bytecode and run that. Works wonders for embeded deployments of Python.
Noone asks you to use Brython. People familiar with Python might prefer writing their frontend code in Python just because they are already familiar with it.
The following argument isn't necessary for folks who do want Python in frontend but still, not all of your points hold true, Python can handle multiple commands in a single line and it does have anonymous functions: lambda.
I would differentiate between marketing speak (designed to replace Javascript) and the practical implications of Brython (designed for folks who want to use Python in frontend)
If I were a JS developer who only wanted to write JS, but I needed to do a database query, should I look for a database that lets me write queries in JavaScript (or a language basically interchangeable with JS)? Or should I just learn SQL?
Sometimes as a programmer you need to learn new tools for new domains, and that's not necessarily a bad thing.
Too often I've seen companies stuck with an old framework just because their developers are used to it. That's how you get a microservice architecture in Java where each containers takes 300MB of space, and requires 1GB of memory.
I'm frankly amazed that the people who brought us node.js haven't also created a JS query language, furthering the spread of the triple-equals to new and greater heights.
Believe it or not most server-side developers find javascript ecosystem an awful experience so I doubt they care about Webpack or any of the JS "innovations". The speed is not really an issue given that most of the client apps just call DOM/Web API functions.
Yea, there always seems to be a disconnect in these conversations between people who aren't yet used to Javascript's grotesqueness and those who are desensitized to it. Javascript was so horrible for so long, and remained horrible every time I tried it because "seriously, it's good now", that there's a fairly significant threshold to get me interested in using it when any other alternative is available.
Naturally, if I was making a decision for a company I worked at, I would do my due diligence and likely end up using JS for any of a number of reasons that don't have to do with how unpleasant and unproductive working in the language is. But for personal projects, I'd happily use something like this, short of discovering a show-stopping problem with it.
The thread OP comment just seems like classic defensiveness about JS; a project like this is never going to be literally perfect for corporate production use on day one or but it doesn't need to be to be useful. Even on the off chance that it were to grow into something widely useful, at that point you'd see a lot of powerful actors polishing off the rough edges. This is exactly what happened to Javascript: the only reason it's defensible at all is because of the millions of dollars poured into it and its ecosystem by companies like Google, Mozilla, etc
This is exactly what BeeWare's Batavia does: compile to bytecode server-side, then run a remarkably small interpreter in the browser. This is a substantial win: parsing is a CPU hog, and Brython's architecture does it every time the page loads.
That said, in order to support `eval` and friends, you still need a full-fat compiler in the browser. So the best route is probably to use a full-service Python->JS compiler, but compile most of the code ahead of time. That's where we're heading with Anvil (we use https://skulpt.org for the client side, but it's the same principle).
My colleague wrote up a pretty wide-ranging comparison of browser-based Python interpreters. It describes how (and why) Brython, Batavia, Skulpt, Transcrypt, and Pyodide differ, and the tradeoffs they're chasing:
In twenty years of professional Python development, I've never used eval once. I'm not saying nobody ever needs it, but it's a niche feature that the vast majority of programs can do without, and is probably not worth the tradeoff.
Even there it's not strictly necessary. You could accomplish the same thing with a variadic function that does its own argument parsing, it'd just be slower and not play as well with reflection. So you could port it to a Python implementation without eval().
It's necessary if you want to offer an interactive Python shell in the browser, e.g. for websites that teach programming or otherwise use programming as a means of user interaction.
You probably have used a Python REPL though? Either on commandline or in iPython shell or similar. This relies on eval type functionality somewhere in the chain.
Would it be hard to define an alternate representation of Python code that uses curly braces instead of white space to use over the wire for delivery of front-end Python (with curly braces that occur in the original Python code escaped)?
This code, for example:
def func(foo, bar):
if foo < bar:
foo += bar
return foo * 3
That could then be subject to the usual minimization approaches.
Going back from curly representation to significant white space is easy and fast, although you could probably build your tokenizer so that it never even has to bother. That could make the client side handling of this essentially free.
Both CPython's parser and Python language grammar works in terms of indents/dedents being represented by brace-like tokens, so this is trivially possible transformation.
> White space significant, good luck minifying it.
Brython supports precompilation to JS, which is obviously minifiable.
> on top of that you are running Python interpreter in the JS VM.
No, you aren't. Brython is not a Python interpreter, but a compiler to JS. There are optimization issues from the need to maintain Python semantics interfering with optimizing the JS, but that's not the same as running a Python interpreter.
Node shows that this is false. You live in a 2002 bubble if you still think anyone would choose any language over Javascript any time. Python to me only ranks above PHP and I wouldn't use it at all if it weren't for its math/ML subcommunities.
first of all, I don't think "most inappropriate languages for frontend development" is a thing, it is just a new way to do web dev that is different to what you used to be doing with. If you don't think it is an approach that you prefer/can accept, you can just move on continue with whatever you like. You should learn from the people who built Brython, they don't like the way how the current web is being built - hence they continue doing what they believe its right, BUT wihtout putting shit on other's people's work.
There are people who think images and JS are far too much for the Web (you can often read comments like that on HN) and want pure text only Web. Should we learn from them too?
I don't mean to put shit on any body's work. I am just noting several obvious flaws to the idea. Now it might sound like putting shit, I don't know, but I am not native speaker so sometimes I guess I am using the wrong tone/working.
The real question for me is why it's such a big deal? In the end its simply an opinion.
While I still think, it would be nice to use a language that doesn't need 3 equal signs for sane comparisons, I wonder if Python with its strong whitespace to code-block correlation is actually a good choice for transmission and remote execution?
It definitely increases the size of transmitted code (tho probably by not so much because I think files are usually transmitted gzip compressed to modern browsers).
Are there other issues anyone can think of? It somehow gives me an uneasy feeling even tho technically a semicolon or repeated 0x20 don't make a difference except size.