Fork me on GitHub
#clojurescript
<
2015-12-30
>
johannjohann00:12:57

did a little googlin

johannjohann00:12:14

for...of is equivalent to obj.forEach

johannjohann00:12:34

which you can access in cljs with the interop syntax

dnolen00:12:12

@grav: see goog.object for many useful helpers when dealing with JS objects

dnolen00:12:24

there is an iteration helper

crocket01:12:24

Look at https://github.com/crocket/convert_to_utf8/blob/4b3bd959d4e45e53ce21d7dd90e06bda5cfe1bb6/src/cljs/convert_to_utf8/core.cljs#L69-L78 if you want to know how transducers can be modified to process a single map rather than a collection.

crocket01:12:02

Perhaps, it's not transducer. It now looks like an express.js middleware.

crocket01:12:23

So, transducer is similar to middlewares.

donmullen01:12:14

@fappy try the #C053K90BR channel

crocket01:12:33

Is there a way to use npm modules on advanced optimization mode without :externs? I run my clojurescript program on nodejs.

dnolen02:12:40

@crocket: no but there’s really few compelling reasons to use any Closure optimization setting at all under Node.js

crocket02:12:34

@dnolen: I want to shave off startup time by optimization.

crocket02:12:19

:simple optimization still doesn't break.

dnolen02:12:28

@crocket: I’ve seen scant evidence that using optimizations on ClojureScript code bases having a worthwhile gain on startup time at all especially under modern JS engine like V8

dnolen02:12:24

so in my opinion you’re just creating unnecessary complication for little benefit - happy to see numbers that prove the effort is worth the trouble

crocket02:12:32

I guess :simple optimization is a sane tradeoff for production build, then. It doesn't break external modules.

crocket02:12:47

Would the effort on :advanced optimization be worth the trouble on web browsers for now?

dnolen02:12:40

@crocket I don’t follow - Closure advanced optimizations is specifically to address web clients

mfikes03:12:03

@crocket: FWIW for minimizing startup latency in non-web applications, I tried :simple in Planck and :none actually ended up being slightly faster.

crocket04:12:22

Can cider debug clojurescript on REPL?

crocket05:12:54

How can I target a nodejs build with optimization :none?

crocket05:12:39

With :simple, there is just one javascript file. With :none, I get plain javascript files incompatible with nodejs.

crocket05:12:29

Somehow, I had to specify :main in :compiler to make my clojurescript program work with no optimization.

crocket05:12:21

On my machine, a clojurescript nodejs program boots up in 0.2 second on :simple optimization. It boots up in 0.4 second on :none optimization.

crocket06:12:08

Is there an existing function that substitutes (defn clj-fn->js [fn] #(clj->js (apply fn %&)))?

loganlinn06:12:34

(comp clj->js f) ?

crocket06:12:12

How do I translate if(require.main === module) into clojurescript? I'm on nodejs.

crocket06:12:26

(identical? (.-main nodejs/require) js/module)???

loganlinn06:12:44

looks about right

loganlinn06:12:18

> How can I target a nodejs build with optimization :none? > With :simple, there is just one javascript file. With :none, I get plain javascript files incompatible with nodejs. Not sure your use case, but :modules compiler option maybe useful https://github.com/clojure/clojurescript/wiki/Compiler-Options#modules

crocket06:12:27

@loganlinn: How do you create npm modules with clojurescript? *main-cli-fn* seems to prevent me from creating an npm module.

crocket07:12:37

It seems I have to use the following code.

;; 
(defn invoked-directly?
  "If it's required, false. If it's invoked by node.js, true"
  [] (identical? (.-main nodejs/require) js/module))

(defn -main []
  (if (invoked-directly?)
    (-main-cli)
    (set! (.-exports js/module) #js {:clean_buffer (comp clj->js clean_buffer)
                                     :clean_file (comp clj->js clean_file)
                                     :clean_file_and_save
                                     (comp clj->js clean_file_and_save!)})))

(set! *main-cli-fn* -main)

drakezhard07:12:36

Does anyone know can you change the print-length variable?

drakezhard07:12:10

*print-length*

drakezhard07:12:41

also how do you type earmuffs in markdown XD

crocket07:12:32

Surround print-length with a pair of backticks.

drakezhard07:12:41

I guess it was an issue with CIDER, set! just hanged forever, I updated it to 0.11.0-SNAPSHOT and it works now.

crocket07:12:09

Binding creates a dynamic scope.

drakezhard07:12:43

I'm sure it was CIDER because (range 0 10 0.001) hung for ever too before the update.

