In Clojure, if I want to pull in the clojure.inspector functions, I can go like this:
(use `[clojure.math.numeric-tower :include (expt)])
From the REPL, and I can now evaluate the function expt.
However, it seems to me that there should be (and probably is) another way to do it - pulling in the code using Leiningen dependencies.
I add this line to my project.clj:
[org.clojure/math.numeric-tower "0.0.2"]
And I restart the REPL to pull in the new dependency. I even do "lein deps" to be safe (there is no output for that command). When I try to evaluate expt, it gives me a RuntimeException, and says its Unable to resolve the symbol.
How can I access the expt function, only using Leiningen dependencies?
You can't. It doesn't work like that. Adding a dependency puts the code on your classpath, which merely means it is available for you to use. In order to actually use the things inside the namespaces, you need to use
(require '[the-namespace :refer [the things you want to use]])
or
(require '[the-namespace :as tn])
(tn/somevar)
or do either of those things in an ns declaration (when not in the REPL and working with a file)
(ns foo
(:require [the-namespace :as tn]))
Related
I've built a library that wraps custom C code and thinking about the best way to build the shared library as part of the ASDF load. The makefile is conditionalised for various OSs, so it could be as simple as uiop:run-program ..., but I thought I'd ask here if there were a more standard idiom for this.
Because the C code is specific to this application, it won't be available through a package manager and must be built specifically for each users machine. I'm fine with documenting a manual build, but if I can smooth things for the user I will. I notice that Python seems to have some kind of automated way of building libs for their CFFI and wonder if there's something for CL.
For an answer to my own question: there seems to be neither a de-facto way of doing this (based on a search of github asd files), nor a definitive method in the ASDF best practices, though there are some ideas to be gleaned from that document.
I'll put my implementation out as a suggested idiom for this use case, along with some possible alternatives. Hopefully some of the ASDF experts here will correct any misunderstandings.
;; Define a makefile as a type of source file for the system
(defclass makefile (source-file) ((type :initform "m")))
;; tell ASDF how to compile it
(defmethod perform ((o load-op) (c makefile)) t)
(defmethod perform ((o compile-op) (c makefile))
(let* ((lib-dir (system-relative-pathname "cephes" "scipy-cephes"))
(lib (make-pathname :directory `(:relative ,(namestring lib-dir))
:name "libmd"
:type #+unix "so" #+(or windows win32) "dll"))
(built (probe-file (namestring lib))))
(if built
(format *error-output* "Library ~S exists, skipping build" lib)
(format *error-output* "Building ~S~%" lib))
(unless built
(run-program (format nil "cd ~S && make" (namestring lib-dir)) :output t))))
(defsystem "cephes"
:description "Wrapper for the Cephes Mathematical Library"
:version (:read-file-form "version.sexp")
:license "MS-PL"
:depends-on ("cffi")
:serial t
:components ((:module "libmd"
:components ((:makefile "makefile")))
(:file "package")
(:file "init")
(:file "cephes")))
This works fine, on both MS Windows and UNIX. Adding a method to perform seems to be the most common method on github.
An alternative might be to use a build-op, as described in building a system. The description
Some systems offer operations that are neither loading in the current
image, nor testing. Whichever operation a system is meant to be used
with, you may use it with:
(asdf:make :foobar)
This will invoke build-op, which in turn will depend on the
build-operation for the system, if defined, or load-op if not.
Therefore, for usual Lisp systems that want you to load them, the
above will be equivalent to (asdf:load-system :foobar), but for other
Lisp systems, e.g. one that creates a shell command-line executable,
(asdf:make ...) will do the Right Thing™, whatever that Right Thing™
is.
suggest to me that this is rather close to the idea of building a C library, and it would map nicely to the mental model of using a makefile and the asdf:make command. I didn't find too many examples in the wild of this being used though and technically we are loading the C lib into the existing image.
Another point that could be reconsidered is the detection of an existing shared library to avoid the rebuild. make will avoid recompiling if the shared library exists, but will still call the linker again. This causes errors because it can't write to the shared library when it's in use, at least on MS Windows. The ASDF example used Lisp code to detect the existence of the library and avoiding recompilation, but an alternative might be to use output-files.
The ASDF docs are a bit muddled on the purpose of output-files and there are no examples that make their intentions clear, but in the manual section on creating new operations we have:
output-files If your perform method has any output, you must define a
method for this function. for ASDF to determine where the outputs of
performing operation lie.
which suggests that defining the shared library (libmd.so or libmd.dll) is the recommended way to avoid a recompilation if the output-files already exists.
Finally, the C library could be considered a secondary system, cephes/libmd in this case, and added to the :depends-on clause in the main system. The section on other secondary systems demonstrates building an executable this way, with build-op. Except for the fact that this is building an executable and hard-codes ".exe" it seems to map well onto the use case:
To build an executable, define a system as follows (in this case, it's
a secondary system, but it could also be a primary system). You will
be able to create an executable file foobar-command by evaluating
(asdf:make :foobar/executable):
(defsystem "foobar/executable"
:build-operation program-op
:build-pathname "foobar-command" ;; shell name
:entry-point "foobar::start-foobar" ;; thunk
:depends-on ("foobar")
:components ((:file "main")))
The build-pathname gives the name of the executable; a .exe type will
be automatically added on Windows.
I didn't use this method because the secondary system would look almost exactly like the primary one does now, but would be slightly less understandable.
I would like to use some ps macros in a .parenscript file. The macros are in a library that will be loaded with quicklisp. I am using sigil to compile the .parenscript file.
I have tried this at the top of the parenscript file:
(lisp
(progn
(ql:quickload 'paren6)
(use-package :paren6)))
but the macro package does not get "used".
Loading the libraries from the command line works:
>sigil --eval "(progn (ql:quickload 'paren6) (use-package :paren6))" sample.parenscript
But it feels clunky, and sigil needs a small hack to prevent it from dumping the output from quickload into the javascript output - indicating that no one else is doing things this way.
I am using sigil because I prefer to build .parenscript -> .js from the command line. Alternatives to sigil will be considered.
What is the best way to indicate a quicklisp dependency for a .parenscript file?
Tracked this one down: Sigil sets *package* to ps except when evaluating lisp forms, where it's left as common-lisp-user so your use-package was affecting the wrong package, and your symbols went wonky.
Try (use-package 'paren6 'ps)
I'm using Clojure to write a small test framework.
(ns pvt.core.runner
(use
[pvt.tests.deployment]
[pvt.tests.files]
[pvt.tests.jms]))
(defn- run-test
[test-name]
{test-name (test-and-log test-name)})
(defn- run-all-tests-in-namespace
[namespace-name]
(map
run-test
(vals (ns-publics (symbol namespace-name))))
)
(defn run-all-tests
[namespace-list]
(map run-all-tests-in-namespace namespace-list))
My run-all-tests function accepts a list of clojure scripts, loads all the public functions in those scripts and runs them. This is great, only that i have to actually import those scripts. I call my function like this (run-all-tests ["pvt.tests.deployment" "pvt.tests.files" "pvt.tests.jms"]), but this only works if I import each of these scripts as seen at the beginning of my code excerpt. This is not ok, since I hvae no idea who will call run-all-tests, and what parameters will be used.
I was wondering if there's a way of importing these scripts at runtime. I already know the namespace of each script, so I have all the required information. Can this be done?
Thanks
Yes, you can import Clojure source files from arbitrary file paths using load-file. If the source file contains a namespace declaration, those namespaces are now available to your Clojure application (framework).
Obviously, at a minimum you'll have to write some code that either takes names of Clojure source files from the command-line, or points to directories where the source files are located. Then your code will load the files using (load-file).
Your stated problem is that you want to execute some tests from the namespace without knowing the namespace names in advance. There are two ways to achieve this:
1) Use a naming convention. i.e. run your tests for each namespace that has the name matching your convention, i.e.
user=> (load-file "/home/noahlz/foo.clj")
#<Var#1e955d29: #<core$foo foo.test.core$foo#48a7a9bd>>
user=> (filter #(re-matches #".*\.test\..*" %) (map str (all-ns)))
("foo.test.core")
Using code like the above, you've obtained a list of namespaces upon which you can execute your framework code.
2) Use metadata. Rather than follow a naming convention, require users of your framework to add metadata to their namespaces. This reduces the chance of accidentally testing a namespace that accidentally followed your convention.
(See: What are some uses of Clojure metadata?)
Note that this is the approach used by Clojure's own clojure.test/deftest macro.
Here is an example of finding namespaces with your custom metadata. Your namespace declaration in a source file defining tests:
(ns ^{:doc "some documentation" :my-framework-tests true}
foo.test.core)
At the REPL, an example of how you can obtain these programmatically:
user=> (load-file "foo.clj")
user=> (filter (fn [[n m]] (:my-framework-tests m))
(map #(vector (str %) (meta %)) (all-ns)))
(["foo.test.core" {:my-framework-tests true, :doc "some documentation"}])
Now you have a list of namespaces that have been flagged as containing tests for your custom test framework. You could even use metadata in the namespace functions to avoid needing a naming convention for those as well.
There might be a more concise way to obtain namespaces having certain metadata (if someone knows of it, by all means, comment!)
Another important note: I'm loading arbitrary files to demonstrate it's possible, buy you really should consider following conventions followed by Leiningen, Maven or other build frameworks. For example, see lein-perforate
Good luck!
Thanks for helping me out. I managed to find what I was looking for. It was actually simpler than I thought. Didn't know that use is actually a function. Now i simply do this:
(defn- run-all-tests-in-namespace
[namespace-name]
(use (symbol namespace-name))
(map
run-test
(vals (ns-publics (symbol namespace-name))))
)
I create a symbol from the namespace name and then pass it to the use function. Works great!
I am trying to optimize my ESS - R environment. So far I make use of the r-autoyas, I set intendation and stuff following style guides, in the mini-buffer there are eldoc hints for function arguments, and I have the option to press a key in order to find information about variable at point (more here).
Are there any other things you use in order to have a nice R environment? Maybe non-ESS people have some nice things to add (I got that info of variable at point from looking at an Eclipser). One example could be an easy way to insert "just-before-defined" variables without typing the variable name (should be something for that?).
(Please help me to change the question instead of "closing" the thread if it is not well formulated)
I am not using autoyas as I find auto-complete integration a better approach.
Insertion of previously defined symbols is a general emacs functionality called 'dabbrev-expand' and is bound to M-/. I have this in my .emacs to make it complete on full symbols:
(setq dabbrev-abbrev-char-regexp "\\sw\\|\\s_\\|s.")
(setq dabbrev-case-fold-search t)
Another thing which I use extensively is imenu-based-jump-to-symbol-definition. It offers similar functionality to emacs tags, but just for open buffers in the same mode as the current buffer. It also uses IDO for queries:
Put imenu-anywhere.el into your emacs load path and add this:
(require 'imenu-anywhere)
(global-set-key [?\M-o] 'imenu-anywhere)
Now, if I do M-o foo RET emacs jumps to the function/class/method/generic definition of 'foo' as long as 'foo' is defined in one of the open buffers. This of course works whenever a mode defines imenu-tags. ESS defines those, so you should not need to add more.
There is also somewhere a collection of R-yas templates. I didn't get around to starting using them but my guess is that it's a pretty efficient template insertion mechanism.
[edit] Activate tracebug:
(setq ess-use-tracebug t)
I ran lein uberjar on my project and it created the corresponding jar files. When I run the jar a ClassNotFoundException: explodingdots.core is thrown. I specified explodingdot.core as my main class. I extracted the jar file and there was indeed no core.class in the corresponding directory. What did I forget?
I have the following code in src/explodingdots/core.clj
(ns explodingdots.core
(:import (java.awt Color Dimension Graphics2D AlphaComposite RenderingHints)
(java.awt.event ActionListener MouseAdapter WindowAdapter)
(javax.swing Timer JPanel JFrame))
(:gen-class))
[ ... ]
(defn -init[] exploding-dots)
(defn -main[_]
(let [ed (new explodingdots.core)]
(.init ed)))
The content of my project.clj is:
(defproject explodingdots "0.1"
:dependencies [[org.clojure/clojure "1.2.0"]
[org.clojure/clojure-contrib "1.2.0"]]
:main explodingdots.core)
Note: I am using leiningen 1.3.1
Ok I solved my original problem. It is kind of embarassing to admit it, but I think I have to do it for the sake of completeness of this thread. I got mixed up with my paths. I have the same file within a Netbeans project and in a leiningen project. And I was editing the Netbeans file. Sorry.
But then I had an other problem. The main method is found but I get an
java.lang.IllegalArgumentException: Wrong number of args (0) passed to: core$-main
I tried changing my main method from
(defn -main [_] ...) to (defn -main [& args] ...) like Arthur suggested but that didn't work. To solve this I wrote just (defn -main[]...) with no args.
The next problem was that calling (init) from (main) resulted in an error. I worked around that by not calling (init) at all but calling (exploding-dots) directly from (main).
So to make everything work my src/explodingdots/core.clj looks like
(ns explodingdots.core
(:import (java.awt Color Dimension Graphics2D AlphaComposite RenderingHints)
(java.awt.event ActionListener MouseAdapter WindowAdapter)
(javax.swing Timer JPanel JFrame))
(:gen-class))
[ ... ]
(defn -main[] (exploding-dots))
By looking at the solution I have to think, why didn't I write that right ahead. It is the most simple and most straight forward way. Maybe I need a vacation ;).
I had to add a third component to my main name space and move everything into the com subdirectory under src.
com.explodingdots.core
I also declare main to take an arg vector, not sure if that makes a diference:
(declare main)
(defn -main [& args]
I ran into this, and fixed it by adding
:gen-class to the corresponding missing class.