get API documentation for Clojure libraries - api

I'm new to Clojure, and I would like to know where is all the documentation
for all the libraries such as those found on clojars.org?
for example using lein I do the following to the project.clj
(defproject Program-name "1.0.0-SNAPSHOT"
:description "FIXME: write description"
:dependencies [[org.clojure/clojure "1.3.0"]
[facts/speech-synthesis "1.0.0"]
[org.clojars.jeffsigmon/maryclient "4.3.0"]
[speech-synthesis "1.0.0"]
[clarity "0.5.6"]])
then uselein deps to install all the libraries
Core.clj
(ns Program-name.core
(:use [speech-synthesis.say :as say])(use [clarity.component]))
(use 'clarity.form)
so how would I import and get the API information for org.clojars.jeffsigmon/maryclient?
note: I read that that the API documentation is stored in the
libraries and you have to import them to access it

The API docs are in the code in the form of docstrings
e.g.
(defn my-func
"This is the doc string"
[a b c]
...)
You can access the doc strings in the REPL:
$ lein repl
user> (doc println)
-------------------------
clojure.core/println
([& more])
Same as print followed by (newline)
user> (apropos "print")
(*print-radix* *print-miser-width* *print-pprint-dispatch* print-table
print-length-loop pprint-indent pprint *print-suppress-namespaces*
*print-right-margin* *print-pretty* with-pprint-dispatch ...)
user> (find-doc "print")
... lots of functions related to print with docs...
Various IDEs also give access to the docs. e.g. in emacs, with swank you can use slime-describe-symbol accessed via the shortcut C-c C-d d

use doc, find-doc, apropos function on REPL, use lein repl start a repl.
BTW: if the library jar is not include .clj files, you cannot use them.

Related

Why clojure.repl/source does not works for my custom functtion

When I execute the clojure.repl/source activate in repl, it gives me the source of the activate function.
Now, I defined a custom function in namespace tutorial.test
(ns tutorial.test)
(defn return_type_of_arg
[x]
(type x)
)
After switching the repl namespace to tutorial.test and loading this file in repl, I tried to execute clojure.repl/source return_type_of_arg.
It's giving me the output as Source not found
What's going wrong?
EDITS:
I have confirmed that the namespace is shifted to the one required. Please see the following image:
These are the exact steps I followed:
Created a file test.clj and added above fucntion into it.
Left clicked this file in Intellij Idea and selected option Switch REPL namespace to current file.
Left clicked this file in Intellij Idea and selected option
Load file in REPL.
Below is a transcript of a REPL session that shows the steps to make this work.
dorabs-imac:tmp dorab$ cat tutorial.clj
(ns tutorial)
(defn return_type_of_arg
[x]
(type x))
dorabs-imac:tmp dorab$ clj -Sdeps '{:paths ["."]}'
Clojure 1.10.3
user=> (require 'tutorial)
nil
user=> (in-ns 'tutorial)
#object[clojure.lang.Namespace 0x187eb9a8 "tutorial"]
tutorial=> (clojure.repl/source return_type_of_arg)
(defn return_type_of_arg
[x]
(type x))
nil
tutorial=>
dorabs-imac:tmp dorab$
Added in edit:
First I created a file called tutorial.clj with the ns form and the defn of the function.
Then I started a REPL with the current directory (.) in the CLASSPATH so Clojure knows where to load the file from.
Then I loaded up the file using require. This loads the function definition into the tutorial namespace.
Then I changed the current namespace of the REPL to be tutorial using the in-ns function.
Then I ran the clojure.repl/source function.
Further edit:
I think I have identified the problem you are facing. It seems that the way you are using IntelliJ, it is sending the contents of the file to the REPL, rather than requireing the file. According to the docs for source, "Prints the source code for the given symbol, if it can find it.
This requires that the symbol resolve to a Var defined in a
namespace for which the .clj is in the classpath." [Emphasis mine]. So, when the file contents are sent to the REPL directly (without using require) there is no .clj file for source to look for the source. The following transcript demonstrates that. Compare the following transcript with the transcript above that does work.
dorabs-imac:tmp dorab$ clj
Clojure 1.10.3
user=> (ns tutorial)
(defn return_type_of_arg
[x]
(type x))
nil
tutorial=> tutorial=> #'tutorial/return_type_of_arg
tutorial=> tutorial=> (clojure.repl/source return_type_of_arg)
Source not found
nil
tutorial=>

Should I define separate module for every file in my Guile project?

Let me explain my problem by comparison. In Common Lisp I could split package definitions to several files, it was enough to declare in each of them that it's in-package and load them.
However in Guile Scheme it looks like I should define-module, separate for each file? Well I still can load some files like in CL and it looks like working, define-modules seems not limited to a single file it is located in like in CL, but I get warnings about undefined names (those that are defined in loaded files), so it gives me feeling that it's not what Guile expects. Is there (1) some way of splitting module across several files like in CL, or (2) should I stick to use-module autoload feature and define-module for each file separatelly?
Indeed in Guile you can load inside a define-module but it will report unbound variable at compile time.
The idiomatic way is the define-module in every file:
;; in earth-software-system.scm
(define-module (earth-software-system))
(use-modules (earth-software-system bullet-train))
(use-modules (srfi srfi-9))
(re-export bullet-train) ;; possibly re-exporting imported bindings
...
Then in earth-software-system/bullet-train.scm you can have:
;; in earth-software-system/bullet-train.scm
(define-module (earth-software-system bullet-train))
(use-modules (srfi srfi-9))
(define-public bullet-train 42)
...
Mind the fact that define-public and a single import per use-modules is not widespread. Here is an example from GNU Guix project that rely on define-module to import and export:
(define-module (guix cpio)
#:use-module ((guix build utils) #:select (dump-port))
#:use-module (srfi srfi-9)
#:use-module (srfi srfi-11)
#:use-module (rnrs bytevectors)
#:use-module (rnrs io ports)
#:use-module (ice-9 match)
#:export (cpio-header?
make-cpio-header
file->cpio-header
file->cpio-header*
write-cpio-header
read-cpio-header
write-cpio-archive))
Also nowadays I prefer the import form which is more easy to the mind that use-modules:
;; in earth-software-system.scm
(define-module (earth-software-system))
(import (prefix (earth-software-system bullet-train) 'bt:)
(import (srfi srfi-9))
(re-export bt:bullet-train) ;; possibly re-exporting imported bindings
...
The prefix syntax is also more easy to the mind than the equivalent using use-modules. This is inspired from R6RS library form and R7RS define-library form. I do not recommend to use library form in Guile since it doesn't report lines correctly.
GNU Guile allow to import forms even if they are not exported using the ## syntax for instance to test some tricky behavior.
You might replace load with include but I never used it in Guile

Could not import module frege.system.Directory (java.lang.ClassNotFoundException: frege.system.Directory)

I tried to import System.Directory in my Frege program (In Eclipse) in order to use functions as getDirectoryContent, etc., and it writes me this error :
Could not import module frege.system.Directory (java.lang.ClassNotFoundException: frege.system.Directory)
What do I have to do ?
It is because the module frege.system.Directory doesn't exist in Frege. A good way to find out about a module is to use Hoogle for Frege at this URL: http://hoogle.haskell.org:8081. If we search for that module there, we can see that it doesn't list any module as opposed to, say, if you search for frege.data.List, we would see the module in the result.
Now for the functions you need like getDirectoryContent, if you look at the search result for frege.system.Directory, the first result is about processes and the third and fourth results are about jars and zip files. If you click on the second result, it would open the module frege.java.IO and you can see some relevant functions that might be useful for you (list for example). However the Haskell module you are trying to find is not yet ported to Frege but it should, of course, be possible to port that module backed by native Java implementations.
Update for OP's comment
Here is a simple snippet to return the files under a given directory:
ls :: String -> IO [String]
ls dir = do
contents <- File.new dir >>= _.list
maybe (return []) (JArray.fold (flip (:)) []) contents
Regarding createTempFile, the following works for me:
frege> File.createTempFile "test.txt"
String -> STMutable RealWorld File

Accessing Internal Symbols of a Package in Testing Package

I have a program that I'd like to test using prove. Currently, I have a separate package for the tests. The problem I'm facing is that I don't really want to have to export every symbol from the primary package (I'm only exporting one currently), but I want to be able to access everything from the testing package.
Using main-package::symbol works, but is ugly and a bad idea I'm guessing. Is there some better way to do this without having to export all my symbols just for testing them? I've considered using the same package for writing the tests, but I don't want to have to have a (:use :prove) in my main package when I'm only using it for the testing code. Is there some way to do something like (:use :package) but only for one file? If there is, would it make sense to use that here?
You could separate the tests into their own system. That way your main system won't have a dependency on prove at all. In the test system you can load the same source files, but different package definitions (this of course assumes you put your package definitions in a different file, rather than using the strange custom of putting them on top of your source file...).
For example, the main program might look like this:
foo.asd:
;; Here I'm obviously putting the package def in the same file
(in-package :cl-user)
(defpackage :foo-asd
(:use :cl :asdf))
(in-package :foo-asd)
(defsystem "foo"
:components ((:file "foo-package")
(:file "foo")))
foo-package.lisp:
(in-package :cl-user)
(defpackage :foo
(:use :cl)
(:export :foo))
foo.lisp:
(in-package :foo)
(defun foo (x)
(+ (bar x)
(bar x)))
(defun bar (x)
(* x x))
And the test system in the same directory:
foo-test.asd:
(in-package :cl-user)
(defpackage :foo-test-asd
(:use :cl :asdf))
(in-package :foo-test-asd)
(defsystem "foo-test"
:depends-on (:prove)
:components ((:file "foo-test-package")
(:file "foo")
(:file "foo-test")))
foo-test-package.lisp
(in-package :cl-user)
(defpackage :foo
(:use :cl :prove))
foo-test.lisp:
(in-package :foo)
(plan 2)
(is (bar 2)
4)
(is (foo 2)
8)
(finalize)
This lets you easily run your tests in a new image (to make sure that the version of the code that's actually on your disk works) with something like sbcl --noinform --eval "(ql:quickload :foo-test)" --eval "(sb-ext:quit)". You could of course put the tests behind a function if you want.

Clojure lein-environ plugin classpath error

I am using InteliJ IDEA to develop my application which was working as expected until I added the [lein-environ "1.0.1"] plugin to my project.clj.
If I run my application using lein it all runs as expected however, if I launch a debug repl (need to test the logic etc) then I get the following error:
Could not locate lein_environ/plugin__init.class or lein_environ/plugin.clj on classpath. Please check that namespaces with dashes use underscores in the Clojure file name.
My 'project.clj' contents:
defproject some-project "1.0.0"
:description "Some random description"
:license {:name "FILLER DATA"}
:dependencies [[org.clojure/clojure "1.7.0"]
[environ "1.0.1"]
[stencil "0.5.0"]
[clj-http "2.0.0"]
[clj-ssh "0.5.11"]
[cheshire "5.5.0"]
[clj-time "0.11.0"]
[amazonica "0.3.33"]
[expectations "2.0.9"]
[im.chit/cronj "1.4.1"]
[dk.ative/docjure "1.9.0"]
[com.draines/postal "1.11.3"]
[org.clojure/data.csv "0.1.3"]
[org.clojure/java.jdbc "0.4.1"]
[...]]
:plugins [[lein-environ "1.0.1"]
[lein-expectations "0.0.8"]]
:resource-paths ["resources" "jobs"]
:profiles {:repl {:env {:in-repl? true}}}
:main source-file.core)
If I remove the [lein-environ "1.0.1"] from the plugins the debug repl launches and functions as expected however, I need the plugin to be able to generate the .lein-env from my profiles.clj
Any idea what is causing this issue? I have tried removing environ from ~/.m2/path/to/lein-environ but no luck.
This was a bug in a recent version of Cursive. If you upgrade it should be fixed.