Consider this test:
(deftest test
(is (= false (nil? (do
(def sym 0)
(resolve 'sym))))))
Put it into a repl and it will pass. Put it instead in a file and now it wont. How so ?
I tried messing with namespaces but without success.
I stumbled upon this question but it doesn't help me.
Related
I'm currently using Leiningen to learn Clojure and I'm confused about the requirement of doall for running this function:
;; take a function (for my purposes, println for output formatting) and repeat it n times
(defn repeat [f n] (for [i (range n)] (f)))
(repeat println 2) works just fine in an REPL session, but not when running with lein run unless I include the doall wrapper. (doall (repeat println 2)) works and I'm curious why. Without it, lein run doesn't show the two blank lines in the output.
I also have:
(defmacro newPrint1 [& args] `'(println ~args))
(defmacro newPrint2 [& args] `'(println ~#args))
The first function I thought of myself. The next two macros are examples from a tutorial video I'm following on Udemy. Even if I wrap the macro calls with doall, such as (doall (newPrint1 1 2 3)), lein run produces no output, but (newPrint1 1 2 3) in a terminal REPL session produces the desired output of (clojure.core/println (1 2 3)) as it does in the video tutorial. Why doesn't doall work here?
for creates a lazy sequence. This lazy sequence is returned. The P in REPL (read eval Print loop) prints the sequence, thus realizing it. For realizing, the code to produce each element is run.
If you do not use the sequence, it is not realized, so the code is never run. In non-interactive use, this is likely the case. As noted, doall forces realization.
If you want to do side-effects, doseq is often better suited than for.
What is the proper way to use macroexpand-1 for testing Clojure macros when not working at the REPL?
The problem is that your expressions outside of the deftest are being run at compile time, while *ns* is bound, and inside of a deftest they are being run later, at runtime, where *ns* is not bound.
Why does this matter? Because macroexpand needs to resolve the symbol iiinc in the current namespace in order to decide if it's a macro or not, and to find its definition if it is a macro, in order to call it. So, you see your macroexpand working at compile time but not at runtime.
What is the solution? Surely not to run your tests at compile time! Instead, you should properly namespace-qualify your forms, so that they do not depend on the compile-time convenience of *ns*. You could do this by hand, by writing
(deftest t-stuff
(println "(macroexpand-1 '(my.ns/iiinc 2)) =>" (macroexpand-1 '(my.ns/iiinc 2)))))
However, the right solution is to do what you should always do when quoting forms that are intended for later evaluation, just as when you write a macro: use syntax-quote, not regular quote. This way the compiler figures out the intended namespace for you at compile time, and inserts it in the form so that it's still there at runtime:
(deftest t-stuff
(println "(macroexpand-1 `(iiinc 2)) =>" (macroexpand-1 `(iiinc 2)))))
Suppose we want to test a macro that adds 3 to any value:
(defmacro iiinc [x]
`(+ 3 ~x))
Rather than working at the REPL, I usually prefer to use my favorite text editor/IDE to develop code, and use the lein test-refresh plugin to continually run my unit tests. However, this doesn't work when trying to use macroexpand-1 to iteratively develop a new macro.
The problem seems to be some conflict between macroexpand-1 and the deftest macro. So, the solution is to avoid using macroexpand-1 inside of a (deftest ...) form. However, it works great outside of deftest, even if it is still in the unit test source file. Here's an example:
; source file tst.clj.core
(newline)
(println "This works when not in (deftest ...)")
(println "(macroexpand-1 '(iiinc 2)) =>" (macroexpand-1 '(iiinc 2)))
(deftest t-stuff
(newline)
(println "But it is broken inside (deftest ...)")
(println "(macroexpand-1 '(iiinc 2)) =>" (macroexpand-1 '(iiinc 2)))
(newline)
(println "However, we can use the macro itself fine in our tests")
(println " (iiinc 2) =>" (iiinc 2))
(is (= 5 (iiinc 2)))) ; unit test works fine
The results of the above are:
This works when not in (deftest ...)
(macroexpand-1 '(iiinc 2)) => (clojure.core/+ 3 2)
Testing tst.clj.core
But it is broken inside (deftest ...)
(macroexpand-1 '(iiinc 2)) => (iiinc 2)
However, we can use the macro itself fine in our tests
(iiinc 2) => 5
Ran 1 tests containing 1 assertions.
0 failures, 0 errors.
Postscript
Please see the following answer for a
more complete discussion of how to write a macro in Clojure:
How do I write a Clojure threading macro?
I am a beginner in clojure. I am trying to solve this simple problem on codechef using clojure. Below is my clojure code but this code is taking too long to run and gives TimeoutException. Can someone please help me to optimize this code and make it run faster.
(defn checkCase [str]
(let [len (count str)]
(and (> len 1) (re-matches #"[A-Z]+" str))))
(println (count (filter checkCase (.split (read-line) " "))))
Note: My program is not getting timedout due to input error. On codechef input is handled automatically (probably through input redirection. Please read the question for more details)
Thank you!
Most text finding exercises are exercizes in regexps, this one no different. It's usually pretty hard to find a more efficient way in whatever programming language that will outpace good regexp implementations.
In this case re-seq, look around regexps, repetition limiting and the multiline regexp flag (?m) are your friends
(defn find-acronyms
[s]
(re-seq #"(?m)(?<=\W|^)[A-Z]+(?=\W|$)" s))
(find-acronyms "I like coding and will participate in IOI Then there is ICPC")
=> ("IOI" "ICPC")
Let's dissect the regex:
(?m) The multiline flag: lets you match your regex over multiple lines, so no need to split into multiple strings
(?<=\W|^) The match should follow a non-word character or the beginning of the (multiline) string
[A-Z]{2,} Match concurrent capital letters, a minimum of 2
(?=\W|$) The match should be followed by a non-word character or the end of the (multiline) string
I can only guess that wherever you run this snippet of code, it doesn't feed anything to your read-line invocation. Or maybe it does, but doesn't send a newline as the last thing. So it hangs waiting.
(defn checkCase [str]
(let [len (count str)]
(and (> len 1) (re-matches #"[A-Z]+" str))))
(defn answer [str]
(println (count (filter checkCase (.split str " ")))))
So at the REPL:
=> (answer "GGG fff TTT")
;-> 2
;-> nil
The answer is being printed to the screen. But probably best to have your function return the answer rather than print it out:
(defn answer [str]
(count (filter checkCase (.split str " "))))
All I have done is replaced your (read-line) with an argument. (read-line) is expecting input from stdin and waiting for it forever - or until a timeout happens in your case.
I am not sure if this is the slow part of your code, but if it is your could try to split up the execution and safe gard the very slow regexp part by executing it when it is necessary. I think the current version with AND already does that. If it does not you can try to do something else, like this:
(defn checkCase [^String str]
(cond
(< (.length str) 2)
false
(re-matches #"[A-Z]+" str)
true
:else
false))
maybe you could try using re-seq instead of spltting the string and checking every item? So you will lose the filter, .split, and additional function call. Something like this:
(println (count (re-seq #"\b[A-Z]{2,}?\b" (read-line))))
You need to submit a Java program. You can test it on the command line before you submit it. You can but don't need to use redirection symbols (<,>). Just type the input and see that every time you do it returns the count after you have typed enter.
You will need aot compilation (Ahead Of Time, which means that .class files are included) and a main that is exported. Only then will it become a Java program.
Actually when they ask for a Java program they probably mean a .class file. You can run a .class file with the java program (which I imagine is what their test-runner does). Put it in a shell or batch file when testing, but just submit the .class file.
Background
I've written a hack for Emacs that lets me send a Clojure form from an editor buffer to a REPL buffer. It's working fine, except that if the two buffers are in different namespaces the copied text doesn't usually make sense, or, worse, it might make sense but have a different meaning to that in the editor buffer.
I want to transform the text so that it makes sense in the REPL buffer.
A Solution in Common Lisp
In Common Lisp, I could do this using the following function:
;; Common Lisp
(defun translate-text-between-packages (text from-package to-package)
(let* ((*package* from-package)
(form (read-from-string text))
(*package* to-package))
(with-output-to-string (*standard-output*)
(pprint form))))
And a sample use:
;; Common Lisp
(make-package 'editor-package)
(make-package 'repl-package)
(defvar repl-package::a)
(translate-text-between-packages "(+ repl-package::a b)"
(find-package 'editor-package)
(find-package 'repl-package))
;; => "(+ A EDITOR-PACKAGE::B)"
The package name qualifications in the input string and the output string are different—exactly what's needed to solve the problem of copying and pasting text between packages.
(BTW, there's stuff about how to run the translation code in the Common Lisp process and move stuff between the Emacs world and the Common Lisp world, but I'm ok with that and I don't particularly want to get into it here.)
A Non-Solution in Clojure
Here's a direct translation into Clojure:
;; Clojure
(defn translate-text-between-namespaces [text from-ns to-ns]
(let [*ns* from-ns
form (read-string text)
*ns* to-ns]
(with-out-str
(clojure.pprint/pprint form))))
And a sample use:
;; Clojure
(create-ns 'editor-ns)
(create-ns 'repl-ns)
(translate-text-between-namespaces "(+ repl-ns/a b)"
(find-ns 'editor-ns)
(find-ns 'repl-ns))
;; => "(+ repl-ns/a b)"
So the translation function in Clojure has done nothing. That's because symbols and packages/namespaces in Common Lisp and Clojure work differently.
In Common Lisp symbols belong to a package and the determination of a symbol's package happens at read time.
In Clojure, for good reasons, symbols do not belong to a namespace and the determination of a symbol's namespace happens at evaluation time.
Can This Be Done in Clojure?
So, finally, my question: Can I convert Clojure code from one namespace to another?
I don't understand your use case, but here is a way to transform symbols from one namespace to another.
(require 'clojure.walk 'clojure.pprint)
(defn ns-trans-form [ns1 ns2 form]
(clojure.walk/prewalk
(fn [f] (if ((every-pred symbol? #(= (namespace %) ns1)) f)
(symbol ns2 (name f))
f))
form))
(defn ns-trans-text [ns1 ns2 text]
(with-out-str
(->> text
read-string
(ns-trans-form ns1 ns2)
clojure.pprint/pprint)))
(print (ns-trans-text "editor-ns" "repl-ns" "(+ editor-ns/a b)" ))
;=> (+ repl-ns/a b)
So, editor-ns/a was transformed to repl-ns/a.
(Answering my own question...)
Given that it's not easy to refer to a namespace's non-public vars from outside the namespace, there's no simple way to do this.
Perhaps a hack is possible, based on the idea at http://christophermaier.name/blog/2011/04/30/not-so-private-clojure-functions. That would involve walking the form and creating new symbols that resolve to new vars that have the same value as vars referred to in the original form. Perhaps I'll investigate this further sometime, but not right now.
I'm learning Clojure and as an exercise I wanted to write something like the unix "comm" command.
To do this, I read the contents of each file into a set, then use difference/intersection to show exclusive/common files.
After a lot of repl-time I came up with something like this for the set creation part:
(def contents (ref #{}))
(doseq [line (read-lines "/tmp/a.txt")]
(dosync (ref-set contents (conj #contents line))))
(I'm using duck-streams/read-lines to seq the contents of the file).
This is my first stab at any kind of functional programming or lisp/Clojure. For instance, I couldn't understand why, when I did a conj on the set, the set was still empty. This lead me to learning about refs.
Is there a better Clojure/functional way to do this? By using ref-set, am I just twisting the code to a non-functional mindset or is my code along the lines of how it should be done?
Is there a a library that already does this? This seems like a relatively ordinary thing to want to do but I couldn't find anything like it.
Clojure 1.3:
user> (require '[clojure.java [io :as io]])
nil
user> (line-seq (io/reader "foo.txt"))
("foo" "bar" "baz")
user> (into #{} (line-seq (io/reader "foo.txt")))
#{"foo" "bar" "baz"}
line-seq gives you a lazy sequence where each item in the sequence is a line in the file.
into dumps it all into a set. To do what you were trying to do (add each item one by one into a set), rather than doseq and refs, you could do:
user> (reduce conj #{} (line-seq (io/reader "foo.txt")))
#{"foo" "bar" "baz"}
Note that the Unix comm compares two sorted files, which is likely a more efficient way to compare files than doing set intersection.
Edit: Dave Ray is right, to avoid leaking open file handles it's better to do this:
user> (with-open [f (io/reader "foo.txt")]
(into #{} (line-seq f)))
#{"foo" "bar" "baz"}
I always read with slurp and after that split with re-seq due to my needs.