Fork me on GitHub
#clojurescript
<
2018-01-31
>
jikuja06:01:06

Does anyone knowledge if with current compiler and js engines I should use advanced optimization when targeting node?

Jakub Holý (HolyJak)08:01:30

Simple is recommended I believe

Jakub Holý (HolyJak)08:01:41

Advaced rarely worth the pain

jikuja06:01:47

My target: decrease amount of minification and remove need of extern files

thheller08:01:11

:advanced is always worth it since it does a lot of performance opts as well. not super critical for node but still worth it.

madstap14:01:49

Would be nice to have a :performance option that doesn't touch the names in the code. As it is I probably wouldn't bother with the whole externs headache if I was targeting node....

jikuja13:02:20

that might be cool. Adding that into todo list

lxsameer11:01:15

hey folks, I'm looking for a stream abstraction library for cljs which covers js streams as well. any suggestions ?

pablore16:01:33

If I have a foreign-lib in my compiler options in project.clj, how do i make that external lib available un my repl session?

vemv16:01:06

A way that works for sure: Require that foreign lib in a regular ns, then (in-ns that-namespace). Dunno if one can require things dynamically.

vemv16:01:58

Any known way to skip arity checking?

vemv16:01:29

e.g I want to pass 3 args to a 2-arg defn. 3rd argument should just get skipped

mfikes16:01:57

@vemv If you are interested in bypassing the analyzer, arity is “stripped” if you use def.

cljs.user=> (defn foo [a b] 1)
#'cljs.user/foo
cljs.user=> (def bar foo)
#'cljs.user/bar
cljs.user=> (bar 1 2 3)
1

mfikes16:01:38

I don’t know if that is guaranteed to be the case, but that is the way things currently behave.

vemv16:01:27

interesting! although I'd need something dynamic. I cannot refactor (literally) 1000 defns. I could spend the same time going defn-by-defn, adapting signatures

mfikes16:01:22

@vemv If you are simply interested in suppressing the arity warnings, that is also possible.

vemv16:01:44

they throw at runtime: Invalid arity: 3

mfikes16:01:54

Hmm. What is doing that?

vemv16:01:16

Bit difficult to debug. But can investigate

mfikes16:01:22

(Normally arity checks are simply a warning)

mfikes16:01:31

I mean, try calling the example foo above with 3 arguments, and it will simply warn at analysis time, but at runtime will still return 1.

vemv16:01:09

True, thanks for the hint. The error is there though 😕

mfikes16:01:05

Ahh, you have a multi arity function.

cljs.user=> (defn foo ([x] 1) ([x y] 2))
#'cljs.user/foo
cljs.user=> (foo 1 2 3)

mfikes16:01:47

In that case, this is not an analysis issue; it is baked into the emitted JavaScript.

vemv16:01:44

Yes! I see so in the compiled JS. Would have taken me a while to realise it was caused by mutli-a defns. 🍻

joelsanchez16:01:45

you may be able to use the meta to develop a function or macro that will call the function properly