drakezhard07:12:19

The error was No response handler with id 4 found, I guess that nrepl was sending the js to dev/null

crocket08:12:40

How would you make an npm library that includes an executable with clojurescript? It's hard to write idiomatic code when I want to build index.js and bin/executable.js from cljsbuild and utilize index.js from bin/executable.js. Doing it seems to require using nodejs/require, and it feels weird to import index.js from bin/executable.js with nodejs/require.

jindrichm08:12:26

I'm getting java.io.FileNotFoundException: The file out/no/en/core.cljc does not exist. when running tests with lein-doo. Does it mean that compilation was unsuccessful (stack trace is not very helpful in this case)?

crocket09:12:32

@jindrichm: Did you check the file actually? By the way, I don't know any better than you.

jindrichm09:12:00

@crocket: Yes. I've found that lein-doo actually compiles JS into /out instead of /resources/public/js/out.

crocket09:12:46

.cljc is a file extension of a source code. It shouldn't be in the build folder. Or, does it compile .js into .cljc?

jindrichm09:12:32

It seems that lein clean does not clean all artifacts from previous compilations. Cleaning them manually fixes this issue for me.

jindrichm09:12:30

However, I still don't get why lein-doo compiles into /out, while lein-figwheel compiles into /resources/public/js/out.

crocket09:12:50

@jindrichm: A good way to figure out is to read their code.

jindrichm09:12:33

Now I see it's the :output-dir compiler setting that defaults to the project root. Thanks for the hints, @crocket!

jindrichm09:12:54

Is it a good idea to use the same :output-dir for both Figwheel and test runner?

crocket09:12:49

I have no relevant knowledge. Wait for someone else.

dnolen10:12:00

@jindrichm: you need to supply :clean-targets to lein, refer to lein documentation about that

dnolen10:12:08

far as doo defaults, I would refer to the docs and if they are not forthcoming - ping bensu when he is around

jindrichm10:12:13

Yes, I used :clean-targets already. The problem was that I was unaware that CLJS build without an :output-dir defaults to the /out. I think this is not specific to lein-doo.

dnolen10:12:01

@crocket: there is very little support to create ClojureScript NPM modules, very few people do this as a result. Most people targeting Node.js are just building applications or just taking advantage of the convenient REPL. If you go down this route you’ll be on your own.

dnolen10:12:14

@jindrichm: yes out is the default output directory if nothing else is supplied

crocket10:12:43

@dnolen: I'm creating a lein template for clojurescript npm modules. It is possible, but it is going to need some template for convenience.

dnolen10:12:52

@crocket: as I said not a highly recommended path unless you’re interested in a very long haul due to my above comments

dnolen10:12:21

a few people have investigated this before and it’s a lot more work to make something that people would actually want to use than it may first appear.

crocket10:12:31

I'm slowly realizing that writing an npm executable in clojurescript is not worth the effort individually.

dnolen10:12:09

At this time I would agree. Would require patches and discussion on both Closure Compiler and ClojureScript compiler dev channels if you want something useable.

crocket10:12:18

The hard part right now is launching REPL for the npm executable.

dnolen10:12:50

GSoC covered some initial work but Node.js is more complicated than CommonJS - because it isn’t actually CommonJS

crocket10:12:54

Leiningen is not suited for launching REPLs for two separate cljsbuilds.

dnolen10:12:35

yeah boot or Figwheel + Component or something like that would be more suitable

crocket10:12:11

I implemented a hack below.

:cljsbuild {
    :builds [{:id "dev"
              :source-paths ["src/cljs" "src/bin"]
              :figwheel true
              :compiler {
                :main to-utf8-unix.core
                :output-to "target/server_dev/to_utf8_unix.js"
                :output-dir "target/server_dev"
                :target :nodejs
                :optimizations :none
                :source-map true}}
             {:id "lib"
              :source-paths ["src/cljs"]
              :compiler {:main to-utf8-unix.core
                         :output-to "index.js"
                         :output-dir "target/server_lib"
                         :target :nodejs
                         :optimizations :simple}}
             {:id "bin"
              :source-paths ["src/bin"]
              :compiler {:main executable.core
                         :output-to "bin/to-utf8-unix.js"
                         :output-dir "target/server_bin"
                         :target :nodejs
                         :optimizations :simple}}]}

crocket10:12:28

The figwheel REPL has access to both library and executable. If it becomes any more complex, I'll have to consider boot.

crocket10:12:25

@dnolen: How do you think npm executable support will be achieved?

dnolen11:12:02

