7 ms·
I feel like Lua would have gotten more traction in the early days, and maybe eclipsed Python, if it wasn't so hyper-focused on being a tiny embed-able language/
by VWWHFSfQ 6y ago
I feel like Lua would have gotten more traction in the early days, and maybe eclipsed Python, if it wasn't so hyper-focused on being a tiny embed-able language/runtime. It was so well-designed from the very beginning.
Every new release of Python seems like it gets bigger and bigger and more and more incomprehensible. The Python 2 -> 3 transition was a (necessary?) disaster. And now we're trying, in earnest, to figure out how to get rid of the GIL. The async/await syntax is a whole other fiasco. Now we have colored functions all over the place. Python code doesn't even work with Python code. It's just an absolute mess.
- gunshai 6y agoSorry can you EILI(have 3ish years of python experience but rarely get this far into the weeds.) What is an example of being more incomprehensible? >Python code doesn't even work with Python code Is this statement a function of the 2 > 3 transition.
- brianjlogan 6y agoProbably additions like the Walrus operator that "complicate" the syntax and negate the "Zen" of Python by having one right way of doing something. Migrating away from the pseudocodeness of Python. Just a guess though I have about the same experience as you.
- pansa2 6y ago> What is an example of being more incomprehensible? Python's type hints, in particular, have added a huge amount of complexity to the last few versions of the language.
- deleted 6y ago[deleted]
- comfydragon 6y agoType annotations are completely optional though. It's possible to write Python that targets 3.5 and 3.8 at the same time.
- pansa2 6y agoThe core developers made data classes unnecessarily dependent on type annotations, which made me worry that annotations would become less-and-less optional over time. Fortunately, that doesn't seem to be happening. However, the numerous (very long) typing-related PEPs are definitely making the language larger and more complex. Also, any code that uses annotations is more verbose and less like what I want from Python - executable pseudocode.
- pansa2 6y ago> Fortunately [annotations becoming less-and-less optional over time] doesn't seem to be happening. On the other hand, Guido himself recently said "new stdlib code should be written with annotations inline" [0] whereas the core developers original position was "it will be the choice of the author of new stdlib modules whether and how to use type hints" [1], or even "We will not be putting type annotations anywhere in the stdlib" [2]. [0] https://pyfound.blogspot.com/2020/04/the-path-forward-for-typing-python.html https://pyfound.blogspot.com/2020/04/the-path-forward-for-ty... [1] https://mail.python.org/archives/list/python-dev@python.org/message/F54JYUKL3MVIN3MS5NE66DGJSW22XFUU/ https://mail.python.org/archives/list/python-dev@python.org/... [2] https://mail.python.org/archives/list/python-dev@python.org/message/3JXOMQR7KSVZTFWL3QUJMUGBOYB6TETL/ https://mail.python.org/archives/list/python-dev@python.org/...
- luhn 6y agoWhat's wrong with the async/await syntax?
- jjtheblunt 6y agoI usually see folks cite that async/await exposes, to the programmer, implementation details that one wishes were hidden by the compiler/interpreter.
- jonahbenton 6y agoThat is python's MO, is why things like the double underscore functions exist. Being able to declare a coroutine (not just use) is not a bad idea, but IMHO it was done badly.
- gonational 6y agoEverybody wishes asynchronous functionality was magically hidden by the interpreter until unexpected shit starts happening.
- VWWHFSfQ 6y agoIt should have been implemented as functions or attributes instead of language syntax sugar. Like Lua did. Like Rust did. Imagine this: def foo(): return "bar" async def foo(): return "bar" How do you know how to call that function? It's called the same thing. It has the same signature.. It returns the same thing. One is sync, the other is async. This is "colored functions". You have to call the 2nd one like: await foo() why do you have to care about that? It's either a coroutine or it's not. All functions in Python should just be callable like normal functions. But the Computer Scientists went and messed that up and made colored functions. It's absurd.
- tick_tock_tick 6y agoIsn't your example exactly how Rust works to?
- 6y ago
- tick_tock_tick 6y agoPython 2 -> 3 was such a waste of everyones time and has done unrepairable damage to it's ecosystem.
- m463 6y agoI tried compiling a machine learning project recently that depended on lua and I had lua version problems (5.2 vs 5.4) I agree with the 2->3 problem. I also wish there were no GIL. That said, python is my favorite language of them all. I wonder if the way forward might just be to expect different incompatible versions from time to time and create robust facilities to handle it.
- pansa2 6y ago> if it wasn't so hyper-focused on being a tiny embed-able language/runtime What do you think Lua's developers should have done differently? What stops Lua from being used as a general-purpose scripting language?
- loeg 6y agoI think Lua is most useful because it's a hyper-focused embeddable scripting language. Probably the biggest errors were the historical either/or integer/floating point numbers, and the weird PHP-like hash-tables-are-the-only-first-class-datastructure.
- nabla9 6y agoIt's the natural progression of tiny programming languages that become popular. The idioms and programming styles change over time. Languages age. You add more syntax and semantics until some people start preferring more simple solutions and everything starts again. C has stayed clean but C++ can be seen as fork of C into never ending complexity. Java started as small language intended to be used like Javascript. JavaScript started as small, now it's becoming Java.
- BiteCode_dev 6y agoI think that the beauty of Python is that is still Python. I mostly still use the same features I used 10 years ago. And so do most of my clients. But occasionally, I have the option to go the extra mile, and use asyncio for perfs or type hints for robustness. The language grew big, but you don't feel it on the day to day coding.
- BiteCode_dev 6y ago> Python code doesn't even work with Python code async / await are just primitives, they are, in no way, incompatible with the rest of Python code. At worst, if you mix blocking and non blocking, you loose the performance benefit, that's all. It all works. You are just back to non async execution. You can use async functions in sync code and vice-versa. In fact, you can use async / await for asyncio, or another lib, or no lib at all, it's a completly lib agnostic concept. It doesn't even need any io. async / await is just a "yield from" which understands __await__. It's an interface. A contract. Like generators. What's more, the python community is now following the best pratice of creating Sans I/O libs (https://sans-io.readthedocs.io/ https://sans-io.readthedocs.io/), which means you can plug in whatever I/O lib you want. There is a lot of confusion around asyncio, partly because of the communication and doc around it, partly because it sucked up until python 3.7, and partly because a lot of python devs have absolutely no need for it and see it from the point of view of their day to day task. But it's definitly not fiasco, it's quite a handy tool, and the generic interface of async / await is nifty and allows cool designs.
- jakogut 6y agoCan you summarize how Python async improved in 3.7?
- BiteCode_dev 6y agoNot async in general, but asyncio in particular. Before 3.7, you had to be able to fetch the loop, handle its reference, pass it around, manage its life cycle, etc. Starting from 3.7, only low level code (E.G: framework authors) would need to, the API is organized so that by default, you always perform something in the current running loop. It's a big deal, and remove a ton of complexity. Maintenance is easier, learning curve is flatter. The best example, is that in 3.6 and lower, you had to do "loop = asyncio.get_event_loop()", then call "loop.run_until_complete()". In 3.7, you use asyncio.run(). It seems trivial, it's really not: https://github.com/python/asyncio/blob/db2fe1d1e1d0f7352167a2ff00c4296115810adc/asyncio/run.py#L11 https://github.com/python/asyncio/blob/db2fe1d1e1d0f7352167a.... This has consequences on the whole design, which is now full of things like that (run_in_executor, create_task, run_forever, etc), changing completly the way to write correct code. Another thing is that in 3.7, the asyncio uses async / await and not yield from. Because of this dog fooding, the whole lib improved. 3.7 has a LOT of patches just for asyncio: https://docs.python.org/3.7/whatsnew/changelog.html#python-3-7-0-final https://docs.python.org/3.7/whatsnew/changelog.html#python-3... Speed (Future has been rewritten in C, and many other tweaks), fixes, _way_ better doc... Obvious shortcomming were resolved, like asyncio.wait_for() that now waits until the cancellation is complete, or asyncio.all_tasks() returning only pending tasks. A lot of little things that add up. The whole ergonomics are better, up to the command line experience with "python -X dev" which automatically add warnings and set asyncio in debug mode, and frankly you can't cleanly code async without. The final nail in the coffin are the context vars (https://docs.python.org/3/library/contextvars.html https://docs.python.org/3/library/contextvars.html). It's the only sane way to deal with a global registery that is dependant of the current running task. It's almost always easier to upgrade to 3.7 than trying to use asyncio before it.
- gizmo686 6y agoI think the Haskell saying "avoid success at all costs" is relevant here. Lua might have become a more popular language if it was not so focused on being embed-able. However, it would likely have failed at its goal of being an embed-able language.