cljs.user=> (defn mytest [a b c] a)
#'cljs.user/mytest
cljs.user=> (meta #'mytest)
{:ns cljs.user,
 :name mytest,
 :file nil,
 :end-column 13,
 :column 1,
 :line 1,
 :end-line 1,
 :arglists ([a b c]),
 :doc nil,
 :test nil}

vemv16:01:49

Cool! Would that survive advanced compilation?

joelsanchez16:01:06

I'd say "not likely" but who knows 🙂

maxt17:01:02

Is there anyway I can run a command after the nrepl has started? I'm using Cursive with figwheel, and I'd like to do a (do (start-figwheel!) (ra/cljs-repl)) automatically. If I put it in user.clj it won't return so I get a No nREPL ack received.

noisesmith17:01:08

if it doesn't return, maybe it should be in a thread?

noisesmith17:01:26

perhaps with a top level handle for the future running the thread for convenience

noisesmith17:01:16

oh wait you want to run a repl and connect it to *in* / *out* - that's tricky

maxt17:01:58

Ah, right, that's what I want.

noisesmith17:01:04

perhaps there's a good way to start the repl with InputStream / OutputStream, and store those so you can connect them to *in* and *out* in a scoped way but still escape to the owning process?

noisesmith17:01:19

maybe there's some tool that does this stuff already - I hope so

maxt17:01:20

Maybe I really want two repls in Cursive, one clojure and one clojurescript. Then maybe I can start the figwheel compiler in one and the cljs-repl in the other. And if I can make cursive automatically launch the server repl when I launch the client repl I should be good

noisesmith17:01:34

or perhaps since it's nrepl, tell it "connect this specific connection's *in* and *out* to the cljs repl, and then you can still access the actual nrepl in another connection

noisesmith17:01:42

that might be what piggyback does already?

noisesmith17:01:05

or it's at least strongly related to piggyback (which IIRC figwheel uses)

maxt17:01:05

I clearly don't know what I'm doing 🙂

noisesmith17:01:34

haha - I'm also not the best expert - but I bet if you read some docs on piggyback and weasel and figwheel you might capture a glimpse of what you need

maxt17:01:35

piggyback is being loaded yes

maxt17:01:39

:repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}

noisesmith17:01:16

right, my hunch is the thing you want can be done via some piggyback tricks

maxt17:01:20

reading the source

rauh17:01:59

@maxt There is :injections in leiningen. Though, why not just create a (defn go! [] ...) that you call?

maxt17:01:26

@rauh I do have a go! but I'd like to be able to just push the big green ▶️ play button in Cursive.

maxt17:01:56

Mostly to have the project to be supereasy to get started with

scaturr17:01:10

does anyone have a recommendation for working with IndexedDB in cljs?

scaturr17:01:16

or some alternative?

gganley19:01:07

Hello, I’m trying to use emacs+cider for clojurescript but when I launch the cljs REPL the js symbol isn’t bound to anything, following is my project.clj and I run cider-jack-in-clojurescript and after it loads js is not bound to anything

gganley19:01:10

If more information is needed to get a grasp I’d be more than happy to provide it

gganley19:01:38

the only other tidbit I think that may be needed is that I have Java 9 on my system

gganley19:01:55

;; CIDER 0.17.0snapshot (package: 20180124.1228), nREPL 0.2.13
;; Clojure 1.9.0, Java 1.8.0_162

gganley19:01:07

I guess java 8

hoppy19:01:51

@gganley, in my setup I wind up with two repls, one for clojurescript and one for clojure. The latter also has to go through being clojure, but then bootstraps into clojurescript repl from there, at least in my world.

gganley19:01:09

Yes that also happens with mine

gganley19:01:18

I end up with a clojure repl and a clojurescript repl

gganley19:01:59

in the clojurescript repl js is not bound to anything but operactions such as (+ 1 1) work just fine

noisesmith19:01:48

I thought I said this before, and this might be a miscommunication, but js shouldn't be bound, but things like js/window should be

noisesmith19:01:56

js is a pseudo-namespace not an actual thing

hoppy19:01:30

the acid-test to see if it's a cljs repl is seeing what it does with ':cljs/quit'

gganley19:01:15

brings me out of cljs.user and puts me into user

gganley19:01:50

and I mispoke I meant to say nothing can be accessed that has the prefix js/

gganley19:01:14

so no js/console etc

gganley19:01:39

Is there a way to print out all available functions from the repl?

gganley19:01:47

like available in the local namespace

greglook19:01:29

(ns-interns *ns*) and (ns-aliases *ns*), ns-refers, etc.

greglook19:01:20

actually, not sure if those work in cljs :thinking_face:

noisesmith19:01:23

those things work in cljs?

greglook19:01:47

forgot what channel I was in 😅

gganley19:01:55

Not sure if it helps debug this but I was digging and came accross loaded-libs

#{"cljs.spec.gen.alpha" "clojure.walk" "goog.object" "clojure.string" "cljs.repl" "goog.string" "cljs.spec.alpha" "cljs.core" "goog.string.StringBuffer"}

gganley19:01:26

