Fork me on GitHub
#clojurescript
<
2017-10-06
>
genekim01:10:31

@paytonrules Thanks for help, folks! Actually, the Lambda Island folks sent this yesterday — and they’ve updated the repo accordingly. I now have “lein doo” working — it’s amazing to have automated tests now in CLJS! https://twitter.com/lambdaisland/status/915521175618498560

bmaddy10:10:02

Does anyone know how to make macros work with cljs.js/eval-str in a browser-repl? I'm getting TypeError: cljs.spec.alpha.coll_of is not a function:

cljs.user> (cljs/eval-str
             (cljs/empty-state)
             "(require '[cljs.spec.alpha :as s])
              (s/exercise (s/coll-of keyword?) 2)
              ;; (s/exercise keyword? 2)"
             'user-eval
             {:eval cljs/js-eval
              :ns 'user-eval
              :load (fn [_ cb] (cb {:lang :clj :source ""}))}
             (fn [res] (println res)))
{:error #error {:message ERROR, :data {:tag :cljs/analysis-error}, :cause #object[TypeError TypeError: cljs.spec.alpha.coll_of is not a function]}}
nil
If I use the (s/exercise keyword? 2) line instead, it works great. Also, (s/exercise (s/coll-of keyword?) 2) works great in the cljs repl when not using eval-str.

mfikes12:10:38

@bmaddy My initial hunch is that since your load fn is returning no source, cljs.spec.alpha is not being loaded into your JavaScript engine.

mfikes12:10:01

Another potential concern is that you are evaluating 2 forms in that string. (Your code is probably OK, but I'm more accustomed to the behavior of evaluating a single form at a time, building up state, and putting :context :expr in the opts map.)

bmaddy12:10:51

Thanks @mfikes, that's helpful. Do you by chance know where I can find some examples of how that load-fn is supposed to work? I didn't really understand it by reading the cljs.js source.

bmaddy12:10:32

Ah, I hadn't found that yet. Thanks, I'll look through that!

anders12:10:36

anyone got any clues on how to implement my type as a cljs function, accepting arguments beyond 20 args? clojure's clojure.lang.IFn protocol has applyTo which covers the case on my clj implementation, but i have yet to find something similar for my cljs implementation. cljs.core/IFn only defines -invoke

dnolen12:10:18

@anders there’s no way to do that - we never did that works since no one ever asked for it

dnolen12:10:27

the runtime stuff is mostly there - but we haven’t done the compiler work

dnolen12:10:25

the compiler isn’t that scary, if you want to try to tackle it you’re more than welcome of course. Lots of knowledgeable people in #cljs-dev if you’re interested in that

dnolen12:10:18

the compiler is simpler than a lot of front end apps I’ve seen in my time 😉

anders12:10:47

that's not really comforting at all 😂

anders12:10:05

i'll take a stab

chris13:10:01

maria geller (sp?) gave a nice overview of the cljs compiler a couple years back at the conj or euroclojure or strangeloop or some place, if that helps

dominicm14:10:53

https://clojurescript.org/news/2017-07-12-clojurescript-is-not-an-island-integrating-node-modules I'm trying to understand the part about consuming jsx as part of your project. I'm guessing this is somewhat impractical currently if you're also using, e.g. reagent. As you're not using the node version of react, but instead the cljsjs.React namespace, which isn't what it is in node-world. I'm not entirely sure I'm making sense. But essentially, I'd like to use a file from a react 15 project without modification, in an existing cljs project, using babel & such. Trying to figure out how that goes in practice.

moxaj14:10:03

say I have 3 namespaces, A, B and X. A requires X and B (in this order), while B uses X (but does not require it, for reasons). Can I trust the compiler not to warn about missing namespaces/vars while compiling B?

bja14:10:38

In practice, the way that ns macroexpands seems to allow this (following the order of the dependency lists). There is nothing in the docstring of ns or require that leads me to believe that this is required of ns or require so I'd consider it implementation specific (and recommend that you make B require X if possible).

moxaj15:10:48

sadly that's not really possible, or I haven't tried hard enough; the features of B which make use of X are gated behind closure defines because I cannot allow X to be included in regular builds

bja15:10:00

something like (when DEBUG_BUILD (X/bar)) I'm guessing

dominicm15:10:42

At the top of B

dominicm15:10:54

do:

(when DEBUG_BUILD
  (require 'X))

bja15:10:17

does require work outside of ns in cljs now?

moxaj15:10:33

@dominicm thought of this, but 2 things: 1. can I use both ns and require in the same file? 2. requires have to be top level, but I guess (when SOME_CLOSURE_DEFINE ...) is special case for the compiler?

bja15:10:31

@moxaj this seems to work and you can certainly use ns and require in the same file. I'm unsure what will happen in an advanced build, you might need to try that out. (at least via the nashorn repl)

dominicm15:10:51

require has always worked outside of ns

dominicm15:10:56

except in cljs maybe

moxaj15:10:12

@bja on it. But it'd still be nice to have a confirmation from a "higher up"

bja15:10:47

@dominicm I specifically meant in cljs. In regular clojure, ns macroexpands into the same thing as a bunch of require statements

dominicm15:10:14

I just realised I'm in #clojurescript 😛

dominicm15:10:32

well, ignore me 🙂

mfikes16:10:19

@moxaj If namespace B makes use of Vars from namespace X and it happens to be compiled when X hasn't yet been loaded, then the compiler should warn.

moxaj16:10:38

@mfikes the question then is (assuming all namespaces which require B AND make use of features which use X, require X themselves before) does compilation happen in the same order as the requires in the ns forms?

mfikes16:10:39

@moxaj At a certain point (we could look up the exact ClojureScript version if important), the compilation partial order was made to satisfy the order specified in ns forms. But, what's to prevent the compiler from choosing to compile B first?

moxaj16:10:51

@mfikes well, I don't know 🙂 That's why i'm asking, is there a guarantee? Or should this be considered an implementation detail?

mfikes16:10:54

(In fact, if :parallel-build is enabled, then B could very well be eligible to be compiled in one of the compiler threads, thus causing a race.)

mfikes16:10:51

@moxaj When a namespace is compiled, there is now a guarantee that the dependent namespaces are compiled in the order listed in the ns form. But that is insufficient to prevent B from being compiled first, given your example, because there is nothing that would cause A to be compiled first.

moxaj16:10:36

@mfikes perhaps you could comment on one of the suggested solutions above (manual "almost-top-level" require)? It seems to work, but https://anmonteiro.com/2016/10/clojurescript-require-outside-ns/ seems to suggest it shouldn't ("A file can have one of: <...>")

mfikes16:10:22

Looking at your example again, @moxaj, it would appear that a legal topological sort is B, X, A

mfikes16:10:32

IIRC you can use a top level require in lieu if an ns form.

moxaj16:10:47

@mfikes re topo sort: that's correct, so :parallel-build can screw me over

mfikes16:10:00

@moxaj Serial build can screw you over

mfikes16:10:14

(Serial build also makes a topo sort)

mfikes16:10:46

I think B, then X, then A is legal according to your example, thus causing the issue.

moxaj16:10:43

@mfikes but can I use both ns and require in the same file? If yes, then I shouldn't have to worry about topo sorts

moxaj17:10:13

the article I linked suggest that it's forbidden, but it seems to work?

mfikes17:10:35

@moxaj I don't think so. In my mind, I think of require being at the top level as a sugared form of ns.

mfikes17:10:40

Putting require and an ns form would be just as legal as putting two ns forms at the top of your file, I suspect.

moxaj17:10:07

@mfikes perhaps worth mentioning that the require forms would only be included in builds intended for self hosted environments, maybe different rules apply there

mfikes17:10:35

@moxaj I'm not aware of any different rules with respect to self-hosted for this kind of stuff.

dnolen17:10:58

in fact we intentionally avoid changing semantics for self-hosted where possible

dnolen17:10:39

generally making self-hosted more flexible just because we can is not going to happen

mfikes17:10:43

@moxaj There is some interesting stuff that is done in the spec.gen.alpha namespace with respect to lazy use of test.check (see the dynaload macro), but I'm not sure if that stuff is making use of internal implementation details

moxaj17:10:13

@mfikes I'll check that one out

mfikes17:10:33

It might be useful @moxaj — I'm speculating that you want to make use of some capability in another namespace without explicitly depending on it, but balking if that other namespace has not been loaded. The dynaload stuff smells very similar.

moxaj17:10:15

@mfikes something like that; it's actually library code which would ship a function which makes use of cljs.js, but this function would only be emitted if a certain closure define is set to a specific value

moxaj17:10:45

I don't want to explicitly require cljs.js because AFAIK that would break advanced builds

dnolen17:10:50

@moxaj you don’t need to bother with all this you know

dnolen17:10:58

put that thing in a special namespace and document it

dnolen17:10:08

if you’re users never require it, they won’t get it

dnolen17:10:30

trying to come up with something convoluted for convenience is not a good use of time IMO

mfikes17:10:25

I suppose, going with David's suggestion, the new resolve macro could prove useful: If something can be resolved, then the end-user loaded it.

moxaj17:10:56

@dnolen at first I almost headdesked, but then I realized: wouldn't this lead to a proliferation of "special" namespaces?

dnolen17:10:19

most users don’t want this special thing

moxaj17:10:11

the only objection I have to that is that it makes my API ugly

moxaj17:10:15

¯\(ツ)

dnolen17:10:13

for some personal definition of ugly 🙂

dnolen17:10:26

your users that don’t want 300k of compiler will thank you

dnolen17:10:39

and you won’t come up with some complicated solution and stay focused on providing actual value in your lib 😉

dhirensr18:10:35

can anyone help in re-learn library for reagent

(def re-learn-component
 (re-learn/with-lesson
   {:id :basic-lesson
    :description "Just testing how to use re-learn"
    :position :bottom}
   (fn []
     [:div
      [:div.h3
       [:h3 "Ich bin Dhiren Serai"]]])))

(def check-re-learn
 (re-learn/with-tutorial
   {:id :test-tutorial
    :name "check list"
    :description "create your learning components"
    :lessons [{:id :willkommen
               :description [:div
                             [:h2 "Welcome"]]}
              re-learn-component]}
   (fn []
     [:div
      [:h5 "Hallo"]
      [re-learn-component]])))

(defn mount-root
 ;;;Start of the application
 []
 (re-learn/init)
 (r/render [check-re-learn] (by-id "test")))

(.addEventListener js/document "deviceready"
                  mount-root
                  false)