Hacker News new | ask | show | jobs
by didibus 1782 days ago
I believe you're mistaken, but please explain otherwise?

None of those seem to require type information from my reasoning (and are also all available in Emacs for Clojure)

For example, moving a function from one namespace to another, you know where this function is being used from the require declarations, and you know where you've been told to move it too and where it currently resides. So you can simply change the old require pointing to its old namespace to point to the new namespace and cut/paste the function from the old to the new. Nothing requires knowing the type or the arguments or the return value of the function.

See a gif of it in action: https://raw.githubusercontent.com/clojure-emacs/clj-refactor...

1 comments

Sure: https://www.beust.com/weblog/2021/06/20/refactoring-a-dynami...

Even Smalltalk's refactoring browser made mistakes which humans had to fix by hand. Which is not surprising, because in the absence of type annotation, the IDE doesn't have enough knowledge to perform safe refactorings.

That blog is talking about refactoring a method, not a function.

In Clojure, I'm talking about renaming a function, which can be done without types.

See the difference is that with a method:

x.f()

You have to know the type of `x` to find the right `f`, but with a function in Clojure:

    (ns foo
      (:require [a :refer [f]]))

    (f x)
The location of `f` is not dependent on the type of `x`, you known statically that this `f` is inside the namespace `a`, because of the require clause that says that in `foo`, `f` refers to the `f` inside of `a`.

And this is unambiguous in Clojure because there cannot be more than one `f` inside `a`.

If you had two `f` this would be the code in Clojure:

    (ns a)
    (defn f [] "I'm in a")

    (ns b)
    (defn f [] "I'm in b")

    (ns foo
      (:require [a :refer [f]]
                [b :refer [f] 
                   :rename {f bf}]))

    (f x)
    (bf x)
You're forced to rename the other f, and now it's clear statically again that `bf` is the `f` from `b` and `f` is the one from `a`, no need to know the type of `x` for it.