6 ms·
This is where the type system debate breaks down. What you point out is a developer error. Mixing variable types in a dynamically typed language is, like gener
by waheoo 6y ago
This is where the type system debate breaks down.
What you point out is a developer error. Mixing variable types in a dynamically typed language is, like generics, a code smell.
Using a dynamically typed language is all about not having to babysit the compiler, its not about playing dumb about types.
If you design your functions in a way that that function will never receive an array, you dont have to test for it. And if some idiot tries one day, it should error very loudly that something is wrong.
Too many abuse dynamic typing to the point they feel safer offloading this headwork to a compiler.
That is, they get the compiler to make sure nobody will ever send an array into that function that takes a string.
All generics do is bring back the lack of typesafety and all the manual typechecking that comes with muddying generalizing the parameter typeset.
I actually dont hate generics, they are super powerful, but I question every usage as suspicious.
I also wish people would remember human brains arent all the same. We have different ways of thinking about problems. Some people need to have a compiler to busy work, some people need to do busy work while they think.
I just wish people shitting on dynamic typed languages would remember they came to solve the mess and monotomy that arose from typesafety.
Someone mentioned they felt go was going backwards from rust, i think both languages are massive steps backward from python.
- icholy 6y ago> If you design your functions in a way that that function will never receive an array, you dont have to test for it. And if some idiot tries one day, it should error very loudly that something is wrong. Then you've moved it from a test to a runtime assertion. You're still re-implementing the type-checker, poorly.
- bonestormii_ 6y agoAnd on top of this, it's usually not "some idiot" calling the function from a REPL. It's "some idiot's code", which may not be executed until the program is running in production somewhere if it is rare. "Oh, someone uploaded THAT kind of file? Well, let me see... AttributeError: Type SomeObject does not have attribute append. Here's a list of 47 functions that were called between the action you took and this error being raised. None of them guarantee the types going in or out, so you should probably get going waking through all this logic. You're welcome! -Python <3, XOXOXO"
- waheoo 6y agoWell if a functions first run is in production youve got other problems. The idiot ref would be right.
- bonestormii_ 6y agoIt ran fine with all the file types we tested! A dependency loads the file into a custom type, but it handles this file type differently! Now it's a stinky old NoneType. :( :( :(
- pansa2 6y ago“Compile-time and runtime are less relevant notions than before-shipping and after-shipping” - Rich Hickey https://twitter.com/richhickey/status/1063086406980026370 https://twitter.com/richhickey/status/1063086406980026370
- bonestormii_ 6y agoHehe. But has anyone ever shipped code that won't compile? I think not. A compile time error is a caught error. A run time error may be, or perhaps not.
- logeprog 6y agoThis!
- randomdude402 6y agoYeah Python has its points where it doesn't shine, but the stacktrace does a consistently good job of telling you exactly where the logic broke down.
- bonestormii_ 6y agoI love Python, and generally I agree, but the place where an error is raised can be significantly distant from the event that occurred which caused it. The lack of static typing can really make it difficult to find such bugs sometimes. A statically typed language with compile-time type checking would flag that immediately, and chances are your IDE will show the error before it even gets to that point. Type hints are a thing, but then you are already moving in that direction while remaining in python.
- throwaway894345 6y agoIn Python, it’s entirely idiomatic to take different types of input and do different things. Look at the pandas dataframe constructor or just about anything in the datascience ecosystem (e.g., matplotlib). Look at the open() builtin—the value of the second string argument changes the return value type. Things aren’t much better in JS land where a function might take an arg or a list or a config object, etc. We see dozens of type errors in production every day.
- waheoo 6y agoFor what its worth, the datascience ecosystem is probably the worst place to get general idioms from. They tend to err towards their own domain language and build stuff for people who arent programmers. i.e. for caller flexibility instead of maintainability. Besides that, i only said it was a code smell, i dont debate that its useful sometimes. Just that its a signal to be careful, check you really need itor there is t some other constraint you can break. My only advice is that narrowing your parameter types at the earliest opportunity is a good practice and results in much easier to understand code.
- nyanpasu64 6y agoI kinda wish Python took the Rust approach of having multiple factory static-methods, rather than one constructor that does different things based on what arguments you pass in.
- duckerude 6y agoIt does that sometimes, e.g. the classmethods in https://docs.python.org/3/library/datetime.html https://docs.python.org/3/library/datetime.html . But perhaps not enough.
- throwaway894345 6y agoYeah, it seems not very idiomatic. I regularly see "senior engineers" doing I/O, throwing exceptions, etc in constructors. I staunchly believe a constructor should take exactly one parameter per member variable and set the member variable. For conveniences, make static methods that invoke that constructor. This will make your code far more understandable and testable (you can initialize your object in any state without having to jump through hoops). This is language agnostic advice, but some language communities adhere to it better than others. Python is not very good about this.
- entha_saava 6y agoI just wish people shitting on statically typed languages would remember they came to solve the mess that arose from dynamic typing.
- waheoo 6y agoIm sorry you feel like i was shitting on statically typed languages. I can assure you I do beleive they have their purpose and place in the world where raw performance or closer to metal abstractions can take place. Personally, my brain much prefers to use a dynamic type system to infer what i mean leaving the thinking part up to me. I just find defining a string is a string when im only ever going to put a string in there kind of redundant. There are other arguments about readability, refactorability, and similar and I think they have some weight in large doverse systems with many many teams interacting. Personally, that isnt a large issue for me. Im working at the scope I can maintain a standard and a level of consitency that alleviates these problems to the point the type safety is simply not wareanted from a return on investment point of view. I do not, for instance, think the kernel or chrome should be rewritten in javascript. Despite what some react developers seem to think.
- entha_saava 6y ago> I just find defining a string is a string when im only ever going to put a string in there kind of redundant. There are 2 problems with this kind of thinking. 1) you aren't going to be so sure. Humans are imperfect and as codebase grows, everyone commits such errors. Eg comparing a string to int without converting it to int in python. It always returns false (IIRC) and it is hard to detect where the problem is. 2) Most type systems aren't that verbose. I guess you got the impression from java / mediaeval C++. But most statically typed languages have local variable type inference. OCaml / Haskell / F# / Swift etc.. have varying degrees of type inference. At this point, types in method signatures, in languages that require it, serve as documentation. And many of these languages are terser than python/javascript.
- waheoo 6y agoThanks for taking the time to respond. 1) I work on a typescript codebase for work. There is a real need for types in this case because the definitions are about 3 layers of abstraction away from their use. It drives me up the wall because I know when you keep definitions close to use, or have some basic conventions this problem melts away. At least to the point of diminishing returns where types are no longer relevant. So, i guess over the years ive been caught out by int + string = 0 all of like, 1-2 times in production, maybe a few more while in dev. Either way its rare enough for me to call FUD on the argument. Stop mixing types and this really doesnt happen. To be fair to your point, at work, i know of a recurring error in production where this is almost certainly the same class of error. Nobody can be bothered fixing it because its too hard to track down and the cost benefit isnt there. 2) Type inference is problematic for me. Doesnt it just open you up to type errors of a different class? 2.5) terse code is not the point, I find rust cryptic and dense to say the least. I prefer something like go wgere readability is a priority over density.
- travv0 6y ago> All generics do is bring back the lack of typesafety and all the manual typechecking that comes with muddying generalizing the parameter typeset. I'm not sure if I'm misunderstanding you here, but generics are type safe. They're statically checked at compile-time.
- dragonwriter 6y ago> If you design your functions in a way that that function will never receive an array, you dont have to test for it. And if some idiot tries one day, it should error very loudly that something is wrong. That's naïve. Unless you code extra defensively (which is the same type of overhead as excessive testing, and needs itself to be verified by testing), there's very little guarantee that type errors will result in loud failure consistently at the first point that the bad value is passed (because functions that don't do unnecessary work often pass their arguments along without doing a lot of work dependent on the very specific type.) And, in any case, failing consistently at compile time (or, with a modern code editor, at writing time) with static type checking is better than failing at runtime, even if it is loud and consistent. Of course things like mypy and TypeScript (especially, in the latter case, because it powers tools that work pretty well when the actual immediate source is plain JS, or JS with JSDoc comments from which type information can be extracted, when consuming libraries with TS typings) mean that some popular dynamic languages have static type checking available with more expressive type systems than a number of popular statically-typed languages.