How do I duplicate a namespace in clojurescript? - namespaces

I would like to copy - or create an alias for - the module other.thing in clojurescript.
Obviously, I can create a file thing in the library my:
(ns my.thing
(:require
[other.thing]))
(def a other.thing/a)
(def b other.thing/b)
(def c other.thing/c)
...
But this is rather verbose.
It would be nice to:
be able to re-export without naming each item by hand
do so without using a separate file
What other options are available?

I believe it is unidiomatic to do that. In the answers of this releated SO question, people are recommending importing explicitly the required namespaces when using them. There's also this Reddit thread where a redditor has created a tool for re-exporting namespaces, but you still have to do it manually for every function.

Related

Bindgen: How to include all functions in some files but only certain functions in other files?

I have two folders that I want to create bindings for:
Include: - I need everything in this folder
Src: - I only need 3 functions (of many) from one file (of many)
All of the required files are included in wrapper.h.
I can create bindings for the correct functions in src by using:
bindings.allowlist_function("myfunc")
However this then means that bindgen only creates bindings for those functions explicitly mentioned. Not the other files in the wrapper.
Is there a way to create the bindings as I wish?
Note: This code is auto-generated so I can't simply move the function.
Furthermore, there are a lot of custom types that are required by these functions and the allowlist_function method brings all of those over automatically. So I need a way to mix allowlist and the files the wrapper.h. I can't manually transfer the functions over as these files change semi-frequently and I am trying to prevent issues in FFI mismatch that manual copying introduces.
**With further research: **
I have found that in Bindgens source code it shows an allowlist_file which suggests it would allow me to allowlist my wrapper and the specific functions.
if let Some(hidden_files) = matches.values_of("allowlist-file") {
for file in hidden_files {
builder = builder.allowlist_file(file);
}
This is included on the documentation at:
https://rust-lang.github.io/rust-bindgen/allowlisting.html
However, when you follow the links it is not in the builder docs and can't be found when running the code. I am confused as to whether this method really exists?

How to make a function file in Ocatve with multiple functions

I know that you can make a function file in Octave in which the file name is the same as the function which defines one function, but I would like to define multiple functions in one file. Is there any way to do this, or do I need a separate file for each function.
In this answer I will assume that your main objective is a tidy workspace rather than explicitly a one-file requirement.
Let's get the one-file approach out of the way. You can create a script m-file (not a function m-file), and define a number of command-line functions there. The octave manual has a section on this. Here's an example:
% in file loadfunctionDefinitions.m
1; % statement with side-effect, to mark this file as a script. See docs.
function Out = Return1(); Out = 1; end
function Out = Return2(); Out = 2; end
% ... etc
% in your main octave session / main script:
X = Return1() + Return2();
However, this is generally not recommended. Especially if you would require matlab compatible code, since matlab introduced 'script-local functions' much later than octave, and decided to do it in a manner incompatible to the existing octave implementation: matlab expects script-local functions to be defined at the end of the script; octave expects them to be defined before first use. However, if you use normal function files, everything is fine.
While I appreciate the "I don't like a folder full of functions" sentiment, the one-function-per-file approach actually has a lot of benefits (especially if you program from the terminal, which makes a wealth of tools twice as useful). E.g. you can easily use grep to find which functions make use of a particular variable. Or compare changes in individual functions from different commits, etc.
Typically the problem is more one of having such function files littering the directory, when other important files are present, e.g. data etc, and having so many files in one place makes finding what you want hard to spot, and feels untidy. But rather than have a single file with command-line definitions, there are a number of other approaches you can take, which are probably also better from a programmatic point of view, e.g.:
Simply create a 'helper functions' folder, and add it to your path.
Use subfunctions in your main functions whenever this is appropriate, to minimize the number of unnecessary files
Use a private functions folder
Use a 'package directory', i.e. a folder starting with the character '+', which creates a namespace for the functions contained inside. E.g. ~/+MyFunctions/myfun.m would be accessed from ~/ via MyFunctions.myfun(), without having to add +MyFunctions to the path (in fact you're not supposed to).
Create a proper class directory, and make your functions methods of that class
The last option may also achieve a one-file solution, if you use a newer-style classdef based class, which allows you to define methods in the same file as the class definition. Note however that octave-support for classdef-defined classes is still somewhat limited.

Use a different React version with clojurescript react libraries (reagent,om,rum,quiescent)

How can I use a different React version with Reagent, Om, Rum, Quiescent or Brutha?
Self answer since this is asked frequently:
First you have to tell Leiningen to exclude the cljsjs/react dependencies:
[rum "0.6.0" :exclusions [[cljsjs/react] [cljsjs/react-dom]]]
If you have other dependencies pulling in cljsjs/react you can use a global exclusion:
:exclusions [[cljsjs/react] [cljsjs/react-dom]]
Next you have to satisfy the compiler since it won't find the namespaces cljsjs.react and cljsjs.react.dom. For this create two files that hold these namespaces in your source directory. For instance
- src/cljsjs/react.cljs
- src/cljsjs/react/dom.cljs
Both only need the namespace declaration and can otherwise be empty (ns cljsjs.react).
Now you can include any React version you'd like manually in your HTML file with a normal <script> tag.
Alternative:
You can also use foreign-libs compiler option.

atom packages, clojurescript, google closure and dependency management

I'm writing some atom (the editor) package with ClojureScript. And i faced dependency load issue.
When compiled ClojureScript produces file like this (main.js):
goog.addDependency("base.js", ['goog'], []);
goog.addDependency("../cljs/core.js", ['cljs.core'], ...)
goog.addDependency("../clojure/browser/event.js", ...)
Obviously, ClojureScript heavily depends on Google Closure dependency management.
But, to be able to use Google Closure i need to include goog/base.js file.
The only way that i found is to add to goog/base.js:
module.exports = goog
and add to main.js:
require('./goog/base.js')
This is very bad approach, because these files are generated - so they can be overridden.
Also, release compilation will not include these lines.
The question is how can i use both these dependency systems?
Or is it possible to use ClojureScript w/o Google Closure?
Please advice, thanks!
If you set your ClojureScript :optimizations to something other than :none (e.g., :whitespace) then the resulting .js file will include the Google Closure code inlined and you won't have to reference it separately.
(Note that this means you might not be able to use a main function in your ClojureScript code, but you can just put a call to your main function somewhere at the toplevel.)

Sharing code between separate scripts (outputs)

I have a project which is not intended to be a single page application, and I'm trying to figure out the best way to share code for common functionality between different script outputs.
For example I may have a stores.js target, and a items.js target built from cljs/stores and cljs/items respectively, but both have some overlapping functionality (say tables with editable cells).
So far the solutions I've come up with are either to symlink common file(s) into both directories that implement the functionality, which I find aesthetically displeasing, but should actually work fine, or to extract the common functionality into a separate package and make the project depend on it. That however involves either requiring developers to setup both repositories and install the dependency locally, or setup a maven server.
This answer from 2012 seems to suggest I should simply do away with multiple targets and instead initialize the functionality I want on the correct page, but it seems to me that having the functionality for the entire site in a single file would make the resulting javascript much larger than it needs to be, increasing the page load time, especially given that I will have more than 2 pages.
Is there a better way?
OK, it turns out the solution is pretty simple, and actually should have been clear from the cljsbuild docs, but I wasn't seeing it. It took trying to reply to #phtrivier for me to actually see what I was missing.
The solution is to use multiple source paths in my project.clj file. So a simple example would look like so:
{:builds [{:source-paths ["src/cljs/items"
"src/cljs/shared"]
:compiler {:output-to "resources/public/js/items.js"
:optimizations :simple
:pretty-print true}
:jar true}
{:source-paths ["src/cljs/stores"
"src/cljs/shared"]
:compiler {:output-to "resources/public/js/stores.js"
:optimizations :simple
:pretty-print true}}]}
from there it's simple:
src/cljs/shared/shared.cljs
(ns shared)
(defn common []
"Hello World")
src/cljs/items/items.cljs
(ns items
(:require [shared :refer [common]]))
(.log js/console (common))
src/cljs/stores/stores.cljs
(ns stores
(:require [shared :refer [common]]))
(js/alert (common))
items.js and stores.js will be their own separate files both containing the shared code.