Hacker News new | ask | show | jobs
by winteriscomming 5001 days ago
Go to function definition, refacor/rename, find references, view object / class hierarchy, and so on. Why not have all this work 100% of the time?

Tooling makes your life so much easier. I don't understand why people would resist optional typing.

1 comments

I'm not saying that tooling isn't nice. On the contrary. I'm asking why can't we have tooling even with dynamic types.
Think about this pseudocode; imagine it's The Hot New Dynamic Language Of The Week.

  print "Which do you like better: cars or trees?
  let a = AskUserForInput()
  var b
  if a=="cars" then
   b = new Car()
  elseif a=="trees" then
   b = new Tree()
  endif
  b.DriveOnExpressway()
Clearly, that's not going to work out too well if the user picks "trees" but it's tough to spot before run time.

While that's a contrived and simplistic example (that you probably could somewhat easily detect with tooling/analysis) think about a language like Javascript where there are no classes and you may be adding or modifying a bunch of an object's methods at runtime. At coding time, the tooling doesn't even know if foo has a .bar() function, much less which .bar() function, much less if the particular .bar() function that foo may have is being called with acceptable parameters.

edit: even my pseudocode is buggy ;-)

I was curious what PyCharm would handle that. Here's a screenshot: http://imgur.com/IvwG5

Basically it will complain if neither Car or Tree have a DriveOnExpressway method, but it's fine if one of them does -- the warning goes away if I uncomment the method. So there's ways to fall through the safety net, but lots of things it will catch.

(In Javascript, it's looser -- it only flags a potential problem if "DriveOnExpressway" isn't defined at all in the file.)

Ok, if I understand you right, your point is that a tool like a linter will fail to warn about this error. I'm not sure what current (say) Python linters do in situations like that.

But a tool like "go to definition" would work fine, wouldn't it? Maybe you would need a heuristic that guesses what are the possible types b could have, and detects that Tree doesn't have DriveOnExpressway, so it takes you straight to the definition in Car. Certainly, there are more complicated cases where guessing b's type is harder or impossible. I'm not denying that.

Because there is no type. It's dynamic. You can't figure out what the type is unless you run the code.

def do_something(thing_a, thing_b): ...

What's the type of thing_a or thing_b?

There is none. There isn't even a type globally. thing_a and thing_b acquire new types at every call instance. This basically screws you for all useful auto-complete information.

You can't even do proper go-to-definition because of things like getattr.

Yes, there most certainly is a type. It's dynamic, but not nonexistent. Now, of course you don't know the type for sure unless you run the code. I said so at the start. But I'm saying, can't you do a pretty good job in most cases? In this case, you could go to all places where do_something is called and see what objects are being passed in.

Yes, maybe there are situations where dozens of different types are passed in by different calls, or where we're building a library and we don't have any calls to do_something in our codebase, and cases where everything is obfuscated by one means or another. But depending on style I bet there are lots of cases where it works out ok.

It is just much more difficult to have tooling since the tools cannot know for sure what the program is doing (and neither can another human looking at it).
To be more specific you have to use some crazy static analysis technology (global interprocedural analysis) that is intractable unless you sacrifice accuracy. Human have similar problems as compilers/tooling, though they are a bit better at understanding nuanced conventions to make better judgements about what dynamic code is doing.
Yes, of course, we sacrifice accuracy. I said so at the very start. But imagine a "go to definition" tool that works correctly for 99% of cases and barfs or goes to the wrong place on the others. If the alternative is no tool at all, that still sounds pretty useful!

I admit there are cases (refactoring is an example) where if you don't trust the tool 100% you won't use it. But many tools are not like that.

Well, you'd be without feedback alot, state of the art in type recovery is nowhere near 99%. Your libraries can exploit the flexibiliy of a dynamic language (meta programming, crazy unions) and make the job much harder. Typescript seems very interesting in the way they handle type retrofits on libraries, but I haven't really absorbed it yet.