Arity of a function - clojurescript

Is there a way in clojurescript to check what the available arity implementations of a given cljs function are?

If you're running Emacs with nREPL, as explained on this gist, when your text cursor is near the function name Emacs will show the signatures of the function in the message area.
Like that:

The only answer from Rodrigo Taboada is dated and now lots of new tools are out.
Light Table and Fighwheel
I think nowadays Light Table is one of the best tools for ClojureScript, especially when coupled with Figwheel. More info for using LT with Figwheel.
In Light Table to check a function signature you can simply put the cursor over the function name and hit Ctrl-D to toggle the inline documentation.
Emacs and Cider + Figwheel
For Emacs Cider coupled with Figwheel is a great choice, interactive repl and debugger all inside Emacs.
For checking a function you can use the shortcut Ctrl-c d d to show the documentation and function signature.
Configure Cider cannot be easy at first but Figwheel makes the task easier, just un-comment the line under the comment ;; for CIDER in your project.clj file of your Figwheel project, like this:
:profiles {:dev {:dependencies [[binaryage/devtools "0.7.2"]
[figwheel-sidecar "0.5.4-7"]
[com.cemerick/piggieback "0.2.1"]]
;; need to add dev source path here to get user.clj loaded
:source-paths ["src" "dev"]
;; for CIDER
:plugins [[cider/cider-nrepl "0.13.0"]]
:repl-options {; for nREPL dev you really need to limit output
:init (set! *print-length* 50)
:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}}}
Then set Cider to use figwheel as repl:
M-x then launch the command customize-variable, the variable name to customize is: cider-cljs-lein-repl then set the variable to Figwheel-sidecar, save the configuration state and you are done.
It is important that Cider is the same version of the cider-nrepl plugin, at the time of this post they HAVE to be both version 0.13.0.

Related

How to author agnostic JavaScript library in ClojureScript?

