Fork me on GitHub
#clojurescript
<
2015-08-06
>
nullptr00:08:31

I submitted a conj talk on cljs, hoping that this year is our breakout!

gigasquid01:08:52

If anyone wants informal feedback from me on an abstract for the Conj, feel free to ping me

gigasquid01:08:18

disclaimer: I am not involved with selection in any way

gigasquid01:08:32

But I am good at feedback simple_smile

gigasquid01:08:11

hmmm I guess I should have put this in the general channel

gigasquid01:08:19

well cross post

gigasquid01:08:09

I’ll say something ClojureScripty while I am here

gigasquid01:08:27

GO CLOJURESCRIPT!

gigasquid01:08:56

Also, now that OS scripting is getting really close, please someone make a replacement for Ansible in ClojureScript

zspencer01:08:46

ansible is great if you like writing all your logic in yaml

pre01:08:36

While migrating [garden](https://github.com/priyatam/garden/commits/master) (3000 LOC) from Cljx to Cljc, I'm stuck on few cryptic errors from cljs compiler 1.7.28. Any help appreciated!

pre01:08:51

here’s one:

Caused by: clojure.lang.ExceptionInfo: Assert failed: Argument to macroexpand must be quoted
(core/= (core/first quoted) (quote quote)) {:tag :cljs/analysis-error}
	at clojure.core$ex_info.invoke(core.clj:4593)

pre01:08:00

I get these errors while running node-repl.

pre01:08:12

Turns out I forgot to wrap a defmacro defn in :clj reader literal. If only compiler error messages could point out to the source of the problem ….

dnolen02:08:09

@pri: patches for better .cljc error messages welcome, hard to guess what people would encounter.

pre02:08:00

can you point me to the right source … as a starting point.

dnolen02:08:31

@pri: the stacktraces give you all the source locations that lead to the error

dnolen02:08:46

and every single function on the way

pre02:08:51

got it, my bad!

dnolen02:08:13

cljs.analyzer is where you want to look

dnolen02:08:23

you’ll see a bunch of multimethod cases for giving more humane errors

pre02:08:25

Back to the usage of cljc reader literals: what’s the idiomatic way of adding literals in extend-protocol

pre02:08:35

Here’s an example that is currently throwing an error:

pre02:08:16

(extend-protocol IExpandable
  #?(:clj
      clojure.lang.ISeq
      (expand [this] (expand-seqs this))
      clojure.lang.IPersistentVector
      (expand [this] (expand-rule this))
      clojure.lang.IPersistentMap
      (expand [this] (list (expand-declaration this)))
      Object
      (expand [this] (list this))
      :cljs
      IndexedSeq
      (expand [this] (expand-seqs this))
      PersistentArrayMap
      (expand [this] (list (expand-declaration this)))
      PersistentHashMap
      (expand [this] (list (expand-declaration this)))
      PersistentTreeMap
      (expand [this] (list (expand-declaration this)))
      default
      (expand [this] (list this)))

  CSSFunction
  (expand [this] (list this))

  CSSAtRule
  (expand [this] (expand-at-rule this))

  CSSColor
  (expand [this] (list this))

  nil
  (expand [this] nil))

pre02:08:55

error:

clojure.lang.ExceptionInfo: Feature should be a keyword: (expand [this] (expand-seqs this)) {:type :reader-exception, :line 274, :column 41, :file “/~/garden/src/garden/compiler.cljc"}

pre02:08:21

The only way I can get this to eval is to create separate :clj and :cljs protocols and repeat the common elements in each. I’m sure there’s a better way ...

dnolen02:08:32

@pri: I don’t see why you don’t do two top level expressions

dnolen02:08:14

#?(:clj ….) #?(:cljs …)

dnolen02:08:26

instead of #?(:clj … :cljs …)

pre02:08:47

top level seems to be taking only one form

dnolen02:08:10

you also have #?@ for splicing but you can’t do that at the top level, but doesn’t really matter much IMO

pre02:08:43

I saw that in datascript but couldn’t understand. what does it splice?

pre02:08:33

(trying your suggestion)

dnolen02:08:44

#?@(:clj [(def x 1) (def y 2)])

dnolen02:08:56

but again you cannot do this at the top-level

dnolen02:08:03

but that’s what it does

pre02:08:09

top-level as in ..

dnolen02:08:41

the top level

dnolen02:08:49

(do (defn foo []))

dnolen02:08:57

foo is not at the top level

dnolen03:08:01

(defn foo [])

pre03:08:29

So i try this:

(:cljs
      LazySeq
      (render-css [this] (map render-css this))
      ….

pre03:08:39

I still get the error Feature should be a keyword: (render-css [this] (map render-css this))

pre03:08:34

What exactly does :cljs take? A form, forms … ? In this case I’m implementing protocols.

pre03:08:26

For simpler forms it’s easy, but I’m struggling with code that has protocols or defrecords implementing protocols

dnolen03:08:52

@pri: you haven’t figured out the conditional reading syntax

dnolen03:08:03

#?(:clj single-form :cljr single-form :cljs single-form)

pre03:08:17

I agree, I haven’t. I’m guesssing from code I read simple_smile

dnolen03:08:35

@pri: if you stop guessing you’ll figure it out instantly

pre03:08:43

so here I am

dnolen03:08:55

you can only supply single forms

dnolen03:08:05

if you need multiple forms you need #?@ + vectors of forms

dnolen03:08:17

the caveat - #?@ doesn’t work at top-level

dnolen03:08:19

those are all the rules

pre03:08:23

but with extend-protocol, I’m dealing with multiple forms at each protocol level. Should I just wrap each and every protocol/impl? https://github.com/noprompt/garden/blob/master/src/cljx/garden/compiler.cljx#L270

pre03:08:24

Is there a way to avoid wrapping the reader literal at every protocol/impl level?

dnolen03:08:55

@pri: step back - I cannot see what problem you are trying to solve that I did not already answer

dnolen03:08:11

you can A) use two separate reader conditional expressions B) use reader conditional splicing

dnolen03:08:26

I do not understand how this doesn’t completely answer your question

dnolen03:08:38

if it doesn’t answer your question you need to be more clear how it doesn't

benzen12:08:18

Hi, i'm trying to use reagent/set-state, but it seems that all my instance of the same component recieve the same reageant/set-state when i change it on only one of them

benzen12:08:03

behind the sceen reageant use a var to keep the current component

benzen12:08:41

I've stored this current component on a let binding at the beging of my reagent component function

benzen12:08:28

So two questions, could we use reageant/set-state with reageant/hipcup plain function ?

benzen12:08:53

Is the dynamic nature of the \var\ related to my issue?

mfikes12:08:50

If interested in getting hands dirty with Planck dev, I’ve started marking “newbie” issues: https://github.com/mfikes/planck/issues?q=is%3Aopen+is%3Aissue+label%3Anewbie

jindrichm13:08:06

