Under the hood of Clojure repl execution - clojure

I understand Clojure code is compiled into classes and executed by JVM. For a Java project, I'm able to see a Jar gets created with .class files in it. But how exactly it works in case of a REPL?

Clojure code is compiled using the ASM library into class files. Those class files are loaded into a custom DynamicClassLoader.
Good talk on the compilation process: https://www.youtube.com/watch?v=-Qm09YiUHTs

Related

how does jvm bytecode get converted to js in cljs build

As I understand most clojure and java libraries can be included in cljs code. How does the cljs compiler accomplish this ?
I understand that if I have a source file, the cljs compiler takes the source and outputs javascript. However how about if I am using java libraries such as joda-time for which I have included its clojure wrapper clj-time. So in this case it only has the java byte code for joda-time. So how will the cljs build tool, generate js code from the byte code of the java jar (joda-time)?
As I understand most clojure and java libraries can be included in cljs code. How does the cljs compiler accomplish this ?
You are mistaken. Many clojure libraries can be compiled for CLJS, with only minimal changes (sometimes even none), but there is no way to use classfiles: it must be .clj source files, compiled to javascript instead of to classfiles.
You cannot use Java libraries in cljs code.

simple tool for compiling Clojure .clj into .class / .jar

I've found two ways of compiling Clojure *.clj files into *.class files, and while they both work, I have some gripes with both of them.
The first one uses a REPL and so cannot be automated (or can it?)
The second one uses lein. To be frank I don't see why I should use a dependency management tool for something that should be part of the core tool-chain of the language. But in any case, using lein soon forces you to use a local Maven repository if your Clojure code needs to access local jars (which is highly likely).
Is there a better way to generate *.class or *.jar files from Clojure code that involves only core Clojure tools and that can be employed in a scripted, non-interactive way?
Clojure provides clojure.core.Compile, which can be used to compile Clojure code from the command-line.
java -Dclojure.compile.path=<targetdir> -cp <targetdir>;clojure.jar <list of namespaces>
For an example of how to use this from ant, look at the compile-clojure task in Clojure's own build.xml file.
clojure.core/compile can be automated via Clojure

make lein uberjar without source files

