Fork me on GitHub
#clojurescript
<
2016-08-03
>
ag01:08:10

can someone help me to fix the syntax here: I’m confused of what should be used refer-macros or require-macros:

(:require  [cljs.core.async :refer-macros [go] :refer [<! !>]])

ag01:08:21

this seems worked:

(ns foo 
  (:require-macros [cljs.core.async.macros :refer [go]])
  (:require [cljs.core.async :as async :refer [put! chan <! >! close!]]))
But I thought require-macros is “old way”, no?

rarous05:08:17

@ag you can’t :refer-macros from cljs.core.async because they are in different namespace cljs.core.async.macros

adamw08:08:24

Hi; has anyone tried using @darwin's dirac tools (repl) from boot/cljs-repl?

adamw08:08:38

For some reason I have great difficulty passing in nrepl-opts

adamw08:08:52

@dominicm: great thanks!!

adamw08:08:57

didn't see that

jannis10:08:34

@anmonteiro: @darwin: Right, my problem from yesterday is not in the expression generated for ClojureScript but that I'm calling the same generation code from Clojure and from ClojureScript - but with a few differences and those differences mean what I get back when calling it from ClojureScript is backtick-quoted once or twice too often, so instead of a list I get back an unevaluated expression made of clojure.core/seq, clojure.core/concat, clojure.core/list etc.

jannis10:08:01

I think I can fix this with a few reader conditionals in the generating code.

jannis10:08:24

To treat the macro case and the call-in-CLJS case differently.

anmonteiro11:08:41

@jannis: unless you’re using bootstrap Clojurescript, reader conditionals won’t work

pesterhazy12:08:24

