getting Moment to work in Clojurescript with cljsjs/moment - momentjs

In my project.clj I've defined the dependency
[cljsjs/moment "2.10.6-0"]
and I'm requiring it in my cljs file using
(:require [cljsjs.moment :as m])
I try and use it like this
(m/from-now 3485736776)
But it says Uncaught ReferenceError: cljsjs is not defined
I also tried
(m/fromNow 3485736776)
Just in case the function call was wrong, but I get the same error ... any ideas?

There's a explanation in cljsjs's wiki page => A Quick JavaScript Interoperability Refresher
basically, require cljsjs's package without :as or :refer. and the library--moment in your case, available in js global namespace. Here is a example from my cljs repl:
(require '[cljsjs.moment])
;;=> nil
(js/moment)
;;=> #object[Moment Sat Oct 24 2015 04:29:19 GMT+0700]
(.fromNow (js/moment) 3485736776)
;;=>"a few seconds"

In (:require [cljsjs.moment :as m]) remove the :as m and that should work. After this the functions in moment will appear under js/.
See https://github.com/cljsjs/packages/wiki/Using-Packages for an example using cljsjs.Showdown.

Related

lexical binding lost when switching package

All I wanted was to load an initialisation file for swank which wouldn't affect my lisp when it's started without swank...
I first tried #+swank (defun...) in my file that's loaded from ccl-init (trying this on ccl 1.10 + windows), and soon realised it's sourced before swank is loaded (obviously).
My aim is to define a simple function in :cl-user everytime I start swank. I just ended up with a swank add-hook to load my init.lisp file, and since I want to define the function in cl-user, I tried this in the init.lisp:
(let ((current-package *package*))
(in-package :cl-user)
(defun cd (dir)
(swank:set-default-directory
(parse-namestring dir)))
(in-package current-package))
Now, I don't recall if a defun in let was allowed, but lisp doesn't complain for it, but rather tells me that cur-pck symbol doesn't exist, and it seems when we switch the package, cur-pck binding gets out of scope. I thought cur-pck is a lexical binding, and that it should be reachable from within the lexical region, being independent from a package, am I wrong?
Why do I switch packages? I'm thinking that loading this file from swank at some initialisation point will define things in some swank package, that's why I wanted to try switching to cl-user first, define the function symbol, and switch back to let swank do it's thing.
At this point I guess I need someone to tell me I'm approaching the problem from the wrong angle, and that I should better choose an easier solution.
Additionally, out of curiosity in case above is the complete wrong approach, is there a way to define a symbol in another package within a function or a closure?
Switching packages in a form has no direct effect on the form
Let's look at this:
(in-package "FOO")
(let ((x 10))
(in-package "BAR")
(setf x 20))
Which x does it set to 20? FOO::X or BAR::X?
Well, it is FOO::X. Switching packages during execution has no effect on the symbols already read. The whole let form is read at once and the *package* value is used for that. Having an IN-PACKAGE in the form itself has no effect on the form itself.
Symbol with a package prefix
If you want to use a symbol in a certain package, just write the package prefix:
cl-user:foo ; if FOO is exported and the package exists
or
cl-user::foo ; if foo is not exported and the package exists
for example:
(defun cl-user::cd (...) ...)
Computing with symbols
You can also compute new symbols in packages you don't know yet:
(let ((sym-name "A-NEW-SYMBOL")
(my-package-name "SOME-EXISTING-PACKAGE"))
(intern sym-name my-package-name))
If the package does not exist, you can create it.
You can also set the function of a computed symbol:
(setf (symbol-function (compute-a-function-symbol))
#'(lambda ()
'foo))
If you want to define a function in a different package that the current one you can use a qualified symbol for a name
(defun cl-user::cd (dir)
(swank:set-default-directory
(parse-namestring dir)))
The binding is not being "lost". To test so yourself add (princ cur-pck) before the in-package form.
If you try evaluating (in-package *package*) you will see why your code fails to switch packages. The in-package macro does not evaluate its argument. The code that would give us the code we would want to evaluate is:
(let ((cur-pck *package*))
(in-package :cl-user)
(defun cd (dir)
(swank:set-default-directory
(1+ 2)))
(princ cur-pck)
`(in-package ,cur-pck))
However, as Rainer Joswig noted in his answer the in-package has no effect on forms already read, so it wouldn't work as desired even as a macro.
A style nitpick, don't use abbreviations, write current-package.
IN-PACKAGE is a macro, not a function. The problem in your code is that saying (in-package cur-pck) tries not to switch into the package denoted by the cur-pck variable but to the package named CUR-PCK (which obviously does not exist).
You can set the package temporarily with
(let ((*package* (find-package :cl-user)))
(defun cd (dir)
...))
But then again, the easiest way to achieve what you are doing would be
(defun cl-user::cd (dir)
...)
which totally eliminates the need to set the current package.

Clojure fn name leaking outside its scope when compiled ahead-of-time

I want to generate named functions with fn and return them from the macro, I tried the following example:
(defmacro getfn
[namestr children]
`(fn fn-name# []
(println "Recursing" ~namestr)
(doall (map (fn [child#] (child#)) ~children))))
(def foo (getfn "foo" []))
(def bar (getfn "bar" [foo]))
(defn -main [& args]
(bar))
The resulting output is usually as expected:
Recursing bar
Recursing foo
However, when I run this compiled ahead-of-time (AOT) I get:
Recursing bar
Recursing bar
...
Recursing bar
Recursing bar
Exception in thread "main" java.lang.StackOverflowError
I find it pretty strange that bar keeps calling itself instead of foo, the only sensible reason for this is for the generated symbol fn-name# to leak outside its scope. Is this a bug in Clojure or intended behaviour?
Update: For clarity should mention that removing the fn-name# symbol and making the function anonymous fixes this problem. However, in my actual code I need to call it recursively sometimes, so naming it is necessary.
One solution I have for this problem is to use gensym to get a new symbol for each version of the macro, this would work by modifying the getfn as follows:
(defmacro getfn
[namestr children]
`(let [fn-name# (gensym)]
(fn fn-name# []
(println "Recursing" ~namestr)
(doall (map (fn [child#] (child#)) ~children)))))
This feels a bit unnecessary since by definition the fn name should be relevant only inside its own scope.
Update: Just tested with alpha releases and it seems Clojure 1.7.0-alpha3 and later work without this hack, Clojure 1.7.0-alpha2 and earlier are broken. Using this workaround is probably ok until stable version of 1.7.0 is released, unless someone can think of something better.

Clojure core.async and clojure.core namespace elements appear to collide

I'm attempting to tinker with Cursive, a plugin for Intellij for the Clojure language. I've imported a very standard new application via Lein, and now attempting to much around with a few core.async constructs.
Here's the project definition:
(defproject app "0.1.0-SNAPSHOT"
:description "Clojure project illustrating basic core.async constructs"
:dependencies [[org.clojure/clojure "1.5.1"]
[org.clojure/core.async "0.1.346.0-17112a-alpha"]])
And the source:
(ns app.core)
(require '[clojure.core.async :as async :refer :all])
(let [c (chan 10)]
(>!! c "hello")
(println (<!! c))
(close! c))
Basic Clojure constructs work without any issue. But after adding the core.async dependency in Lein, each time I attempt to run a piece of code these warnings crop up:
WARNING: partition-by already refers to: #'clojure.core/partition-by in namespace: app.core, being replaced by: #'clojure.core.async/partition-by
WARNING: map already refers to: #'clojure.core/map in namespace: app.core, being replaced by: #'clojure.core.async/map
WARNING: into already refers to: #'clojure.core/into in namespace: app.core, being replaced by: #'clojure.core.async/into
WARNING: reduce already refers to: #'clojure.core/reduce in namespace: app.core, being replaced by: #'clojure.core.async/reduce
WARNING: partition already refers to: #'clojure.core/partition in namespace: app.core, being replaced by: #'clojure.core.async/partition
WARNING: take already refers to: #'clojure.core/take in namespace: app.core, being replaced by: #'clojure.core.async/take
WARNING: merge already refers to: #'clojure.core/merge in namespace: app.core, being replaced by: #'clojure.core.async/merge
It appears to be a namespace collision of sorts.
Is there a simple means to resolve this?
The reason namespaces exist is to give context to names so that they can be reused. This is just an example of that. By using :refer :all you are attempting to pull in many functions that conflict with clojure.core functions. I usually bring only a subset of the more syntactic elements of core.async into my ns and create an alias for the rest:
(require '[clojure.core.async :as async :refer [>! <! >!! <!! go]])
Most of the overlapping names are actually now deprecated and will be removed in the future as they are no longer needed with transducers. For example, instead of using clojure.core.async.take, you will create a chan with a clojure.core.take transducer with Clojure 1.7.
Turns out there's a means to exclude elements. Its a bit cludgy as I'd imagine core.async is popular enough there'd be a default means to avoid basic name collisions. But alas, here's the modified ns/require statement which got me up and running:
(ns app.core
(:refer-clojure :exclude [map reduce into partition partition-by take merge])
(:require [clojure.core.async :refer :all :as async]))
Discovered here on Github

Why can I not access my Leiningen dependencies with Clojure code?

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]))

'lein jar' and 'lein uberjar' not setting the main-class properly

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.

Resources