@crocket: I have no idea, I do not intend to work on it myself nor am I aware of anyone else that intends to. It’s also a lot of work for incredibly marginal benefit today - most users are not using Node.js on the backend.

crocket11:12:26

I guess they use clojure.

crocket11:12:34

I use node.js for shell scripts.

dnolen11:12:05

it is of interest to me but the cost / benefit ratio is way off

dnolen11:12:26

Node.js has always been a testing path, REPL thing - few users seem to care about it for anything else.

crocket11:12:03

If clojure on JVM was fast to launch, I wouldn't have had to walk on this path. I'm looking for a way to use a decent functional langauge for shell scripts. Is there an already established alternative?

dnolen11:12:18

Clojure is fine for non-trivial shell scripts, 0.5-0.7 seconds on modern hardware just makes this less and less interesting every day.

dnolen11:12:45

that said the primary use case for Clojure and ClojureScript isn’t shell scripts so again a vast lack of interest

crocket11:12:51

I vaguely remember it took 3-4 seconds on my machine....

dnolen11:12:04

maybe with Leiningen

dnolen11:12:18

but not starting up Clojure directly

crocket11:12:09

I packaged an uberjar via leiningen, and it took 3-4 seconds to make it print anything. Do you know any decent functional language for shell scripts?

dnolen11:12:36

what does uberjar have to do with shell scripts?

dnolen11:12:49

these two things in the same sentence doesn’t make much sense

dnolen11:12:06

you invoke Clojure JAR passing along the CLJ file you want to run

crocket11:12:12

I was experimenting with clojure as a potential language for shell scripts in the past.

dnolen11:12:16

this takes 0.6 seconds to start on my i7 iMac

dnolen11:12:39

if you’re building uberjars you’re not interested in shell scripts

crocket11:12:29

At this point, I am considering OCaml, Haskell, Racket, and other scheme dialects for shell scripts.

glenjamin11:12:05

What are the scenarios where you need figwheel into the executable and fast startup?

crocket11:12:26

shell script development.

glenjamin11:12:27

I'd have thought that if the startup was fast, you'd iterate by running the script again

glenjamin11:12:52

Modifying the code in-place is most useful in a long running process

glenjamin11:12:34

So you could Dev in a nodejs repl, then export to a runnable script

crocket11:12:04

@rm That's not bad, but I prefer building an actual program for my task.

rm11:12:53

so why you're trying to use compiling language for scripting?

rm11:12:03

ah wait

rm11:12:09

i saw some cheat

crocket11:12:21

REPL alleviates compiling problems.

rm11:12:21

I forgot, but there is some kind of server where you could send your clojure code and it will run it fast

rm11:12:56

also, I just have to recommend my ruby shell :) https://github.com/s-mage/rush

crocket11:12:57

Ok, I don't want to write a shell script but a small command line program. Bash is ok for composing command line programs.

dnolen11:12:21

This conversation is now becoming less relevant for this channel :) let's stay focused on ClojureScript or take it elsewhere.

crocket12:12:34

(js->clj (clj->js {:a 1 :b 2})) == {"a" 1, "b" 2}

crocket12:12:40

How can I recover keywords in a map?

crocket12:12:36

It seems {:keywordize-keys true} is needed.

crocket12:12:00

I just realized that requiring a library namespace from an executable namespace is way better than importing the library as a nodejs module.

glenjamin12:12:17

yeah, build up a lib mostly in the repl and then when you’re done expose that lib via a main function

crocket13:12:28

I created a new npm module written in clojurescript. https://github.com/crocket/to-utf8-unix

bensu14:12:46

hey @jindrichm, in case you didn't find your answer. So far, doo has no "defaults" it passes the compilation options directly to the compiler. The compiler has out as default :output-dir which is not included in lein's :clean-targets. It is not a good idea to target the test build and dev build to the same dir.

jindrichm14:12:50

@bensu: Thanks for clarification. I have eventually figured out, that my problem was indeed a generic compiler thing, rather than something specific to lein-doo.

crocket14:12:08

If multiple namespaces have *main-cli-fn* set to their own -main and :main is set to one of those namespaces, what happens to *main-cli-fn* in every other namespace?

dnolen16:12:51

@crocket: if you set dynamic vars multiple times in multiple namespaces that will just clobber the bindings if they are a part of the same build

gabe16:12:47

I realized it's only an issue using cljs.core.async

gabe16:12:19

@dnolen: i can file a bug, but wanted to make sure i’m not missing something obvious

dnolen16:12:00

@gabe: I don’t actively work on core.async