Let's say I have a cljs file containing the following:
(ns foo)
(defn add [x y]
(+ x y))
and wish to make this available as a JavaScript library to non-ClojureScript devs (primarily focused on node.js). I can do this:
clj -m cljs.main -c foo
But the problem is that the output is geared towards google closure's module system (e.g. goog.require). I can set the target to none with the -t flag (as opposed to browser or node), and that... doesn't fix this. Setting it to node also doesn't fix the issue: no index.js (it's called main like in Java), no module.exports = blah blah. Seems like it's geared towards standalone, full node apps, rather than libraries.
I understand that ClojureScript uses google closure for it's own sub-modules, and I'm not necessarily looking to get rid of all of that (I'm not sure you could). And I get that es2015 native JavaScript modules are out because of their static nature.
I could massage the output by hand or by script to play nice with the npm ecosystem, but I'm surprised that there's no compiler option that can actually output a npm-friendly module. Or is there? Am I just reading --help wrong?
This assumes that you already have a working installation of ClojureScript and Node.js
Given:
math101
|-- package.json
|-- src
| `-- com
| `-- example
| `-- math.cljs
package.json
{
"name": "math101",
"version": "1.0.0",
"main": "dist/index.js",
"license": "MIT",
"devDependencies": {
"shadow-cljs": "^2.8.52",
"source-map-support": "^0.5.13"
}
}
Notes:
dist/index.js - This will contain our ClojureScript code converted to JavaScript
shadow-cljs - The build (and dependency management) tool that we need
source-map-support - Required to run ClojureScript on Node.js
📣Please make sure you have installed these two NPM dependencies before you proceed further.
math.cljs
(ns com.example.math)
(defn add [x y]
(+ x y))
1. Setup the build tool
At the root of math101 run yarn shadow-cljs init.
This will create a file called shadow-cljs.edn with some default settings:
;; shadow-cljs configuration
{:source-paths
["src/dev"
"src/main"
"src/test"]
:dependencies
[]
:builds
{}}
Let's make some changes.
First you don't need that many source paths for this:
{:source-paths
["src"]
:dependencies
[]
:builds
{}}
Then let's add a build configuration:
;; shadow-cljs configuration
{:source-paths
["src"]
:dependencies
[]
:builds
{:math101 {:target :node-library
:output-to "dist/index.js"
:exports-var com.example.math/add}}}
Notes:
:math101 - This the build id that we will use later
:target :node-library - This tells shadow-cljs that you intend to author a library
:output-to "dist/index.js" - The code you intend to publish
:exports-var com.example.math/add - "Fully qualified name" of the function you intend to publish. This will produce a default export.
Additional notes:
The :target :node-library emits code that can be used (via require) as a standard node library, and is useful for publishing your code for re-use as a compiled Javascript artifact.
Source
There is a :npm-module target available but so far :node-library has checked all the boxes for me.
2. Let's build this!
Run yarn shadow-cljs compile math101.
The first time you run this, shadow-cljs will download a bunch of stuff. Eventually it will finish and when it does...
$ node
> var add = require('./dist')
> add(40, 2)
42
✨✨✨
Need to export more than just one function? No problemo.
Let's add subtract:
(ns com.example.math)
(defn add [x y]
(+ x y))
(defn subtract [x y]
(- x y))
And now let's update our build config:
;; shadow-cljs configuration
{:source-paths
["src"]
:dependencies
[]
:builds
{:math101 {:target :node-library
:output-to "dist/index.js"
:exports {:add com.example.math/add
:subtract com.example.math/subtract}}}}
Run yarn shadow-cljs compile math101 again and when it finishes:
$ node
> var math101 = require('./dist')
> math101.add(40, 2)
42
> math101.subtract(44, 2)
42
✨✨✨✨✨✨
ADDENDUM
This is only intended to get you started. shadow-cljs compile generates non-production code (i.e. it's not minified, dead code is not removed AFAIK and Google Closure hasn't run any optimisation yet).
The command for generating production-ready code is shadow-cljs release but you may want to tweak your build config before.
I would highly recommend that you invest time reading up the shadow-cljs documentation. It is an amazing tool.
shadow-cljs supports output in a CommonJS format via :target :npm-module which does support exactly what you are asking for. Node and other JS tools (eg. webpack) can consume separate namespaces independently. The default CLJS tools do not support this mode.
ClojureScript however is very much written with the assumption that your whole program will be optimized by the Closure Compiler. This makes it less than ideal for writing libraries to be included in other builds. Each "library" built this way will contain its own version of cljs.core and therefore will be pretty large to begin and including 2 libraries built this way is a recipe for disaster since they won't be compatible with each other.

What is "$" in Chrome console?

When we type $ in chrome console it returns a function. I am sure it's not jQuery's $.
If I want to use jQuery in console, What is the best way to trigger jQuery in chrome console as $.
$ is an alias for document.querySelector. In the same vein there is $$ which is an alias for document.querySelectorAll.
It is defined in the Command line (console) api.
Command Line API Reference
The Command Line API contains a collection of convenience functions for performing common tasks: selecting and inspecting DOM elements, displaying data in readable format, stopping and starting the profiler, and monitoring DOM events.
If you have $ defined on the page as a global (perhaps by using jQuery), you'll get that global, not the command-line built-in.
There are other handy functions defined there.
To run jQuery, without having it in the page source code, you may find Chrome extensions to be handy, or simply copy-paste the jQuery source code in the console.

Clojurescript libraries - goog.require could not find

New to clojurescript, and working through the "Modern CLJS" tutorial here.
It instructs to pull in domina by adding it to the project.clj:
:dependencies [[org.clojure/clojure "1.4.0"]
[compojure "1.1.5"]
[domina "1.0.0"]]
And then use it in your script by referencing it in the ns form
(ns cljstut.login
(:use [domina :only [by-id value]]))
However, when I actually run this in a browser, I see the following in the console log.
goog.require could not find: domina
Seems like I'm missing some declaration somewhere? But as a newb, this whole build process is rather opaque. Any troubleshooting tips are greatly appreciated.
Dependencies in your project.clj file and your namespace declarations look fine.
If you are building your clojurescript code using lein cljsbuild auto, you will need to restart that process. I believe it should automatically pull in new dependencies after a restart.
If that doesn't work, or you aren't using lein cljsbuild auto, try running the lein deps command inside your project's folder manually - it will fetch all missing dependencies from remote repositories.
Also, make sure you have saved your project.clj file and try running lein clean and lein cljsbuild clean.
I'm in the process of updating modern-cljs to the latest versions of the used libs and lein plugins. At the moment I updated the series up to the 7th tutorial of the series. You should now be safe by updating to domina 1.0.2-SNAPSHOT into project.cljs :dependencies and to lein-cljsbuild 0.3.0 into project.cljs :plugins.
Mimmo
Just want to add that a typo in the namespace would trigger the same error message:
goog.require could not find: domina
Example (note the missing "j" in modern-cljs):
(ns modern-cls.login
(:use [domina :only [by-id value]]))
I was using a different project name thus a different namespace just to be brave.
It bit me in the ass when I copy-pasted from the guide and the error had me puzzled for a while :)
I ran into this same issue while working through the "Modern CLJS" tutorial. My problem was inadvertently adding the "domina" dependency to the :plugins section of project.clj rather than the :dependencies section.
I got past this error message by putting lines in the right order in the index.html file.
Correct order:
<script src="js/expanding_gases.js" type="text/javascript"></script>
<script type="text/javascript">goog.require("expanding_gases.flow_gases");</script>
Incorrect order:
<script type="text/javascript">goog.require("expanding_gases.flow_gases");</script>
<script src="js/expanding_gases.js" type="text/javascript"></script>
By the way a good read for understanding 'goog' messages is here:
https://github.com/clojure/clojurescript/wiki/Quick-Start

Is there Octave's equivalent for iPython's "!"

For example,
!vim
in iPython opens vim. Is there such a thing in Octave?
The following might work system("vim");
If you want the interactivity of calling something inside of Octave and interactivity with it directly try exec("vim") instead.
See Controlling Subprocesses for more examples.
Otherwise you can either combine calls to system, fork and exec or extend octave with Python/iPython or C++.
If you only want to run another process then , the already suggested system() or exec() should work.
However, if you plan on using this to simply open up a text editor and edit an Octave file, set the value of EDITOR with EDITOR ("vim") (you can add this to your .octaverc file) and then use edit (foo) to open up the foo function on the text editor.

How can I load changes to my .emacs without rebooting Emacs? [duplicate]

How can I get Emacs to reload all my definitions that I have updated in .emacs without restarting Emacs?
You can use the command load-file (M-x load-file, and then press Return twice to accept the default filename, which is the current file being edited).
You can also just move the point to the end of any sexp and press C-x, C-e to execute just that sexp. Usually it's not necessary to reload the whole file if you're just changing a line or two.
There is the very convenient
M-x eval-buffer
It immediately evaluates all code in the buffer. It's the quickest method if your .emacs file is idempotent.
You can usually just re-evaluate the changed region. Mark the region of ~/.emacs that you've changed, and then use M-x eval-region RET. This is often safer than re-evaluating the entire file since it's easy to write a .emacs file that doesn't work quite right after being loaded twice.
If you've got your .emacs file open in the currently active buffer:
M-x eval-buffer
Solution
M-: (load user-init-file)
Notes
you type it in Eval: prompt (including the parentheses)
user-init-file is a variable holding the ~/.emacs value (pointing to the configuration file path) by default
(load) is shorter, older, and non-interactive version of (load-file); it is not an Emacs command (to be typed in M-x), but a mere Elisp function
Conclusion
M-: > M-x
M-x load-file
~/.emacs
Others already answered your question as stated, but I find that I usually want to execute the lines that I just wrote.
For that, Ctrl + Alt + X in the Elisp part works just fine.
The following should do it...
M-x load-file
I suggest that you don't do this, initially. Instead, start a new Emacs session and test whatever changes you made to see if they work correctly. The reason to do it this way is to avoid leaving you in a state where you have an inoperable .emacs file, which fails to load or fails to load cleanly. If you do all of your editing in the original session, and all of your testing in a new session, you'll always have something reliable to comment out offending code.
When you are finally happy with your changes, then go ahead and use one of the other answers to reload. My personal preference is to eval just the section you've added/changed, and to do that just highlight the region of added/changed code and call M-x eval-region. Doing that minimizes the code that's evaluated, minimizing any unintentional side-effects, as luapyad points out.
Keyboard shortcut:
(defun reload-init-file ()
(interactive)
(load-file user-init-file))
(global-set-key (kbd "C-c C-l") 'reload-init-file) ; Reload .emacs file
C-x C-e ;; current line
M-x eval-region ;; region
M-x eval-buffer ;; whole buffer
M-x load-file ~/.emacs.d/init.el
Define it in your init file and call by M-x reload-user-init-file
(defun reload-user-init-file()
(interactive)
(load-file user-init-file))
I'm currently on Ubuntu 15.04 (Vivid Vervet); I like to define a key for this.
[M-insert] translates to Alt + Ins on my keyboard.
Put this in your .emacs file:
(global-set-key [M-insert] '(lambda() (interactive) (load-file "~/.emacs")))
Besides commands like M-x eval-buffer or M-x load-file, you can restart a fresh Emacs instance from the command line:
emacs -q --load "init.el"
Usage example: Company backends in GNU Emacs
Here is a quick and easy way to quick test your config. You can also use C-x C-e at the end of specific lisp to execute certain function individually.
C-x C-e runs the command eval-last-sexp (found in global-map), which
is an interactive compiled Lisp function.
It is bound to C-x C-e.
(eval-last-sexp EVAL-LAST-SEXP-ARG-INTERNAL)
Evaluate sexp before point; print value in the echo area.
Interactively, with prefix argument, print output into current buffer.
Normally, this function truncates long output according to the value
of the variables ‘eval-expression-print-length’ and
‘eval-expression-print-level’. With a prefix argument of zero,
however, there is no such truncation. Such a prefix argument also
causes integers to be printed in several additional formats (octal,
hexadecimal, and character).
If ‘eval-expression-debug-on-error’ is non-nil, which is the default,
this command arranges for all errors to enter the debugger.
Although M-x eval-buffer will work, you may run into problems with toggles and other similar things. A better approach might be to "mark" or highlight what’s new in your .emacs file (or even scratch buffer if you're just messing around) and then M-x eval-region.
You can set a key binding for Emacs like this:
;; Reload Emacs configuration
(defun reload-init-file ()
(interactive)
(load-file "~/.emacs"))
(global-set-key (kbd "C-c r") 'reload-init-file)
If you happen to have a shell opened inside Emacs, you can also do:
. ~/.emacs
It may save a few key strokes.