Fork me on GitHub
#clojurescript
<
2015-07-09
>
dnolen02:07:20

^ the Gregor Kiczales talk

dnolen02:07:19

Sadly now w/o images but also a big source of inspiration by Kiczales http://people.engr.ncsu.edu/efg/517/f00/syllabus/annotations/lec13.html

dnolen02:07:37

“Why are black boxes so hard to reuse?"

afhammad05:07:25

core.async gives zero hints as to where an error is happening (difficult when you have quite a few go blocks), will this ever improve?

martinklepsch08:07:19

@afhammad: you stack traces get lost? In newer versions of chrome this should work I think. There is something about that I'm the re-frame wiki

a.espolov08:07:35

Guys fn cljs.test.run-tests should return something?

mikethompson08:07:46

@afhammad: recent versions of Chrome are waaaaaaaay better at giving you a proper stacktrace from within a core.sync go loop.

mikethompson08:07:56

So using Canary may be worth your time

crisptrutski08:07:17

@a.espolov: it’s async, hence no return value (in earlier version the results were returned)

mikethompson08:07:35

@afhammad: background: Chrome 43 (and prior) does not give proper stack traces when an exception is rethrown ... it reports the stack trace for the rethrow point, rather than the original throw point ... and core.async go-loops catch exceptions and rethrow them. Result: useless stacktraces

mikethompson08:07:18

Summary: use Chrome 44 (Canary?) for debugging anything involving core.sync. Chrome Stable is currently 43.

crisptrutski08:07:40

@a.espolov: the best way to get at the results is to extend the cljs.test/report multimethod to create a custom reporter

a.espolov08:07:58

