[HN Gopher] Python's "disappointing" superpowers
___________________________________________________________________
Python's "disappointing" superpowers
Author : nalgeon
Score : 111 points
Date : 2023-02-01 15:37 UTC (7 hours ago)
(HTM) web link (lukeplant.me.uk)
(TXT) w3m dump (lukeplant.me.uk)
| fallingfrog wrote:
| Don't fool yourself- if your programming language has an eval()
| function, you are writing in Lisp and you are a Lisp programmer
| now. Embrace it!
|
| All joking aside, I do think Python is pretty handy.
| tmtvl wrote:
| Oh no, Lisp is so much more powerful. For example you can
| update the definition of a class in a running system and update
| all existing instances of that class. When an error occurs you
| can inspect local variables in any of the stack frames and
| execute commands in them. And that is only the tip of the
| iceberg, Lisp is, as far as I know, without equal in terms of
| power.
| progval wrote:
| > you can update the definition of a class in a running
| system and update all existing instances of that class
|
| Like this? >>> class MyClass: ...
| attr = 0 ... >>> my_object = MyClass()
| >>> MyClass.attr = 42 >>> my_object.attr 42
| >>> MyClass.method = lambda self: self.attr >>>
| my_object.method() 42
|
| > When an error occurs you can inspect local variables in any
| of the stack frames and execute commands in them
|
| What is the difference with
| https://lukeplant.me.uk/blog/posts/pythons-disappointing-
| sup... ?
| [deleted]
| DarkNova6 wrote:
| Before I read this article I was not aware of exclusive
| advantages to dynamic typing.
|
| At least now I know what is achievable despite its presence.
| ImprobableTruth wrote:
| Which of these do you think require dynamic typing?
| joshuamorton wrote:
| A lot of the orm style things are not really feasible in
| static-er languages without clunky approaches like codegen.
| ImprobableTruth wrote:
| What part specifically? Java is (in)famous for its orms
| after all. Unless you want to count that as clunky codegen?
| I'd argue that all metaprogramming boils down to that
| though.
| david2ndaccount wrote:
| Java is actually a very dynamic runtime with a very
| static language front end.
| arcturus17 wrote:
| The thread is about programming semantics though, so what
| does that have to do with anything?
| DarkNova6 wrote:
| _cough_ Reflection. This also includes Annotations which
| can give clear semantics to code generation.
| jononomo wrote:
| Unless you want to count Java as clunky? Well, I
| definitely think Java is clunky. This article by Steve
| Yegge, titled "Execution in the Kingdom of Nouns" sums up
| Java for me: https://www.eecis.udel.edu/~decker/courses/2
| 80f07/paper/King...
| DarkNova6 wrote:
| that's the point, none of these examples are intrinsically
| linked to dynamic typing.
| amelius wrote:
| Is there any language out there that improves on Python in
| various ways but still allows convenient access to literally the
| entirety of Python's ecosystem of libraries?
| sundarurfriend wrote:
| PythonCall [1] and PyCall [2] provide pretty convenient ways to
| interoperate with Python from the Julia language.
|
| It has great package/environment management, excellent
| (potentially close-to-C) performance, automatic type inference,
| and a good set of interactive tools that make for a rich REPL.
|
| But any such FFI (from any language) is an additional point-of-
| failure, an extra gear that could break and has to be
| maintained. And on the con side of Julia, there's an initial
| compilation time (which is improving version to version, but
| still a factor to consider).
|
| Also it should be mentioned that the advantage of Python is not
| only its ecosystem of libraries, but also the vast array of
| tutorials and learning resources, and of development tools.
| Those are areas where most other languages have to play catch-
| up with Python, especially a relative newcomer like Julia.
|
| [1] https://github.com/cjdoris/PythonCall.jl [2]
| https://github.com/JuliaPy/PyCall.jl/
| qsort wrote:
| Hy: https://docs.hylang.org/en/stable/
|
| I tend to stick to vanilla python though, mainly because Hy is
| too much of an hassle for my use cases.
| DarkNova6 wrote:
| GraalVM myb?
| cb321 wrote:
| While I agree with the @elcritch reply
| (https://news.ycombinator.com/item?id=34616755) that Nim is
| just nicer overall, depending upon one's idea of "convenient
| access to literally the entirety", Cython may be more to your
| liking as mentioned else thread:
| https://news.ycombinator.com/item?id=34616052
|
| While usually pitched as "only" a language for fast extension
| modules and/or bindings to existing C/C++ code, Cython is
| really a language in its own right. https://cython.org/ has
| some more details.
|
| It works by generating C code that calls the regular CPython
| API, managing all the ref count and tuple jazz that's rather a
| hassle to write in C directly. Then you run a C compiler
| against this code and it literally just links against the
| CPython .so's/DLLs. So, it's not just calling module code the
| same way as CPython, but actually calling the core built-in to
| Python code the same way as well.
|
| As you add more `cdef` type annotations to your cython code,
| the generated C code becomes closer & closer to hand-written C
| code (both in hazards and efficiency).
|
| Of course, a caveat is that may be Cython also doesn't improve
| upon Python very much as a language, except for allowing
| gradual static typing.
| elcritch wrote:
| I've come to really enjoy programming in Nim. Note that Nim is
| very different language despite sharing a similar syntax.
| However, I feel it keeps a lot of the "feel" of Python 2 days
| of being a fairly simple neat language but that lets you do
| things at compile time (like compile time duck typing).
|
| There's a good Python -> Nim bridge:
| https://github.com/yglukhov/nimpy
| bayesian_horse wrote:
| Coconut, F# (Fable)...
|
| https://github.com/vindarel/languages-that-compile-to-python
| dunefox wrote:
| F# is a great language... I wish I could use it at work.
| lostmsu wrote:
| Any .NET language with https://github.com/pythonnet/pythonnet
| revskill wrote:
| Let's stop calling "dynamic" and "static" versus "runtime" and
| "comptime" instead ?
|
| Also, "dynamic code generation" for "meta programming" ?
| [deleted]
| benreesman wrote:
| I kinda hope we can just let Python be Python: it's in a global-
| ish maximum for what it's for, and I suspect any big move away
| from that will make it worse overall.
|
| Obviously things like UTF-8 support, or maybe getting a clean
| lexical scope option, or other "fixes" are good. Performance
| improvements are good.
|
| But there are lots of mainstream languages that have mature
| static type systems, strong metaprogramming facilities, higher
| performance, or all of the above.
|
| I'd _way_ rather see effort go into getting the package
| management thing figured out, or the static analysis stuff
| improved further than any big movement in the language proper.
|
| Just my 2c.
| lordgroff wrote:
| I maintain Python code bases for a living, and feel that the
| language has simply been pushed too far. Static typing in Python
| doesn't give you the advantage of actually static typing and even
| IDE support is -- well it's not terrible, just not great.
|
| The thing is, once we go through all this static typing exercise
| in Python, we get no performance advantages, and the whole thing
| seems bolted on, with worse semantics than most modern typed
| languages. And yes, it can stifle undeniable advantages a dynamic
| language like Python can provide.
|
| Python remains a fantastic prototyping and scripting language,
| but my feeling is that it now handles more than it should.
| phlakaton wrote:
| I think the mistake is to assume that Python's type hints form
| a complete static typing system. Of course they fall short if
| you think that's what they're supposed to be. I think of it
| instead as a sometimes-useful subset of checks that you might
| get from a static typing system, and I use it in those places
| in my projects where I think it will be the most useful. The
| very fact that I can _think_ of it as an option I can enable
| puts it in a totally different space from traditional static
| typing systems.
| arcturus17 wrote:
| Yea this is exactly how it feels to me. Like "reinforced
| dynamic".
| zerodensity wrote:
| I also maintain a large python codebase at work, typing makes
| things simpler. For example using pydantic 90% of serialization
| code just goes away. Mypy eliminates a large number of bugs.
| Also when working with multiple people in the same codebase
| typing makes intent so much clearer. The type system itself is
| not perfect but it's a clear improvement of not having it at
| all.
| arcturus17 wrote:
| I could not agree more. I'm fairly language agnostic but
| typed Python with pydantic is a joy to work with.
| ReflectedImage wrote:
| I disagree, it makes things more complicated by bringing in
| concepts such as generics.
|
| Using MyPy will on average double your bug count per software
| feature. You might not think it does that. But if you
| actually go and measure it, the bugs go through the roof.
| There are studies on this. It's for subtle reasons revolving
| around where bugs come from in code.
| [deleted]
| ImprobableTruth wrote:
| Honestly, static typing encouraging data shape documentation
| alone makes it worth it to me. Yes, they're pretty hacky in
| Python and don't feel great, but I'm sure it'll continue to
| improve.
|
| I'm just so over having to guess what a function might accept
| or return. Life is too short to spend it constantly reverse
| engineering code because people can't be arsed to write proper
| documentation.
| cameroncairns wrote:
| There have been some efforts to utilize the type hints to give
| performance boosts. There's a project called mypyc that
| apparently has been used by black (python formatting library)
| that will compile type hinted python into c extensions.
| Unfortunately I think development has stalled, but as more
| people start using type hints I think there will be more
| motivation for similar projects.
| KRAKRISMOTT wrote:
| I think the issue with Python is that it is relatively
| underfunded compared to other languages of its size. The entire
| Python ecosystem lacks leadership. Packaging is a clusterfuck,
| Pypa today still doesn't contain package metadata (which
| massively slows down downstream resolvers like poetry and
| wastes terabytes of bandwidth every year). Non-security issues
| take forever to resolve. Nothing encourages parties to
| contribute, unlike Go or Rust. You end up with companies having
| their own subtly-imcompatible internal forks. The benevolent
| dictator never cared about performance until recently. Most of
| Python's changes have been simple syntactic sugar. Python as a
| compiler engineering project is an exercise in mediocrity
| compared to V8 or LuaJIT.
| abdullahkhalids wrote:
| > the whole thing seems bolted on, with worse semantics than
| most modern typed languages
|
| One of the biggest sources of ugliness is the "None". The
| standard way of declaring variables ahead of time is setting
| them to None. But then, the type hints just become these ugly
| unreadable Optional[ActualTypeofVar] everywhere.
| mjr00 wrote:
| That's because your type _is_ Optional[TypeOfVar] though; if
| you try using that variable in a place that expects just
| TypeOfVar before it 's set, you _should_ get an error.
| abdullahkhalids wrote:
| Let me restate. To prevent ugliness in typing, either
|
| * Python should have a way of declaring variables without
| setting them to None, so we can type hint them to their
| actual types. Pre-declaration is very important for a
| prototyping language, and needs to be done in a way that
| the variable is visible to dir().
|
| * Come up with a cleaner syntax than the wordy Optional[].
| Thankfully, they have recently moved on from the ugly
| Union[a,b] to the more readable a | b. Something more
| readable could be done for Optional.
| thatfunkymunki wrote:
| but Optional[foo] is literally a union of foo | None
| already!
| travisjungroth wrote:
| a: int b: str | None = None
| joshuamorton wrote:
| Right, in langs with c-style scoping, this is an issue, but
| in python if foo: x = a
| else: x = b
|
| Works, so there's no need to predeclare.
| abdullahkhalids wrote:
| A very common pattern in python is to declare all
| instance variables of a class in the __init__ method by
| setting them to None. This is done for
|
| * code readability; all relevant variables are in one
| place
|
| * Python is a prototyping language, and a very common
| usage pattern is doing dir(object) to determine the names
| of all variables that could be set to something.
| VygmraMGVl wrote:
| You can declare a type-hint beforehand without setting the
| value of the variable. See:
| https://peps.python.org/pep-0526/#global-and-local-
| variable-...
| abdullahkhalids wrote:
| Yes, but then those variables are not visible when we
| dir(object), which makes it harder for the user to
| prototype. Certainly, type hinting should not get in the
| way of the users.
| 9dev wrote:
| Im used to just doing x: list[str]
| if foo: x = []
|
| And if a variable is nullable, I use a union:
| x: list[str] | None = None
|
| That's much more readable to me!
| pdonis wrote:
| _> The standard way of declaring variables ahead of time is
| setting them to None._
|
| I'm not sure this method is actually "standard". For many use
| cases there is an obvious "null" value of the desired type
| (for example, just set an int variable to 0), so there's no
| need to use None.
|
| For use cases where you can't just initialize the variable to
| the "null" value of its type (because that value has some
| other meaning for your program), then the true type of the
| variable _isn 't_ just the type you're thinking (e.g., not
| just an int), _because_ you need to be able to distinguish
| the variable having the "null" value from it not being set
| at all (the None case). And for that kind of use case,
| Python's type hints are correctly forcing you to declare that
| variable's type the way that reflects the actual situation.
| SAI_Peregrinus wrote:
| The problem with separate prototyping languages is that the
| most permanent fix is always a temporary one. The prototype
| usually becomes the final product. If your language isn't
| suitable for use as a final product, then you're going to have
| a problem. If it's not suitable for writing a prototype, then
| you already have a problem.
| dunefox wrote:
| That's why I love the idea of a language like Common Lisp.
| Performance, 'debugability', and flexibility in one package.
| lostmsu wrote:
| > Python remains a fantastic prototyping and scripting language
|
| I think it sucks for prototyping too if your prototype is
| constantly evolving. I have a WIP with about 100 files in it
| that I've been aggressively evolving over the past year, and I
| already want to rewrite everything in something statically
| typed, because any kind of change became pain in the ass. Too
| bad the project requires Python-first libraries.
| yummypaint wrote:
| I routinely use cython to compile python for heavy workloads. A
| big part of the ~10x speedup i usually see comes from
| strategically assigning true static types to certain variables
| that get frequently iterated or compared. Most variables are
| left as standard python as it isn't necessary to change them
| for performance.
|
| My experience has been that cython "just works" even with lots
| of external libraries etc, and the code ends up performing as
| well as any c++ code i could realistically write while being
| much more understandable.
| nextaccountic wrote:
| > I routinely use cython to compile python for heavy
| workloads.
|
| an alternative is rust + pyo3 https://pyo3.rs
|
| here's a web framework written with it, https://robyn.tech
|
| the other poster child for pyo3 is polars,
| https://www.pola.rs
|
| it's simply, amazing.
| samstave wrote:
| which of these links should I start with with zero xp?
| dereg wrote:
| I'm so glad I found Polars. I replaced the most time-
| consuming parts of my Pandas code with Polars and it has
| reduced data manipulation times by literally 90-95%.
|
| Amazing is not an overstatement.
| wefarrell wrote:
| That's also true of Typescript, which has been wildly
| successful and taken over the javascript ecosystem. The main
| advantage of types is that it makes your code more maintainable
| by adding guardrails. You'll still possible run into issues at
| runtime and they're not perfect, but they're better than not
| having types at all.
| scrollaway wrote:
| Typescript really rarely feels bolted on to JavaScript. That
| also has to do with typescript introducing new syntax to JS.
| goodoldneon wrote:
| There's very little new syntax added by TS
| KurtMueller wrote:
| Python the language doesn't give you super powers and I would say
| that its clunkier and less elegant than Ruby and obviously not as
| powerful as languages like F#. Python's ecosystem and
| contributors are its biggest benefits and they help you succeed
| in spite of the language itself.
| [deleted]
| jgeada wrote:
| The ecosystem exists because Python does make it possible. That
| was one of the main thrusts of the article!
| pdimitar wrote:
| > _The ecosystem exists because Python does make it
| possible._
|
| Only to a certain point, after which the network effects
| override everything else.
| wheelerof4te wrote:
| Either embrace dynamic typing and provide good error guards...or
| try to use type hints and still make good error guards.
|
| We had an entire history of Python 2 without type hints. Why use
| them now?
| ok123456 wrote:
| And most of that python2 code is completely rotted.
| markrages wrote:
| By definition, since it won't run on a supported runtime.
| 9dev wrote:
| How come everyone realised the benefits of typing by now,
| except the Python community?
| scrollaway wrote:
| Because python got a half baked, overall poor quality type
| hinting system so devs that haven't been exposed to the
| benefits of eg. Typescript don't understand why this is
| better.
|
| Many of us in the python community know the benefits, and
| we're simply changing our stack so python is as contained as
| possible, and dropping lower quality libraries for higher
| quality typed ones.
| pdonis wrote:
| The benefits of typing _for certain kinds of applications_.
|
| Many people in the Python community simply aren't writing
| those kinds of applications. They're writing applications
| where typing is not a benefit, it's a hindrance, so they
| don't use it, and Python makes that easy.
| arcturus17 wrote:
| I'm also part of the Python community and I use typing
| extensively. I find them useful for app development but
| also in scripting. There must be at least be a good dozen
| of us seeing the popularity of mypy, pyright and the fact
| that the language designers saw fit to add them, too.
| zerodensity wrote:
| Could you give an example of a type of application where
| typing is a hindrance?
| randomluck040 wrote:
| Not a hindrance but I work with image data a lot. Usually
| what comes in is any kind of Numpy array and what comes
| out at the end is either statistics or a Numpy array. I
| try to type hint everywhere I can but I feel stupid doing
| so because all I do is work with arrays. Maybe I'm not
| proficient/knowledgeable enough though so take it with a
| grain of salt.
| zerodensity wrote:
| If it's truly "any" kind of Numpy array typing won't help
| much there I agree.
|
| But often it can be helpful to know the shape of the
| input and the shape of the output. Eg are we working with
| a 2D,3D or ND array.
|
| Before 3.11 it was not simple (possible?) To type this.
| But https://peps.python.org/pep-0646/ makes it possible.
| If somewhat clunky on the definition side.
| spookylukey wrote:
| I did a fairly detailed breakdown regarding the Python
| library Parsy: https://lukeplant.me.uk/blog/posts/python-
| type-hints-parsy-c...
|
| This is not to make the general claim "Typing is a
| hindrance in parsing applications", or anything close.
| It's saying "the current static type system(s) available
| in Python would have made this Python library much
| worse".
| ReflectedImage wrote:
| Developing with static typing reduces development speed by
| 2.5x and increases bugs by 2.5x per the emperical studies on
| the topic.
|
| There isn't a benefit to static typing in Python, it's a
| massive drawback.
| Jtsummers wrote:
| > Developing with static typing reduces development speed
| by 2.5x and increases bugs by 2.5x per the emperical
| studies on the topic.
|
| I hate "Citation needed" comments, but this is a very
| strong claim and so deserves it:
|
| Citation needed
| anhner wrote:
| Any source for those made-up-sounding numbers?
| llanowarelves wrote:
| Not to be rude, but scientific/ai/data scientists are
| typically not the best "programmers" (best practices and code
| hygiene) , and their stuff is the main reason to be on Python
| these days (other than for small CLI and scripts), which
| pulls everything around into it like a black hole ("oh let's
| make the api in Python too, to keep it one language").
|
| And Python has a ton of newbies, college kids etc. Though
| this is also true of JavaScript.
|
| As an industrial language/environment with best practices for
| very large codebases, it's really weak and I much prefer
| TypeScript despite the occasional tooling fatigue (has slowed
| down).
|
| But a ton of money has been poured into JavaScript (v8) which
| really set that into motion.
| fasttriggerfish wrote:
| I think type hints have mostly changed Python for the better but
| I still get frustrated by the number of half baked features and
| inconsistencies in the language. You end up fighting quirks (
| like isinstance not working properly with generics ) all the time
| and it can get pretty tedious.
| packetlost wrote:
| ... what? You're not supposed to use isinstance with
| generics??? It's a type-hinting only feature afaik
| Spivak wrote:
| > But typing.Callable has zero support for them, meaning they
| can't be typed in a higher-order context.
|
| https://peps.python.org/pep-0612/ from typing
| import Awaitable, Callable, ParamSpec, TypeVar P =
| ParamSpec("P") R = TypeVar("R") def
| add_logging(f: Callable[P, R]) -> Callable[P, Awaitable[R]]:
| async def inner(*args: P.args, **kwargs: P.kwargs) -> R:
| await log_to_database() return f(*args, **kwargs)
| return inner @add_logging def
| takes_int_str(x: int, y: str) -> int: return x + 7
| await takes_int_str(1, "A") # Accepted await
| takes_int_str("B", 2) # Correctly rejected by the type checker
|
| I think the author and the people working on Python's type
| annotations actually agree here. The goal is to have type
| annotations powerful enough to statically describe all behavior
| _generically_ without library specific extensions. There hasn 't
| been much push for it but I expect a lot of the author's concerns
| would be alleviated by a type annotation for types themselves.
| Being able to say, "alright I'm gonna so some dynamic
| metaprogramming magic bullshit, but at the end will pop out a
| class of this shape" probably gets you 80% of the way where.
| ImprobableTruth wrote:
| Metaprogramming does not require dynamic types, but this post
| seems to equate them. As far as I can see all this could be done
| in e.g. Java (and probably is).
|
| IME this kind of "magic" very quickly loses its appeal when you
| have to debug it. The author's idea of libraries wrapping this
| stuff up so users don't have to care about it just doesn't pan
| out at all in my experience.
| ajuc wrote:
| LISPs are the quintessential metaprogramming languages, and
| they learnt the lesson of "use macros sparingly and only as the
| last resort" very early on.
| taeric wrote:
| I mean, you aren't wrong. But most of what they learned was
| "step debugging is hard in the presence of macros." And step
| debugging has largely been tossed out of the window in many
| modern setups. Just look at Java's "stream" apis. I swear
| they did what they could to replicate the LOOP macro.
| vkou wrote:
| I am very rarely concerned about debugging my usage of Java
| streams, and step debugging works fine in the context
| surrounding them.
| taeric wrote:
| That is also the case for macros in lisp, at large.
|
| Similarly, any heavy use of lambdas in java will make
| step debugging confusing. As will any annotations you may
| use. Which is largely why many people grow to hate
| annotations.
|
| Which is all a fancy way of saying we learn the same
| lessons again and again. Used smartly, all of these are
| great tools. Defining what is "smartly" is a place of
| dragons.
| jchw wrote:
| I also strongly dislike the idea that static type systems are
| only being added to Python because spoilsports from other
| languages are forced to use Python and don't want to. Not true.
| That's especially strange considering Python is one of the only
| traditionally dynamic languages that has mostly led it's own
| static typing system, joined mainly by just PHP in that regard.
| Why does it not support features like kwargs? Dunno. TypeScript
| has no trouble supporting _tons_ of JavaScript patterns you
| could _never_ do in other languages, even C# from which it is
| heavily influenced due to its heritage, and TypeScript is a
| fully separate effort from JS.
|
| On the contrary, static typing in Python is still extremely
| nice to have. When I was at the peak of my Python career, I had
| a bug where I changed the return type of a function to be a
| tuple, and somehow unit tests missed one of the worst possible
| invocations, leading to an awful failure that occurred after a
| payment was processed but before actually completing the task,
| causing it to be retried repeatedly. To be clear, like any
| failure of this nature, it is one caused by many different
| problems, and we employed many different solutions; we started
| paying attention to test coverage, we began using MyPy (it was
| still quite new; this was also in Python 2 so it needed type
| erasure compilation among other things) and we made our payment
| processing logic more robust to prevent processing the same
| payment twice even in the case of everything else (like retry
| logic) failing to stop it again. But the thing that sucks is,
| fairly simple type inference without any additional type
| annotations could've detected that sort of bug without a
| potential for false positives.
|
| So I feel like it's silly the way that some dynamic language
| proponents feel like static typing systems on top of dynamic
| languages is all from outsiders. On the contrary, the relative
| weakness of MyPy is actually what ultimately made me quit using
| Python, and if I had to use it today, then yes, of course I
| would opt for the highest degree of type safety, as a primary
| concern above being "pythonic." I like pretty code, but I like
| correct code more.
|
| Sometimes this does prevent "better" solutions from working,
| but in my opinion nearly 100% of the time that this is the
| case, it's because:
|
| - The type system in question is not sufficiently advanced to
| express the types elegantly.
|
| OR
|
| - The approach is inherently not safe and probably not a good
| idea. Like patching the request object inside of middleware in
| Django, for example.
|
| I think TypeScript proves that with a sufficiently advanced
| type system, even arguably bad ideas can be type safe. For
| example, the ability to express dotted object paths safely in
| modern TypeScript is pretty impressive, and lets you map out
| older JS that does this accurately, but in general that seems
| like an unnecessary trick that will just make your code slower
| at runtime for the slightest terseness improvement over
| alternatives, lacking a language with sufficiently advanced
| metaprogramming.
|
| The thing is though, eventually this thought process comes
| true. If a given programming language community winds up
| bleeding members who are moving on due to the lack of better
| static type checking systems, then the people left will
| invariably be much more likely to be against static type
| systems.
| ReflectedImage wrote:
| You quit Python because you tried to use static typing in a
| dynamic language and for obvious reasons that doesn't work.
|
| You could have introduced an UAT environment and done basic
| QA.
| jchw wrote:
| We had dedicated QA testing. QA testing failed to create
| the requisite conditions.
|
| Type checking is not a replacement for QA testing. However,
| it is much cheaper and also finds bugs that might be
| _incredibly_ hard to find through random chance or through
| structured smoke testing, because it does not depend on how
| common a given code path is. QA testing is even less likely
| to find issues than automated test suites, since at least
| you can qualify branch coverage with test suites (which
| _still_ will not enumerate all of the possible _code paths_
| , and thus... Type checking is incredibly useful.)
|
| So while type checking really is _not_ a replacement for
| QA, QA is also not a replacement for type checking.
|
| I ultimately quit Python for many reasons, but the desire
| to write more correct code was the big one. Not just me,
| but my entire team was burned out on Python. Investing so
| much into unit testing and increasing coverage, upgrading
| Python versions, and adding type checking as much as
| possible was still not yielding the benefits we'd hoped for
| despite how much effort it took. We eventually found much
| better success with the then-still-new Go programming
| language, which we used on most new projects going forward.
| There was still the occasional head scratcher in
| production, but deployments were as quiet as a church
| mouse. YMMV of course; there's plenty of success and
| failure stories with any programming language. I think we
| were all ready and willing to put a lot of investment into
| improving our robustness situation and just felt that we
| got more out of that effort with Go than Python for our
| programs. Python still has plenty of advantages too, so we
| didn't completely quit it; we wound up using Django and
| SQLalchemy here and there, but definitely most stuff moved
| to Go over time. (And personally, I stopped using Python
| for those things too, since moving on.)
| ReflectedImage wrote:
| Are you aware that code written in the statically typed
| code style has on average 2.5x the number of bugs as the
| equivalent code in the dynamically typed code style per
| software feature?
|
| I'm sorry to burst your bubble, but static typing is
| REALLY REALLY bad from a code correctness standpoint.
|
| "write more correct code was the big one" Well you have
| completely failed on that account.
|
| Static typing has nothing to do with code correctness,
| it's purely about code performance.
| posix86 wrote:
| Yeah thought so too... in particular the example where you pass
| a a generator to a db, the generator isn't actually executed,
| and instead the expression is parsed & transformed to SQL.
|
| This is cool if it works. Good luck when it doesn't due to user
| error, and more luck if it doesn't due to a bug.
|
| You need to develop a whole strategy to tell the user what went
| wrong and how, and why, basically from scratch; admitting that
| you didn't, in fact, execute the generator, and that they have
| to change it. because of that.
|
| It's pretty awesome that it's possible. And it would be pretty
| amazing to write something like that. But... idk if it's a good
| idea from a developer stand point. I like being able to
| understand what's happening in a library with a single click.
| RobotToaster wrote:
| Isn't the C preprocessor a type of metaprogramming?
| Jtsummers wrote:
| Yes since metaprogramming is just programming that generates,
| modifies, or extends other programs.
| agumonkey wrote:
| it's probably discard as being string-based, you could do the
| same with sed
| [deleted]
| teaearlgraycold wrote:
| TypeScript is the language Python wants to be. If only JS came
| with a Go-level stdlib there'd be nothing to complain about.
| [deleted]
| revskill wrote:
| Seems valid, most modern Python code is almost the same as
| Typescript without {}
| TeeWEE wrote:
| All these features are nice and stuff... But they are often
| runtime features... At compile time Python doesnt tell you wether
| a program is correct. Which is fine for small programs or small
| services. But any big system is written in python is really hard
| to maintain without LOTS of unit tests...
|
| Static typing, compile time checks just win in the long run. And
| with languages like kotlin you still have all the advantages, and
| you have nice tools like python has which execute at COMPILE time
| using DSL, which are type safe themselve..
|
| Python has become mostly a toy language for me to write scripts
| in.
| ReflectedImage wrote:
| No programming language tells you if a program is correct at
| compile time. Type errors aren't a very common type of bug
| either.
| chatmasta wrote:
| What does "compile time" even mean for Python?
| RedTachyon wrote:
| The moment you run the script, before it actually gets
| executed.
| CoastalCoder wrote:
| > At compile time Python doesnt tell you wether a program is
| correct.
|
| This is a general limitation of type systems, IIUC. If you want
| a type system to guarantee 100% program correctness, I think it
| can't handle an arbitrary Turing-complete program.
| bayesian_horse wrote:
| When I did most of my work in Python, typehints weren't a thing.
| I still feel like static typechecking is less useful in Python
| since its datamodel is overally less of a hot mess compared to
| Javascript for example.
|
| And Python modules/frameworks can be a lot more "typed" than
| you'd expect. Django models, forms etc offer more runtime
| validation than typesystems can easily achieve. Yes, at runtime.
| But between not having a build process and in general being more
| readable and concise, I feel like Python lets you run into the
| runtime error long before you get the same thing done "error
| free" in C#. Not that C# doesn't have runtime errors...
| phailhaus wrote:
| > its datamodel is overally less of a hot mess compared to
| Javascript for example.
|
| I don't understand this, what do you mean? TypeScript is such a
| success partly because everything is an object in Javascript.
| There's no need to distinguish between classes and "dicts", as
| you have to with Python. Another example: Python functions have
| args and kwargs, which make typing significantly more complex
| (as the article points out, Callable doesn't even support
| kwargs). Javascript doesn't, so typing functions is trivial.
|
| Part of the point of static typechecking is documentation that
| can be verified by tooling. If you have no types in your
| codebase, and you decide to change something from a dict to a
| class, good luck! You're going to have to manually trace all
| the data flows through your entire application to figure out
| what's affected.
| pdonis wrote:
| _> everything is an object in Javascript_
|
| Everything is an object in Python too.
|
| _> There 's no need to distinguish between classes and
| "dicts", as you have to with Python._
|
| "dict" in Python (or at least Python 3, but Python 2 is EOL
| now so Python 3 is the only active Python there is) _is_ a
| class. You can even subclass it, which if you want a
| customized dict for some reason in your particular
| application is often the best way to do it. Or you can
| subclass MutableMapping, which dict itself is a subclass of,
| and which is what is supposed to be used for isinstance
| checks now that Python has established abstract base classes
| for all of its standard "built-in type" interfaces.
| KyeRussell wrote:
| OP is not saying that type checking is useful. They're saying
| that it's not as useful.
| paganel wrote:
| > I'm worried that a de-facto move away from dynamic stuff in the
| Python ecosystem, possibly motivated by those who use Python only
| because they have to, and just want to make it more like the C#
| or Java they are comfortable with, could leave us with the very
| worst of all worlds.
|
| It is certainly happening, and I'm not sure Python the language
| is all the better for it. I say that as a guy who explicitly
| mentioned this "Python Is Not Java" blog-post during my first job
| interview as a professional programmer, more than 15 years ago.
|
| [1] https://dirtsimple.org/2004/12/python-is-not-java.html
| bayesian_horse wrote:
| Over the years C# (and probably Java, but I'm not so well
| versed in that) gained quite a few features to improve "Meta-
| Programming", one could argue in an attempt to compete with
| dynamic languages. In C# that is mainly possible through
| introspection, generics and maybe dependency injection. Entity
| Framework Core can mostly figure out an SQL Table and its
| queries by looking at a simple class. It's not as good as the
| Django ORM or SQLAlchemy, but it tries to achieve similar
| things...
|
| So maybe some stuff in the Dotnet ecosystem got started because
| Python programmers were forced to use C# and tried to make that
| more dynamic.
| acedTrex wrote:
| How is SQLAlchemy or django better at any of that? in my
| experience EF is far far superior
| pjmlp wrote:
| Check the history of IronPython and IronRuby and how that
| spun the Dynamic Language Runtime, likewise do the same for
| jython, jTcl, jRuby and invokedynamic bytecode.
| simplicio wrote:
| My theory is that Python and C++ are slowly evolving towards
| eachother, and in 20 years will merge into the same (very
| confusing) language.
| rich_sasha wrote:
| C++ consuming whatever popular paradigm is around and growing
| into a jumbled mess? Surely you're joking...
| ok123456 wrote:
| eval() makes it harder to reason able your code and opens you
| up to injection attacks. Steering the boat toward C# or Java is
| better than crashing into TCL.
| thereisnospork wrote:
| While this might be about my most unpopular opinion, it feels
| like it is time to start putting together a Python 4.0. I don't
| particularly have skin in the game but there is(?) enough meat on
| the bone around things like improving the GIL status quo, JIT
| compiling, static typing, and presumably etc. to be worth a
| breaking change.
| JonChesterfield wrote:
| That's definitely an unpopular opinion. The 2 to 3 change
| caused a lot of pain. I can't see the python community
| attempting that again.
___________________________________________________________________
(page generated 2023-02-01 23:01 UTC)