Fork me on GitHub
#clojurescript
<
2018-09-29
>
13tales04:09:28

Hey there. I'm a relative clojure newbie with a little side-project in mind that I'd like to tackle — I want to write a little program that talks to the Asana API and pulls down all the tasks currently assigned to me. I'd had it in mind to try and accomplish this by writing a Node script with clojurescript. 1) Is that a reasonable choice, or given that I'm a relative newbie, am I better off starting out with the JVM? 2) I'm looking for a simple HTTP library I can use to talk to the API; can't tell if the errors I'm getting when trying to use https://clojars.org/cljs-http-node are due to my unfamiliarity with the tooling, or because it's very out of date. Any recommendations?

priornix04:09:14

Any ideas what's causing these errors in lein uberjar?

Sep 29, 2018 12:22:43 PM com.google.javascript.jscomp.LoggerErrorManager println
SEVERE: ERROR - Duplicate extern input: file:/.m2/repository/cljsjs/moment/2.22.2-1/moment-2.22.2-1.jar!/cljsjs/common/moment.ext.js

Sep 29, 2018 12:22:43 PM com.google.javascript.jscomp.LoggerErrorManager println
SEVERE: ERROR - Duplicate extern input: file:/.m2/repository/cljsjs/react-dom/16.3.2-0/react-dom-16.3.2-0.jar!/cljsjs/react-dom/common/react-dom-server.ext.js

Sep 29, 2018 12:22:43 PM com.google.javascript.jscomp.LoggerErrorManager println
SEVERE: ERROR - Duplicate extern input: file:/.m2/repository/cljsjs/react-dom/16.3.2-0/react-dom-16.3.2-0.jar!/cljsjs/react-dom/common/react-dom-test-utils.ext.j

ERROR: JSC_DUPLICATE_EXTERN_INPUT. Duplicate extern input: file:/.m2/repository/cljsjs/moment/2.22.2-1/moment-2.22.2-1.jar!/cljsjs/common/moment.ext.js at (unknown source) line (unknown line) : (unknown column)
ERROR: JSC_DUPLICATE_EXTERN_INPUT. Duplicate extern input: file:/.m2/repository/cljsjs/react-dom/16.3.2-0/react-dom-16.3.2-0.jar!/cljsjs/react-dom/common/react-dom-server.ext.js at (unknown source) line (unknown line) : (unknown column)
ERROR: JSC_DUPLICATE_EXTERN_INPUT. Duplicate extern input: file:/.m2/repository/cljsjs/react-dom/16.3.2-0/react-dom-16.3.2-0.jar!/cljsjs/react-dom/common/react-dom-test-utils.ext.js at (unknown source) line (unknown line) : (unknown column)

priornix04:09:59

@thomas.armstrong I think most clojure libraries are pretty stable, because the API doesn't change much. What errors are you getting? Alternatively, use npm's request library

priornix04:09:07

As for which is easier, Clojure runs on JVM far longer than on node-js. Thus there are many Clojure libraries out there compared to cljs/nodejs. As a beginner, I would say stick with JVM first, less moving parts and more "native" experience.

13tales04:09:53

The error is: Caused by: clojure.lang.ExceptionInfo: No such namespace: cljs-http.client, could not locate cljs_http/client.cljs, cljs_http/client.cljc, or JavaScript source providing "cljs-http.client" (Please check that namespaces with dashes use underscores in the ClojureScript file name) in file ... {:tag :cljs/analysis-error}

13tales04:09:00

In my code I require it with:

(:require [cljs-http.client :as client]
            [cljs.core.async :refer [<!]])

priornix04:09:09

What packaging system are you using? lein or shadow-cljs?

priornix04:09:32

You need to specify the dependencies in your project.clj

13tales04:09:11

I don't have one; I'm just using the clj cli tool as per the Clojurescript quick start guide.

priornix04:09:41

Okay, if you want to go down the nodejs route, I suggest shadow-cljs

priornix04:09:20

It manages the configuration files, and works well with npm/`yarn`. Otherwise, use leningen for the JVM.

priornix04:09:10

I haven't used deps.edn so I can't help you on that. But leiningen/`shadow-cljs` works well.

priornix04:09:51

For leningen: lein new <project-name> this creates a JVM project

priornix04:09:25

For shadow-cljs: lein new shadow-cljs <your-project>

priornix04:09:08

You need lein as a template generator, which you can install easily

13tales04:09:26