@crisptrutski: I did so, but there is a but(

a.espolov08:07:04

in the js script that I run into phantom js. I expect that will return 0 or 1.

a.espolov08:07:07

And there's always 0 returned and finally I have the step of testing in the CI all OK, and on the fact the console was hatched testing errors(

crisptrutski08:07:51

not familiar with vovzvraŝaetsâ - but good thing you had zero of those (sound scary)

a.espolov08:07:21

"vovzvraŝaetsâ" - returned

crisptrutski08:07:56

maybe you want something like this in your reporter? (when (pos? (:fail m) (System/exit 1))

Petrus Theron08:07:32

In breaking up my growing cljs app into functional modules (as opposed to concerns like handlers, views and subscriptions), I find myself having to :require the same list of dependencies in each file. Is there a way to include a preset list of deps in each file? :use comes to mind, but it's considered "bad style".

crisptrutski08:07:14

clojurescript doesn’t have a wildcard :use, so not sure that’s relevant 😉

crisptrutski08:07:42

in clj some libraries (eg timbre) provide macros to load all the namespaces and refer particular things

crisptrutski08:07:06

but i don’t think cljs has a require statement (i could be wrong though.. i know cljs repls do, the boot one at least)

crisptrutski08:07:01

here’s @luke saying that there’s no require statement, but that might have changed http://stackoverflow.com/questions/12879027/cannot-use-in-clojurescript-repl

a.espolov08:07:07

@crisptrutski in cljs (System/exit) ?)

crisptrutski08:07:05

good point. are you using lein or boot?

crisptrutski08:07:07

cljs-build should be taking care of exiting with the right code, guess i need to know more about the task your ci is running

Petrus Theron08:07:00

Can I write a macro that expands into the (:require ...) statement that I need?

crisptrutski08:07:45

@petrus (ns ..) is a macro in cljs I believe, so it executes before the inner forms

crisptrutski08:07:18

perhaps you can use a macro to generate the ns form itself.. not sure

crisptrutski08:07:35

chicken and egg actually - how do you load that macro without an ns form

crisptrutski08:07:40

maybe you can have repeated ns forms though?

crisptrutski08:07:43

out of my depth here

crisptrutski08:07:26

think there’s a reason implicit requires not in clojure though - think grinning and bearing the imports is more “simple”

crisptrutski08:07:53

depending on what the concerns actually are, should be able to have a small stable set of namespaces you boilerplate

Petrus Theron08:07:08

Hmmk. I want to save myself having to import each function as I need it, because there is a set of common functions that each functional module eventually needs.

crisptrutski08:07:23

just alias the namespace rather than refering to functions

crisptrutski08:07:26

@a.espolov: ok, so it’ll come down to how you’re loading that html

crisptrutski08:07:06

could throw an exception in the reporter and listen for exceptions in the html runner - that was the approach taken in the repo i linked you to

Petrus Theron08:07:33

Hmk. Last thing on deps: can I have a "base" ns that pools in some common functions and exposes it through a hypothetical :export, e.g. (ns myapp.utils (:require [myapp.events] :export [handler-fn] ...) so that anything that aliases myapp.utils :as utils can refer to utils/handler-fn?

Petrus Theron08:07:26

...instead of each sub namespace having to :require myapp.events.

crisptrutski09:07:23

potemkin provides the classic macro for re-exporting vars in clojure (and people have often rolled their own thing)

crisptrutski09:07:48

there are people doing it with clojurescript too, but no canonical version i’ve seen, no tricks without their flaws afaik

crisptrutski09:07:13

saw discussion on re-frame around doing exactly that - suggest skimming their issues and seeing where things are at

borkdude10:07:55

@dnolen: is it ok if I use your core.async webinar examples for a talk about clojurescript?

borkdude10:07:06

@dnolen: of course with full credit simple_smile

dnolen10:07:40

@petrus @crisptrutski fwiw I don't think things like Potemkin are any good. It’s become idiomatic to just alias a ns and not even bother with :refer most of the time.

dnolen10:07:12

also in the ClojureScript context I would avoid any Potemkin like thing until somebody proves it does not defeat dead code elimination.

pyr12:07:21

@dnolen do you have examples of people already leveraging an om-next approach in the wild ? I'm most interested in seeing how they wrap around the persistence layer to expose a query route which handles auth, scoping & similar matters

pyr12:07:40

(hi btw)

dnolen12:07:48

@pyr: nope and I’m unlikely to ever provide such a thing.

dnolen12:07:53

problems for other people to sort out.

pyr12:07:02

@dnolen: this much i got from what you produce simple_smile

pyr12:07:15

@dnolen: was just interested in knowing if it was a problem already tackled somewhere

dnolen12:07:33

yeah I’m just not interested in obviously solveable problems

dnolen12:07:42

Facebook did it, Netflix did it

dnolen12:07:47

it’s just boring and not part of the big picture

pyr12:07:11

no need for the argument, I get your point

dnolen12:07:14

and not just boring, very app specific

dnolen12:07:29

not arguing

dnolen12:07:42

just clarifying, people keep asking this question, now they can read the backlog

pyr12:07:53

ack. thanks for the clarifications

pyr12:07:07

I also get the point about it being app (and very much persistence layer) specific

dnolen12:07:48

similarly why we probably won’t do anything really deep about sorting or paging

dnolen12:07:01

all this stuff ties deeply into what the backend actually looks like

pyr12:07:12

yes, gotcha

pyr12:07:30

my naive vision was that there might be room for a somewhat generic query endpoint which would support wrappers to do pre-flight checks on a request, but it might indeed end up being so generic that it wouldn't be very useful

pyr12:07:55

one last question re: om-next. is an approach similar to what fb relay's seem to use for mutation (optimistic updates, and available mutations) likely to end up in components or do you expect this to be provided by 3rd parties as well

dnolen12:07:20

there will probably a be a basic router thing supplied a la Falcor

dnolen12:07:32

but we’re talking a couple hundred lines of code at most

dnolen12:07:41

people can use that as a jumping off point

pyr12:07:22

(referring to the points mentioned in: https://speakerdeck.com/laneyk/mutations-in-relay)

dnolen12:07:31

optimistic updates and change tracking will never be supplied by default

dnolen12:07:39

again assumes too much

dnolen12:07:06

however, again we’ll supply a store that can do this if you couple it to the router I mentioned and you have Datomic as your DB

dnolen12:07:31

this will just work, but they will be simple components, again easy to study and supply your own thing

dnolen12:07:17

so we’re more like Falcor in this regard, no assumptions about what your stack is capable of

dnolen12:07:36

but we’ll ship a full working basic example of the machinery required to accomplish a full Relay thing.

dnolen12:07:39

for auth the idea is you should just be able to do what you were always doing.

dnolen12:07:49

introducing any kind of novelty here doesn’t make much sense

pyr12:07:16

yup. (my main concern regards authorization, not authentication)

pyr12:07:25

but this paints a much clearer picture, thanks a lot for clarifying

dnolen12:07:42

authorization is very much a query storage level concern

dnolen12:07:00

it’s not like Om Next actually encourages running queries directly at all

dnolen12:07:14

like Falcor and Relay there is a notion of a “root"

wildermuthn12:07:23

Hello Clojurescript world.

dnolen12:07:39

this thing is the real query with whatever policies in place

dnolen12:07:48

leveraging pull just lets client get exactly the side information they might need - but sanitizing the keys, filtering the database - that’s the code you have to write.

wildermuthn12:07:36

Hi! A millions thanks for the work you’ve done on Clojurescript!

pyr12:07:18

@dnolen: awesome. I'll tackle this to see if I end up with something satisfying enough, every excited by the direction om-next goes in, thanks again

pyr12:07:45

s,every,very

dnolen12:07:56

@wildermuthn: thanks, but there’s a lot of people to thank these days, a 108 last time I checked 😉

wildermuthn12:07:40

Is there a cljs repl that supports tab completion?

dnolen12:07:07

@wildermuthn: nothing out of the box at the command line that I’m aware of, I think only Cursive and Cider reliably support that.

wildermuthn12:07:10

ok thx. I use vim, so that’s probably my first problem.

wildermuthn12:07:51

Fireplace is great, but without knowing vimscript, kind of limiting.

dnolen12:07:00

Yeah not a VIMer myself so I can’t offer much guidance.

tcrayford12:07:41

@wildermuthn: think fireplace can't offer completion in the places where you enter commands (the pseudo-repl), due to vim limitations 😞

wildermuthn12:07:40

@tcrayford: that’s been my experience, so I use figwheel’s repl most of the time unless I’m doing inline evaluation of a form. More often than not, I’ll use a #_ (…) and evaluate from vim rather than switch to the repl.

wildermuthn12:07:55

So when I have a bug inside a go loop, the dev tools call stack doesn’t always give me information I understand:

wildermuthn12:07:37

The exception helps, in that it tells me I’m conjoining with a bool, but is there data somewhere inside the call stack that would help me identify where?

wildermuthn12:07:23

Fairly often, printing out the exception to the log will give me a line number. But sometimes not.

dnolen12:07:44

Chrome bug, fixed in Canary based on what other users have been saying

wildermuthn12:07:48

Hmm, same with Canary. I think I figured out what’s happening. The go loop is inside a macro. When I create the same bug manually, without a macro, I get the right call stack.

dnolen13:07:01

@wildermuthn: if you don’t have a line number is seems like the actual bug has not been solved

wildermuthn13:07:22

Right. I mean that I narrowed down when the bug occurs for me. I’m looking through the issues on dev.clojure for mention of something like this.

dnolen13:07:04

dev.clojure?

dnolen13:07:40

Right you want to search ClojureScript tickets

dnolen13:07:04

but even so do not open a ticket about stuff like this unless you’ve absolutely determined it isn’t a Chrome issue

dnolen13:07:08

we’ll never look at it otherwise.

dnolen13:07:03

Safari and Firefox also source support source mapping so you’ll need to verify similar results there

dnolen13:07:13

finally this isn’t a ClojureScript thing in the end

dnolen13:07:03

it maybe a manifestation of a core.async issue Clojure had which was remedied by switching to tools.analyzer and the fact that this stuff hasn’t yet been ported to ClojureScript.

wildermuthn13:07:09

That’s Canary, actually. Might have to keep Safari open! Interesting.

wildermuthn13:07:28

Like you said, it wasn’t the go loop or macro, but core.async

dnolen13:07:41

tangential - giving every single function a name was probably the best enhancement to source mapping in a long time - sort of slipped in for other reasons, but it really helps when debugging.

wildermuthn13:07:43

errr, plus Chrome.

wildermuthn13:07:51

@dnolen, Firefox works fine as well. Yeah, the names are really helpful. One more reason to switch from JS. https://www.dropbox.com/s/k77tw0varqlll64/Screenshot%202015-07-09%2009.35.08.png?dl=0

danielgrosse14:07:25

A beginners question. I like to instantiate a javascript libary in clojurescript.

clojurescript
(def xhr net/xhr-connection)
But the compiled javascript looks like
javascript
webvr_menu_creator.core.xhr = clojure.browser.net.xhr_connection;
So no class is created. What did I do wrong?

danielgrosse14:07:10

Shouldn't look like

webvr_menu_creator.core.xhr = new clojure.browser.net.xhr_connection;

danielgrosse14:07:57

Its referenced from http://clojure.browser.net the method is

(defn xhr-connection
  "Returns an XhrIo connection"
  []
  (XhrIo.))

dnolen14:07:30

(def xhr (xhr-connection)) is what you want

dnolen14:07:58

xhr-connection is a simple function which takes no arguments

danielgrosse14:07:13

How can I define, which google closure library is used? Somehow there are different version in the IDE and in the browser.

danielgrosse14:07:06

Okay nevermind, found the error. I call send with

(.send xhr url callback)
which then calls goog.net.XhrIo.prototype.send But i want to call goog.net.XhrIo.send How can I do this?

dnolen14:07:31

@danielgrosse: there is no such thing

mcgivernsa14:07:35

so you want to call the static method, not the instance method?

dnolen14:07:38

the first one is the correct one

dnolen14:07:48

@mcgivernsa: there is no static method

dnolen14:07:29

there is a function (I suppose it follows the static method convention)

dnolen14:07:49

but really in Google Closure it’s just a function in a namespace

dnolen14:07:33

@danielgrosse: if you want to do that skip

dnolen14:07:18

(:require [goog.net.XhrIo :as xhrio]) in your ns form

dnolen14:07:25

(xhrio/send …)

danielgrosse14:07:32

@dnolen: thank you again, that is the solution.

dnolen14:07:01

@danielgrosse: yeah sorry I didn’t realize that goog.net.XhrIo.send existed, should have checked first.

teslanick15:07:47

What would be the core.async equivalent to Promise.all? [(<! (go ...)) (<! (go ...))]?

ghadi15:07:12

core.async/merge

ghadi15:07:30

analogous but not equiv

teslanick15:07:23

The results wouldn't be in the same order that they are declared and there's no obvious way to know which value came from which channel.

teslanick16:07:04

Use case: I want to do two asynchronous "subtasks" in parallel and coordinate on the result.

coyotespike16:07:39

I'm attempting to round-trip a map (ClojureScript-Clojure, client-server) in EDN format, with cljs-ajax and Carmine. Since that wasn't working, I'm just trying with cljs-ajax and clojure.edn. (Previously, I couldn't do it with JSON either). Is there something obvious I'm missing?

coyotespike16:07:00

I removed all my Ring middleware, just to be sure.

dnolen16:07:55

@coyotespike: fogus did some Ring edn middleware that I’ve used before, worked for me.

dnolen16:07:29

however these days I would just use Transit, cljs-http and some transit middleware worked for me

coyotespike17:07:54

@dnolen - thanks! I'm now trying cljs-http with :transit-params, and ring-transit with wrap-transit-body. It's sort of starting to work.

escherize17:07:40

are we allowed to show off cljs side projects here? or is that an offtopic thing simple_smile

dnolen17:07:56

@escherize: but of course!

escherize17:07:23

It's not ready yet but i just made some progress and am really excited about it! http://take.ms/SDjBe intractive graphs in cljs

escherize17:07:20

I'm using http://marvl.infotech.monash.edu/webcola/ so I can't take a lot of credit 😄

Frank Henard17:07:00

@dnolen: Halfway through watching Om Next, and decided to change my side project from reagent to Om Next. Thanks!

dnolen18:07:13

I hear they are hiring if anyone is looking simple_smile

coyotespike18:07:13

Earlier David kindly pointed me toward how to send a map - and success! With cljs-http, I can POST and then GET a map. Now I'm trying to pass some parameters with a GET request, using cljs-http, and then use those parameters on the Clojure side.

coyotespike18:07:17

(http/get "/redis-get" {:query-params {:key1 "value1"}} passes the map along with it, which is good. And then on the server side, using wrap-keyword-params, I can use :query-string to get out the map - but it's just a string, not a Clojure data structure.

coyotespike19:07:21

Never mind, got it! (wrap-keyword-params (wrap-params handler)), and then (keyword-params-request request), did the trick. Fireworks, applause. Sorry for the noob question.

bhauman21:07:59

@dnolen: some small dept in the navy uses clojurescript and figwheel

zane21:07:57

So, I'm trying to start a cljs repl as per https://github.com/clojure/clojurescript/wiki/Running-REPLs , and I'm getting Exception in thread "main" java.io.FileNotFoundException: Could not locate cljsbuild/compiler__init.class or cljsbuild/compiler.clj on classpath.. I'm wondering if I've maybe run into this issue? https://github.com/emezeske/lein-cljsbuild/issues/204

zane22:07:03

Works fine without trampoline.

bhauman22:07:42

Are you using clojure 1.7.0?

zane22:07:28

Now realizing that this particular project is still on 1.7.0-beta3. Is that the culprit?

bhauman22:07:14

you are trying lein trampoline run -m clojure.main browser_repl.clj

bhauman22:07:23

at the end

zane22:07:29

Upgrading worked, weirdly.

bhauman22:07:04

zane: you probaby needed a lein clean

zane22:07:22

Ah, yeah. Works with -beta3. Must have needed a clean.

zane22:07:27

What made you guess that?

bhauman22:07:33

dnolen: but I think its on the down low as to the department, the guy was a bit evasive

bhauman22:07:09

zane: that is always the answer

bhauman22:07:18

dnolen: should the cljs .. macro use aget so that things work in advanced builds?

zane22:07:27

When people are running their tests in the REPL via https://github.com/clojure/clojurescript/wiki/Testing#running-tests are they restarting a new lein process every time? There's no tools.namespace analogue, right?

bhauman22:07:35

you can reload the namespace with (require [] :reload)

zane22:07:26

Ah. I'm also seeing the :watch option on the REPL function: https://github.com/clojure/clojurescript/wiki/REPL-Options

zane22:07:50

Though now I'm having trouble including my files in the classpath. I guess the REPL script isn't what I want, and I should just lein repl and launch the appropriate REPL function from there?

zane22:07:31

Ah, or maybe I need a call to cljs.build.api/build in my REPL script.

bhauman22:07:31

@zane: :watch just compiles it doesn't load the compiled files into the REPL

bhauman22:07:05

@zane: have you done the Quick Start?

Frank Henard22:07:17

Newbie question: Should I use leiningen for a cljs node.js project? It seems to look like it's not a favorite approach here: https://github.com/clojure/clojurescript/wiki/Quick-Start

afhammad22:07:56

@mikethompson, @martinklepsch: thanks, installed Canary and now getting stack traces.

zane22:07:21

@bhagany: I didn't, because I already had a good figwheel-based workflow before I started grappling with unit testing.

bhagany22:07:52

heh, that's the second time that's happened now. I'm sorry, @bhauman

bhauman22:07:06

@bhagany: no worries at all simple_smile hope you are well

bhauman22:07:46

@zane: will probably save you tons of time experimenting

zane22:07:55

I'll give it a shot! Thanks.

bhauman22:07:30

@zane: you can get test running really easy with figwheel though

zane22:07:37

Oh yeah?

bhauman22:07:19

@zane: seperate build in a separate tab on your browser and the launch fighweel with lein fighweel dev test

zane22:07:33

Ah, and the just launch tests in that REPL?

bhauman22:07:13

@zane: you can have a runner that has :^fighweel-always on it and (run-tests) at the bottom

zane22:07:32

Aaaah, I think I get it.

bhauman22:07:55

@zane: look at that setup

bhauman22:07:17

@zane: it has a bonus favicon indicator

zane22:07:22

Oh, cute.

bhagany22:07:29

@zane can confirm, it's sweet

bhauman22:07:48

Also if it works for you I would really love it if someone could write a wiki for that and

zane22:07:09

Ooh. I'd love an opportunity to smooth the path for others.

bhauman22:07:34

Also maybe package up the favicon coloring library would be cool to.

bhauman22:07:45

@zane: that would be a great help for others

zane22:07:39

Ah, I get it. They just :main the test-runner.

zane22:07:58

What's the right method for submitting new wiki pages?

bhauman22:07:11

@zane: just write it simple_smile

bhauman22:07:28

@zane: on the figwheel wiki

bhauman22:07:39

@zane: is what I was thinking.

zane22:07:52

Makes sense.

bhauman22:07:55

because it's figwheel centric

bhauman22:07:10

@zane: I would be remiss, if I didn't mention that the new new devcards has pretty sweet integration with cljs.test but it's a very easy path to integrate an existing cljs.test suite so I would keep heading the way you are now

zane22:07:08

Huh. I hadn't heard of devcards.

dnolen22:07:03

@bhauman: hrm? .. works regardless of advanced builds or not

bhauman23:07:36

@dnolen: I get it. Just need to wrap my head around why (.. this -props -my_prop) wasn't working in advanced mode

bhauman23:07:12

@dnolen: the #js {:my_prop {:blah 1}} gets munged

dnolen23:07:35

JS literal uses strings

dnolen23:07:36

on purpose

dnolen23:07:50

JS literal is really for interop only

bhauman23:07:23

oh It's because the key was a string?

dnolen23:07:36

no JS literal keys are always strings

dnolen23:07:42

and we can’t change that now

bhauman23:07:13

@dnolen: no, thats cool should have looked into it further.

dnolen23:07:36

this why Om uses internal helpers to hide this stuff

dnolen23:07:04

#js for users is only for directly giving React objects

dnolen23:07:03

or any plain JS API really

bhauman23:07:33

@dnolen: so to be clear. it seems that this code (.. #js {:some #js {:thing 5}} -some -thing) worked in :none and :simple but not :advanced

bhauman23:07:03

@dnolen: but of course I was using it with React. I can check quickly if this explicit example behaves as I stated

dnolen23:07:09

string based properties never work in advanced

dnolen23:07:25

doesn’t matter how you produced it

bhauman23:07:31

@dnolen: well there we go simple_smile

dnolen23:07:02

-foo is a static thing susceptible to minification

dnolen23:07:04

strings aren't