This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-09-01
Channels
- # admin-announcements (1)
- # aws (1)
- # beginners (14)
- # boot (19)
- # cljs-dev (10)
- # cljsrn (2)
- # clojure (64)
- # clojure-android (4)
- # clojure-dev (5)
- # clojure-greece (7)
- # clojure-italy (10)
- # clojure-russia (42)
- # clojure-spec (117)
- # clojure-uk (78)
- # clojurescript (160)
- # cloverage (1)
- # conf-proposals (1)
- # cursive (8)
- # datomic (93)
- # editors (8)
- # editors-rus (5)
- # figwheel (1)
- # flambo (14)
- # hoplon (95)
- # jobs (2)
- # jobs-rus (1)
- # lambdaisland (4)
- # lein-figwheel (6)
- # leiningen (3)
- # om (106)
- # onyx (33)
- # planck (6)
- # proton (3)
- # protorepl (2)
- # random (2)
- # re-frame (9)
- # reagent (5)
- # ring (1)
- # untangled (61)
- # yada (50)
hello. i'm getting an error compiling my project with 1.9.227.... "Wrong number of args (1) passed to: nodes/ranges at line 25 target/cljsbuild-compiler-2/clojure/core/rrb_vector/trees.cljs". things work fine with 1.9.183. any help or hint appreciated!
@jao: looks like a cljsbuild plugin error
shaunlebron, yes, that was my impression too. there's no direct reference to any of my code in the full stacktrace, so i'm having a hard time discovering a workaround
@jao: are you using cljsbuild 1.1.4?
@shaunlebron i had the same error with 1.1.3
@jao: I’d report an issue, but if you’re looking for a workaround, you can convert the project to a mies-like build to see if it works that way
@shaunlebron pardon my ignorance: a mies-like build?
it’s hard to know sometimes when errors are caused by build tools, since cljs changes pretty frequently
so the Quick Start tutorial uses direct build scripts
but that setup doesn’t establish a practical way to retrieve dependencies, so “mies” is a way to use lein with those build scripts to handle dependencies
it’s something I’m trying to fix with: https://github.com/cljs/tool
but you can use lein new mies
to generate an example project with manual build scripts: https://github.com/swannodette/mies
@shaunlebron i see
it'd be nice if i could produce a minimal test case, because right now this is happening with a biggish project i cannot share
@jao: if you DM me a cljsbuild project config, I can help you port it to one of the tools above if you want
for posterity, here’s @jao’s project config migrated off cljsbuild to use direct build scripts: https://github.com/shaunlebron/migrating-off-cljsbuild
Since Elm posted a perf test, I added Respo here, Respo is totally in ClojureScript, and I got some questions, 1. Is ClojureScript essentially about 1.5 times slower comparing to native JavaScript? 2. why it looks a lot better when Timeline is running, compared to React, which is in native js?
@jiyinyiyong 1. It is not that simple. As this benchmark is for DOM libraries, I doubt language has much effect here, what this shows is that your DOM library is slower.
yeah, the result is mixed of the library and the language runtime. Have you seen some tests on ClojureScript alone? I want to compare this result with that kind of things.
Hmm, I don't remember seeing language perf results. I remember seeing some React vs. Om vs. Reagent tests but don't remember where.
@jiyinyiyong benchmarking is tricky, potential cljs slowdown compared to raw javascript can be caused by: 1) persistent data structures 2) the way how code is generated to achieve cljs semantics (wrapping code in immediately executed anonymous functions to introduce proper scoping for let, cljs truth checking, etc.) 3) DOM/browser APIs interaction In general I’m not afraid of cljs performance. I write code primarily in cljs. When I anticipate a performance-critical code I write it still in cljs but without persistent data structures using js interop. And lastly when encountering a performance issue, I use Chrome DevTools to analyze the problem and replace the hot code with a javascript implementation.
Actually I want to make sure my code is faster enough since ClojureScript is probably slower than native js. I ran out of ideas to optimize it. And I will not rewrite it with js because I will want full power of the virtual DOM in immutable data.
I'm just going to put this here 🙂 http://developers.googleblog.com/2016/08/closure-compiler-in-javascript.html
> 1. Is ClojureScript essentially about 1.5 times slower comparing to native JavaScript? @jiyinyiyong This is a tough question. There's a lot of ways to sabotage JS performance in pure JS - for instance, if you are creating a lot of classes dynamically with overloaded operators, you'll see performance degradation because the JITs aren't designed for that thing. It's harder to write this sort of thing in ClojureScript because it simply doesn't expose that stuff to you. Moreover, there are many different JS engines - Google's V8, Firefox's SpiderMonkey, Apple's Nitro, Microsoft's Chakra and Java's Nashorn. YMMV depending on what engine you are using.
Now, I'm probably going to be booted from this channel for saying this, but honestly being puritanical about writing everything in ClojureScript is silly. In ClojureScript especially, it's really easy to write vanilla JS that calls clojurescript and vice versa. Here's an example of my own - https://github.com/Sepia-Officinalis/secp256k1/blob/master/src/js/secp256k1/sjcl/hash/Ripemd160.js
@xcthulhu not completely true, we implemented Murmur3 in ClojureScript for value hashing
it does require experience to understand what style of ClojureScript produces optimal JS
Yeah, you are right. I could rewrite RIPEMD-160 in cljs using a ton of set!
assignments and it would compile to the same thing.
@jiyinyiyong Even though you can use JS side-by-side with CLJS just fine, it might not be a good idea, since I'm not sure this is officially supported and could break in a future release. Similarly, it's definitely not good practice to use (js* "...")
hey @dnolen you around? The other day you explained to me that the #js
reader happens before macro compile time, and that clj->js
happened at runtime, and a couple other similar details. So I have a macro that takes a #js
form, and I can inspect and operate on the map wrapped in that JSValue by accessing (.-val jsval)
... is there anyway to mutate that map within the JSValue? Or to create a new JSValue in it's place with the updated map? (at macro expand time)
why do you have to (:require [cljs.tagged-literals :as tags])
but (:import [cljs.tagged_literals JSValue])
@nickt hyphens are not valid in Java names, so Clojure munges them to underscores
@anmonteiro and import
references java types?
import
imports Java classes, yes
(`deftype` and defrecord
generate Java classes)
reading above — is JSValue
a placeholder for something, or like that is actual code I can use? 😜 (don’t see it here: http://cljs.github.io/api/)
@hueyp: if you look at the sidebar of http://cljs.github.io/api/ you’ll see some namespaces under “Compiler"
I decided to only document the namespaces that are public, so the Compiler’s cljs.core is just left out, where JSValue
would be
but it might be good to document those anyway since I’ve seen people here starting to use it for browsing the compiler in general
thanks, I didn’t mean it as a complaint, I just wasn’t sure if it was literally JSValue
in code or a placeholder for like JSObject
/ JSArray
/ etc in the conversation 😜 … but thanks to the docs I just looked at the reader literal source code (so thanks)
didn’t take it as one, just thought it might be a good time to clarify something that could possibly change in the future. glad the reader literal source helped!
any ideas how to work-around this? http://dev.clojure.org/jira/browse/CLJS-1631 have some code heavily using ES6 symbols and this makes cljs printing unusable for anything including symbols 😞
Hi. I'm trying to use core.async in the browser to "avoid callback hell"... and I've seen people do the following gist more or less but without setting a buffer size. When I try to do the same, my code never gets past the first put and I need to manually set the buffer size to a value greater than 1. I'm trying to basically get the code to park after step 2 to wait for a value to be put on the channel from step 1. This works but I'm wondering if I'm doing something wrong by having to set the buffer size. https://gist.github.com/jdkealy/17b4e3649c646067f666aa4cff05e7f3
@darwin will look at that one eventually but until then you’ll just have to sort out some hack on your own
I just read through the comments in other linked issues, and it looks that a performant solution will be hard to achieve 😞
(:x (atom nil))
— why does this work? Is there a use case or is that more of a coincidence?
(note the lack of deref
)
@martinklepsch it only works because keywords as a function only work on things that are associative, and return nil
when they aren't
so (:x “cat”)
will also return nil
and (:x (atom {:x "five"}))
returns nil
as well, since atoms don’t work with keywords
ugh, even strings... 😐
so rather than throwing an error to say that this type doesn’t work with keywords, it just returns nil
, assuming that because the argument doesn’t support associative values, then the value associated with the keyword doesn’t exist, i.e. nil
; which is terribly useful because this means we don’t have to make nil
a special case for associativeness and still don’t have to check to see if if a map exists before passing it into the keyword
Numbers too! (:x 5)
==> nil
@tanzoniteblack thanks for the explanation
I'm not sure I understand why this is terribly useful though. When doing (:x nil)
and that returns nil that seems handy, yes but in any other case I can think of there's likely a programming error
but I guess this is a very fundamental thing about typed vs. dynamic so I'll just accept it 🙂
@jdkealy: try using (.setTimeout js/window #(put! c “hello”) 10000)
instead, looks like >!
parks if there’s no buffer. I’ve never used >!
though
@martinklepsch I think you could override IFn
on the Keyword
deftype and make it behave your way - a great way how to confuse people reading your code 😉
Gonna put that into every library (I make) 😄
since macro arguments are not evaluated, I would assume outer-inner order
or, just try this in planck to prove it:
cljs.user=> (macroexpand-1 '(+ 1 (+ 2 3)))
(js* "(~{} + ~{})" 1 (+ 2 3))
oh, brew install planck
, it’s just a really fast native cljs repl
as well as a way to use cljs scripts as shell scripts
I really want to write a config management system in cljs via planck now. Tired of yaml as a programming language.
@selfsame As you can see it is in Alpha. If you need to build for another distro instructions here: https://github.com/mfikes/planck/tree/master/planck-c
Using goog-define
with integers appears to be broken - the cljs compiler calls .setDefineToIntegerLiteral on the closure CompilerOptions object instead of .setDefineToNumberLiteral. Does anyone know whether this has been reported?
if I get an unqualified symbol blah
how can I check whether or not it exists in a given namespace?
@tomc: search for goog-define
at top right of http://dev.clojure.org/jira/browse/CLJS, I don’t see an issue related to your problem, so you may wanna report
@shaunlebron thanks. I did the same thing but am wholly unfamiliar with jira so I assumed I'd done something wrong.
well, i don’t think anyone is wholly familiar with jira
> we compile the Java source to JS to run under Node
The path to a full-JS cljs build tool is: 1. bootstrapped compiler ✅ 2. closure compiler in js ✅ 3. maven dependency retrieval in js
getting closer!
if anyone is interested in tackling it, we essentially need this in Node: https://github.com/cljs/dep-resolver
Is there something like Clojurescripts specify
in Clojure?
E.g. I want to add a protocol implementation to a given value
@martinklepsch the design document on specify
makes no mention of one in clojure: http://dev.clojure.org/display/design/specify+i.e.+reify+for+instances
@martinklepsch by “given value” do you mean instance?
right, so that’s not possible
it’s a limitation of Java that JavaScript doesn’t have
I essentially want to create a default atom with an extra Protocol implemented and no changes otherwise
But I wouldn't really want to modify the Atom type itself
you can use reify...
but then I need to add all the default atom protocols as well, no?
hrm, probably
Ideally I'd create some kind of proxy type that would default to Atom
but extended by one protocol
@shaunlebron not sure exactly was is it that we need, do you mind expanding a little more
@martinklepsch couldn’t proxy
do the job?
clojure.lang.Atom
is a class after all
ah but it’s final
😞
@anmonteiro what does that mean? after looking at it I'm thinking it might work...
(defprotocol IDisposable
(dispose! [this]))
(defn make-disposable-atom
[]
(proxy [clojure.lang.Atom IDisposable] []
(dispose! [] (prn 'disposing))))
java.lang.VerifyError: Cannot inherit from final class
this is what I got
Ah I see
also you’d have to definterface
, not defprotocol
Well, I got to sleep but I'll get back to this tomorrow. Protocols seem to be much nicer/easier in CLJS than CLJ (interestingly)
@martinklepsch I don’t think you can blatantly say “nicer"
it’s just that JavaScript allows you to patch an Object at runtime 🙂
you can’t add methods to a Java instance, that I know of
well yes, it comes at other costs. It just seems more consistent in CLJS, probably only made possible by being dangerous elsewhere 🙂
exactly
Thanks for your suggestions Antonio. I'll see what I end up with 🙂 👋