Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> You are basically not writing Python code at all.

I really dislike this take. I believe Python is about rapid iteration, doing more of functionality with less code, and enjoying the process of programming. You know what I enjoy? Easily knowing what features (methods, attributes, keys) an object has. You know what I really don't enjoy? Having to dig through reams of source code to figure out what attributes I can use, or what *kwargs a function takes.

Nothing about duck typing prohibits saying `def func(duck: Duck)`, because maybe it's a French duck and has .coin() instead of .quack().

Also also, how is static typing completely incompatible with dynamic features? Usually there exists an abstraction with static types that actually captures the behavior you want. Its rare you want to be able to handle literally anything. Ask oneself, "could this function receive absolutely, truly, anything, or is it just shortcut for not finding the right types?"



You might dislike the take, but it's correct. If I write a side-effect free Python program in Haskell style, that isn't a "real" Python program. Using a static type checker is a similar type of change to the code style.

"Having to dig through reams of source code to figure out what attributes I can use, or what *kwargs a function takes."

Figuring out the attributes and what kwargs a function takes is the role of your intelligent IDE and docstrings. You think you need to static typing for this since you haven't spent the time to learn how Python does these things.

Duck typing says, duck doesn't have a type, not even Duck, anything that quacks is a duck even a 115 ton truck.


> You think you need to static typing for this since you haven't spent the time to learn how Python does these things.

I've been writing python for over 15 years and use Pycharm extensively. Please don't make assumptions about other users' experiences without evidence.

IDEs absolutely do not infer what fields *kwargs take, let alone what types those fields are. I'm not talking named fields, I mean literally

    def func(*args, **kwargs): ...

Afaict, no IDE and no type system can help you there, in python, save for some really arcane type inference magic on every single call site.

> duck doesn't have a type, not even Duck

It absolutely does, if Duck is a protocol. If you have some object, and you call .quack(), it implements the Quacker interface, even without inheriting BaseDuck. You can still statically type it no problem, and it'll take a Truck no problem, so long as Truck.quack() is defined. Almost everything has a type, it just takes some effort to uncover it.


That's an IDE problem, with sufficently powerful code inspection, the fields can still be found. It is not the developers' job to manually add that type of information into their source code.

Ahh so if a method on an object dynamically adds in the quack() method at runtime, does the object spontaneously change type?


> Ahh so if a method on an object dynamically adds in the quack() method at runtime, does the object spontaneously change type?

Yes, actually.

This is an antipattern in the vast majority of use cases. There are far better patterns out there than just sticking a method on an object, and I detest codebases that do this sort of thing. It's almost always someone who uses the phrase "pythonic" unironically way too much, writing these sorts of things, and a nightmare to debug.

There's less problem with doing something like

    def quackerizer(foo: Any) -> Quacker:
        foo.quack = lambda...
        return foo

Still kinda odd, but at least you are doing a formal cast.

> That's an IDE problem, with sufficently powerful code inspection, the fields can still be found.

Ok, name one. Pycharm and vscode don't currently do it afaik. Maybe some vscode plugin, haven't used vscode much.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: