How to reload namespace into repl after error? - clojure

During development, I often require a namespace and then discover that the source file has an error that prevents it from being compiled:
(require '[foo.bar :as fb])
CompilerException java.lang.RuntimeException: ...
After I fix the error, I try to require the namespace again, but I can't:
(require '[foo.bar :as fb])
CompilerException java.lang.Exception: namespace 'foo.bar' not found, compiling: ...
My solution has been to kill the repl and run lein repl again, but that's obviously not ideal.
Is there a way to clean up the effects of the previous failed require?
(And why is the error "namespace ... not found"? That doesn't make sense to me. The source file is still there, and Clojure was able to find it a minute earlier--that's how I knew about the error.)

require takes an optional :reload argument that forces reloading of changes, even if require has already been run.
(require '[foo.bar :as foo] :reload)
This is useful when there was an error upon the initial loading of the namespace, or if you just want to load a newer version of the namespace.
There is also :reload-all for loading all the recursive required code of that namespace as well.

Related

how to get meaningful dependency errors in clojure?

If I add the following require:
(ns project.core
(:require
[compojure.route :as route])
(:gen-class))
(defn -main [& {:as args}]
(println "hello"))
an do
lein run
I get
Syntax error macroexpanding clojure.core/ns at (ring/util/mime_type.clj:1:1).
((require [clojure.string :as str])) - failed: Extra input spec: :clojure.core.specs.alpha/ns-form
is there a way I can get
"compojure.route not found; not defined; or whatever" e.g. something meaningful?
if I remove it it works fine. e.g. it says Hello
using Leiningen 2.9.4 on Java 14.0.1 OpenJDK 64-Bit Server VM
The project you are using is using very old dependencies. Clojure spec (introduced "recenlty") added macro/compile time checks and the mentioned file there triggers it.
compojure.route actually is found and it then requires its transitive deps. And while going down the chain ring.util.mime-type is required and the version you are using is not ready for current Clojure versions.
Your best bet here is to upgrade your deps. E.g. if you are following a book or if you are using a template this things can happen. If you have lein-ancient installed, it can attempt the update for you. Otherwise your best bet is to start in your project.clj and compare versions (e.g. check clojars).
If the problem still persists, have a look at lein deps :tree and see what is going on with the transtive deps.

Can't get browser repl to work from chestnut template (figwheel, weasel)

I try to get started with ClojureScript using the chestnut leiningen template which combines piggyback, figwheel and weasel. After upgrading my leiningen installation to 2.5.0, I can start the clojure repl, but after issuing the recommended run and browser-repl commands, I run into a cryptic error. There seems to be a core.async issue as well, which I don't know whether it's related.
chestnut-borked.server=> (run)
2014-10-07 12:38:06.506:INFO:oejs.Server:jetty-7.6.13.v20130916
2014-10-07 12:38:06.545:INFO:oejs.AbstractConnector:Started SelectChannelConnector#0.0.0.0:10555
Starting figwheel.
Starting web server on port 10555 .
#<Server org.eclipse.jetty.server.Server#6cdd377c>
Compiling ClojureScript.
Figwheel: Starting server at http://localhost:3449
Figwheel: Serving files from '(dev-resources|resources)/public'
Compiling "resources/public/js/app.js" from ["src/cljs"]...
WARNING: Use of undeclared Var cljs.core.async/do-alts at line 62 file:/home/schauer /.m2/repository/org/clojure/core.async/0.1.278.0-76b25b-alpha/core.async-0.1.278.0-76b25b-alpha.jar!/cljs/core/async/impl/ioc_helpers.cljs
WARNING: Bad method signature in protocol implementation impl/Handler lock-id at line 214 file:/home/schauer/.m2/repository/org/clojure/core.async/0.1.278.0-76b25b-alpha/core.async-0.1.278.0-76b25b-alpha.jar!/cljs/core/async.cljs
WARNING: Use of undeclared Var cljs.core.async.impl.protocols/lock-id at line 217 file:/home/schauer/.m2/repository/org/clojure/core.async/0.1.278.0-76b25b-alpha/core.async-0.1.278.0-76b25b-alpha.jar!/cljs/core/async.cljs
WARNING: Use of undeclared Var chestnut-borked.dev/put! at line 14 src/cljs/chestnut_borked/dev.cljs
[... some warnings removed after first answer ...]
WARNING: Bad method signature in protocol implementation impl/Handler lock-id at line 214 resources/public/js/out/cljs/core/async.cljs
WARNING: Use of undeclared Var cljs.core.async.impl.protocols/lock-id at line 217 resources/public/js/out/cljs/core/async.cljs
Successfully compiled "resources/public/js/app.js" in 21.377 seconds.
notifying browser that file changed: /js/app.js
notifying browser that file changed: /js/out/goog/deps.js
notifying browser that file changed: /js/out/chestnut_borked/core.js
notifying browser that file changed: /js/out/chestnut_borked/dev.js
Besides from the warnings, so far, so good -- Jetty seems to have started successfully. However, when I try to start the browser-repl, I run into an error and the connection seems to be broken:
chestnut-borked.server=> (browser-repl)
WARNING: Bad method signature in protocol implementation impl/Handler lock-id at line 214 file:/home/schauer/.m2/repository/org/clojure/core.async/0.1.278.0-76b25b-alpha/core.async-0.1.278.0-76b25b-alpha.jar!/cljs/core/async.cljs
ArityException Wrong number of args (0) passed to: compiler/with-core-cljs clojure.lang.AFn.throwArity (AFn.java:429)
chestnut-borked.server=> (browser-repl)
java.io.IOException: No client connected to Websocket
at weasel.repl.server$send_BANG_.invoke(server.clj:25)
at weasel.repl.websocket$send_for_eval_BANG_.invoke(websocket.clj:130)
at weasel.repl.websocket$websocket_eval.invoke(websocket.clj:109)
at weasel.repl.websocket.WebsocketEnv._evaluate(websocket.clj:34)
at cljs.repl$evaluate_form.invoke(repl.clj:113)
at cemerick.piggieback$cljs_eval$fn__5152.invoke(piggieback.clj:115)
at clojure.lang.AFn.applyToHelper(AFn.java:152)
at clojure.lang.AFn.applyTo(AFn.java:144)
[...]
UPDATE: After the input from lnmx, it's becoming clear that weasel isn't functioning properly. If I take a look at the JS elements that the browser sees, the dev script apparently doesn't get loaded and neither is the repl.js from weasel, although there are goog.addDependency calls for them in app.js.
Chestnut 0.5.0 has been released now. It contains an updated ClojureScript which should fix the issue with Weasel (the browser-connected REPL), as well as several other improvements.
I had some success with chestnut 0.5.0, but some changes were needed. I am new to Clojure so I may be missing something -- anyway, here's what I found:
It looks like the README file for chestnut describes the usage of version 0.5.0, but that version is not available on clojars as of today.
So, per the README, I installed from a local copy:
git clone https://github.com/plexus/chestnut.git
cd chestnut
lein install
...and created a new project:
lein new chestnut tree
Attempting to compile the cljs with lein cljsbuild once produced the Bad method signature warning related to lock-id. So, I started by adding the latest core.async to project.clj under :dependencies
[org.clojure/core.async "0.1.346.0-17112a-alpha"]
Then there were some errors related to undefined core.async functions, so I fixed the requires in src/cljs/tree/core.cljs:
(ns tree.core
(:require [tree.dev :refer [is-dev?]]
[cljs.core.async :refer [chan <!]]
[om.core :as om :include-macros true]
[om.dom :as dom :include-macros true])
(:require-macros [cljs.core.async.macros :refer [go alt!]]))
and src/cljs/tree/dev.cljs:
(ns tree.dev
(:require [figwheel.client :as figwheel :include-macros true]
[cljs.core.async :refer [put!]]
[weasel.repl :as weasel]))
The next issue is that tree.dev needs a reference to the re-render-ch owned by tree.core. So I wrapped the "dev mode" setup into a function called from tree.core (src/cljs/tree/core.cljs):
(defonce re-render-ch (chan))
(when is-dev?
(tree.dev/setup re-render-ch))
...and implemented in tree.dev (src/cljs/tree/dev.cljs):
(def is-dev? (.contains (.. js/document -body -classList) "is-dev"))
(defn setup [re-render-ch]
(when is-dev?
(enable-console-print!)
(figwheel/watch-and-reload
:websocket-url "ws://localhost:3449/figwheel-ws"
:jsload-callback (fn []
(println "reloaded")
(put! re-render-ch true)))
(weasel/connect "ws://localhost:9001" :verbose true)))
With those changes, I can start lein repl, (run) and (browser-repl) OK.
During (run) I get this error:
ArityException Wrong number of args (0) passed to: compiler/with-core-cljs
(not sure where this is coming from). However, if I edit tree/src/cljs/tree/core.cljs and add
(reset! app-state {:text "Hello There?"})
the change is compiled automatically and shows up in the browser shortly after I save the file.
Per the comment, this still doesn't fix the browser-repl. For that I had to get a local copy of weasel, and hack src/clj/weasel/repl/websocket.clj ~line 88:
- (cmp/with-core-cljs)
+ (cmp/with-core-cljs {} (fn [] (println "foo")))
It seems to be related to an API change in the cljs compiler. With that, I can (browser-repl) without any warnings, and (do (js/alert "Hello world!") 42) produces an alert in the browser.

lein repl fails: "No such var user/help"

I experience the following error:
CompilerException java.lang.RuntimeException: No such var: user/help, compiling:(/private/var/folders/xy/8l2mmnsj0gv3myj72y0s2kmr0000gn/T/form-init6632573911186472967.clj:1:10884)
#<Namespace user>
Error loading namespace; falling back to user
This only happens in this one project. The project happily compiles to uberjar, and lein run works just fine, it's only the repl that doesn't work.
Anyone have any idea what this could be about?
The entire project is available at https://github.com/Skinney/coc-helper
I stumbled upon this question because I had the same problem. I have opened an issue for that problem, with minimal reproducing project and workaround, on the Leiningen github project.
Since the OP has apparently already solved the problem, here is the TL;DR for anyone else arriving here: the problem is that you require :as user in the main namespace. Changing the alias solves the problem, as the OP has done in this commit.

clojure namespaces .core file and repl

A beginners question.
running clojure using lein + emacs + nrepl.
I am slightly confused about the following:
I wish to use the exponent function. This function lives in the following place clojure.math.numeric-tower. I add [org.clojure/math.numeric-tower "0.0.1"] to the dependencies and run lein deps.
Now is it possible (I'm sure it is possible) to add this to my .core ns as follows:
(ns learning.core
(:require [clojure.math.numeric-tower :as math]))
(def i-know-the-answer
(math/expt 2 10))
now when I try to load (ctl-x e) this into the REPL, it throws errors.
clojure.lang.Compiler$CompilerException: java.lang.RuntimeException: No such namespace: math, compiling:(NO_SOURCE_PATH:2)
do the dependencies need to be loaded into the REPL directly? Can I not just change the source file / recompile it and use that?
Load the file with ctrl-c ctrl-l then Switch your repl to the namespace in that file with either
(in-ns 'learning.core)
Or hit ctrl-c alt-n from the Clojure buffer to switch the repl to the buffer's namespace. You can tell if it worked by looking at the prompt in the repl.

Getting slime to find files on classpath, and contrib

I recently decided to start using Slime/Swank for writing Clojure. I installed Incanter, Clojure, Slime and Swank yesterday by following this blogpost to the letter, which worked fine. However, I'm experiencing a problem getting Slime to find directories and files on the classpath. I'm running Slime using lein swank and slime-connect in Aquamacs on OS X 10.6. I have two questions:
1) I set up a small project to build a game of life simulation. I have a file called grid.clj from doing this earlier, which I put in the project's lib directory. In core.clj I put the following
(ns gof.core
(:require grid))
(def w (grid.make_grid 8))
Doing C-x C-e after this piece of code gives this error message in the repl:
Could not locate grid__init.class or grid.clj on classpath:
[Thrown class java.io.FileNotFoundException]
so I looked at my classpath using
(doseq [p (.getURLs (java.lang.ClassLoader/getSystemClassLoader))] (println (.getPath p)))
which produced this:
/Users/zjanes/Documents/gof/test/
/Users/zjanes/Documents/gof/test-resources
/Users/zjanes/Documents/gof/src/
/Users/zjanes/Documents/gof/classes/
/Users/zjanes/Documents/gof/resources
/Users/zjanes/Documents/gof/lib/clojure-1.3.0.jar
/Users/zjanes/Documents/gof/lib/grid.clj
/Users/zjanes/.lein/plugins/swank-clojure-1.3.4.jar
nil
user>
It seems to me that grid.clj is on this classpath, so why am I getting the error message?
2) In trying to solve this I had a look at clojure-1.3.0.jar and couldn't find anything that looks like it comes from clojure.contrib. Is contrib not included when installing clojure as described above?
I'm sure it's obvious I'm a complete novice with clojure, so the clearer the answer, and the less presumed knowledge, the better.
For completeness, I've looked at these answers (1 2 3) and this page, plus some googling around.
Thanks in advance
that tutorial is from 2009 and as far as I can tell it can't be made to work using those instructions.
Clojure contrib has been split up into many sub projects in clojure 1.3 so it no longer exits under that name.
in general clojure namespaces now have two parts, for instance:
(ns gof.core
(:require [incanter.grid])