./file.src:
func api_foo()
for x in objs
x.a = fetch(x.b)
ui.btnok.enabled = yes
commit()
And have foo exported as api, and when called, all clients/servers, databases synced, validations passed, schemas updated, triggers and reactions done, errors handled, developer errors reported.I also find that python has reserved a whole bunch of keywords that I can't use as function names, making APIs hard to create with appropriate names. You also have to pollute your code with self everywhere.
It is also really slow, has no where near the number of libraries on github as javascript, is not a client-side language, doesn't have anything like babel, which can allow you to do a lot more than reflection/introspection (but not the same things exactly), etc.
Python is one of the imperative languages with fewer number keywords in existence. Compare for example the number of keywords in Python[1] with Javascript[2].
Maybe you're confusing the built-in functions in Python language, like len() or str(), however since they're functions you can reassign them (not a good idea, however in a limited scope it works).
[1]: https://en.wikipedia.org/wiki/Python_syntax_and_semantics#Ke... [2]: https://www.w3schools.com/js/js_reserved.asp
> It has so little syntax you can't tell the difference between various things. A variable declaration, a reassignment, a keyword, a whatever else, they don't have any visual distinction from each other.
The fact that you don't know the difference between keywords and built-in functions makes your argument weak. But I will bite, if you're having difficult to make the distinction between a keyword and a variable you probably have a very bad editor. Syntax highlighting helps a lot here (like in almost every other language).
> You also have to pollute your code with self everywhere.
I really like the fact that self is explicit in Python. It makes OO patterns more explicit (there is no magic variable like self or this, just a parameter that is passed as the first argument in any Class method) and it helps making a distinction between attributes and local variables. Really, I would go even further and make super() a method from Object, so instead of calling a magic method super() I would call:
class Test:
def __init__(self):
self.super().__init__(self)
Ugly? Maybe, however it is so much easier to understand what is happening.> has no where near the number of libraries on github as javascript
Most JavaScript libraries in GitHub are pure toys/garbage, though. Python has a number of useful libraries and if you don't concur with me, please give examples of areas where Python is lacking a good library (I can easily give an example for JavaScript: ML and scientifc computing).
1) In scientific/ML CPython libraries, most critical parts are compiled anyway, and the core language is fast and expressive enough to provide a nice and fast interface to it; so your statement makes little sense without more context
2) Python != CPython
Python is really neat to quickly experiment platform independent but it's definitely extremely slow.
The difference between 'npm install' (and even an added 'gulp') and the chickens I've had to sacrifice at crossroads to get Python packages working is notable.
Oblig XKCD - https://imgs.xkcd.com/comics/python_environment.png
Yes, you need to get the right version of Node, just like you need the right version of Python. I've had both largely just work with directions of "Version Y.X", where Y is defined. I've also had the occasion where it still broke with a specific version where both Y and X were defined.
In general, if I have the right version of Node (and I agree, I'd prefer package.json to also indicate the version of Node that was used to initialize it), things work when installing from package.json. Things also generally just work with Python if I have the right major version of Python, and an environment file. My issue is more that the 'simple' steps a lot of people do when creating Python projects -don't- use an environment. They just use whatever is installed globally on their computer, and they pip install any dependencies, then write a readme to pip install things with, rather than lock it down with a virtual environment.
It's kind of ironic, really. With the Zen of Python stating "There should be one-- and preferably only one --obvious way to do it" why is it that it's so common for people to not do the thing that makes it reasonably portable?
I mean, I currently am working with some code that, as part of its readme, has a pip install of a lib -off of master-, and yes, obviously that caused problems. Is the author not a Python developer? Well, he's a researcher. Why is the obvious thing for someone coming naively to develop in the language not building a portable environment?
I think this is why the situation is bad in Python: we have too many non-programmers in the community, that simply want something to work and get on with theirs life. If they can get by it by installing a bunch of libraries by running some command incantations as root, they're happy enough.
You don't have this problem with Node because the only niche that Node really matters is Web, and WEB DEVELOPERS know that their environment should be reproducible.
*: Even in Node this isn't really true, since we have yarn vs npm. Ruby is way more stable thanks to bundler.
The impact of those people in the ecosystem is zero, though. They don't inconvenience anyone by producing badly-written libraries, they literally do their job, produce what they want to produce and everyone is happy. I'm not sure why they get lumped in with "this problem".
I don't know why I hear this a lot, it certainly doesn't echo my experience. I've rarely had dependency problems, even the regular requirements.txt (without pinning to specific versions) tends to work well enough on reasonably current code. Pipenv pretty much solves the problem by introducing a lockfile.
It doesn't impact the ecosystem very much for sure, however I wouldn't say that the impact is zero.
Also, I think scoping rules in Python are terrible. I always end up with a namespace that is a mess. And you can't do something like this in a clean way:
counter = 0
def add(n):
counter += n
add(1)
add(2)
add(3)That's what nonlocal is for: https://docs.python.org/3/reference/simple_stmts.html#the-no... Just stick "nonlocal counter" in your function and it works.
Also nonlocal implies that other variables are local, which is not true. E.g., the following works without "nonlocal" keyword:
counter = [0]
def add(n):
counter[0] += n
add(1)
add(2)
(This used to be my workaround.)Your example works because you are mutating an existing object, not reassigning a new one.
It's a disingenuous comparison IMO.
What's messy about it?
>>> (lambda f: lambda x: f(x) * 2)(lambda x: x + 1)(100)
202clos = 42
def foo(x): return x + clos
def bar(y): return y * clos
higher_order(foo, bar)
What's so hard about that?
You could do this with a lambda construct in Python; but this only works if the function has a single expression-statement; it doesn't work e.g. when you have a bunch of assignments inside the function you are inlining.
Sure, it's ugly but I think it's a silly challenge. Complex functions defined in the function call are un-maintainable anyway IMO.
I'd hate to see Python become as popular as JavaScript and to have it be used as the defacto standard in browsers because honestly, it's nowhere near as enjoyable to use as JS.
It feels to me like JS is more for people who want to write "clever" code and Python is for people who want to write boring, more maintainable code. It doesn't help that JS has a gentler learning curve and attracts more people who just want to get things done without thinking whether those things should be done that way.
IMO JavaScript is for people who want to get things done quickly and efficiently and have their program work everywhere. Python is for people who like to think they are doing things “the right way” as if there were such a thing.
Indeed I can't. I can say no to "JS is more enjoyable than Python", which is what you said in your upstream comment.
> JavaScript is for people who want to get things done quickly and efficiently and have their program work everywhere
If by "everywhere" you mean "in a browser", sure. I don't see how that's related to the common definition of "everywhere", though.
> Python is for people who like to think they are doing things “the right way” as if there were such a thing.
I don't know what you mean by that.
As a concrete example, here's a library I made that relies on symbols and dynamic inheritance to extend the built-in data types: https://github.com/slikts/symbol-land
./file.js:
function foo(ctx) { // @export
for (let x of ctx.objs.iterate()) {
x.a = await fetch(ctx, x.b);
}
ctx.ui.btnok.enabled = true;
ctx.commit();
}
autoexport(module, x => eval(x));
And more boilerplate, ceremony and fud down the way, if you go vanilla.(Thank you and all commenters here for sharing your code and experience. In particular, symbol-land looks very interesting and haskell-y.)
Destructuring would make your example look better: foo({ui, commit, objs}), and then there's no need for typing out ctx. Another thing that's not needed with for-of loops is .iterate().
Using eval() is a very strong anti-pattern, and it's not needed there anyway. JS has the `with` statement that allows running code with a specific context, but its use is discouraged as it's really bad for readability and hard to optimize.
Destructuring looks good here, you’re right. Actually, this thread somewhat relaxed my js hostility and I see it as an alternative that has reasonable tradeoffs (but still not as a friend though).
The Function constructor is a better alternative for eval(), but still only as a last resort. eval() itself has no use cases.
I find that most JS criticism is ill-informed, because people are too quick to jump to blaming the language due to its reputation. Not that I'd call JS a great language, but it has redeeming aspects.