Does that help any?

noisesmith19:01:28

@gganley maybe this would help

+cljs.user=> (require '[goog.object :as gob])
nil
+cljs.user=> (gob/getKeys js/global)
#js ["g__18723__auto___18933" "g__18749__auto___19193" "g__18749__auto___19230" "COMPILED" "g__18749__auto___19189" "g__18723__auto___18980" "initialize" "g__18749__auto___19272" "cached_var_17060" "g__18723__auto___19019" "g__18723__auto___18937" "g__18749__auto___19276" "g__18723__auto___18999" "g__18749__auto___19289" "lazy_map" "g__18749__auto___19185" "TRANSIT_NODE_TARGET" "lumo" "cognitect" ... (lots of boring stuff here) ...]

noisesmith19:01:47

of course if js/global can't be found either...

noisesmith19:01:46

equivalent:

+cljs.user=> ((js/Function. "return goog.object.getKeys(global)"))
#js ["g__18723__auto___18933" "g__18749__auto___19193" "g__18749__auto___19230" "COMPILED" ... (etc.)]

noisesmith20:01:47

@gganley wait, could this be because you explicitly named something js as a prefix in your namespace? if you did that who knows what happens next...

dpsutton20:01:53

this is a surprising divergence from clojure.

(assoc {}
       :a 1
       :b 2
       :c
       :d 4)
in cljs is {:a 1, :b 2, :c :d, 4 nil} and an illegal argument exception in clj

noisesmith20:01:29

@dpsutton I think that's unavoidable because js lets you leave out args and they just show up as nil when the function looks at them

dpsutton20:01:04

i guess. but i feel like an assert even? might be in order on this one

gganley20:01:13

No this is without declaring anything, let me check my .lein/profiles.clj though

gganley20:01:02

That shouldn’t effect anything

gganley20:01:43

#js ["___repl_env" "__repl_opts" "out" "err" "CLOSURE_IMPORT_SCRIPT" "global" "goog" "COMPILED" "G__12011_12014" "G__12010_12013" "G__12009_12012" "G__11768_11771" "G__11767_11770" "G__11766_11769" "G__11652_11655" "G__11651_11654" "G__11650_11653" "G__11618_11621" "G__11617_11620" "G__11616_11619" "G__11561_11564" "G__11560_11563" "G__11559_11562" "G__11551_11554" "G__11550_11553" "G__11549_11552" "G__11505_11508" "G__11504_11507" "G__11503_11506" "G__11421_11424" "G__11420_11423" "G__11419_11422" "G__11409_11412" "G__11408_11411" "G__11407_11410" "G__11388_11391" "G__11387_11390" "G__11386_11389" "G__11375_11378" "G__11374_11377" "G__11373_11376" "G__11330_11333" "G__11329_11332" "G__11328_11331" "G__11317_11320" "G__11316_11319" "G__11315_11318" "G__11263_11266" "G__11262_11265" "G__11261_11264" "G__11199_11202" "G__11198_11201" "G__11197_11200" "G__11150_11153" "G__11149_11152" "G__11148_11151" "G__11142_11145" "G__11141_11144" "G__11140_11143" "G__11111_11114" "G__11110_11113" "G__11109_11112" "G__11089_11092" "G__11088_11091" "G__11087_11090" "G__11077_11080" "G__11076_11079" "G__11075_11078" "G__10504_10507" "G__10503_10506" "G__10502_10505" "G__10324_10327" "G__10323_10326" "G__10322_10325" "G__10313_10316" "G__10312_10315" "G__10311_10314" "G__10290_10293" "G__10289_10292" "G__10288_10291" "G__10274_10277" "G__10273_10276" "G__10272_10275" "G__10266_10269" "G__10265_10268" "G__10264_10267" "G__9809_9812" "G__9808_9811" "G__9807_9810" "G__9802_9805" "G__9801_9804" "G__9800_9803" "G__9788_9791" "G__9787_9790" "G__9786_9789" "G__9740_9743" "G__9739_9742" "G__9738_9741" "G__9734_9737" "G__9733_9736" "G__9732_9735" "G__9728_9731" "G__9727_9730" "G__9726_9729" "G__9719_9722" "G__9718_9721" "G__9717_9720" "cljs" "clojure" "g__19782__auto___21417" "g__19782__auto___21413" "g__19782__auto___21409" "g__19782__auto___21405" "g__19782__auto___21401" "g__19782__auto___21397" "g__19782__auto___21393" "g__19782__auto___21389" "g__19782__auto___21385" "g__19782__auto___21381" "g__19782__auto___21377" "g__19782__auto___21373" "g__19782__auto___21369" "g__19782__auto___21365" "g__19782__auto___21361" "g__19782__auto___21357" "g__19782__auto___21353" "g__19782__auto___21349" "g__19782__auto___21345" "g__19782__auto___21341" "g__19782__auto___21337" "g__19769__auto___21312" "g__19769__auto___21308" "g__19769__auto___21304" "g__19769__auto___21300" "g__19769__auto___21296" "g__19769__auto___21292" "g__19769__auto___21288" "g__19769__auto___21284" "g__19769__auto___21280" "g__19769__auto___21276" "g__19769__auto___21272" "g__19769__auto___21268" "g__19769__auto___21264" "g__19769__auto___21260" "g__19769__auto___21256" "g__19769__auto___21252" "g__19769__auto___21248" "g__19769__auto___21244" "g__19769__auto___21240" "mkg_21220" "g_21219" "g_QMARK__21218"]

gganley20:01:59

that is the output of

(gob/getKeys js/global)

noisesmith20:01:13

OK - so js/goog should give you the global for the goog library, etc.

gganley20:01:52

wait js/global is defined

gganley20:01:59

how strange

noisesmith20:01:56

I would expect that - looks like the js pseudo-scope isn't broken (which is a relief) - it's just that it doesn't have some things you might expect to find in it

noisesmith20:01:11

it could be because you are using an odd vm, or code is making invalid assumptions about what vms provide

gganley20:01:28

vm as in jvm?

gganley20:01:36

no that’s normal clojure

gganley20:01:42

are we speaking of Rhino?

noisesmith20:01:44

I mean js vm

noisesmith20:01:53

Rhino is one js vm, is it the one you are using?

gganley20:01:00

let me see

gganley20:01:16

"(cemerick.piggieback/cljs-repl (cljs.repl.rhino/repl-env))"

gganley20:01:36

so yes rhino in the piggieback wrapper

noisesmith20:01:19

it lacks a bunch of the globals that a lot of js and cljs assumes

gganley20:01:34

Ok I’ll switch to node for a moment one sec

noisesmith20:01:36

I'm feeling much more sane now

gganley20:01:32

It sucks Rhino is the default if half the code has (js/alert ...) etc

noisesmith20:01:02

yeah - sounds like something that calls for a fix or a change of defaults or something...

gganley20:01:41

@U051BLM8F is here, I can talk to him

joelsanchez20:01:33

regarding the ns-interns in cljs thing...

(defmacro get-current-ns-interns []
  (let [current-ns (:name (:ns &env))
        the-keys (cljs.analyzer.api/ns-interns current-ns)]
    `(~'quote ~the-keys)))
now you do this (cljs.pprint/pprint (ventas.macros/get-current-ns-interns)) I got:
{page
 {:protocol-inline nil,
  :meta
  {:file "/home/joel/Desarrollo/self/ventas/src/cljs/ventas/core.cljs",
   :line 52,
   :column 7,
   :end-line 52,
   :end-column 11,
   :arglists '([])},
  :name ventas.core/page,
  :variadic false,
  :file "/home/joel/Desarrollo/self/ventas/src/cljs/ventas/core.cljs",
  :end-column 11,
  :method-params ([]),
  :protocol-impl nil,
  :arglists-meta (nil nil),
  :column 1,
  :line 52,
  :end-line 52,
  :max-fixed-arity 0,
  :fn-var true,
  :arglists '([])},
 app-element
 {:protocol-inline nil,
  :meta
  {:file "/home/joel/Desarrollo/self/ventas/src/cljs/ventas/core.cljs",
   :line 60,
   :column 7,
   :end-line 60,
   :end-column 18,
   :arglists '([])},
  :name ventas.core/app-element,
  :variadic false,
  :file "/home/joel/Desarrollo/self/ventas/src/cljs/ventas/core.cljs",
  :end-column 18,
  :method-params ([]),
  :protocol-impl nil,
  :arglists-meta (nil nil),
  :column 1,
  :line 60,
  :end-line 60,
  :max-fixed-arity 0,
  :fn-var true,
  :arglists '([])},
 init
 {:protocol-inline nil,
  :meta
  {:file "/home/joel/Desarrollo/self/ventas/src/cljs/ventas/core.cljs",
   :line 63,
   :column 7,
   :end-line 63,
   :end-column 11,
   :arglists '([])},
  :name ventas.core/init,
  :variadic false,
  :file "/home/joel/Desarrollo/self/ventas/src/cljs/ventas/core.cljs",
  :end-column 11,
  :method-params ([]),
  :protocol-impl nil,
  :arglists-meta (nil nil),
  :column 1,
  :line 63,
  :end-line 63,
  :max-fixed-arity 0,
  :fn-var true,
  :arglists '([])},
 start
 {:protocol-inline nil,
  :meta
  {:file "/home/joel/Desarrollo/self/ventas/src/cljs/ventas/core.cljs",
   :line 83,
   :column 16,
   :end-line 83,
   :end-column 21,
   :export true,
   :arglists '([])},
  :name ventas.core/start,
  :variadic false,
  :file "/home/joel/Desarrollo/self/ventas/src/cljs/ventas/core.cljs",
  :end-column 21,
  :method-params ([]),
  :protocol-impl nil,
  :export true,
  :arglists-meta (nil nil),
  :column 1,
  :line 83,
  :end-line 83,
  :max-fixed-arity 0,
  :fn-var true,
  :arglists '([])},
 on-figwheel-reload
 {:name ventas.core/on-figwheel-reload,
  :file "/home/joel/Desarrollo/self/ventas/src/cljs/ventas/core.cljs",
  :line 87, 
  :column 1, 
  :end-line 87, 
  :end-column 25, 
  :arglists '([])}}

noisesmith20:01:43

you could convert the long comment into a "paste" so it is collapsed by default right?

noisesmith20:01:46

slack is weird

gganley20:01:12

That’s fine, there is the ability to add code snippets using the plus button thing to the left

joelsanchez20:01:57

well, gets the point across

joelsanchez20:01:23

thank you, clearly I need more slack-fu

gganley20:01:45

plus button -> add snippet -> top right add font coloring thingy

gganley20:01:44

It says that the macro get-current-ns-symbols is not callable because it fails symbol? which is frightening

joelsanchez20:01:13

idk, I got it to run here

joelsanchez20:01:01

i guess ¯\(ツ)

gganley20:01:10

alright I’m going to try an build up from just bare lein

gganley20:01:21

Ok so node has console

gganley20:01:30

js/console that is

noisesmith20:01:23

yes, that's my experience as well

gganley21:01:03

ok, esentially this was much ado about nothing, just needed to change to nodejs

gganley21:01:36

Thank you folks for your help

cfleming21:01:13

@maxt I’m actually planning to do exactly what you describe with two REPLs in Cursive.

richiardiandrea21:01:03

So I just discovered that you cannot close an async/promise-chan at least in lumo. Did not know that, I was wondering if it matches expectations

noisesmith21:01:37

@richiardiandrea you can close it,but if it ever got a value it will continue to return that value

noisesmith21:01:59

I remember an extensive conversation about this, iirc there were very weird gotchas for any other behavior

richiardiandrea22:01:15

@noisesmith that's right, so I misinterpreted it and actually the doc does not mention that. So I was using it with into and everything was (of course) stuck 😉

richiardiandrea22:01:17

it is still a bit counter intuitive imho, as you would expect a closed chan to return nil, but well...it is what it is