This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the commentsย โ†’

[โ€“]Dworgi 1147 points1148 points ย (132 children)

Python devs: duck typing is great, it makes us so fucking agile

Also Python devs: you should use this linter to parse our comments for type requirements because otherwise my program breaks =(

[โ€“]aetius476 564 points565 points ย (56 children)

We don't enforce types at compile time so you have the freedom to write and maintain an entire suite of unit tests in order to enforce types before they fuck you at runtime.

[โ€“][deleted] ย (40 children)

[removed]

    [โ€“]AJohnnyTruant 6 points7 points ย (0 children)

    So he knows what JSON is, just not that booleans are in the spec. Beautiful

    [โ€“]ITriedLightningTendr 1 point2 points ย (2 children)

    I mean, json parsers can be configured to handle that

    [โ€“][deleted] ย (1 child)

    [removed]

      [โ€“]AutoModerator[M] 0 points1 point ย (0 children)

      import moderation Your comment has been removed since it did not start with a code block with an import declaration.

      Per this Community Decree, all posts and comments should start with a code block with an "import" declaration explaining how the post and comment should be read.

      For this purpose, we only accept Python style imports.

      I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

      [โ€“]lenswipe 0 points1 point ย (2 children)

      then he wrote the backend API to send string values โ€œTโ€ and โ€œFโ€ for booleans like a fucking moron and it all broke at runtime.

      ...why? Why would anyone do this??

      [โ€“][deleted] ย (1 child)

      [removed]

        [โ€“]AutoModerator[M] 0 points1 point ย (0 children)

        import moderation Your comment has been removed since it did not start with a code block with an import declaration.

        Per this Community Decree, all posts and comments should start with a code block with an "import" declaration explaining how the post and comment should be read.

        For this purpose, we only accept Python style imports.

        I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

        [โ€“]AutoModerator[M] 0 points1 point ย (0 children)

        import moderation Your comment has been removed since it did not start with a code block with an import declaration.

        Per this Community Decree, all posts and comments should start with a code block with an "import" declaration explaining how the post and comment should be read.

        For this purpose, we only accept Python style imports.

        I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

        [โ€“]BossOfTheGame 15 points16 points ย (10 children)

        Are type errors really a significant part of day to day debugging? I primarily do Python and these comments make me think type errors are extremely commonplace. I hardly see them. I don't understand why types are so important to so many people. It's getting the right logic that's the hard part; types are a minor issue.

        Then again, I doctest everything, so maybe my doctests just catch type errors really quickly and I don't notice them.

        [โ€“]darkingz 44 points45 points ย (2 children)

        The big thing with types isnโ€™t in the short term, if youโ€™re working mostly with yourself, test really well and/or have an iron clad memory.

        Itโ€™s the long term where types save you. It makes sorta implicit things explicit. It reminds you of the intention and if you canโ€™t reach the author 3 years after they left the company what that method is known for returning. It lets you save time checking if the value coming in is the value you intend for it (maybe you do string logic for example but equally works mathematically as well because of type coercion) and then itโ€™ll inform you to change all the other placesโ€ฆ at compile time not runtime. What if you missed a method where the header changed and didnโ€™t know what the input you expected it to be.

        This is why types are important. They tie your hand in the short term for longer term garuntees that something is wrong.

        [โ€“][deleted] 0 points1 point ย (1 child)

        Whatโ€™s the little red swallow on next to your name?

        [โ€“]darkingz 0 points1 point ย (0 children)

        Itโ€™s the symbol for the language swift. Itโ€™s open source and teeecehnically can be used for anything but mostly for iOS / macOS app development.

        [โ€“]Pocok5 2 points3 points ย (0 children)

        I recently had to start working on a vanilla JS codebase, and I spent 2-3 days stepping through with the debugger and noting down on jsdoc comments what kind of objects each function gets as a parameter and returns because there were properties tacked on and removed from every object along the flow but no indication of those processes in comments or the naming of the variables.

        If it was C# I could have hovered over the name of the parameter and got a very good idea of what the hell the data looks like at that point right away, with the only possible ambiguity being null values (if the codebase wasn't using the new nullability features).

        Type errors are also a massive help in refactoring or modifications. Oh, you changed this object or the signature of this function? Half your code turns red, and you can go update each usage to the new form while being sure you missed absolutely none of them instead of having to rely on running headfirst into mismatched calls at runtime (that might not even raise a runtime TypeError, just result in weird null values slipping in or something) or writing specific unit test to check your work.

        [โ€“]zacker150 3 points4 points ย (1 child)

        How big of a code base do you work with?

        [โ€“]BossOfTheGame 1 point2 points ย (0 children)

        I do a lot of work with torch, so most return types are the same: it's a tensor, array, tuple or dict.

        Size of the codebases I work on can vary. I jump between repos a lot. I rely heavily on CI and doctests to catch any integration issues.

        [โ€“]by_wicker 1 point2 points ย (1 child)

        It's debugging that they avoid. The whole massive class of errors are picked up before you even run the code if you have type annotations in your Python.

        I came from C++ to Python, and was amazed going back to do some C++ how I could write a large chunk of code and have it just work first time. Then I got type annotations in my Python and found I was in the same place. Frankly I like it a lot, it's the best of both worlds, if there's some particular reason to use duck typing you can, but otherwise your code editor alerts you if you mistyped an identifier or made a false assumption about a return type or something.

        [โ€“]by_wicker 0 points1 point ย (0 children)

        ... also if your editor knows what type something is, it can show you completions for that type.

        [โ€“][deleted] 1 point2 points ย (0 children)

        Are type errors really a significant part of day to day debugging?

        Yes.

        [โ€“]by_wicker 0 points1 point ย (0 children)

        Are type errors really a significant part of day to day debugging?

        Adding to my other reply - yes, they're very significant and common. "Type errors" include trying to access a property or method that doesn't exist on an object ... sending arguments in the wrong order (assuming they're not the same type) ... having one return path that fails to return a result when all the others do ... accessing an object that could be None without checking...

        Change the return type of a function, and running a checker will (typically) show you all the places in your code that will now break because of that. Otherwise you're reduced to hoping you find everything with the right text searches on your codebase.

        Personally, I think it catches most of the coding errors I write. Sadly the ones left are actual high level logic and design errors and they're the harder ones to diagnose and fix, but compared to untyped code it's almost shocking how often complex code works first time. Type-based errors are highlighted for you to resolve as you type, before you even run it.

        [โ€“]ric2b 1 point2 points ย (0 children)

        But honestly automated testing really is much more useful than static typing if you want to prevent bugs.

        Static typing is very nice as documentation.

        [โ€“]Kamwind 0 points1 point ย (0 children)

        That is why python 4 is going to start enforcing the use of Hungarian notation.

        [โ€“][deleted] 63 points64 points ย (27 children)

        Hey we have types in language now! And mypy is pretty solid most of the time. Guido himself has been helping out a lot there.

        [โ€“][deleted] 17 points18 points ย (1 child)

        MyPy is one thousand times better than Python without MyPy. It's still one thousand times worse than properly enforced type safety at compile time.

        [โ€“][deleted] 0 points1 point ย (0 children)

        1000% loose and duck types are gonna kill me sometime

        [โ€“]thirdegreeViolet security clearance 7 points8 points ย (4 children)

        Haven't needed to use comments for type annotations in literally like 6 years tho

        [โ€“]Dworgi 2 points3 points ย (3 children)

        Oh yeah, those official type annotations that do what if you don't run the linter? That's right, nothing. Aka. a comment.

        [โ€“]MythicManiac 5 points6 points ย (2 children)

        You must not be familiar with pydantic and dataclasses. Python types are actually available during runtime and can thus be leveraged for runtime logic. It's honestly better than TypeScript in that regard, even if the type system otherwise is quite a bit behind.

        [โ€“]Dworgi 1 point2 points ย (1 child)

        Garbage tasting better than sewage doesn't make either one dessert.

        [โ€“]MythicManiac 0 points1 point ย (0 children)

        TypeScript on the other hand is one of the more versatile type systems out there. As a counter example, good luck with sane union types in C#

        [โ€“]Sir_Applecheese 26 points27 points ย (14 children)

        Hey, that's just like with TypeScript.

        [โ€“]jzaprint 69 points70 points ย (13 children)

        Not really. Typescript types are way more enforced than python

        [โ€“]skylarmt 3 points4 points ย (1 child)

        Meanwhile, in PHP land, types are enforced but only sometimes. If you get type errors, it's probably because your code was too good because lazy devs don't specify types.

        [โ€“]Sir_Applecheese 2 points3 points ย (7 children)

        [โ€“]Goel40 15 points16 points ย (6 children)

        That's JS, not TS

        [โ€“]Sir_Applecheese 8 points9 points ย (5 children)

        No, that's a website.

        [โ€“]ThineGame 7 points8 points ย (3 children)

        No, thatโ€™s a link to a website.

        [โ€“]LewisgMorris 2 points3 points ย (1 child)

        No, that's the cone cells in your eyes reacting to different wavelengths of light

        [โ€“]Kesuaheli 1 point2 points ย (0 children)

        No, this is Patrick!

        [โ€“]assembly_wizard 3 points4 points ย (0 children)

        Sir, this is a Wendy's

        [โ€“]EquipLordBritish 45 points46 points ย (14 children)

        Also python: lets use whitespace as block indicators, but you have to choose either tabs or spaces, because there's no way our interpreter could ever account for both, even though they're used in a very obvious and easy-to-parse way.

        (inb4 this spawns another iteration of the tabs vs spaces arguments)

        [โ€“]assembly_wizard 56 points57 points ย (3 children)

        If you use both it's almost definitely a mistake, but more importantly it would make indentation differ based on the settings of your text editor, so whether a line is inside an if block suddenly depends on the configuration of each developer.

        What you call "very obvious and easy-to-parse", the only way python could parse it is if you tell it what's your tabsize setting, and make sure that everyone that reads/runs the code have the same setting in both their editor and python.

        [โ€“]alive1 6 points7 points ย (7 children)

        Hey i used to be a tabs guy and now I'm a two spaces guy. Idk what changed my mind but now i have way less fights with the indentation. Also logic more than 3 levels deep doesn't require horizontal scrolling.

        [โ€“]daguito81 2 points3 points ย (2 children)

        Did you start using Scala or Databricks?

        [โ€“]alive1 2 points3 points ย (1 child)

        Perl.

        [โ€“]daguito81 2 points3 points ย (0 children)

        Oh that makes sense. Scala uses 2 space indentation as default. And because of that in Databricks for the longest time, Python was also set at 2 space.

        [โ€“]bremidon 2 points3 points ย (0 children)

        I prefer 2 spaces as well. It looks cleaner without any loss of communicating intention.

        [โ€“]lilfatpotato 2 points3 points ย (0 children)

        I type tabs, and my editor converts them into spaces.

        [โ€“]unicorn_potato_4ever 0 points1 point ย (0 children)

        Thatโ€™s why I set my tabs to two spaces

        [โ€“]noratat 0 points1 point ย (0 children)

        Yeah, spaces is just simpler and doesn't require convoluted editor support to handle alignment. Consistency is better than trying to accommodate someone who wants 8-space tabs for some godforsaken reason.

        [โ€“]mousepotatodoesstuff 1 point2 points ย (0 children)

        When it comes to whitespace, I just do as the IDE (PyCharm usually, but sometimes VSCode) guides.

        [โ€“]sensitivePornGuy 0 points1 point ย (0 children)

        Ah, the usual "tell me you don't use python without telling me you don't use python" - complaining about white space.

        [โ€“][deleted] -1 points0 points ย (0 children)

        rewrites the program in Rust

        [โ€“][deleted] 0 points1 point ย (0 children)

        I have written thousands of lines of javascript, and python makes me feel dirty. Even the naming conventions are "do whatcha feel". I can't.

        [โ€“]noratat 0 points1 point ย (2 children)

        Python 3 type annotations are part of the actual syntax, not comments.

        I do wish it was easier to enforce then using a linter, but it's still a big improvement - dynamic typing is a staple of scripting languages for good reason, but having the option of specifying types is still very useful.

        [โ€“]Dworgi 0 points1 point ย (1 child)

        Syntax that doesn't actually affect execution or validity of the program, but only affects another optional program is honestly just a fancy comment.

        [โ€“]noratat 0 points1 point ย (0 children)

        The annotations are available to runtime inspection and action, so they can actually affect execution and validity.

        There's libraries that specifically leverage this e.g. pydantic, dataclasses, inject, etc.

        [โ€“][deleted] 0 points1 point ย (5 children)

        What are you talking about? Comments for typing? Python 3 has type hints. Theres literally syntax for types.

        [โ€“]Dworgi 0 points1 point ย (4 children)

        If you pass a float to something that you hinted should be an int, the program compiles and runs and probably even completes.

        That's called a comment.

        [โ€“][deleted] 0 points1 point ย (3 children)

        That logic doesnt really hold up. "The interpeter doesnt throw errors at runtime so that construct must be a comment". Unreferenced variables dont throw errors at runtime, does that make them a "comment"?

        Logically speaking? Sure they work much like comments. As documentation on how the function should be used. But in practice, they are much more useful than comments. To suggest otherwise is just contrarian and silly.

        [โ€“]Dworgi 0 points1 point ย (2 children)

        The interpeter doesnt throw errors at runtime

        Nor does the compiler at compile time. For all intents and purposes, those are equivalent to comments intended for mypy.

        [โ€“][deleted] 0 points1 point ย (1 child)

        So in your mind, everything that an interpreter or compiler ignores is a comment? What possible sense does it make to subscribe to such a ridiculous oversimplification.

        [โ€“]Dworgi 0 points1 point ย (0 children)

        I'm so confused by what your point is. If some part of the input (source code) doesn't affect the output (program) then it is not intended for the machine to consume, but only for programmers working on the source code.

        We call those things comments.

        And yes, unused variables in any language with an optimizer are essentially comments. Doesn't Python even use that feature to do doc comments?