Yeah, my thought had been to try and start out with the vanilla Clojure tooling. The tooling ecosystem seems pretty bewildering if you're starting out (Leiningen, Boot, Figwheel, Shadow-cljs, Lumo, Planck, Macchiato, etc. etc.)

priornix04:09:47

Yes, correct. But the easiest approach is to start off with leningen + JVM

priornix04:09:10

That's the simplest approach. Other things like shadow-cljs, figwheel can come later.

priornix04:09:50

leningen is very simple for small projects. You do not need to understand the advanced features for now.

priornix04:09:44

So just create a lein new <project name> then add your dependencies, next run lein repl and enjoy 🙂

13tales04:09:13

Fair enough. Thanks for the feedback; very helpful. Given the scope of my intended project (ie. it could be a bash script...), any thoughts on Lumo or Planck?

priornix04:09:12

Well Lumo may not work with all cljs libraries since some libraries depend on JVM. As for Planck, I think it's the same

priornix04:09:29

For ease of learning and as a start, stick to JVM for the best library support.

priornix04:09:11

If you need speed, perhaps try GraalVM.

priornix04:09:54

You can look at compiling the JVM to native code using GraalVM later.

valtteri08:09:32

@thomas.armstrong I warmly recommend Lumo for your use-case. You can use any http library directly from npm and you get fast startup time for your script.

valtteri09:09:48

Here’s a simple example how to get started: 0. install node 1. download lumo, add it to PATH and make it executable (on a Mac as simple as brew install lumo but I think you can also use npm install -g lumo to achieve the same thing) 2. mkdir my-project && cd my-project 3. npm install request request-promise 4. touch core.cljs 5. use your favourite editor to edit core.cljs

(ns my-project.core)

(require '[request-promise :as rp])

(-> (rp "")
    (.then println))
6. save and execute with lumo core.cljs

mfikes16:09:56

No need for step 0

13tales09:09:05

@valtteri Hey, thanks a lot! I ended up trying out Planck, since in this case it seems suited for my use-case (a little script to be run from the command-line), but I'll definitely have to investigate Lumo for the future.

valtteri09:09:57

Np! Afaik the experience with Planck should be pretty much the same. Never tried it myself though.

13tales09:09:20

It seems to bundle a few useful (and idiomatic) tools, including an http library and some libraries for working with the command line, so it seemed like a good place for me to start 🙂

👍 4
valtteri09:09:09

The catch with Lumo is that you have the whole npm ecosystem at hand. In good and bad. 😉

Digital Baboon10:09:21

So like, if I have a :thing that is null, how do I check it with an if? (if (="null" :thing) :isNull :isNot) doesn't seem to work for me as expected

valtteri11:09:48

@im a couple of things here. null is named nil in Clojure(script) and there’s a core function nil? that takes one argument and returns a boolean value. Symbols that begin with : are interpreted as keywords. A keyword is never nil. https://clojuredocs.org/clojure.core/keyword Usually in Clojure(script) we check if symbol evaluates to a truthy or falsey value. Explanation what is considered truthy and what falsey can be read here starting from “Control logic” https://www.braveclojure.com/do-things/ There’s also #beginners channel with many friendly and helpful folks. You might get answers there more quickly.

valtteri11:09:00

No problem!

mfikes11:09:33

@thomas.armstrong If you end up using Planck to talk with Asana, Planck has built-in HTTP support: http://planck-repl.org/planck-http.html

mfikes11:09:03

@im To clarify a little further, both JavaScript null and undefined are the same as ClojureScript's nil. (The nil? predicate will return true for both.) If it turns out that you need to specifically identify undefined for some reason, you'd use (identical? js/undefined x)

😳 4
😮 4
jrychter19:09:16

Is there a good way to check if something is an atom/cursor in ClojureScript? Or more generally, if it is derefable?

jrychter19:09:56

(I'm having trouble with Rum cursors causing my components to re-render — I was certain that derefable things are equal, even if the pointed-to contents changes, but it seems to not always be the case?)

orestis19:09:31

Perhaps (implements? x IDeref) (I’m not sure, just speculating)? But I think trying to compare two derefable things might be a bad idea.

mfikes19:09:05

Use satisfies? with IDeref instead

mfikes19:09:49

(`implements?` is really meant for use in the std lib. It is like satisfies? but does not check for natives that extend the protocol.)

ClashTheBunny20:09:32

This may be a general clojurescript change with the updates to macros and including. Or is this just shadow-cljs?

mfikes21:09:13

FWIW, :include-macros must be followed by true. That posh ns form isn’t valid.

mfikes21:09:51

See (doc ns)