This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2015-08-10
Channels
- # admin-announcements (21)
- # announcements (1)
- # boot (91)
- # cider (2)
- # cljs-dev (46)
- # clojure (77)
- # clojure-berlin (1)
- # clojure-czech (2)
- # clojure-dev (22)
- # clojure-france (2)
- # clojure-india (1)
- # clojure-japan (16)
- # clojure-russia (6)
- # clojure-uk (1)
- # clojurescript (195)
- # cloxp (2)
- # cursive (15)
- # editors (6)
- # jobs (10)
- # ldnclj (18)
- # liberator (3)
- # off-topic (2)
- # onyx (24)
- # re-frame (4)
- # reagent (57)
anyone here used figwheel for daily development on a 10kloc or larger application? If so, how did the process scale (still < 0.25s per change? was caching assets/sourcemaps an issue? any gotchas that came up?) thanks!
what do I need to do in order for (.indexOf col x) not to give me this: Uncaught TypeError: col.indexOf is not a function
? I'm guessing it has something to do with name-mangling when the javascript is compiled?
col being normal vector
maybe (.indexOf (clj->js col) x)
hm thanks. works in repl but not my code. i probably shouldn't be using a vector here anyways
@lucien.knechtli: indexOf
isn’t a method on vectors
@paradoxquine: far as I know Figwheel is incremental so compile time just depends on the size of the file you are working on
yea, bad use of vectors anyways... What type should I be using if I want an ordered set of objects that I can insert / remove items from by index or value-match (which doesn't really matter)? sorted-map with index values as a key? The set will never be very large, and will usually be iterated over in order unless inserting/deleting.
that would be excellent. i read/saw it does minimal change calculation but don’t know enough yet to be confident in how that plays out if you have, say, an om component that depends on 20 helper files, or a helper that is used in 20 components. I recall bruce mentioned there was a core advantage in the way google closure’s dependency system works vs javascript 2015 modules/commonjs modules/etc, but not sure if that would make the aforementioned use-cases still blazingly fast
stumbled across this while searching for something else and smiled https://news.ycombinator.com/item?id=3639726
Hi. How do I install "cljs.jar standalone jar", so that I would be able to run "java -cp cljs.jar..." ?
ah, I just need to make it avaliable in PATH
if you run java -cp <path to cljs.jar>
you are explictly specifying the location of cljs.jar
Obviously u need java installed and on your path
-cp is classpath switch to tell java where to find archive files
@dnolen: the work you’ve been doing is just great. clojurescript using jsdoc to be used by the closure compiler is awesome. optional type checking using a mature tool. a big win, imho. Q: what is your stance on jsdoc type documentation for the core lib?
@dnolen: I love your comment about good for demo’s only…it’s like when I revisit architectures/applications I worked on 5-6 years ago, I’ve always moved on so much.
@rohit: if you’ve looked at core.typed at all you’ll know that Closure type annotations are far too weak to properly type many common fns. So I don’t see much value there.
@agile_geek: haha, I think most of my points are still somewhat valid if you’re talking about the web - ClojureScript was entirely focused on the web 3 1/2 years ago. good Node.js integration, React, React Native, JavaScriptCore integration, comprehensive source mapping support - none of these things existed then.
@dnolen: agree wholeheartedly. I look at message-driven architectures i designed 10+ years ago and think about how conceptually they are still valid but tools like Kafka have moved them on so much in that time.
I played with this http://slipset.github.io/posts/automator-in-clojure-script/ almost a year ago.
So the other day, I thought about getting planck to do some of the same, but I realized that osascript and javascriptcore are not the same.
But I still think it would be super-cool if one could hook into osacript from planck, allthough I have no idea how to achieve it.
@rohit: I think the type annotation support is for developers who are OK with trading less expressive variants of the core fns for compile time checking. nullability tracking is a big win in this regard. Also I think bridging pre/post conditions into type annotations would be a big win.
@rohit: so given we cannot capture all of ClojureScript semantics, we have to settle for simple type checking.
but I’m strong believer than anything that helps catches errors is always a win, regardless of the form
pre/post conditions, schema things, tests, generative tests, property tests, simple compile time checking
If I would need to convert .cljs to .js from Clojure, should I use https://github.com/bhauman/clojurescript-build , or there's some built-in thing?
@rohit: something I’ve been pondering which I think is not in the Closure Compiler authors minds yet is making Closure Compiler an extensible type checker.
so maybe in the long run could get custom annotations & analysis to capture more of ClojureScript’s semantics
@andrewboltachev: you should really look at the Quick Start for ClojureScript. https://github.com/clojure/clojurescript/wiki/Quick-Start
thanks bhauman!
@dnolen: that’ll be great. i am reading through ‘closure the definitive guide’. its really illuminating.
I am porting a JS game to cljs and have a question. I have a vector of “bullets” and a vector of “enemies.” I need to iterate over both vectors, testing if there is an collision, if so, remove the both items from their respective vectors. The Javascript code has nested for-loops and then just mutates global state to remove the items by their indexes. What function or functions should I use to accomplish this?
@monjohn: for
can take several vectors and will run with all "permutations" of the vectors
You could filter over the resulting tuples and then pull the 'dead' stuff out of your game state.
@monjohn: do you have an id for the enemies and bullets? Is the order important in how you process them? It might be better to use maps to model them instead of vectors.
I looked at for
. Since it runs over all permutations, wouldn’t that multiply the number of enemies and/or bullets?
It would give you the pair of coords for each enemy and each bullet.
Which you could then test.
Since two for-loops nested essentially does the same thing it should perform similarly.
@monjohn: The part where you test wouldn't happen in render logic.
@monjohn: consider using ids and maps then since there is no upside to using vectors. when removing the enemies, if you have an id you can use dissoc
with it. if you have a vector, you only have the position as a reference, and with each enemy you remove, the rest of the positions change. it is now your job to track them
@monjohn: also, using for
and expanding into enemies x bullets
and then filtering it is straightforward and good advice, but not necessary. Reconsider the approach if that part seems to be a performance bottleneck
It took me some typing the on repl but I see how it do it now. Thanks for the input @bensu @angusiguess @profil
This weekend, I realized I didn't have a good answer to a really common need. Let's say I have a fairly complex JSON-decoded object consisting of mixed vectors and maps. Something like this:
{:user "Alan"
:library {:albums [{:name "Excellent Music"
:artist "Jane Smith"
:tracks [{:name "Intro"
:length 1.2}
{:name "First Actual Song"
:length 3.9}]}
{:name "Also Pretty Decent Music"
:artist "Bill Jones"
:tracks [{:name "I'm Sad About Love"
:length 4.35}
{:name "Love: Pretty Sad, Guys"
:length 5.0}]}]}}
Let's say I want to let a user look up tracks and edit their names. It's easy to walk the tree to get to a specific track node, but then I'm not sure of the best way to apply that change to the entire structure. Since there are vectors, assoc-in
and update-in
don't do the job. I experimented with making a custom zipper, which comes close to working, but it's a serious hassle.
Is there a well-known solution for this kind of problem? You'd think it would be pretty common, especially in CLJS apps.(Obviously my first thought was cursors, since if I had an Om component representing one of those tracks, it would be obvious to say (om/transact! track #(assoc % :name new-name))
. But actually generating the cursor during the lookup operation is a hassle; nice thing about a zipper, if you zip/next
your way to a matching node, then zip/edit
, you can theoretically zip/root
to get the entire changed structure. On the other hand, that was one of the bugs I couldn't solve...)
@amacdougall: have you looked at Specter - https://github.com/nathanmarz/specter
Oh whoa, that could be just what I need! I'll try it out later today. Thanks for the guidepost!
@dnolen @rohit: I’m also excited to be able to offer better completion etc in Cursive with the annotations
@amacdougall: don’t know if it helps, but you can use an index into a vector as a key in (update-in)
or (assoc-in)
: (assoc-in data [:library :albums 1 :tracks 2] :name “Title”)
@amacdougall: also consider using zippers: http://josf.info/blog/2014/03/21/getting-acquainted-with-clojure-zippers
and follow-up, http://josf.info/blog/2014/03/28/clojure-zippers-structure-editing-with-your-mind/
@bhauman: I suspect that can be more easily done with the URL handler, but I don’t know the details. How much can that be customised in figwheel?
@cfleming: I'm happy to add something if you need it. I'm unfamiliar with the URL handler.
@bhauman: How are the links generated? Can that be customised? It seems like in OSX you can use an idea:// link, but I’m not sure if that’s cross platform or not. There’s also a plugin that seems to help that can use http:// links.
@cfleming: I'm really not on the same page as you right now. Not understanding what you are invoking with the link. Currently figwheel is just shelling out to a script with a file and a line number.
Actually, recent IntelliJ versions can use http:// with no plugin, like: http://localhost:63342/api/file/relative/to/module/root/path/to/file.kt:100:34
@bhauman: If you can make the filenames clickable links in that format, IntelliJ will open them (it listens on an internal server)
Having a hard time with live reloading cljs websockets: Error during WebSocket handshake: Unexpected response code: 414
OSX Firewall is off. I tried upgrading to ClojureScript 1.7.48 and Boot 2.1.2. Same issue.
414 Request-URI Too Long. Hmm, maybe too many cookies...
Upgrading Chrome seems to have solved it
@darwin: the thing about zippers is that they don't natively support a mix of sequences and maps. You have to supply custom functions to them, which requires a deeper understanding of just how they do their stuff—see http://stackoverflow.com/a/12503049 for the general approach I tried, but note that I had to include a little bit of http://stackoverflow.com/questions/15013458/clojure-zipper-of-nested-maps-repressing-a-trie to get it to work on my data structure.
@bhauman: I asked you about Figwheel over WSS on Twitter a while ago. I finally had time to get it working! I had to use nginx to reverse-proxy from an SSL endpoint (e.g. http://local.example.com:443) to <ws://localhost:3449>. It wasn't hard in any absolute sense; it just took a lot of fumbling around, and help from a friendly sysadmin.
i've also found that a bit tricky. is this a reasonable approach?: https://www.refheap.com/108050
@amacdougall: very cool, proxying seems like a requirement here. For local dev there is tunnels https://github.com/jugyo/tunnels
Is there any online reference for Closure library? https://google.github.io/closure-library/api/ looks broken
this can also be useful depending on what you’re doing https://google.github.io/closure-library/source/closure/goog/demos/
@dottedmag: I would bet that extension injects some not-very-careful code into pages most chrome extensions that i’ve seen do, and break on crazy things like a div with a classname they weren’t expecting
@dottedmag: http://www.closurecheatsheet.com/ is a great birds eye view for some important parts
very nice!
paradoxquine: This time it is dossier.js which chokes on the code injected by the extension
Hi all, can someone tell me how to determine whether an object I’ve got was created by a specific (defrecord)
call in ClojureScript?
Was trying to use (instance?)
but it doesn’t seem to be working
@timgilbert: record?
(defrecord Testing [])
=> user.Testing
(instance? Testing (->Testing))
=> true
(defrecord Testing123 [])
=> user.Testing123
(instance? Testing (->Testing123))
=> false
Hmm, yeah, that does seem to work, thanks
hey, novice question: I have a reagent project where I'm using LESS as a CSS preprocessor for static styles. Currently, I'm running lein less auto
in a separate process. However, I don't like this, and I don't like committing both the .less files and the .css files (for deployment).
I can't quite figure out how to add lein less to figwheel for dev, or to uberjar for deployment..
@martinklepsch: Sweet! Now declare
works in REPLs in master. (David took are of it here https://github.com/clojure/clojurescript/commit/5800cfba697c8c261d8a3ff4c22a49fb749a827b)
@mfikes: yeah I honestly couldn’t remember why we didn’t emit declares. I think I may have disabled it while figuring out how DCE worked a couple of years ago.
@dnolen: Cool. I’ll give it a shot and document it on the Wiki. Planck’s tests are failing with ClojureScript master, so I figure I’d start with bootstrapped unit tests.
What does Clojurescript use to find Clojure namespaces to require macros from? E.g., if I have:
Caused by: clojure.lang.ExceptionInfo: Could not locate crunch/test_macros__init.class or crunch/test_macros.clj on classpath. Please check that namespaces with dashes use underscores in the Clojure file name. {:tag :cljs/analysis-error}
at clojure.core$ex_info.invoke(core.clj:4593)
at cljs.analyzer$error.invoke(analyzer.cljc:525)
at cljs.analyzer$analyze.invoke(analyzer.cljc:2548)
at cljs.compiler$compile_file_STAR_$fn__3060.invoke(compiler.cljc:1120)
at cljs.compiler$with_core_cljs.invoke(compiler.cljc:1048)
at cljs.compiler$compile_file_STAR_.invoke(compiler.cljc:1071)
at cljs.compiler$compile_file$fn__3101.invoke(compiler.cljc:1232)
... 38 more
Caused by: java.io.FileNotFoundException: Could not locate crunch/test_macros__init.class or crunch/test_macros.clj on classpath. Please check that namespaces with dashes use underscores in the Clojure file name.
… and I have test/crunch/test_macros.clj
, which source path is missing?Okay, that’s what I thought. lein classpath has the absolute path for test/crunch
on it first, though
@pixel: chaining multiple build steps is generally challenging with leiningen. I'd recommend checking out boot which covers this use case better imo
It's a one off so I'm going to just stick with current situation, but in the future I'll look into boot
@pixel: I made a template "tenzing" that could help getting started.
Yeah, I was thinking that this is probably not the answer you were looking for but well :)
@martinklepsch: And, I already checked, meta works with declare
@pixel: boot tooling can cover most of the ground that figwheel covers (just for the record :))
@mfikes: haha yeah, I figured that out in the meantime :)
Still embarrassed by trying to get meta from the symbol, something I've been stumbling upon before 🙈
@dnolen: about to make an issue on figwheel about possibly replacing cljsbuild with the quick start’s build scripts. would you give some reasons for avoiding cljsbuild? I’ve seen you alluding to them here briefly
@dnolen: Thanks, that fixed it. Little confused as to why the default source path would be so broken, but hey, it works
@shaunlebron: the main issue is just that cljsbuild isn’t actively maintained and hasn’t kept up like other tooling has w/ the various ClojureScript changes
shaunlebron: I think that’d be a cool contribution; I think a lot of people just use it because it’s there and that’s what the template did, so
@shaunlebron: fighwheel barely uses cljsbuild anymore just the config expectations, It's been on my list to remove the absolute dependency. But people still use it. And its helpful for folks getting started to say do an advanced compile.
@bhauman: oh neat, I guess the main benefit here is to have that all the build configuration in the project.clj, looks like you are also supporting builds to be under the :figwheel
key in project.clj instead of :cljsbuild
alright, I’ll leave this issue alone since most of the work has been done
I thought there was something inherently wrong with cljsbuild since we’re basically required to use the quick start build scripts when reporting cljs bugs
wonder how we could share config between the build scripts and figwheel
I’ll file the issue
Can anyone help with this? https://github.com/plexus/chestnut/issues/149
not sure, but I put my initial thoughts here: https://github.com/bhauman/lein-figwheel/issues/209
@shaunlebron: I've been thinking about this for a while. Even though I'm very irritated with cljsbuild I don't think that discarding lein completely is a good idea. Why add extra config edn files when we already have a project.clj
?
Your comment prompted me to write this very simple plugin (right now) https://github.com/bensu/lein-cljs
It's an experiment to see if we can use the modern cljs compiler from lein without much indirection.
If it turns out to be a good idea (and we find a better name!) we could use it as a starting point for new tooling.
@dnolen: I've joked before that implementing cljsbuild
would take 5 lines, well, it took 15 including with assertions
Or perhaps we should just start with cljsbuild+
and that way we have some room to improve.
Actually, “I can’t be held responsible for the consequences” is actually a pretty good tagline for a build tool.
quick unrelated note, I'm thinking of publishing that small blogpost. where should I do that, any Clojure things besides the mailing list?
Fortunately between the ML and here, you’ll get most people in the community I think. Although I guess for an article like that you’d probably like it spread further than just people who are already converts.
I'm not going for reach, just feedback. I didn't know about Planet Clojure (really don't understand how...)
What I would like to see is a set of example scripts and tutorials that guide people on how to create their own build tools. A cookbook of build scripts that include precompilers, less etc.