JS question: If I have a chain of promises like (-> (js/fetch url #js {:method "POST"}) (.then #(.json %)) (.then #(handle %)) (.catch #(prn "Opps" %))) -- if handle raises an Error, this will be caught by the .catch handler. What if I don't want to catch those exceptions there?

pesterhazy12:08:51

I.e. I'd like an actual exception to be raised, not just an errback to be called

niwinz12:08:10

the promise handlers are async so you can't reraise the exception like synchronous exception

pesterhazy12:08:10

but my handle function may do nay kinds of operations that have nothing to do with this promise

pesterhazy12:08:21

so I don't want those exceptions if they occur to be caught by the fetch .catch method

pesterhazy12:08:22

hah, according to http://stackoverflow.com/a/30741722/239678 the way to throw inside a .catch block is to use setTimeout. The JS world really is weird and wonderful

anmonteiro12:08:01

@pesterhazy: you might not want to add such a dependency in your project for X reasons, but that’s the type of problems core.async solves really well

pesterhazy12:08:45

yeah, core.async wouldn't help in my case (it's about interop with a JS library)

jannis12:08:10

@anmonteiro: I'm calling a function in a .cljc file from the macro and from ClojureScript, so there I can detect whether or not I'm "in the macro" or not. It's already working 🙂

niwinz12:08:30

core.async does not solves very well something that promise and rx streams (imho much better)...

niwinz12:08:37

it lacks of error handling and you should build your own, if you join that together to the idea of if every one uses core.async every library will use its own approach for handle errors...

pesterhazy12:08:51

it's not an option for me

niwinz12:08:53

core.async is very nice piece of software but it is not a silver bullet and I think it does not fits very well as promise abstraction

pat13:08:08

I just got a fighweel repl into the atom editor and its amazing

pat13:08:16

gotta remove the CSP from atom's index.html

pat13:08:18

it's in app.asar.. unpack, edit, pack. good to go

ag17:08:06

I understand that

ag17:08:22

but why this:

(:require [cljs.core.async.macros :refer-macros [go]])
still doesn’t work?

ag17:08:38

whereas this

(:require-macros [cljs.core.async.macros :refer [go]])

ag17:08:00

I am confused and I don’t know how to explain to someone when should we use require-macros and when require with refer-macros.

timothypratley17:08:09

@ag it is confusing 🙂 the rule is: refer gets cljs, refer-macros gets clj ... but it becomes cloudy when you introduce cljc 🙂

ag17:08:12

Initially I thought they both are basically the same - just the first form is deprecated. Apparently Clojurescript compiler thinks differently

timothypratley17:08:25

they are different yes.

timothypratley17:08:42

Macros can only be defined in Clojure (clj) and applied at compile time

timothypratley17:08:14

(this is not strictly true because the bootstrap compiler exists now, but that's the easiest way to think about it)

timothypratley17:08:09

There are other forms that work, such as putting clj macros and cljs code in a cljc and requiring with refer-macros

timothypratley17:08:27

but I encourage you to avoid the syntactic sugar, because it is hard to keep track of in your head.

timothypratley17:08:51

ie: always use require-macros imo

timothypratley17:08:58

never use require refer-macros

timothypratley17:08:11

(just my opinion)

timothypratley17:08:57

more specifically to your question of why :require ... :refer-macros ... doesn't work... because that namespace cannot be required (there is no clojurescript file for that ns)

ghaskins18:08:01

hi all, I was working on a proof-of-concept to implement a swagger-based API with a node/clojurescript backend. I keep running into an issue that perhaps one of you will understand

ghaskins18:08:39

the issue, as far as I can tell, is that lots of the swagger libraries end up using other NPM libraries like uri-js

ghaskins18:08:11

but this library has conditionals that act differently for compiled vs not compiled javascript, that I dont fully grasp

ghaskins18:08:45

what I do understand is that when I run this in my cljsbuild, it is trying to compile those libraries and bad things happen

ghaskins18:08:21

so, what I am wondering is: is this behavior of compiling node_modules configurable in the cljsbuild

ghaskins18:08:30

or is this just a dead end

ghaskins18:08:01

the end result is, that ends up getting skipped since cljs is trying to compile it

ghaskins18:08:45

i was wondering if there is something like a cljsbuild flag, or perhaps an option in the nodejs/require form that allows it to be treated differently

pat18:08:52

@ghaskins im not sure what you mean by compiling these other libs. You can require node modules with js/require at runtime just as you would the built in libs

pat18:08:35

the meaning of compiled in a 3rd party lib is different than a cljsc concern

ghaskins18:08:05

it seems like at line 6, its trying to compile http.js, etc

shader18:08:15

I'm trying to use :foreign-libs; the example showed the use of a url (http://...) to load the file, but my cljsbuild is giving a "no such file" error and simply appending the url to the classpath. What am I supposed to be doing?

ghaskins18:08:24

but the problem is, all of those libraries basically shut themselves off if they are being compiled

ghaskins18:08:03

for instance, snippet above wont define URI if COMPILED==true

pat18:08:09

try just npm installing them locally to your project and using node's require

ghaskins18:08:10

and thus http.js ends up with a nil

pat18:08:02

i am unfamiliar with the details of packing up foreign libs, i know there was alot of work on that done recently, someone else will have to help

ghaskins18:08:03

@pat: as far as I know, that is what i am doing….i have lein-npm reference the deps, they get pulled down into node_modules, and then I (nodejs/require) them in my cljs code

pat18:08:45

if you have done that i dont think you need to include that in your build config

ghaskins18:08:48

sorry, missed a step, lein-npm def in project.clj, "lein npm install” pulls them into node_modules, and then (nodejs/require) at run time blows up

ghaskins18:08:41

you mean do not reference them in lein-npm/project.clj and just npm-install manually?

pat18:08:22

under the :foreign-libs key in your build. if its npm installed, just js/require them

ghaskins18:08:33

it seems the act of invoking the (nodejs/require) form is what triggers the Module._compile

ghaskins18:08:45

ah, ok, let me google that

ghaskins18:08:57

I am not familar with :foreign-libs but it sounds promising

pat18:08:01

nothing to google. just comment out that key

ghaskins18:08:45

not sure what you mean: i dont have it currently

pat19:08:10

wait i think i may have mixed in shader's question

ghaskins19:08:28

ah, ok, heh

ghaskins19:08:30

that makes more sense

pat19:08:11

@ghaskins : clean your project, ignore 'lein npm'. just use npm manually to install package and then require globally through js/require

ghaskins19:08:30

ok, ill try that

pat19:08:54

@ghaskins: if that works, then theres a problem with lein-npm or the package

shader19:08:10

well, I just downloaded it locally, and it's not giving errors when I give it the right path, so I assume that part is working

pat19:08:14

(not the package i mean)

shader19:08:15

how do I require it though?

shader19:08:42

just requiring the same name that I put in :provides doesn't seem to be working

pat19:08:20

@shader anything that is not cljs or goog needs to be accessed globally

pat19:08:15

you require the same thing you put in provides, but its a pseudo-namespace, have to use js/somelib to access it

pat19:08:10

for example: look at all the react wrappers out there. React is bundled in by you still have to use js/React.... to use it

shader19:08:56

sure, but the error I'm getting is "no such namespace"

pat19:08:33

where is that error

ghaskins19:08:55

@pat: same error when I use pure npm plumbing instead of lein-npm

shader19:08:28

either when I run (require 'JSEncrypt) in the repl, or try to build a file with :require [JSEncrypt :as jse]

ghaskins19:08:30

my guess its either an incompatiblity for this particular library with clojurescript, or I need to pass an option to the js/require

pat19:08:35

you can't alias it either. (ns foo.core (:require [some-js-lib])) (def a (.-a js/somelib))

shader19:08:17

so the alias caused the error?

pat19:08:30

we are talking about two different requires, ignore what i said to ghaskins

shader19:08:50

well, some reason it worked after I removed the alias...

shader19:08:53

I'm kinda confused

pat19:08:56

:require in you ns form is different that using js/require to use a npm package

shader19:08:57

but it seems to be working now

pat19:08:29

ok yeah its not a real ns, just a convenience

shader19:08:43

yeah, I rather assumed that

shader19:08:31

well, adding the alias back in didn't break it again, so something else must have changed

pat19:08:47

are you using figwheel

pat19:08:49

@ghaskins can you start just a simple node javascript repl and require it? theres no reason why cljs should be incompatible

ghaskins19:08:02

sure, let me try that

ghaskins19:08:51

@pat: same issue from repl

ghaskins19:08:22

i was able to js/require most things, but the “swagger-tools” package blows up

ghaskins19:08:28

perhaps its just not cljs compatible

ghaskins19:08:05

actually all it takes is (js/require "uri-js")

pat19:08:20

@ghaskins i meant try a javascript repl

ghaskins19:08:22

it seems most of the swagger libs rely on that, which perhaps is not cljs compat

ghaskins19:08:37

understood, i am in figwheel

ghaskins19:08:47

oh, you mean literally a js repl, not cljs?

pat19:08:11

@ghaskins : no a literal javascript repl. just start node: $node

ghaskins19:08:10

pardon me, I am not a node/js expert…what is the syntax to require from a pure node repl?

ghaskins19:08:36

i tried that but it wasnt happy

ghaskins19:08:03

cool, thank you

ghaskins19:08:35

yes, “require(‘uri-js’)” works in node repl, (js/require “uri-js”) blows up in figwheel with the same stack trade

ghaskins19:08:50

(as my run time problem)

ghaskins19:08:26

I am reasonably confident its because of that Module.compile() being invoked, but I dont know enough about what the js/require form really does

ghaskins19:08:37

hmm, it does seem there are options in the js/require form

ghaskins19:08:49

maybe I need to tweak how its required

shader19:08:51

@pat yes, I'm using figwheel - seem to have broken again

pat19:08:26

@ghaskins thats bootstrapped cljs, not same require

pat19:08:09

@shader hot-reloading code has its own state to consider. start clean without the alias, should be fine

pat19:08:24

@ghasking js/require is identical to using reuire from node. does it work without figwheel? ($ lein cljsbuild once)

pat19:08:44

^@ghaskins

ghaskins19:08:08

I see the same behavior regardless of whether I do the js/require in figwheel repl or on cljsbuild output

ghaskins19:08:39

though, I am using cljsbuild for the figwheel setup too

ghaskins19:08:45

so that isnt surprising

pat19:08:10

@ghaskins to be clear, you tried a build without figwheel, just a $lein cljsbuild once, ran the file, same problem?

ghaskins19:08:17

would a stripped down reproduction help?

ghaskins19:08:56

im sure I could create a minimal test case of this

jasonjckn19:08:20

so I have a clojure webserver that serves clojurescript, how can I pass environment variables into the clojurescript code?

christianromney20:08:07

same way you pass all other data 🙂

jasonjckn20:08:14

which would be?

jasonjckn20:08:24

ajax call into the webserver?

christianromney20:08:32

depends on your app, but that's one good approach

jasonjckn20:08:38

yah that's kind of overkill

jasonjckn20:08:41

but would work

jasonjckn20:08:22

any other patterns.. I could serve the HTML file and inject javascript in script tags taht contains the ENV vars

jasonjckn20:08:24

kind of hacky

christianromney20:08:58

and really no different than the ajax call. browser still has to request a different resource

jasonjckn20:08:40

ok, i guess those are the options

ghaskins20:08:01

clone, “make && node js/demo.js"

ghaskins20:08:17

blows up in the same way ive been seeing

snowell20:08:01

Hey all. I have a protocol defined in one namespace and a record that implements that protocol stored in my app’s state. In a different namespace I pull that record out of the state. Now how do I execute a function on it?

snowell20:08:44

I tried (.my-func rec) and get TypeError: rec.my-func is not a function

jr20:08:54

no interop needed ie (.function foo)

jr20:08:26

(require ‘[namespace.with.protocol :as p])
(p/my-func record)

jr20:08:20

or refer my-func from the protocol ns

snowell20:08:07

@jr Thank you so much! I didn’t realize the function was defined in the ns versus in the protocol itself

pat20:08:11

@ghaskins i changed it to :optimizations :simple and it worked. so it looks as though whatever build system the lib author is using is interacting with our closure code somehow, node dependencies aren't resolving correctly

ghaskins20:08:29

oh cool, you are awesome

ghaskins20:08:34

thanks for taking the time to look

pat20:08:07

well simple is a pain. would have to dig deeper for a fix

ghaskins20:08:41

yeah, probably best to say “swagger+cljs” isnt ready for prime time quite yet

pat20:08:49

when dnolen swings around ask him he may have idea whats going on

pat20:08:04

fwiw theres lots of ppl doing swagger on JVM

ghaskins20:08:06

for server side anyay

ghaskins20:08:24

yeah, probably is I am forced on node for other reasons

ghaskins20:08:46

I mostly work on JVM clj but was forced to learn node/cljs because of an environmental factor

pat20:08:56

if you can find a way around that particular dependency you are probably fine

ghaskins20:08:47

yeah, right now I have the cljs talking GRPCs fine…but problem is I cant currently surface HTTP2 through the load balancer

ghaskins20:08:13

so, i was wondering if I could swap out the GRPC interface for swagger over HTTP/1.1 but I might have to tier it

pat20:08:02

maybe just use cljs as glue code, use it as a library

ghaskins20:08:26

not sure what you mean

ghaskins20:08:35

oh yes, i get you

ghaskins20:08:40

thats exactly what I am thinking

pat20:08:55

cljs just for data processing, use all the node bs for endpoints

pat20:08:28

tag your functions with ^export tags and you'll be able to advanced compile too

ghaskins20:08:36

[service-endpoint]-> [swagger::clj-jvm] -> [grpc:cljs:node -> sdk] -> backend

ghaskins20:08:21

oh, i get you

ghaskins20:08:41

problem is, I love clojure and loath javascript, heh

ghaskins20:08:44

not sure I could cope

pat20:08:03

yeah i hear that

ghaskins20:08:25

but that grpc tiering kinda/sorta acts like a library

ghaskins20:08:45

so that might work and allow me to stay mostly in clojure[script]

ghaskins20:08:09

its a microservice architecture anyway, so splitting up the tiering is trivial

ghaskins20:08:30

but thanks for all the help, it is greatly appreciated

pat20:08:47

are you trying to rig up API Gateway endpoints with a swagger spec?

ghaskins20:08:26

well, what I wanted to do was surface the GRPC natively, but the version of HAProxy that is baked into OpenShift seems to puke on the binary HTTP2 payload

ghaskins20:08:03

so, as an alternative, I was wondering if I could swap out the GRPC endpoint for something HTTP/1 based, like a basic swagger REST endpoint

pat20:08:18

ok i thought this was an AWS thing

ghaskins20:08:25

no, openshift in this case

ghaskins20:08:29

though perhaps similar problems

pat20:08:38

@ghaskins i put (set! js/COMPILED js/undefined) at the top and it worked

ghaskins20:08:53

oh interesting

ghaskins20:08:07

i def owe you a beer

ghaskins20:08:25

ill play with that, that seems workable

pat20:08:42

@ghaskins no problem, goodluck

ghaskins21:08:20

I was trying to use (.use app …) but my app was a standard (def app (js/require ..))

ghaskins21:08:11

im thinking its something like (def foo (app.)) and then (.use foo) but its inclear to me

ghaskins21:08:07

oh, maybe I just need to invoke it as a form

ghaskins21:08:14

e.g. (.use (app))

ghaskins21:08:40

yep, that worked, NM

ghaskins21:08:15

(def app ((js/require “connect”))) is the same as ‘require(“connect”)()'