dnolen16:12:06

there’s no reason to direct anything at me about it

gabe16:12:42

i thought since it was cljs specific. my bad

dnolen16:12:29

if doesn’t have to do with the ClojureScript, core.logic, or core.match don’t assume I have anything to do with it simple_smile

dnolen16:12:46

I have worked on core.async on the past as a contributor but I was never involved in the nitty gritty compilation bits

dnolen16:12:48

only runtime perf stuff

dnolen16:12:10

I do know enough to say that sure file an issue

gabe16:12:28

should i file a bug in cljs.core.async under cljs or async?

dnolen16:12:37

but it will likely just sit around until somebody in the community starts working on it again

dnolen16:12:45

@gabe: there is only one JIRA project for core.async

grav16:12:11

@dnolen: thanks for the goog.object hint

grav18:12:15

Couldn’t find anything in the Google Closure library that works with JS iterators (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator), so I created a simple function that does:

(defn js-iterator-to-vec 
  [it]
  (loop [a []]
    (if-let [v (-> (.next it)
                   (.-value))]
      (recur (conj a v))
      a)))

grav18:12:07

@johannjohann Problem with these things are that they can only be handled with for .. of (not always forEach), or by repeatedly calling .next()

dnolen18:12:40

@grav: ClojureScript already supports them. es6-iterator-seq

grav18:12:55

@dnolen: Darn! I’ve googled "js iterator clojurescript" a million times without any luck!

dnolen18:12:18

It's a newer thing

dnolen18:12:33

Not sure if many people leverage it yet

grav18:12:56

I hereby do simple_smile Thanks!

glenjamin18:12:21

at the risk of re-opening the not-terribly-productive discussion from the other night - is there a general rule for stuff like that about whether it’ll be added to cljs.core or some other namespace?

grav18:12:32

I guess it’s much more idiomatic turning it into a seq, since js iterators can be lazy?

gabe19:12:16

@grav: yes, especially if they’re created using a generator

gabe19:12:21

i was in the middle of implementing itr->seq when i saw the reference to es6-iterator-seq

puppybits19:12:37

I published a post of how to interop with ClojureScript from vanillaJS and React. http://bit.ly/fluxless

puppybits19:12:39

And an entry into ClojureScript and how we built a full data layer for the Capital One web app. http://bit.ly/triforce-of-power

polymeris19:12:50

There is a typo in your first code example, @puppybits

puppybits19:12:40

in the data fetching section?

polymeris19:12:53

(sort ["truth" "simple" "powerful" "learn" "happy"])

puppybits19:12:20

right. thanks.

dnolen19:12:17

@glenjamin: the normal answer to whether something will be added to core is usually “no"

dnolen19:12:45

there are some caveats for interop with the changing JS ecosystem of course

dnolen19:12:12

supporting ES6 Map / Set / Iterator interfaces has obvious forward looking benefits

dnolen19:12:12

so they were added nearly a year and a half ago if I recall

dnolen19:12:04

further ES6 enhancements should be discussed in #C07UQ678E or the ClojureScript mailing list

glenjamin19:12:41

I was thinking they could go in cljs.es6 or similar - much like the nodejs and browser namespaces - would bring core into more parity. Probably not worth moving stuff that's already in though

dnolen19:12:43

@glenjamin: we’re not going to make an es6 namespace

dnolen19:12:13

the browser ns is effectively deprecated and nodejs namespace is just 2 or three helpers - so they aren’t really precedents anyhow.

glenjamin19:12:03

I guess my question was more, is 1-1 parity with clojure.core a goal?

dnolen20:12:16

sans concurrency stuff, more or less

dnolen20:12:19

but we’re already basically there

glenjamin20:12:18

I was thinking more about the other direction - how many vars are in cljs but not clojure.

dnolen20:12:07

the vars in cljs not in clojure are generally JS host-y

dnolen20:12:16

and no zero interest in keeping host-y stuff in sync

dnolen20:12:55

at least as far as going back upstream

glenjamin20:12:57

I see, host stuff you'd expect to stay at the edges of a program - and not affect portability heavily

dnolen20:12:11

we do downstream stuff like clojure.string

dnolen20:12:01

yes portable libraries keep this stuff at the edges and reader conditionals paper over the things we can’t yet or won’t ever sync up

crocket23:12:54

@dnolen : Which dynamic binding is going to win? The one in the :main namespace?

crocket23:12:16

In my experiences, the one in the :main namespace seems to win, but I don't konw if other namespaces had a chance to execute their own -main furtively.