I'm using 'lein uberjar' to make a executable jar file of my project.
the jar is created correctly and runs as expected.
I just want to know if it is possible to NOT include my source .clj files in the generated .jar, since I'm planning to distribute it, and I don't want my source files available to the public.
I'm using lein 1.7.1
if not possible with lein, would it work if I just manually removed the .clj files from the jar? I did a test and it worked, by I want to be sure that this is safe to do.
thanks in advance.
Use :omit-source true in lein's project.clj.
Have you tried using the aot compilation step that is provided? See here for an example.
Also, someone blogged something not too long ago about aot compiling their entire project: http://blog.japila.pl/2012/02/aot-compile-all-namespaces-in-a-clojure-project-aot-all-in-project-clj-leiningen/
In that case, too, you might still have to dig in and remove the .clj files, I'm not sure. Maybe this is somewhere to start, though.
Edit 1
I should note that even if you were to use compilation to just distribute the .class files, there are really good tools to decompile those classes in a way that users can read (I've used this in the past when the documentation was so poor I had to look elsewhere to see how it worked).
In those cases, you'd be better off finding a way to implement your own code obfuscator, although I know little/nothing about that topic, here's a start.

Does Clojure require a JDK?

I want to distribute a Clojure program. Do I need a JDK or can a JRE handle everything in Clojure?
You only need the user to have a JRE (v1.5 or above)
Clojure programs can be compiled into a jar file. You don't have to use something like
leiningen, but it's a lot easier.
Check out this page on the Clojure.org site for how to compile and run a program.
You can compile to a jar file from the REPL:
(compile 'clojure.examples.hello)
Here's how you would run a compile jar:
java -cp ./classes:clojure.jar clojure.examples.instance asdf
You just need a JRE.
https://github.com/technomancy/leiningen/blob/master/TUTORIAL.md explains in more detail, but I believe you just want an "Uberjar" which will contain all the dependencies that you need to distribute your application.
JRE is required! You can easily download it from Internet.

Lisp Executable

I've just started learning Lisp and I can't figure out how to compile and link lisp code to an executable.
I'm using clisp and clisp -c produces two files:
.fas
.lib
What do I do next to get an executable?
I was actually trying to do this today, and I found typing this into the CLisp REPL worked:
(EXT:SAVEINITMEM "executable.exe"
:QUIET t
:INIT-FUNCTION 'main
:EXECUTABLE t
:NORC t)
where main is the name of the function you want to call when the program launches, :QUIET t suppresses the startup banner, and :EXECUTABLE t makes a native executable.
It can also be useful to call
(EXT:EXIT)
at the end of your main function in order to stop the user from getting an interactive lisp prompt when the program is done.
EDIT: Reading the documentation, you may also want to add :NORC t
(read link). This suppresses loading the RC file (for example, ~/.clisprc.lisp).
This is a Lisp FAQ (slightly adapted):
*** How do I make an executable from my programme?
This depends on your implementation; you will need to consult your
vendor's documentation.
With ECL and GCL, the standard compilation process will
produce a native executable.
With LispWorks, see the Delivery User's Guide section of the
documentation.
With Allegro Common Lisp, see the Delivery section of the
manual.
etc...
However, the classical way of interacting with Common Lisp programs
does not involve standalone executables. Let's consider this during
two phases of the development process: programming and delivery.
Programming phase: Common Lisp development has more of an
incremental feel than is common in batch-oriented languages, where an
edit-compile-link cycle is common. A CL developer will run simple
tests and transient interactions with the environment at the
REPL (or Read-Eval-Print-Loop, also known as the
listener). Source code is saved in files, and the build/load
dependencies between source files are recorded in a system-description
facility such as ASDF (which plays a similar role to make in
edit-compile-link systems). The system-description facility provides
commands for building a system (and only recompiling files whose
dependencies have changed since the last build), and for loading a
system into memory.
Most Common Lisp implementations also provide a "save-world" mechanism
that makes it possible to save a snapshot of the current lisp image,
in a form which can later be restarted. A Common Lisp environment
generally consists of a relatively small executable runtime, and a
larger image file that contains the state of the lisp world. A common
use of this facility is to dump a customized image containing all the
build tools and libraries that are used on a given project, in order
to reduce startup time. For instance, this facility is available under
the name EXT:SAVE-LISP in CMUCL, SB-EXT:SAVE-LISP-AND-DIE in
SBCL, EXT:SAVEINITMEM in CLISP, and CCL:SAVE-APPLICATION in
OpenMCL. Most of these implementations can prepend the runtime to the
image, thereby making it executable.
Application delivery: rather than generating a single executable
file for an application, Lisp developers generally save an image
containing their application, and deliver it to clients together with
the runtime and possibly a shell-script wrapper that invokes the
runtime with the application image. On Windows platforms this can be
hidden from the user by using a click-o-matic InstallShield type tool.
Take a look at the the official clisp homepage. There is a FAQ that answers this question.
http://clisp.cons.org/impnotes/faq.html#faq-exec
CLiki has a good answer as well: Creating Executables
For a portable way to do this, I recommend roswell.
For any supported implementation you can create lisp scripts to run the program that can be run in a portable way by ros which can be used in a hash-bang line similarly to say a python or ruby program.
For SBCL and CCL roswell can also create binary executables with ros dump executable.
I know this is an old question but the Lisp code I'm looking at is 25 years old :-)
I could not get compilation working with clisp on Windows 10.
However, it worked for me with gcl.
If my lisp file is jugs2.lisp,
gcl -compile jugs2.lisp
This produces the file jugs2.o if jugs2.lisp file has no errors.
Run gcl with no parameters to launch the lisp interpreter:
gcl
Load the .o file:
(load "jugs2.o")
To create an EXE:
(si:save-system "jugs2")
When the EXE is run it needs the DLL oncrpc.dll; this is in the <gcl install folder>\lib\gcl-2.6.1\unixport folder that gcl.bat creates.
When run it shows a lisp environment, call (main) to run the main function
(main).