Hi, is using cljs.build.api in custom scripts now recommended over lein-cljsbuild? I got the impression that's the currently recommended practice. For example, the Clojurescript wiki doesn't recommend starting with lein-cljsbuild (https://github.com/clojure/clojurescript/wiki/lein-cljsbuild).

Tom H.14:08:23

@benzen perhaps someone in #C0620C0C8 might know

borkdude14:08:19

I discovered this function by accident: is it intended for public use, if so, in what cases would one use it? https://github.com/clojure/clojurescript/blob/master/src/main/cljs/cljs/core.cljs#L9935

mfikes14:08:20

@borkdude: Hah, I was wondering the same when I noticed that Planck auto completes it for te

dnolen14:08:00

@jindrichm: that’s not what that page says, it’s not a recommended starting point

dnolen14:08:44

lein, boot, Maven, or nothing else at all are perfectly fine ways to work with ClojureScript

benzen14:08:23

thanks @tomisme , didn't notice that there is a dedicated channel for reagent

mcgivernsa15:08:06

bit of self-promotion - I wrote a Chrome extension in Clojurescript to help with code review on GitHub - https://github.com/smcgivern/gitique

mcgivernsa15:08:47

and I very much like the usability of the build scripts, no lein or boot here, much less to think about when getting started simple_smile

jindrichm15:08:55

@dnolen: You're right. Do I read that correctly that recommended starting point is to use custom scripts using cljs.build.api?

jindrichm16:08:08

@dnolen: Is it favoured as a starting point because it doesn't hide the complexity of the build process as lein-cljsbuild does?

dnolen16:08:31

@jindrichm: build scripts aren’t any more complicated then lein-cljsbuild

dnolen16:08:50

what it does is show you how it actually works so you can diagnose the issues 3rd party tooling tends to introduce

dnolen16:08:23

also we don’t take bug reports that involve 3rd party tools anymore

jindrichm16:08:37

Yes, I very much agree with the build scripts being more transparent.

dnolen16:08:40

so if you want to file issues, it must be with ClojureScript only

jindrichm16:08:26

OK, thanks for the clarifications.

dnolen19:08:51

kinda surprised no one asked for this before simple_smile

gtrak19:08:56

node can be debugged?

gtrak19:08:05

news to me simple_smile

dnolen19:08:53

@gtrak: for at least 4 years various reasonable debugging solutions have existed

dnolen19:08:13

but the above means for Cursive users and non-Cursive users you can get decent debugging of ClojureScript on Node

teslanick19:08:48

Is line 103 strictly good practice? A discarded side effect inside a let binding?

teslanick19:08:31

(it predates the commit, so if it's bad and it works it can't be that bad, but I've never seen that before)

martinklepsch20:08:11

Anyone else getting SyntaxError: Unexpected token ; when doing (declare x)?

martinklepsch20:08:37

Only getting it when calling declare with a single arg, works with 2+.

dnolen20:08:02

@martinklepsch: I suspect this is a REPL specific issue around :def-emits-var, \cc @mfikes

mfikes20:08:23

That’s the same as (def x)

mfikes20:08:30

It won’t work in a REPL.

dnolen20:08:40

@teslanick: I wouldn’t blindly copy any idiom you find in the ClojureScript compiler

martinklepsch20:08:18

uh, interesting, thanks!

mfikes20:08:51

@martinklepsch: Turn on :repl-verbose and you’ll see why.

mfikes20:08:38

@martinklepsch: I take that back… I think you need to actually debug things to see why. But in short it becomes a NOOP which fails for the JS emitted at the REPL. I think this has been the case for at least a year.

martinklepsch20:08:30

@mfikes: "Error evaluating:" (declare test-var) :as “” this made me understand

martinklepsch20:08:13

declare only modifies the compiler env but doesn’t actually emit anything

mfikes20:08:24

@martinklepsch: Here is the JavaScript sent to the engine for (declare test-var):

javascript
(function (){try{return cljs.core.pr_str.call(null,(function (){var ret__4371__auto__ = ;
cljs.core._STAR_3 = cljs.core._STAR_2;

cljs.core._STAR_2 = cljs.core._STAR_1;

cljs.core._STAR_1 = ret__4371__auto__;

return ret__4371__auto__;
})());
}catch (e7994){var e__4372__auto__ = e7994;
cljs.core._STAR_e = e__4372__auto__;

throw e__4372__auto__;
}})()

mfikes20:08:33

So it has to do with the REPL’s “wrapping” JavaScript to instrument *1 and *e resulting in the derailment.

mfikes20:08:45

@martinklepsch: You can work around it (and cause the compiler analysis metadata to be updated) by doing something like this (do (declare test-var) nil)

martinklepsch20:08:29

@mfikes: thanks that’s very handy!

mfikes20:08:48

It could probably be fixed in cljs.repl or in the compiler (which would be nicer for the case when :def-emits-var is enabled and you are doing something like (def x)), the challenge being perhaps knowing when to do it.

martinklepsch20:08:32

@mfikes: I’m currently trying to figure out if I can declare something with metadata but it seems not possible, is that correct?

mfikes20:08:24

@martinklepsch: To be honest, for something like that, I’d fire up lein repl and see how Clojure behaves.

mfikes20:08:08

@martinklepsch: And if you find something that works in Clojure but not ClojureScript. Don’t give up. (http://dev.clojure.org/jira/browse/CLJS-1333 for example)

martinklepsch20:08:31

Well it seems to work in none of them 😛

martinklepsch20:08:03

boot.user=> (declare ^{:w true} test-var)
#'boot.user/test-var
boot.user=> (meta test-var)
nil

mfikes20:08:42

@martinklepsch: Meta is on the var

mfikes20:08:52

user=> (declare ^{:w true} test-var)
#'user/test-var
user=> (meta #'test-var)
{:ns #<Namespace user>, :name test-var, :w true, :file "NO_SOURCE_PATH", :column 1, :line 1, :declared true}

mfikes20:08:54

@martinklepsch: That works in Planck simple_smile

mfikes20:08:12

@martinklepsch: And in Ambly. So it works in ClojureScript and bootstrapped ClojureScript.

martinklepsch20:08:55

ugh, I’m so stupid 😄

mfikes20:08:25

@martinklepsch: No… you can have meta on collection values as well. Probably not what you meant but, nevertheless:

user=> (def x ^{:w true} [1])
#'user/x
user=> (meta x)
{:w true}

mfikes20:08:16

(Just saying that (meta test-var) is reasonable.)

martinklepsch20:08:46

yeah, that makes sense. Thanks!

mfikes20:08:09

I think the only other place meta can go is on symbols. (As in CLJS-1333.)

coyotespike21:08:53

I'm trying to use the Google Maps Place Search API

coyotespike21:08:10

I can successfully add a map (with the help of the reagent cookbook), and I feel like I'm really close with the Place Search

coyotespike21:08:23

Just, you know, not quite there.

coyotespike21:08:19

When I try to implement

service = new google.maps.places.PlacesService(map);
service.nearbySearch(request, callback);

coyotespike21:08:41

It fails with the error null has no properties

coyotespike21:08:39

Function looks like:

coyotespike21:08:41

(defn get-places []
  (let [lat 56.325760
        lng 44.004964
        center (google.maps.LatLng. lat, lng)
        map-opts (clj->js {:center center
                           :zoom 12})
        map-canvas  (.getElementById js/document "map-canvas")
        mappy    (js/google.maps.Map. map-canvas map-opts)

        request (clj->js {:location center :radius 10000 :types "['store']"})]

    (.nearbySearch (google.maps.places.PlacesService mappy) request 
                   (js/console.log (pr-str)))))

coyotespike21:08:15

I'm expecting to get back an array.

coyotespike21:08:04

Does anything seem obviously wrong with this?

antishok21:08:58

@coyotespike: one thing that may be affecting it is that you're just calling google.maps.places.PlacesService but in the js example you showed there is a new which you don't seem to take into account

jeremyraines21:08:21

I am trying to use transit & cljs-ajax together, but i can't seem to read the json response correctly:

jeremyraines21:08:44

(def reader (t/reader :json))

(defn render-app [resp]
  (println (t/read reader resp))
  (q/render (App) (.getElementById js/document "app")))

(GET "" {:handler render-app})

antishok21:08:49

@coyotespike: and another thing - your callback is missing a # to make it into a function. (js/console.log (pr-str)) isn't a function

jeremyraines21:08:18

I get an Unexpected end of input and an Unexpected string

antishok21:08:20

@coyotespike: and not sure what you're doing with pr-str there

dnolen21:08:49

@jeremyraines: more information - what does resp print as before attempting to read it

antishok21:08:47

@coyotespike: and, the api docs say that the request "types" option should be an array but yours is a string

coyotespike21:08:42

@antishok: thanks for the suggestions!

coyotespike21:08:08

I changed to #(js/console.log), and also tried using a plain array.

antishok21:08:37

#(js/console.log) is a function that just calls console.log with no arguments

antishok21:08:59

#(js/console.log %) would pass the first argument

jeremyraines21:08:13

[{name Pants, id 1339254, color_name Dark Gray, keywords joseph other pants joseph farfetchcom dark gray pants other pants female, large_default_image_url  {name Bag, . . .
 

coyotespike21:08:00

Even that change isn't working

jeremyraines21:08:23

oh, I get it I think. cljs-ajax is already converting it to a clojure vector

coyotespike21:08:52

I believe you initialize a new google.maps.placesService object by calling it, or assigning to a variable. The new isn't necessary.

coyotespike22:08:58

I have a function that looks pretty similar, but just makes the map, and a marker on the map.

coyotespike22:08:03

and that works...

antishok22:08:00

@coyotespike: from a simple test i'm doing (in javascript) the new is needed

coyotespike22:08:58

@antishok: yes, but not when it's translated into ClojureScript simple_smile

coyotespike22:08:05

did you get it to work in js?

dnolen22:08:31

@jeremyraines: yeah doesn’t look like JSON to me simple_smile

antishok22:08:39

not sure what you mean not when it's translated to cljs? in cljs you need to just add the dot, no?

antishok22:08:00

@coyotespike: i just got this working in js, not really familiar with the api. http://jsfiddle.net/6aucyony/1/

coyotespike22:08:16

you can see how they "translate" to CLJS

antishok22:08:40

new google.maps.Map(stuff) is tranlated to (js/google.maps.Map. stuff)

antishok22:08:02

the dot after Map is the new

antishok22:08:24

so in your code (google.maps.places.PlacesService mappy) should be (google.maps.places.PlacesService. mappy)

coyotespike22:08:48

lol I was just typing in that I tried that and that error is gone!

coyotespike22:08:05

That is pretty exciting

coyotespike22:08:28

Thanks for helping me sort through that, I'd been stuck a lot longer simple_smile

antishok22:08:52

no prob. js interop is not much fun in my experience

coyotespike22:08:15

Yeah, I'm so bad at it, but slowly getting better