Jaunt – A friendly Clojure fork
arrdem.com
arrdem.com
BUT, there is a more important thing, and there I support the author: instead on pushing Rich (the author of Clojure) to include any shiny feature that someone thinks would be nice, and then complaining that Rich ignores the request, the OP forked Clojure and tries to prove that his ideas are better. I think Rich does quite well on keeping Clojure sane and useful. I have no doubt that he will include stuff that really proves to be better. But, 99% of stuff is better only while is on scratchpad, but turns out either irrelevant, or, even worse, outright horrible in practice.
That's why I think that everything that can be a library should be a library instead a part of clojure.core. Those things that could not be libraries (not many of those come to my mind) should first be proven in some sort of "experimental" clojure. clojure.core should stay as it is :)
Re-running an entire test suite every time I make a tiny change to the code isn't viable.
> cider reloading
If only it didn't take forever! I really like Clojure the language, but having to restart CIDER every time I want to make the REPL forget my old wrong definitions is killing me. Not resetting the REPL's state is also pretty bad: I might accidentally use an old definition that was supposed to be discarded. The difference in behavior between macros and normal code exacerbates this problem: when you redefine a function, all existing uses of the function now point to the new version; but when you redefine a macro, all existing code that was generated by macro expansion retains its old form. So reasoning about the effects of the old definitions still being there can get quite complicated. There ought to be some way to tell the REPL, in a single instruction: “Please forget that previous versions of my code ever existed. They're all wrong.”
> Because namespaces are mutable, even if I were to perform a rename correctly, the old name is still present in the namespace.
First, ns-unmap your old name (a refactoring tool should do that for your, I guess). (edit: Clojure is a Lisp-1).
> What if we gave Namespaces and Vars version numbers? When a Namespace is re-defined (the ns form is evaluated) then the Namespace's version is incremented. When a def is evaluated, the version of the Var bound by the def is set to be the version of the Namespace in which that Var exists.
Your environment could keep track of definitions and usages of your symbols (see for example slime-who-calls, etc.). That would be a good improvement for Clojure.
There is another problem: define namespace N, define variable N/x, using it in another namespace M, remove namspace N. Then, an old name x is referenced from M which does not exist in any namespace. Also, you redefine namespace N with a new x, and now old-x and new-x are different objects. I don't think version numbers would help you here.
I am just thinking aloud, but when remove-ns is called, you could re-parent orphaned names from that package to a global "orphans" table. When you intern a symbol in a namespace, first you try to see if you can recycle objects from "oprhans" based on their fully qualified name. So that new-x and old-x are in fact the same name object. Or, you just use a global map to store fully qualified names in the first place. Maybe the metadata attached to orphaned symbols should be cleared in this approach, to avoid keeping irrelevant data about a name when it is reused.
But again, you should be careful when you rename namespaces. Maybe the best answer is to simply be aware of the possible pitfalls.
If nothing else, it's a pretty interesting idea.
clj-refactor has a cljr-rename-symbol function.
https://github.com/clojure-emacs/clj-refactor.el
Here's a full list of its features:
Clojure developement is driven by the needs of Rich/Datomic these days, it's understandable this might be frustating for users who wish clojure was more community driven, and exploring other areas.
I personally gave up on it because of this (I used to do clojure full time).
They stay in business by selling the cure to the poisonous snake oil they sell.
No ill-will directed at the OP, but it's hard not to take umbrage at the suggestion that I am a snake-oil salesman. So yes, references please!
I think this particular example supports this "Cognitect snake oil" theory very poorly. I don't think PersistentQueue can be properly considered a first-class data structure in Clojure, as it doesn't even have a constructor function in clojure.core. The Clojure documentation, and the other writings of Rich Hickey and Cognitect don't encourage people to use this data structure. It exists, I think, for completeness and because there are some situations where it's appropriate, but unlike the core Clojure persistent data structures - maps, vectors, seqs, etc. - it's not designed as a general abstraction that covers the vast majority of general use cases.
Clojure is meant to be a practical language. It's hosted on the JVM and other platforms, and designed to make it is easy to use what those platforms provide. Where it's sensible to do so, Cognitect and other Clojure developers would certainly advocate using Java libraries to solve problems.
The other thing mentioned in the GP post was the idea of not using STM. This falls under the same umbrella. There are problems for which STM is the best solution, but there's a big space where something simpler is the right answer. In my observation, overuse of Clojure's STM is far more often the result of a developer impulse of "wow this is a cool looking feature, I want to try it" than any advocacy by Rich or Cognitect.
I also have some firsthand knowledge here, having been involved in a Cognitect engagement. I have some concerns about Cognitect as a result, but certainly nothing like this suggestion that Clojure is a real manifestation of the old fake Bjarne Stroustrup interview. [1]
The first is that I've actively used Clojure on a number of (small) projects, and tend not to have had significant performance issues with the persistent data structures. Where I have run into issues is around laziness, but that's probably a design issue more than anything else. (http://www.ksmpartners.com/2014/01/clojure-lazy-seq-and-the-...)
Having said that, I do find it very easy to believe that the persistent data structures cause performance problems. A few months ago, I was working on a small search program using ES6 and ImmutableJS. Removing ImmutableJS (and retaining the same number of object copies in my replacement code) resulted in something like a 100-fold increase in performance (making my program fit for the intended purpose.)
I need to do a bit more analysis, but my general thought on the reason why this happened is that the the data structures I was managing were too small for the structure sharing to offer any real benefit. The net result being that the negative performance impact caused by the more complex underlying data structure and API access just swamped whatever gains there were in the faster copying. Of course, for this to become favorable for the persistent data structure, the size of the data would need to be considerably larger. I don't know how common a use case that really is.
I agree, if it was more community oriented there would probably lots of cool ideas, exploring lots of other areas, but, for me, that's what other languages are for. And for what it's worth, they don't solve real world problems as well as clojure does.
I do wish Cognitect was more engaged with the community at large, but they've been solid stewards in my opinion, and all the features that have come since I started with clojure (1.6) have been extremely useful in real-world situations and has made my job easier and more enjoyable.
I'm happy to make that tradeoff.
That said, I have to second the other opinions in this thread, namely, that Jaunt is solving a problem in Clojure that already has other solutions. When I'm writing Clojure for work (I use it full time), I use Cider, and I often make use of C-c u, which is cider-unset, allowing me to make sure I remove a var from a namespace. That plus cider-reload gives me assurance that my namespace mutations are pretty reliable.