top | item 27961622

(no title)

galimaufry | 4 years ago

One thing that I miss coming from python to Julia, is typing-as-documentation. In python I often write type annotations that are much more restrictive than they need to be. They work as checkable documentation of how a function is expected to be used (and under what circumstances do I guarantee it will work), without restricting how it can be used.

discuss

order

gugagore|4 years ago

I think this is a real conflict. In my opinion (not just mine), the only reason to write type constraints on a method definition in Julia is to control dispatch. Adding types to method arguments for the purposes of documentation is counterproductive to generic programming.

ChrisFoster|4 years ago

I used to think this was true (as a developer of a lot of generic Julia code and small data analysis applications).

But now as a developer of larger amounts of "application style" code, I'm not so sure. In an application, you've got control of the whole stack of libraries and a fairly precise knowledge of which types will flow through the more "business logic" parts of the system. Moreover, you'd really like static type checking to discover bugs early and this is starting to be possible with the likes of the amazing JET.jl. However, in the presence of a lot of duck typing and dynamic dispatch I expect static type inference to fail in important cases.

Static type checking brings so much value for larger scale application work that I'm expecting precise type constraints to become popular for this kind of non-generic code as the tooling matures.

galimaufry|4 years ago

You're not wrong. I guess what I'd like is the ability to apply (up to) two type annotations, with the second one a subtype of the first, and use the first for dispatch and the second for documentation/testing/static analysis...

... which actually seems like it might be doable with some macros? Those are beyond my ken right now, but the goal would be

  @doubly_typed f(x::Number|Integer) = x
  f(6.0)            # Same as g(x::Number) = x; g(6.0)
  @strictify f(6.0) # Same as g(x::Integer) = x; g(6.0)
Then you would use @strictify when running tests to ensure that the stricter types in your codebase are all compatible. But you'd still need to figure out what to do about return types and the help command...