Python has added lots of features to stay current with the latest trends in programming languages, but this has come at the cost of complexity and redundancy (e.g. look at all the ways to format strings or do filesystem operations). And many of the new features such as type annotations have a compromised design due to their being added to Python late in the game. Python's "batteries included" approach of a large standard library was a great asset in the days before package managers but these days I think it would be better to start with a much leaner stdlib and add things in more stringently.
I would also want some kind of a typing support, ala Pydantic built in. If for nothing else, I would like to know wtf is this function taking in as args.
Can we also run this in a browser!? One can dream.
...although that might all be the fault of aws-cli. Which by the way doesn't install on a vanilla Ubuntu 20.04 ami via apt which is just... really really bad.
Aws cli continues the inexplicably horrible aws interface that makes me shake my head at people lauding their might, along with their console.
The console rewrite... anyway, pip seems to be a headache, certainly not as good as gems.
I was sad to hear about the change to ReScript though. ReasonML targeting the browser and native seemed nice to me, although I do agree the documentation situation and DX wasn't ideal.
For what it's worth, there are a lot of good interesting languages out there that aren't Python and have pretty good library ecosystems. Kotlin, Elixir, and Elm come to mind. But they don't exactly fit the Python niche.
What you're describing sounds to me like a modernized Common Lisp with commercial backing. Rework CLOS a bit, clean up some of the other crufty old weirdness, and give me a big selection of high-quality well-supported libraries like Numpy, FastAPI, Trio, etc.
The advantage of doing it in some Common Lisp derivative is that things like React JSX are pretty much "free" and wouldn't much seem out of place, whereas in Javascript they need a whole separate build/compilation step and are often portrayed as black magic fuckery.
edit 1: Arguably Julia could be used for a task like this, but its library ecosystem and language runtime are heavily skewed towards numerical computing and data analysis.
edit 2: Raku also sounds like a possible candidate here, but it obviously lacks widespread adoption and last I heard it fell significantly short of Perl 5 performance. I'm not sure what kind of library ecosystem it has nowadays and I doubt we're going to see big commercially-backed library development efforts for it, soon or ever. Perl 5 has a huge ecosystem of course, but it's such a nasty warty language with nasty warty tooling.
This is offensive. Whether the people who work hard to make and share (for free) half baked libraries are addicted to drugs is really not part of the main thrust of your argument. You could leave it out, save words, and not have distracting comments from people like me while still making your point.
I know the mantra is that the standard library is where things go to die, but I believe that to be cultural. I still have code running somewhere probably that uses the cgi library, which was perfectly well-suited for a Windows serve where the page in question got an average of seven hits a day, never to scale much beyond that (you'll have to trust me on this, for amusement I reviewed ten years of logs for just that page to find nothing out of the ordinary, and there are reasons it would not need to "scale" in the future).
Each library and each string-formatting method and so on is a choice, and those choices impose a lot of speedbumps and cognitive friction.
import cv2
Yes, Stack Exchange, I know OpenCV can do this for me, but integrating that into my package dependencies is time down the drain which I am never getting back.This, and library documentation. It's probably the single practica issue I have with D and Nim. They seem to have fairly robust standard libs but when I look for something specific it always turns out this feature is missing, outdated, or badly documented.
- Just learn the language with all of its quirks
- If you are new, ignore the quirks until you are ready
Creating a new language sounds ideal, but there are a whole slew of caveats. Python tends to be recommended as a beginner language since it is reasonably easy to learn and offers considerable room for growth By the time the Next Python reached that stage, we would have accumulated a new two decades of techniques and features that would leave Next Python in a similar position to Python today. That assumes that people would even agree upon which language would serve as Next Python as a standard recommendation. One of the advantages of having so many people agreeing upon Python as a starting point is it eliminates the first hurdle novices most novices face: figuring out where to start.
As for the batteries being included, it is also a strength of Python. Choosing libraries can be difficult. That's true for the novice and it's true for anything but trivial projects. Lean standard libraries encourage fragmentation. We should have learned that from the shortcomings of C, yet many languages have followed in the same footsteps with similar results. We should have learned that large standard libraries can be useful, from the success of languages like Java and Python. Package managers don't change the degree of fragmentation, they only make it easier to deal with.
I seriously cannot think of anything I could do to exceed Python.
Does it do everything? No. But name a tool with significantly greater overall reach. Some compete, but seriously. . .
If you are new, chances are do not yet know what is a quirk and what is idiomatic.
It can be challenging and frustrating trying to follow guides or tutorials and they are all doing things differently - which is the "right" way? You have no idea as a beginner.
I think that package managers or not, the "batteries included" approach is great, because it leads to most of the code for useful things already available, and also helps third party packages be smaller (since they can depend on things available in the standard lib).
Imagine 3 different packages, for example, each bringing its own different json parser depedency -- as opposed to all leveraging the included json package.
That's how you get no community standards but tons of packages for the same basic things in slightly different ways, each with 20%-30% adoption.
That's also how you get 1GB node_modules folders.
That's also how you have the "leftpad" situation.
- A simplified/sounder natively integrated version of Typescript's type system - Javascript's easy notation for manipulating objects - None of Javascript's other baggage/cruft - Something akin to go routines
Basically, something with the performance of Go/Java (so there would be no need to rewrite your code once it starts serving millions of people) but the elegance of Typescript.
Not sure if this is similar to your vision of a "next Python" but it feels somewhat similar.
Basically I think right now:
C -> Zig
C++ -> Rust
Java -?-> Go
Python/Javascript --> ???
With native typing we could get a language as fast as Java/Go but with the cleanliness of Typescript.
If dealing with uses after free and lack of bounds checked access in release code is still a fun factor.
> Java -?-> Go
Not at all, unless one misses Java 1.4 with loots of if/else boilerplate.
Having said that, isn’t Deno close to what you’re looking for?
It wasn't arcane at the time that using exceptions for decision logic, or letting loops run by assignment, rather than by creating a new scope, were not the most salient ideas.
The following Python code contains a bug:
list_of_adders = []
for x in iterator:
list_of_adders.append(lambda y: y+x)
Namely, since `x` is assigned with each iteration of the loop, rather than that a new scope is created, the `x` that the closure encloses is re-assigned with it, so all anonymous functions contain the value that `x` had in the last loop, which is almost certainly not what the programmer intended.In fact, if within the same scope, which is quite large, since Python does not like block scope, x ever be re-assigned, which is quite likely, as Python uses the same syntax for initialization and assignment, then all the closures collected in the list shall thenceon refer to the new value that x is assigned to.
These are not design choices that many other programming languages at the time made; they were bad with the knowledge of the time, and continue to be bad now. There is no justification to have loops be implemented by assignment, and not create a new scope.
In turn, implicit variable declarations (using the same syntax for initialisation and assignment) are a reasonable choice for a language that aimed to be “executable pseudocode” and that supports mixing initialisation and assignment in a single statement (e.g. `a, b, self.c = foo()`).
It's amazing that people can program in imperative languages at all, yet it feels easy. I wonder how much trouble this causes for somebody learning how to program in a modern high level language.
The one big selling point a future language could have would be inherent parallelization that uses all the 32+ cores of the developers machine, but that are as beginner-friendly as python. Such language does not exist. A dynamic, easy to use, and built from the ground up to always utilize all cores all the time without demanding that the programmer are handling side effects.
Maybe golang comes closest to that (and concurrency is messy in there), but I'm not sure if it fulfills the "beginner-friendly" criteria from the perspective of a python developer.
Making programs execute faster could be. And there using many cores is one implementation strategy among many complementary ones. But the current landscape of programming languages shows that languages focusing on execution speed and parallelism have smaller user bases.
Also, re this data interpretation of Python's killer app, this usage of Python is something fairly recent and happened after Python had already broken into mainstream usage in the industry. A lot of small and big applications have been built using it before the data and ML things got in vogue (like Youtube, Dropbox, Spotify etc at the bigger end).
However, their scheduler really needs speed ups, and they do run into weird data handling bottlenecks in my experience.
I for one, think it's more likely that Python will evolve. The mathematicians and physicists, biologists, astronomers etc. that have finally gotten rid of C++/Fortran and learnt Python aren't going to change to anything with forced static typing any time soon...
I’m sure it’ll only take a couple of years for everyone to migrate
I feel like Python just went through that big shift. Doubt we need a other one of those.
Also, I'd just look at Julia for some of what you're describing. It's basically going for a more focused approach with the learnings of Python in place.
We could call it Python 6.
Notwithstanding the various ways of doing the same thing (which sometimes goes against the zen of Python), as of Python 3.6 there's been a constant trend towards f-strings above all else (barring maintenance and legacy code), and generally beginners have no need for anything beyond f-strings. If they'd like to go into the old string formatting techniques, they're welcome to, but they're not that complex.
I don't understand how type annotations constitute a 'compromised design' - they've worked quite elegantly with Python's dynamic typing, they greatly assist linters and IDEs when you turn them off, and they can be disregarded when you don't need them, which is a far cry from the enforced typing of other languages.
And I certainly do not agree that there is a need for a "next Python". Python does a lot of things very well - it's design is clear, the design patterns are methodical, the language is well-governed, the central packaging system is reliable (and not like the insane NPM and dependencies of JavaScript), there is a distinct idiom/style consistency amongst Pythonistas, a and a large gathering of minds behind the language. Further, Python reads very well, and can be even pseudocode without being pseudocode, which makes it very much suited for beginners who can stray as far as they want to into the language when they feel ready for it.
Python is a great language for beginners, so I have no idea what you're talking about.
But they tend to get ironed out over time. Python 3.9 adds parametrized generic type hints based directly on container types, alleviating the need for a parallel type-hint type system. i.e. `dict[str, list[int]]` over `typing.Dict[str,...]`
What does it matter to you if there are features in the standard library you don't use? The full python embedded distribution is only 8MB including runtime.
Many seem to be happy replacing Python with Go, to get better performance, parallelism and packaging support. However, for my uses I'd much rather replace it with another high-level scripting language, even if it's still slow and single-threaded.
Can we make that the standard and get rid of the ugly str.format(UGLINESS) syntax.
Yes please, and thank you
But otherwise, yes - make f-strings the “one obvious way to do it” and use `format` only when necessary. And get rid of the old %-formatting.
Also consider making f-strings the default: https://pyfound.blogspot.com/2020/04/all-strings-become-f-st...
`format` is still useful, particularly when working with pre-templatized strings. It's also a (relatively) new feature; Python 2 didn't have it at all.
OTOH, I wouldn't cry if Python 3.X finally removed %-formatting. `format` does everything that `%` does, with a much nicer API (especially in 3.7+).
f-strings work well in simple cases. But once the things you want to output are somewhat larger expressions, format() works much better.
Example: instead of something like
print(f'{id:<5} | {", ".join(members}:<50} | {", ".join(str(score) for score in scores):<30}')
This is much clearer IMO: print('{:<5} | {:<50} | {:<30}'.format(
id,
", ".join(members),
", ".join(str(score) for score in scores),
))
Actually, what do you mean by "ugly" and "UGLINESS" in "the ugly str.format(UGLINESS) syntax"? The UGLINESS are simply the things you want to format. Ugly is in the of the beholder of course; personally I don't really see anything ugly about format. The f-string equivalent here is much uglier and much less clear/readable to me, because the formatting and the expressions are mixed and parsing the whole thing to see what is what is more effort than it should be.No, please.
F-strings are useful for some things, but there's a good reason. to define templates other than deep in code for ease of editing them distinct from functionality (often, completely externally to code) and using str.format supports that.
If anything, I'd prefer r-strinfs as the default with both escape handling and formatting non-default options, but the status quo is acceptable and better than r-strings as the base.
I wish Python went with static typing from the offset, and I wish it had better parallelism, but with Python you can get a library for just about anything with a simple pip install, and that's worth a great deal.
Need a WebSocket library? No problem. Need a cross-platform TUI library? No problem. Python's maturity means you can do a lot of things with little hassle. Some of the less mainstream programming languages are nowhere close to Python in this regard, even after many years.
That can compile to binary, javascript and other languages?
That would be https://nim-lang.org/
https://pypi.org/project/flake8-simplicity/
https://github.com/wryun/flake8-simplicity/blob/master/flake...
Golang is easy to get started with tooling and packaging is good. but then the code in the wild is littered with pointers for when you wouldn't need them.
Sounds great. What made Python so beginner-friendly and readable? Most of the "let's improve Python" gang I see can't begin to answer that - by their metrics, the language must be a failure.
Beginners have the advantage of not thinking "this is the best way to do it because that's how C/C++/Java do it".
With all these memory safe languages getting popular NSA needs more npms, not less.
Kotlin solved the syntax and language warts on top of a good runtime.
For python the syntax is (mostly) good but the runtime and package management needs a rehaul.
A language with a consistent design can have layers, and beginners can just do with the external bits without getting too deep initially, but with enough space to grow.
IMHO Python is a good language on that regard.
"To boldly create programming languages no man has created before."
Clear/Verbose -
def maxWidthOfVerticalArea(self, points: List[List[int]]) -> int:
x_coords = sorted(x for x, _ in points)
greatest_diff_so_far = 0
for i in range(len(x_coords)-1):
diff = x_coords[i+1] - x_coords[i]
if diff > greatest_diff_so_far:
greatest_diff_so_far = diff
return greatest_diff_so_far
Pythonic - def maxWidthOfVerticalArea(self, points: List[List[int]]) -> int:
xs = sorted(x for x, _ in points)
return max(x2-x1 for x1, x2 in zip(xs, xs[1:]))
I'm curious which approach is bad/worse? On the one hand, the "pythonic" approach seems brief and kind of neat and I feel clever writing it. On the other hand, it is also ~20% slower per my testing, it's less obvious what it's doing, and it would be harder to make some change to the logic (or add logging/metrics) without completely rewriting it.On the one hand, just from the reasons I wrote above, it seems to me like the first way is better and the second worse, but on the other hand, the first way is what I would write while knowing zero python features. Curious if anyone else has thoughts on this.
1 - https://leetcode.com/problems/widest-vertical-area-between-t...
def maxWidthOfVerticalArea(self, points: List[List[int]]) -> int:
xs = sorted(x for x, _ in points)
neighboring_coordinates = zip(xs, xs[1:]))
return max(right-left for left, right in neighboring_coordinates)
or even naming the width generator: def maxWidthOfVerticalArea(self, points: List[List[int]]) -> int:
xs = sorted(x for x, _ in points)
neighboring_coordinates = zip(xs, xs[1:]))
widths = (right-left for left, right in neighboring_coordinates)
return max(widths)
Same thing, just with more built in explanation. It's easy to go overboard, of course, but it's a useful go-to to make stuff more obvious.I save clever for the real mechanics of problems, for data structures, and occasionally optimization of running time if that is a factor (it often is not as much as you would think).
I eschew clever if it seems like it is just a way to pack a lot of stuff into fewer lines of code. One of the reasons that Perl attained a reputation of "write once, read never" unmaintainable code (whether or not it was justified) is a culture that cultivates "one-liners" and packing everything down into a minimum space. Our filenames in Windows no longer have to be 8.3. We are not constrained to write our code in a few kilobytes.
I programmed in the days where you might have two kilobytes in which to program. In those days, extreme terseness was a value. It is not any longer. "Cat" and "man" and "mv" are holdovers from those days. This is not a telegram where you are charged by the word. I program for total obviousness and sometimes that makes my code seem "dumb." I might do only one or two things per line. That's really fine.
Just as an example, I wrote this obnoxious web app in Perl as part of my job. At some point, some students were to take it over, but they didn't know Perl. I received an excited phone call from them at some point: they were able to understand and port my application to a language they were familiar with because I commented, I was not clever in packing, and I kept it to "one or two things per line."
I personally think either function is fine. The max finding code pattern in the long function should be familiar to most. For the Pythonic function, I don't think it's less obvious enough to matter. You have a list of stuffs and you want to find the max so you wrap it in the max function. Maybe zip(xs, xs[1:]) can take a bit to recognize but I think it's eh. For the Pythonic one, one can also write
all_diffs = [x2-x1 for x1, x2 in zip(xs, xs[1:])]
return max(all_diffs)
Using list is also markedly faster than the Pythonic generator for me, which is to be expected: ~16% faster than both.[0] https://gist.github.com/squaresmile/8dd08898851a4e19359cdb30...
This is a very personal opinion, but I do like the second one more. I find it easier to read, but maybe that's just because I'm used to that style. And maybe you're more likely to have to rewrite it for a change, but that's kind of okay since there's less code there.
On readability, here's how I'd read it out loud:
Sort all the Xes from points. Return the max of the difference between two points that are next to each other.
I find that quicker to put in my head than the equivalent parsing of the first solution, and exactly the intention of the code.
def maxWidthOfVerticalArea(self, points: List[List[int]]) -> int:
x_coords = sorted(x for x, _ in points)
max_diff = 0
for x1, x2 in zip(x_coords, x_coords[1:]):
max_diff = max(max_diff, x2 - x1)
return max_diffParticularly the for loop into the range of the length of the coords minus one, is difficult to wrap my head around and easy place for mistakes to sneak in.
With that being said, I have had my difficulties wrapping my head around zip, and don't have difficulties anymore, which might actually be in favor of parents point.
return max(xs[1:]-xs[:-1])
...using something like numpy. I wonder if APL/J has successive element operator.I’m fine with most of the rest of Python’s functional-style iterable helpers. But something about zip just doesn’t work for me.
zip(xs[:-1], xs[1:]) # explicit
zip(xs, xs[1:]) # implicitDepends on your team. If you wrote stuff in the second way you would be obstructing, adding friction to less python experienced developers but you would be minimizing the amount of code written.
It's hard to say, which is right or wrong here but the opacity of the second approach as you mention adds unpredictability.
I honestly think Dart is a very good solution from the culmination of various classical languages we've been using so far with Java and Javascript but there just doesn't seem to be any major FANG company investing in creating something more "modern" with Python.
I think it is a testament to Python's accessbility and also the depth it provides for experts as well. I guess the forced indentation is what gets to some developers but its a minor inconvenience.
And I think most Python developers that produce bad code do so because they try to use too many of the whiz-bang features - or overuse bad design patterns.
You can do almost anything with functions namespaced in modules - KISS.
People say scheme is hard but it is by far the easiest to teach, especially compared to Python.
I would suggest something small, that you can realistically fit all in your head. I honestly believe Pascal is still an excellent choice. For something a little less low-level and more scripting-like, Lua seems nice. The JavaScript ecosystem is awkward, and there are things to criticize (no integers?) but by itself, it's a nice small language as well.
When i tried to learn python i got caught up in trying to learn imports and classes and other things before i actually fully understood how stuff like variables, arrays and functions worked.
I am very happy that I started with C. It has surprisingly few features compared to most languages and it gave me a good appreciation for how memory is managed at a relatively low level. The biggest downside was that it took me a long time to learn how to make anything I thought was "cool" at first (like GUIs, graphics, sounds, or networking). Some people might struggle with that.
I rarely write C code now. It's not as practical for the kinds of things I make and I have nitpicks with it just like any other language. But I don't think that's the point. Your first programming language is an instrument for learning first and foremost. Once you've become adapt at one language, it's relatively easy to pick up more.
It has substantial pain points, the most significant in my opinion being the semantic white space that never really ever stops being a problem.
JavaScript runs in the browser, has relatively trivial syntax, no semantic white space, C-like, a superior and more useful GUI, etc.
I see no reason to teach Python per se unless people request it.
Really? At one point I was looking into using a linter program in my Intro-To-Programming-With-JavaScript and then realized that it didn't really catch any syntax errors because there were so few.
For example - you might call a function like this:
x = myFunction();
But what if you leave off the (), which is an easy to make, beginner/novice type mistake. Then you get this, _which is still valid JS_:
x = myFunction;
What if you leave out parameters that your function needs? What if you include extra parameters? What if the parameter types that you're expecting don't line up with ones that are provided (perhaps because you left out / added in an argument?)?
On the one hand I get it - JS is a loosely typed language so it doesn't do a lot of syntax checking at code-writing-time/"compile-time"/linting-time, but on the other hand there is a _ton_ of easy to make novice errors that are actually valid JS code.
I'm not saying that Python is a better choice for beginners, I'm just not convinced that JS's relative lack of syntax-based limits is a great choice either :)
On the other hand, your example is valid Typescript, although if you use attempt `x + 1` then Typescript will yell at you for incompatible types.
Unfortunately your example is also a problem in Python, if not worse:
def foo() -> int:
return 42
# valid
x: int = foo()
# also valid
x: int = foo
Why is this valid?! Well, Python doesn't actually check your type annotations, you have to choose and use a type-checker (example: mypy). There is no default type checker for Python, and invalid types are silently ignored by the interpreter.[1] (You should be indenting to indicate your block structure anyway. A lot of beginners I've seen get their indents mixed up with the actual block structure. Not so with Python: The code runs like how it looks.)
First, is that in no other text form, does white-space change meaning such that the text becomes "unreadable" (sure your docs may be formatted a little weirdly, but hey someone can still read it). Simple python is close enough to prose that people get confused.
Second, is that they haven't learnt to grok compiler messages - the program either works or doesn't work. Coupled with number 1, it basically means they can't /see/ any issues or fix them.
Part of me wants to forbid all "dumb" text editors for introductory programming courses and make everyone use an AST-based one that only allows you to create syntactically correct programs. Unfortunately there's zero chance of that happening any time soon...
JavaScript syntax is outright bizarre compared to Python. Care to share your slides teaching the semicolon rules, four or so different scopings, the damn "new", type coercions and so on to learners?
Javascript has mostly nicer semantics, but buried deep in ugly pile of mess. And CPython is a disgrace.
As for teaching JavaScript’s pain points... that’s not really how I operate. I’d rather they know the general rules and come across edge-cases when they’re in a position to solve them, rather than overload them with information. Automatic semi-colon insertion is powerful enough to get you through several large-scale projects, so there’s essentially no point to discuss it prematurely as anything but a curiosity, “this could be a gotcha, so keep your code clean”.
Finally, comparing the error linters in VSC for Python versus javascript, especially if you //@ts-check... I think JavaScript actually does a better job.
If your beginners prefer C like syntax then I doubt they are really beginners at all.
Incidentally, Ruby has a similar problem for self-learners.
Python's whitespace rules are a minor nuisance to some, but at least there is consensus among Python devs on how to do something as fundamental as iterating over a list.
I write JavaScript all the time. It has improved a lot over the last decade. But I could never teach it to a beginner.
Don't get me wrong, though. I wouldn't teach Python to a beginner either.
As someone not really familiar with python besides using it instead of one off bash scripts, I have the same feeling about using it. When is python to appropriate language to pick? Not high performance, not safe, does not run in the browser, not embed friendly, no unique features. There are more mature and bigger ecosystem out there with better tooling and there is the whole python 2 vs python 3 thing.
Yet I see so many python positions advertised, that I consider picking it up.
For almost every science or engineering domain, python has some of the best in class libraries available (either native or as bindings to the standard C libraries everybody uses). It is more likely than not a plug in or scripting language for the engineering desktop application you use. It will let you do everything from interactive data analysis to web development, to scripting and devops, to cutting edge ML research in the same language using mature and battle tested tools. This is extra nice if you are combining many different domains, like doing Machine Learning and Computer Vision on GIS data and presenting the results on an interactive web site.
Especially if you're ambition in life isn't to be a professional programmer, but rather a professional that uses programming to do his job, then learning just one language is very enticing and python is probably the language that is most likely do have everything you need to get the job done, no matter what that job might be.
Numpy, scipy, matplotlib, flask, django, tensorflow, ... all the way down to tiny packages like emcee makes it an extremely compelling ecosystem to develop software in.
Shell scripting, e.g. dev ops? Ruby for me, Perl for complex regular expressions.
Web development? This depends.
High performance environment? Golang, C.
Basically, the care where Python is called for is the scenario where it offers a library you absolutely need, not anywhere it’s definitely the best language for the job, because it rarely is.
https://mobile.twitter.com/reuvenmlerner/status/129031712499...
Another big benefit is how it makes your code self-documenting -- and makes that self-documentation self-enforcing. If you are making an API for consumption, it's dead simple to make it very clear how it's structured, and to set & enforce contracts for its usage.
For me, in general it is more about its power to ease the cognitive load associated with coding. Having to constantly look up documentation to see what the types of arguments are and in what order they need passed brings me out of flow. When I don't have to think about that, I can spend more time focused on the problem at hand. That doesn't mean I can't program without them; I have to do a fair amount of Vue stuff at work and I make it work despite not being a front end guy. But my preference is always for static typing.
Over time, this has a very noticable impact on development speed, and in a very painful way for the individual developers who need to spending your time tracing the various call paths in unrelated code and build up a mental model of the involved types every time they want to do a nontrivial change, and then deal with the fallout of unintentional bugs due to missed code paths for an unpredictable amount of time as they are discovered.
So when there is a solution that can completely eliminate this class of bugs in an automated way, this sounds like a very appealing feature.
How do you know what the argument “details” should be?
The function documentation says “takes the query details” ... so people sit down in the repl and just screw around with the functions to try to figure out what they do, or search for examples of how they’re used.
with type hints, this discovery process for other programmers was significantly quicker and on boarding was faster.
I mean, sure, just write better docstrings, but type hints can’t get out of date, because it’s a type checking error.
Maybe a better solution is rust style “compiled doc strings” so the documentation can’t be wrong, or rust style inline unit tests that show examples of how to use functions... but python has neither.
It’s been my experience that type hints for your own code... eh. But if you’re working in a team, they’re valuable.
For example I'm sure you've had runtime production errors where you tried to call a method on a null object many times. That is the kind of thing last generation type systems couldn't help you with, and new systems do.
(In statically typed languages with implicit nullability, nulls create the same problem.)
Basically, explicit contracts are Good, and types are a subset of explicit contracts that are more easily enforceable than most.
Same here. The arguments for it seem to be:
- It allows you to find bugs in your code without running it. I’ve concluded that my workflow must be different from people who make this claim - I never write code without testing it. This is more comprehensive than relying on a type checker, because it finds all kinds of errors, not just type errors.
- It’s a form of documentation of function parameter and return types. This is better served by comments, because type hints are usually inaccurate in a duck-typed language like Python. For example, I see hints like `def twice(x: int) -> int: return x+x`. The correct type for a function like that isn’t `int`, it’s something like `addable`.
Guess you're just a better programmer. I've run into many in JavaScript and Python.
There are many, many things that can be expressed with types... depending on the type system. In Haskell, when you look at a function type, you instantly know whether it returns an optional value (a Maybe), or if it has side effects (IO), etc. You can also tell how general the function is, by how abstract its parameters are.
An example of something that becomes possible with a rich type system: https://hoogle.haskell.org/
The Rust compiler is doing a reasonably good job on error messages. It's especially good at explaining that thing A being done here is incompatible with thing B way over there. It prints the source for both places, which is a rare feature.
A compiler that does global analysis can tell you more about what's wrong. Python, in its interpreter implementation, doesn't have the global info to tell you about global problems.
It's very disturbing from the application Dev world view where people seek longer names for reasons, but after spending time in FP/LP and math you quickly forget long names. You seek variable count reduction most the time also.
for outer_index over array1
for inner_index over array1[outer_index]
print array1[outer_index][inner_index]
Bleh.The only thing I can dream about is some type of typescript like version of Python with good old-fashioned type checking. I prefer C# and Flutter only because I really need types when my applications get larger.
That was python 2...
Python 3 is "growing up" and losing the simplicity and ease of use for complex hard to understand power-user features... It's the lifecycle of any language - see C++ which is 20 years ahead on the same curve...
x = list[1, 2, 3, 4]
I assume yet another new bit of python syntax thats unguessable what it means...
Typical use would look more like this:
x: list[int] = []
i.e. x is a list of integers that starts out empty.It doesn't automatically do anything at runtime, it's basically a glorified comment for tools and libraries to use. So that does make it harder to figure out what it is.
Basically they alias all of the old builtins like list to typing.List etc. (Or maybe one should say the goal is to un-alias the alternative type system in typing-module and only use the original builtins).
It can be useful when you for example want to create a type alias like UserList = typing.List[User], which was possible even before, the change is that it now affects the old builtin also, so things that were previously syntax errors are now valid type aliases. Usually such alias assignements are more useful once you have more complex generics with nested dicts and stuff.
Or it could work with a custom type with overridden operators through __getitem__.
It's a stretch to call it "completely normal" though I believe you're correct in a strict sense: you could always construct the rest of your program such that it would contain that line and still compile. It would be extremely bad style.
>>> print range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Integer math works exactly the way you would expect with no horrible surprises at all: >>> print [x * 3 for x in range(10)]
[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
>>> print [x / 3 for x in range(10)]
[0, 0, 0, 1, 1, 1, 2, 2, 2, 3]
Python is great for little one-off tasks; say you want a color half the brightness of #308cfb >>> hex(0x30 / 2)
'0x18'
>>> hex(0x8c / 2)
'0x46'
>>> hex(0xfb / 2)
'0x7d'
The built-in support for dictionaries and JSON parsing make data conversion easy: >>> import json
>>> json.dumps({'foo': 42, 'bar': 132}.values())
'[42, 132]'
If there's one thing I love about Python, it's how easy and consistent it is. It sure is great that we've spent the last decade teaching Python to every scientist, academic, and hobbyist.If there are two things I love about Python, it's that and the reliable, well-supported Python package manager.
>>> print [x / 3 for x in range(10)]
[0, 0, 0, 1, 1, 1, 2, 2, 2, 3]
Wont that print floats nowadays?Half of them are about functions like range() and .values() becoming lazy instead of returning simple lists. I think this is a genuine blow to ease of use, though it does get rid of performance pitfalls.
The other half are about / always doing float division. But I think that's actually more intuitive for people who aren't already used to other programming languages, and it's much more predictable given that Python is dynamically typed and floats and ints sometimes get mixed up. It's also not awkward to work around, you can just write // instead of /. (Working around the other issue requires wrapping list() around things, which gets ugly very fast.)
>>> print(range(10))
range(0, 10)
>>>I was so upset when Boo was ditched from Unity, I loved it so much!
I appreciate the ability to format things on the next line without worry about how the system will handle it. It's more of a formatting edge case but it comes up enough to be useful.
In the end, I feel like it doesn't matter to me nearly as much as other syntax choices in languages, as I've done a lot of Python with no braces and a lot of other stuff with them. I don't even notice anymore (although maybe counterintuitively I find braces a bit more readable now).
I would humbly suggest that maybe the name "friendly traceback" is not the most beginner-friendly thing, since if you are a beginner programmer you are perhaps not 100% sure what a "traceback" is, and why you would benefit from friendlier tracebacks.
Python is the biggest victim of its own success. There have been warts in Python since the beginning, but they mostly only look like warts in retrospect because of how much Python has shifted the conversation about what a language _could_ be.
I hope someday something truly better along all the relevant axes will replace Python. But Python has maximized utility along so many of those axes that it's an (observably) uphill battle for everybody who is currently trying.
I don't see type annotations as adding a fundamental difficulty to the sorts of error reporting described in the article, just something which makes it a bit more challenging to achieve.
Python feels like a mess by comparison. As a computer science type myself, my tribe’s provincialism towards “languages like C”, like Python, just gets old.
That level of debug information is useful to "advanced" users. Sometimes the hardest things to debug are brain fart moments. also when a library raises an exception that you've never seen before, extra context is useful.
I frankly couldn't give a shit about :=, but I would give money for GIL-less multithreading.
Thank you for yet another example of why there’s really no such thing as an “optional” feature.
One is that traditionally, there was a clear split between "system languages" which were usually fast, compiled languages that were relatively verbose, not very comfortable, and comparatively unsafe -- and "scripting languages", which were dynamically typed, dynamic memory management, often interpreted, offered more data types and facilities, but were slower.
C belonged clearly to the first group and shell scripts, Perl and Python to the second.
But the gap between these two groups has been shrinking, as languages are overall converging: Java uses dynamic memory management, Go has a very fast compiler, C++, Scala and Rust have iterators, type inference and such. On the other hand, script-like languages added type annotations, got generally faster, and so on. Much of this is due to better and better compilers.
Python stands out in this landscape like a sore thumb - its performance did not profit much from better compilers.
There is another axis which is the range between direct low-level manipulation of bits and bytes and symbolic computation and functional languages. Lisps, OCaml, Scala and Haskell are from the family tree of symbolic computation. Traditionally, these languages were heavy-weights and slow compared to the system languages, but they also have seen enormous progress from better compilers - Common Lisp implementations like SBCL can now produce code which is almost as fast as C. As a consequence, there is also a convergence of general languages with "symbolic" features like first-class functions, type inference, list comprehensions, and so on.
The third observation which I find very interesting is how much Python and modern Lisps/Schemes do have in common. If one has a close look, the extend of this convergence is really astonishing.
Here are some things that modern Lisps like SBCL, Schemes and functional languages on the one hand side, and Python3 do have in common:
* a Read-Eval-Print Loop (REPL)
* strong dynamic typing
* automatic memory management
* memory safety
* exceptions
* a wide choice of built-in data types: lists, strings, vectors, arrays, dictionaries / hash maps, tuples, sets
* keyword arguments and optional arguments in functions
* handling of names in scopes and names spaces
* closures and lambda functions
* list comprehensions
* pattern matching (limited support for tuples and lists in Python)
* Unicode strings
* arbitrarily long integers
* complex numbers
* rational numbers
* number type are part of a hierarchical type hierarchy (numeric tower)
* empty sequences, containers and strings are logically false
* support for threads (but no real parallelism in Python)
* low-level bit operations (a bit limited in Python)
* easy way to call into C code
* type annotations
* if ... else can be used as an expression
* string formatting is a mini language
* hexadecimal, octal and binary literals
* standard functions for functional programming like map and filter
* support for OOP (e.g. by the Common Lisp Object System)
* support for asynchronous execution
The few remaining distinctions between Lisps and Python are:
1. Lisps use parentheses to determine scope, while Python uses indentation and white space.
2. Lisps usually compile either to native code or to JIT-compiled byte code, while standard Python uses interpreted byte code.
3. Python does not support true parallel execution within the same process.
4. Lisps have of course the typical macro system which, for example, allows to define new control constructs, while Python does not have macros.
5. Lisps and Schemes have with conditions, restarts, and continuations some unique way to handle errors and manipulate the control flow (see http://www.gigamonkeys.com/book/beyond-exception-handling-co... )
So, what I find really interesting is that for example Common Lisp, which was standardized first in 1984, has so many features in common with more recent languages - and still much better performance than python:
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
In fact I think Javascript fits the title better. Python3 is still simple and advanced enough over Python 2, I just don't really agree with the author here.