Dynamically generate global vars in a namespace from a list - clojurescript

I'm working on a thin wrapper around a js library and I want to dynamically generate variables from a list for use in other namespaces.
e.g. Given a list of (:foo :bar :baz), I want to dynamically generate:
(def foo (some-fn foo))
(def bar (some-fn bar))
(def baz (some-fn baz))
I found some solutions for Clojure using interns, but that differs in implementation in CLJS. Alternatively, I can generate and print the necessary expressions and evaluate it each time but I'm hoping for a more programmatic solution.

Related

Clojure/Clojurescript: Argument to resolve must be a quoted symbol

I'm attempting to use a string saved in a variable to call a function like so:
(defn update-product-list [] "Test")
(defn handle-state-change [action]
((resolve (symbol action))))
(handle-state-change "update-product-list")
However, this gives me the following error: Assert failed: Argument to resolve must be a quoted symbol
I've also tried changing the above line to:
((resolve (quote (symbol action))))
But this still gives an error. I also tried changing it just to:
((resolve 'action))
But this gives a different error I don't quite understand: js/action is shadowed by a local. I don't want to override the function just call it. Not sure where I'm going wrong. I've looked at a few examples, but can't see to pin it down.
ClojureScript supports :advanced optimization, in which Google Closure Compiler will rename, inline, or eliminate (unused) functions in order to implement minification. In short, the name of the function you want to look up will, in general, simply no longer exist under :advanced.
Because of this, ClojureScript's resolve is a compile-time facility (a macro requiring a literal quoted symbol).
If you are using :simple or self-hosted ClojureScript, more options are available to you because the support needed persists into runtime. For example Planck has a planck.core/resolve that behave's like Clojure's resolve. A similar approach is possible in Lumo, and similar facilities can be fashioned if using :simple.
In general though, given :advanced, if you need to map strings to a set of functions, you need to somehow arrange to have a static mapping constructed at compile time to support this (the set of functions must be known a priori, at compile time).
If you have a namespace (the name of which is statically known at compile time) which defines functions that need to be dynamically called via strings, you could consider making use of ns-publics:
cljs.user=> (ns foo.core)
foo.core=> (defn square [x] (* x x))
#'foo.core/square
foo.core=> (in-ns 'cljs.user)
nil
cljs.user=> (when-some [fn-var ((ns-publics 'foo.core) (symbol "square"))]
(fn-var 3))
9
This will work under :advanced. The mapping constructed by ns-publics is static; built at compile-time. If you have multiple namespaces that need such treatment, you could merge several calls to ns-publics to build a larger map.
The advantage of this approach is that the code involved is pretty short and requires little maintenance. The disadvantage is that it dumps all of the public vars of the namespace (foo.core in this example) into your generated code (and the generated code for vars is somewhat verbose). Another disadvantage is that you need to statically know the namespace(s) involved at compile time.
If you need to further minimize generated code size, you could just build / maintain a simple static map from string to function value as in
(def fns {"square" foo.core/square})
and use it appropriately, keeping it up to date as your codebase evolves.
Another option would be to mark the functions that you need to access using ^:export meta, and then to call those functions using JavaScript interop. For example if you define the function this way
(defn ^:export square [x] (* x x))
then you can use strings / interop to lookup the function and call it at runtime. Here's an example:
((goog.object/getValueByKeys js/window #js ["foo" "core" "square"]) 3)
The use of ^:export and :advanced is covered here. If you know that you are using :simple or less, then you can simply use JavaScript interop to call the functions of interest, without needn't to use ^:export.
Note that there is no general solution that would let you look up a function by name at runtime under :advanced without somehow putting some aspect of that function into your code at compile time. (In fact, if a function is not referenced in a way that Google Closure Compiler can statically, see, the function implementation will be completely eliminated as dead code.) In the above, ns-publics grabs all the vars for a namespace at compile time, rolling your own lookup map sets up static code to refer to the function value, and using ^:export statically arranges to make the name of the function persist into runtime.
You need to use it like this:
((resolve 'inc) 5)) => 6
or, deconstructed a bit:
(let [the-fn (resolve 'inc)]
(the-fn 7))
=> 8
If you have the function name as a string, use the symbol function to convert from string => symbol (from clojuredocs.org):
user=> ((-> "first" symbol resolve) [1 2 3])
1
And, never forget the Clojure CheatSheet!

Clojure: re-export vars

Is there a way to re-export some namespace's vars from another namespace? I'd like to be able to do this:
(ns mine.core
(:use [incanter core charts datasets io]))
; re-export Incanter somehow
Then in the REPL I would be able to use Incanter's functions by just use-ing mine.core.
user=> (use 'mine.core)
nil
user=> (view (histogram (sample-normal 1000)))
Thanks!
I used to accomplish this by putting the commonly REPLd use expressions in a separate file that I can load-file when I start my REPL. This worked fairly well because I could put everything in there and then get at more than just one namespace.
Later I switched to defining an 'everything' namespace and starting my repl in that using leiningend :main directive like in this SO question which was like my first approach but seemed more elegant.
my ways continued to change and i now always switch to the namespace containing the code. This has worked well because on larger project It helps keep track of what code goes where and I think this practice helps me learn the layout of the code faster. Of course everyone's experiences are different and personal, YMMV :)
Try http://code.google.com/p/clj-nstools/
I suggest to consider importing all necessary dependencies explicitly as suggested in other answers. This usually leads to less complex code.
However if you do want this, e.g. to present a consistent interface, then you can do this with clojure.core/intern function that makes any symbol "native" to given namespace. For example:
(ns user)
(intern 'user 'map clojure.core/map)
(ns new-ns)
(require 'user)
(user/map inc [1 2 3])
; => [2 3 4]
(use 'user)
; => WARNING: map already refers to: #'clojure.core/map in namespace: new-ns,
; being replaced by: #'user/map
(map inc [1 2 3])
; => [2 3 4]
Note that changes in symbol's original namespace will not be reflected until you re-intern the symbol.

is this swing tablemodel code badly designed?

Context: I have a clojure-based crossword app whose main ui is a JTabbedPane with two tabs, a grid and a clue table. The clue table is a view over a vector of clues, but the vector itself is not the authoritative store of the data, but dynamically generated from a couple of internal data structures via an (active-cluelist) function, triggered by the clue tab being selected.
So this is the implementation of the clue table:
(def cluelist [])
(def update-cluelist)
(def model)
(defn make []
(let [column-names ["Sq" "Word" "Clue"]
column-widths [48 200 600]
table-model (proxy [AbstractTableModel] []
(getColumnCount [] (count column-names))
(getRowCount [] (count cluelist))
(isCellEditable [row col] (= col 2))
(getColumnName [col] (nth column-names col))
(getValueAt [row col] (get-in cluelist [row col]))
(setValueAt [s row col]
(let [word (get-in cluelist [row 1])]
(add-clue word s) ; editing a cell updates the main clue data
(def cluelist (assoc-in cluelist [row 2] s))
(. this fireTableCellUpdated row col))))
table (JTable. table-model)
]
; some pure display stuff elided
(def model table-model)
)
(defn update-cluelist []
(def cluelist (active-cluelist))
(.fireTableDataChanged model))
Someone in another discussion noted that it is a major code smell for (update-cluelist) to be manually calling fireTableDataChanged, because nothing outside the TableModel class should ever be calling that method. However, I feel this is an unavoidable consequence of the table being dynamically generated from an external source. The docs aren't too helpful - they state that
Your custom class simply needs to invoke one the following
AbstractTableModel methods each time table data is changed by an
external source.
which implicitly assumes that the CustomTableModel class is the authoritative source of the data.
Also there is a bit of a clojure/java impedance mismatch here - in java I would have had cluelist and update-cluelist be a private member and method of my TableModel, whereas in clojure cluelist and the table model are dynamically scoped vars that update-cluelist has access to.
My main problem is that there is not a lot of clojure/swing code around that I can look to for best practices. Does anyone have any advice as to the best way to do this?
Suggestion: use an atom for cluelist. Constantly redefining cluelist is not the right way to represent mutable data. Honestly, I would expect it to throw an exception the second time you define cluelist.
If you use an atom for cluelist, you can call the fireTableDataChanged method from a watcher instead of calling it manually. This would mean that anytime (and anywhere) you change the atom, fireTableDataChanged will be called automatically, without an explicit call.
The issue with def is that calling def multiple times doesn't work well in a multi-threaded environment and Clojure tries to make everything default to fairly threadsafe. As I understand it, the "proper" way to use a var is to leave its root binding alone (ie, don't call def again) and use binding if you need to locally change it. def may work the way you are using it, but the language is set up to support atoms, refs, or agents in this sort of situation and these will probably work better most of the time (ie you get watchers). Also, you don't need to worry at all about threads if you add them later.

What function/macro to check what namespaces are currently 'used' and how to check if one in particular is used?

Is there a function/macro in Clojure to check what namespaces are currently 'used'? Which one? So I don't mean 'what namespace are we currently in' but for example, I want to find out if 'clojure.contrib.string' is currently 'used' as in (use 'clojure.contrib.string). I don't mean 'required'.
How does one write a function that give true when for example 'clojure.contrib.string (the name of the namespace provided via a symbol) is used and false otherwise?
(defn ns-used? [name] (...)
all-ns as suggested by kotarak, is close to what you are looking for, but it also gives you all the namespaces that have been required without having been referred.
Otherwise ns-refers gives you a map of all the functions that are referred in the namespace. Similar and possibly also of interest are ns-map and ns-imports which gives you a mapping of all the imported classes or records.
If you want to strictly find all the namespaces from which functions have been referred, you could do something like this:
(defn ns-used? [ns]
(let [referred-namespaces (set (map (fn [[k v]] (:ns (meta v))) (ns-refers *ns*)))]
(contains? referred-namespaces (find-ns ns))))
If you are happy to check if the namespace has been required or used you could do
(defn ns-used-or-required? [ns]
(contains? (set (all-ns)) (find-ns ns)))
You will have to pass the symbol in quoted:
(ns-used? 'clojure.core)
all-ns for some suitable definition of 'used'.
ns-refers for some other definition of 'used'.

Splitting a Clojure namespace over multiple files

Is it possible to split a Clojure namespace over multiple source files when doing ahead-of-time compilation with :gen-class? How do (:main true) and (defn- ...) come into play?
Overview
Certainly you can, in fact clojure.core namespace itself is split up this way and provides a good model which you can follow by looking in src/clj/clojure:
core.clj
core_deftype.clj
core_print.clj
core_proxy.clj
..etc..
All these files participate to build up the single clojure.core namespace.
Primary File
One of these is the primary file, named to match the namespace name so that it will be found when someone mentions it in a :use or :require. In this case the main file is clojure/core.clj, and it starts with an ns form. This is where you should put all your namespace configuration, regardless of which of your other files may need them. This normally includes :gen-class as well, so something like:
(ns my.lib.of.excellence
(:use [clojure.java.io :as io :only [reader]])
(:gen-class :main true))
Then at appropriate places in your primary file (most commonly all at the end) use load to bring in your helper files. In clojure.core it looks like this:
(load "core_proxy")
(load "core_print")
(load "genclass")
(load "core_deftype")
(load "core/protocols")
(load "gvec")
Note that you don't need the current directory as a prefix, nor do you need the .clj suffix.
Helper files
Each of the helper files should start by declaring which namespace they're helping, but should do so using the in-ns function. So for the example namespace above, the helper files would all start with:
(in-ns 'my.lib.of.excellence)
That's all it takes.
gen-class
Because all these files are building a single namespace, each function you define can be in any of the primary or helper files. This of course means you can define your gen-class functions in any file you'd like:
(defn -main [& args]
...)
Note that Clojure's normal order-of-definition rules still apply for all functions, so you need to make sure that whatever file defines a function is loaded before you try to use that function.
Private Vars
You also asked about the (defn- foo ...) form which defines a namespace-private function. Functions defined like this as well as other :private vars are visible from within the namespace where they're defined, so the primary and all helper files will have access to private vars defined in any of the files loaded so far.