I'm C++ programmer learning Clojure and have limited experience with Java. Now, I have Clojure program referencing just one functions from a library:
(ns app.main
(:gen-class)
(:require [clojure.string :refer [join]))
...
;; Code using join
...
In C/C++ linker will eliminate unused functions, so there is no significant overhead to reference single function from a library. What happens in JVM/Clojure world? Is it Clojure-compiler specific or JVM general? Will result binary contain all functions from clojure.string or just used?
In JVM land there is no linker. The JVM handles loading and linking. Everything in Java | Clojure is a shared object, so dead code elimination isn't possible. You never know what is going to get used by the code that loads yours.
In clojure every function gets its own .class file(smallest 'binary' file on the JVM). These get zipped into a JAR file which is the standard unit of distribution(this is about equivalent of a .dll or .so). So only the functions you use will get loaded. However if you are worried about distribution size then you are out of luck or have to manually rip apart JAR files to find the right class files.
Related
Normally, Clojure source files are named (for example) foo.clj, and Clojurescript source files are named foo.cljs. My impression is that in Clojure versions >= 1.7, I can name a file foo.cljc if I want it to be available for loading with require or use both from Clojure and Clojurescript.
Is this correct? It seems to be implicit in the primary documentation pages on Using cljc
and reader conditions, but as far as I can see it's never explicitly stated.
This is not a question about using reader conditionals to specify alternate code for running in Clojure and Clojurescript; it's more fundamental. For example, I have a source file that contains code that's completely generic: It will run in both Clojure and Clojurescript unchanged. Can I assume that by naming it with ".cljc", require will always find it from inside both Clojure and Clojurescript (assuming it's named correctly, is in the correct location, etc.)?
[I'm pretty sure that I'm right, but I'm not certain, and I thought it would be worth having the answer documented here if I'm correct.]
That's correct. When Clojure or ClojureScript needs to load a namespace, they first look for the platform-specific file (.class then .clj on Clojure and .cljs on ClojureScript) and if not found, then they look for the .cljc file.
You do still need to make sure it is available to the language on the classpath, as with other source files.
Yes.
The nuances is the precedence of loading, which is explained here:
https://github.com/clojure/clojure-site/commit/010134bcc2e8af899ba2b1e5816b0fcf7e007ba4
In short, cljc files are loaded last, and conditionals are only valid in cljc.
I am just started on clojure and have a very basic question about core.clj.
What is a convention about it? What code should go there? Public API?
It is generated by leiningen when creating a project.
I have looked into source code of some libraries and this file is also present there (per package?).
Thanks
There's no defined meaning for it, but in an application it's often where you'll find the entry point, the main- function. For libraries, foo.core is often the namespace users will import to get your main functionality.
You don't have to do it that way, but it's a semi-predictable place to have the 'central bit' of whatever it is you're writing - even if your actual logic and algorithmic code is somewhere else.
Leiningen generates foo.core because it needs to pick a name and core is generic enough that it probably wont' be wrong. It's a style decision, but I typically opt to rename core.clj to a name that is actually meaningful for my project.
It's just a template file emitted by Leiningen. If I run lein new foo there is no specific or standard meaning to the namespace foo.core. It is entirely legal for the namespace foo to be the main API container for a project. It's just a free file for you to start working in.
That said, if you have a project foo, it is expected although not enforced that all your code for that one project exist in the foo.* namespace. Leiningen will allow you to build a project with the files src/foo.clj and src/bar.clj and it is entirely reasonable for foo to require bar, however when packaging your code for distribution this is probably a bad idea.
Apologies in advance for the somewhat discursive nature of this clump of related questions; I hope the answers will be a useful resource for newcomers to Clojure.
I have just begun to learn Clojure, motivated in part by this essay. I'm not a professional developer but I have several decades of programming experience (ARexx, VB/VBScript/VBA, then Perl and daily use of R starting in 2011). My platform is Windows 7 64-bit. I'm using Emacs 24.3, cider 20131221 and Leiningen 2.3.3 on Java 1.7.0_45 Java Hotspot 64-bit server. I have bought Clojure Programming and the Clojure Data Analysis Cookbook and dipped into both. I have found them promising but I am getting lost in the detail.
Obviously the thing to do is to get stuck in and experiment with code exercises and small tasks, but the immediate problem for me has been the complexity of structuring, organising and even just plain running projects in Clojure. With R I can get away with a file of plain text containing the bulk of the code, perhaps with one or two others containing common functions for larger projects.
Clojure is very different and with no experience in Java I am struggling to put the pieces together. Clojure Programming has a whole chapter on organising and building projects, but it is so comprehensive that conversely I'm finding it difficult to tease out the information relevant to me now. I guess I'm looking for something like this answer on Swank, but the tools seem to have moved on since then. So here goes.
Leiningen produces amongst other things a project.clj file that contains the project definition and dependencies. I think I get this. Can I use this file for code not related to the definition, below the defproject, or is it best to leave this untouched and have the code itself in different clj file(s)?
If the answer is to leave the project.clj file alone, how is the relationship between that and other files established? Is it simply that all the clj files in the project folder are counted part of the project?
How do I define the main code file, the 'entry point' of the project? Let's say I have project.clj and main.clj with some helper functions in common.clj - how are the relations between these three files defined? I can call functions from main.clj but how does the project know that main is the core of the project if/when I package the project into an uberjar?
If I have a number of clj files, what is the best way to import functions? I have read about require and use (and import and refer and...) but I don't fully understand the difference and those two keywords are difficult to search for. The examples for REPL in the Clojure Data Analysis Cookbook most often opt for use. I found a similar question but it was a little over my head.
This is more tool-specific, but as Emacs seems to be widely used it seems fair to ask: what's a good workflow to run small bits of code given (say) the main.clj example given above? Currently I just open the main.clj file in Emacs, do an M-x cider-jack-in to establish the REPL, experiment in the REPL, then when I want to try something I select the whole buffer and select Eval region from the CIDER menu (C-c C-R). Is this standard operating procedure or utterly misguided?
Is there a convention for defining namespaces? I think I understand that namespaces can cover multiple clj files and that ns is used to define the namespace. Should I explicitly define the namespace (at the beginning of) every file of code? Clojure Programming has some recommendations but I'm interested in input from other users.
Clojure programming says to "Use underscores in filenames when namespaces contain dashes. Very simply, if your namespace is to be com.my-project.foo, the source code for that namespace should be in a file located at com/my_project/foo.clj". (EDIT as explained in this useful answer and also this one). This restriction would never have occured to me. Are there any other gotchas with regard to naming namespaces and variables? R frequently uses dots in variable names but I guess given the Java connection that dots should generally be avoided?
No, don't put actual code in there unless you know what you are doing (e. g. generate the version number for defproject from the local git repository like in the repositories of juxt)
The project.clj is simply one big parameter to Clojures build tool leiningen. See an example here https://github.com/technomancy/leiningen/blob/master/sample.project.clj. For example, you could specifiy a different source directory than src in the :source-path.
Default is the -main function in project.core, but you can specify various different configurations in the project.clj.
require is preferred. :use imports all publics of a namespace unless you use it in conjunction with :only. Require let's you use an alias for an entire namespace with :as, but you can have the same effect from use with :only using :refer. Notice that in ClojureScript :use without :only is not even allowed.
This is normal. There are other combos like e.g. C-c C-k to reload the entire file of the buffer. If you find yourself entering too many forms into a REPL and would rather edit them in a separate buffer https://www.refheap.com/22235.
I like to experiment trying to name namespaces in in verbs rather than nouns, e. g. I prefer myproject.parse, myproject.interpret, over myproject.parser, myproject.interpreter etc. But that's a question of personal style. EDIT: Yes, explicitly define the naming of the namespace by its filename and the ns form at the beginning of the source file. It is unusual to have multiple source-file defining one namespace.
Afaic this is the only caveat regarding naming of namespace. You can hardly know it in advance.
I like your "worried" approach. You will (hopefully) find out that Clojure and especially Leiningen are almost nonsense-free in terms of these questions.
Regarding REPL use: I saw your comment under #Mars answer that you want to use a REPL in a fashion that you can re-use what you are entering. Two things:
Dynamic development is awesome, allowing you to test small components or functions interactively without the need to run an entire program written for that purpose.
If you find your self entering huge forms at the REPL that you intend to de-/recompose into functions or tests later, I recommend editing them in a seperate clj file that is not part of the project source (i. e. not in a namespace). You can then use this Emacs hack to eval forms from a Clojure buffer in the REPL. Ideally split your Emacs in two windows (C-x 3) with the nrepl buffer on one side and your .clj on the other side. Then use C-x C-. from within the clj file to have the form at point pasted into the nrepl and be evaluated. Installation instructions are at the link (and your .emacs file usually resides in the home directory).
#Igrapenthin's answers are great. Here are a few other thoughts.
On namespaces, this tutorial is great.
Just to clarify re #2: No, don't just put the .clj files anywhere under the project. They have to be under src/, or in whatever directories are listed (as strings) in the vector after :source-paths in project.clj, if that entry exists. Then strip off that initial path when you're making your namespace names. This drove me crazy until I figured it out. (People who know better, please correct me if something here isn't right.)
One #3, you need Igraphenthin's answer, but why not just start by evaluating expressions in the REPL? I've been working on a project on and off for weeks, and it does a lot, but my -main function still doesn't do anything. I just run whatever parts I'm working on. Well, you're used to languages with fully operational prompts--you decide.
EDIT: Whether or not you define the -main function to do anything, you can also put :use or :require keywords in the ns statement that defines the namespace for that same file. These will automatically get invoked when you start the REPL with lein repl, and so whatever you have made available through the ns keywords will be available at the REPL. That way, you have your previous work available, but you can play around with it in different ways in the REPL. (Also, if you don't like the default name for the file that's automatically loaded, you can redefine it in project.clj with :main. Igraphenthin alluded to that.)
I read somewhere Clojure is compiled. Is it really compiled, like Java or Scala, rather than interpreted, like Jython or JRuby?
Clojure is always compiled.
The Clojure compiler produces Java byte code, which is typically then JIT-compiled to native code by the JVM.
The thing that can be confusing is the dynamic and interactive nature of Clojure that means you can invoke the compiler at run-time if you want to. This is all part of the Lisp "code is data" tradition.
For example, the following will invoke the Clojure compiler at run-time to compile and execute the form (+ 1 2):
(eval '(+ 1 2))
=> 3
The ability to invoke the compiler at run-time is very useful - for example it enables you to compile and run new code in the middle of a running Clojure application by using the REPL. But it's important not to confuse this "interactive" style of development with being "interpreted" - Clojure development is interactive, but still always compiled.
Both-ish! (when it comes to generating bytecode)
Clojure is on-the-fly-compiled at code load time into JVM bytecode, which has the feeling and flow of an interpreted language, and ahead-of-time compiled into JVM bytecode, which has the flow of a compiled language. both of these are then JIT compiled into machine code by the Java Hotspot compiler which takes care of the dynamic optimization that Clojure depends on for speed. just to make things interesting "loaded/evaluated" code can compile on the fly at runtime, and AOT compiled code can load and evaluate source at runtime.
If you want "interpreted" then you can (load "/my/file.clj") from the repl.
If you want Ahead-Of-Time compiling, may I suggest using the leiningen clojure project management tool.
In this case when i mention compiling vs. interpreting I should be clear that I am talking about turning source code into JVM bytecode. All JVM languages are compiled by the JVM at runtime so that distinction is not really very interesting.
Clojure is a compiled JVM language. That means that the first step it takes when confronted with a new program is to compile it to JVM bytecode.
Some of the JVM bytecode may later be compiled to machine code by HotSpot, if you're using OpenJDK or a derivative of it.
As a high-level language, Clojure has a form of dynamic typing, which is what the "completely dynamic" phrase is referring to.
Simple question. I'm new to Clojure.
How can I use one file from my project in another file? Basically how can I include, import, or require another file? Not from libraries but fro my own code.
Thanks,
Alex
Normally you'll want to use the same method that you use with library code, which is to use / require your namespaces (through an ns form at the top of the file and sometimes the use / require functions at the REPL). For this to work, you have to make sure they are on the classpath. A short guide to that:
Follow the usual Clojure project structure: a src/ directory containing all your source files, where file src/foo/bar/baz.clj defines a namespace called foo.bar.baz. Note that you must maintain the directory structure / namespace name structure correspondence; things won't work otherwise. Also note that you must not use the _ character in namespace names or the - character (the hyphen) in filenames and whenever you use _ in filenames you must use a - in namespace names (and the other way around.) Finally, the directory hierarchy will be slightly more complicated with Maven projects, but don't worry about this for now (unless you're already a proficient user of Maven, in which case this won't be a problem for you).
Also see this answer of mine to an earlier SO question about Java classpath handling with Clojure for a more detailed step-by-step explanation of the filesystem hierarchy / classpath hierarchy correspondence.
If your code from the foo.bar namespace needs to use code from the foo.quux.baz namespace, do something like (ns foo.bar (:require [foo.quux.baz :as baz])) in foo/bar.clj and call functions from baz as baz/some-function. Or you can put (:use foo.quux.baz) in the ns form instead to call them directly (without the namespace qualifier, e.g. some-function). That's exactly the same thing as what you'd do for library code.
When working with your project's code from the REPL, make sure you include the src/ directory (the directory itself, not any of the files therein) on the classpath. You should probably consider using some tool to automate the REPL setup (including classpath management) for you; Leiningen is very popular with Clojurians and there are plugins for using Maven with Clojure too.
Warning: Your JVM-launching command might (in fact, probably will) recognise an environment variable called $CLASSPATH. As for its relationship to your Clojure projects, well, basically there should be none. More likely than not, your projects will require a different classpath each, with some possibly using versions of certain jars incompatible with those required by others (notably if you're using Clojure 1.1 -- latest stable release -- for some projects, while experimenting with 1.2 snapshots with others). Thus the correct way of managing the classpath is to prepare a minimal version for each project and pass that to the JVM launching command. As mentioned previously, you should invest some time in learning to use a good tool (like the above mentioned Leiningen) to set up the classpath for you as soon as possible so you don't need to care about this yourself.
(As a side note, you might have to add more than just the src/ directory and your jars to the classpath in some scenarios, e.g. if you plan on calling compile to produce .class files, you'll have to put the target directory on the classpath too. That's beyond the scope of this question, though.)
BTW, I've started this answer with the word "normally", because you could also use things like load & in-ns to split a single namespace into multiple files. Most of the time this won't be what you really want to do, though; just use a well thought out namespace layout instead.