- Do I need to know Java to use Clojure?
Not at first, but it helps to know the standard Java APIs.
The Java Ecosystem
- What's a JAR?
JAR is an acronym for "Java Archive." It's the standard format for distributing Java code, and also Clojure code. The format is basically just a ZIP file with some extra metadata. The Java Development Kit (JDK) includes the "jar" command-line program to manipulate JAR files, but typically this task will be handled for you by a build tool such as Ant or Maven.
- What's the classpath?
The classpath is a list of directories and JAR files where the Java runtime searches for code to load. Java does not have a system-wide library directory like Perl, Ruby, or Python. Instead, each program has its own classpath, supplied as the "-cp" command-line argument to the "java" executable. On Unix, Linux, and OSX, entries in the classpath are separated by the colon character; on Windows, it's a semicolon. In order to use a Java class or Clojure namespace in your program, that class or namespace must be "on the classpath," that is, inside a directory or JAR file listed in the classpath.
- How can I change the classpath of a running program?
You can't. The classpath cannot be changed after a program has started, except by very advanced Java programming. Some IDEs and application servers provide this functionality.
- How do I run Clojure code in a file?
java -cp /path/to/the/clojure.jar clojure.main /path/to/your/code.clj
- How do I start a Clojure REPL (console)?
java -cp /path/to/the/clojure.jar clojure.main
- Why can't I require/use my
Because here, your namespace is loaded from the disk. For good interop with JVM features, Clojure does some "munging/unmunging" of names depending of them having to be "consumed" by the "clojure side" or the "jvm side" of the equation. So a "_" in a namespace "folder name/file name" has to correspond to a "-" in the namespace name. Check that your namespace on disk is in "project_name/foo.clj", while your namespace is declared as "project-name.foo" (e.g. in a (ns project-name.foo) directive).
- How can I make a namespace A that "exports" all the public symbols from namespaces B and C?
You can't. "Public" symbols are not transitive. As an alternative, you can define a function in namespace A which calls
referfor namespaces B and C, then call that function in any namespace where you want all those symbols to be available. Be aware that this makes it harder for people reading your source code to see where the symbols come from.
- Why doesn't
Because it expands to
#()always expands to include parens around the expression you give it. You might try
- Why doesn't
nthwork on sets and maps?
"There is a difference between a sequential view of a collection (i.e. what you get from seq) and the collection itself. Maps are not sequential data structures. nth is only supported for sequential data structures, and that is by design." – nth on maps thread
- How do you refer to a nested/inner class?
- Why doesn't
(. Integer getName)work?
. is a special operator. In particular, it does non-standard evaluation of its first arg. Because . can call static and instance methods, it determines if it is static call be seeing if the first arg names a class. In the case of
(. Integer getName), it tries to find the static getName member and doesn't, because there isn't one. You can use this syntax to call a static method on Integer:
(. Integer parseInt "42"). In short, if you can't say x.y() in Java you can't say (. x y) in Clojure, and you can't say Integer.getName() in Java.
How do I call a Java method that takes a variable number of arguments?
The variable arguments are actually just an array:
How do I get primitive types like
- When using
gen-class, how do I specify which method to override based on type signature?
This problem can appear if the class/interface you want to extend/implement defines methods with the same name and arity, only differing on the arguments types.
The solution is to suffix the function name in clojure with the types names, separated by slashes.
Example1, the parent class/interface defines 2 methods
: In clojure you'll write:
Example2, the method to override has no argument, eg.
. Then just append -void:
Example3, case of a java array, specific syntax, eg. for overriding
: You'll use the the-type<> syntax:
- How do I copy a file?
- Does Clojure support custom reader macros?
No, and support is not planned.