Fork me on GitHub
#clojurescript
<
2016-12-14
>
talexxx00:12:26

What’s the idiomatic way to use clojure functions from CLJS in a project?

talexxx00:12:15

e.g., I have something in src/clj/foo.clj that I want to use in src/cljs/bar.cljs, either as a function or its precomputed output

gfredericks00:12:22

you either write it in cljc/cljs or call it from a macro

talexxx00:12:13

Thanks, I’ll give it a try

talexxx01:12:30

I’ve got some functioning Clojure written in a cljc file that works in the lein repl, but (:require [my-cljc-namespace :refer [thing1 thing2]]) doesn’t add it to the CLJS namespace. Is there some more I need to do to interoperate?

dbsgtk02:12:53

I'm trying to use slurp in clojurescript at compile time, much like https://gist.github.com/noprompt/9086232

dbsgtk02:12:31

and it works, but it throws a warning when i start figwheel.

dbsgtk02:12:05

specifically: WARNING: Use of undeclared Var cljs.core/slurp at line 6 /home/gtk/src/pairwise/src/pairwise/cljsmacros.cljc

dbsgtk02:12:13

it's the (clojure.core/slurp file) line that throws the warning

acron09:12:21

@dbsgtk use refer-macros rather than include-macros

acron09:12:25

let me find an example...

acron09:12:41

(ns app.routes
  (:require [secretary.core :as secretary :refer-macros [defroute]]))

thheller10:12:44

@rauh probably a topic better suited for #cljs-dev

rauh10:12:37

@thheller You're right, moved it.

Aron11:12:43

how do i break up a large clojurescript file into smaller ones?

anmonteiro11:12:10

@ashnur create new files with new namespaces

anmonteiro11:12:24

not possible to have a namespace span multiple files like in Clojure

Aron11:12:35

i am just curious what others do 🙂

anmonteiro11:12:09

clojure.core, for example, is divided into multiple files

anmonteiro11:12:20

In ClojureScript this is not possible because of its compilation model

anmonteiro11:12:41

it's also not uncommon to have one big file

anmonteiro11:12:47

cljs.core has ≈10k LOC

Aron11:12:01

that might be good for distribution

Aron11:12:09

i can't deal with more than 1-200 loc files

anmonteiro11:12:58

I know a number of projects which break them apart like this: 1. have only your public API in your project.core file 2. have multiple namespaces which have implementation for the internal fns

Aron11:12:00

normally in javascript i just make small modules and require them

Aron11:12:29

i use commonjs modules a`la nodejs

Aron11:12:36

@anmonteiro i am trying to comprehend what you said but you mention things i was not aware that are relevant

Aron11:12:28

i have one core.cljs now and i would like to use some functions from another file, lets say graph.cljs Besides giving a new namespace to the new file, what else do i need?

Aron11:12:46

how will the compiler find it and load it?

anmonteiro11:12:59

in core.cljs you need to require your graph.cljs

anmonteiro11:12:34

(ns myproject.core
  (:require [myproject.graph :as graph]))

(graph/call-my-graph-function)

anmonteiro11:12:08

the ClojureScript compiler will parse your NS forms to figure out the order in which to load the dependencies

Aron11:12:31

cool, i am trying now just need a quick update before it

Aron11:12:49

i was trying to google around (load) and others

Aron11:12:37

thank you anmonteiro, this is great

anmonteiro11:12:01

@ashnur I think you should go through the ClojureScript website / Wiki if you haven't already

Aron11:12:09

many times

anmonteiro11:12:12

all of this is explained there

anmonteiro11:12:22

OK to ask questions here too

Aron11:12:37

if something is not relevant, i can not remember it

Aron11:12:09

especially because all the different naming conventions, i don't even recognize a lot of useful things because i don't know the difference between what is just described and what is talk about actual abstraction details

Aron11:12:50

i try to search every time, but the words i look for are not the words you all use, and often there are limitations in the way i am used to do things that i don't know and it's often not mentioned in the wiki either

Aron11:12:37

for example when dnolen told me to read again the dependency page, there was this phrase "build configuration" that only appears once on that page and it's not explained what it is, there is no link, nothing

Aron11:12:18

took me at least 10 minutes to realize it's just the build.cljs file its talking about but for some weird reason, it's not called that but something way more general and vague

Aron11:12:04

rtfm was never actually a good advice, and i feel bad about all those times when i was the one telling people to do it

abstruselyarcane12:12:24

hmm when I feed a vector over ipc it becomes an array?

jannis13:12:19

Hi! I’m a little clueless - how do I call a JS object method (that needs access to this) from optimized CLJS code? I’ve tried e.g. ((aget <JS object> “functionName”) <param...>)) but that seems to call the function “functionName” with this being null.

dnolen13:12:57

@jannis are you familiar with this-as ?

jannis13:12:22

I haven’t used it yet

jannis13:12:38

(this-as <name of JS object> ((aget <name of JS object> “functionName”) <param…>)))?

dnolen13:12:10

@ashnur it’s easy enough to add a link, I agree that would be less confusing. Feedback about confusing aspects of the existing documentation is always welcome.

dnolen13:12:42

@jannis sorry I didn’t understand what you were asking

dnolen13:12:19

you want call and the first arg should be this

dnolen13:12:33

this-as is irrelevant here, was just confused about your question

dnolen13:12:41

(.call method this …)

jannis13:12:09

@dnolen Thanks, that did the trick 🙂

Aron13:12:11

not sure i should start adding links to a wiki page about a subject i know almost nothing about

dnolen13:12:52

@ashnur the Dependencies page assumes you’ve not only read but actually worked through the Quick Start, it starts off saying that - did you do that?

dnolen13:12:06

I did find some inconsistencies and I went ahead and fixed those

Aron14:12:56

i did worked through the quick start, but not at once and not today but weeks or maybe months ago

Aron14:12:26

i did read most of it again the last time you told me rtfm

Aron14:12:54

so i think i did what is to be expected from a newbie like myself

Aron14:12:02

and i think that there is no way i could remember details that i have not used, no matter how clearly they are expressed in the documentation

dnolen14:12:11

@ashnur you will need to go through it again if you want to understand Dependencies

dnolen14:12:23

if these things could be easily explained in chat we wouldn’t have written all this documentation

Aron14:12:27

i solved the dependency question for now

Aron14:12:04

@dnolen i never asked explanations in chat, it's just that it's nicer to have a link that doesn't point to a smaller book, but rather a paragraph of that book 🙂

Aron14:12:57

anyway, right now everything works and stuff for me, the only reason i said anything is that i really do not understand why would you suggest to a beginner to edit your documentation 🙂

dnolen14:12:22

@ashnur many beginner have made approved edits to all this documentation

dnolen14:12:25

happens all the time

Aron14:12:38

ok, that's a high ball if i've seen one

dnolen14:12:44

it’s the only way for things to improve, tell us what’s confusing, we’ll point how to make it better - go fix it yourself 🙂

Aron14:12:54

i managed to include jsnetworkx using the cljsjs method and then i realized that it does not support the algorithm i want (talk about stupid 😞 ), so now i am implementing a different algorithm anyway 😄

Aron14:12:36

i love that i can use - in variable names 😄

Aron14:12:59

"variable" probably not the best word

dnolen14:12:24

yes it’s very Lisp-y, !, ?, +, are all nice to use in names if you’re a Lisp programmer

anmonteiro14:12:24

@dnolen I assume you edited the Wiki

anmonteiro14:12:31

we should probably keep the site in sync too

dnolen14:12:45

@anmonteiro yes, I added one link - and I switched cljs.closure/build -> cljs.build.api/build

dnolen14:12:53

that’s definitely confusing ^

dnolen14:12:36

fixing now

iecya14:12:18

i saw ! and ? used for naming but i actually never saw names that contain + and . is there any naming convention or particular situation in which i might want to use them? doesn’t cause any issue with the evaluation if positioned at the beginning of the name?

dnolen14:12:56

(let [x' (conj x 1)] …), which is kind of a math-y convention

dnolen14:12:46

foo+bar and foo&bar are things you’ll see if you've read a bunch of Lisp/Scheme

iecya14:12:04

actually i am quite new to programming and lisp in general 😄

iecya14:12:48

for math-y convention you actually mean math related function or, like in the example, list manipulation (add/remove elements) stuff?

dnolen14:12:49

I just mean “x” and “x prime"

dbsgtk15:12:13

@acron thanks, but it gives the same warning. It basically gives the same warning in every case, but also works in every case, so ¯\(ツ)

dnolen15:12:53

@dbsgtk your :require form probably won’t work - just use :require-macros

dnolen15:12:33

feel free to open a JIRA issue about that case though, it seems relatively simple to fix

dbsgtk15:12:17

@dnolen thank you, as always!

samueldev15:12:06

are there any resources online WRT allowing a cljs lib I've written to be consumed from JS as an es6 module? lots of resources online around the inverse - bringing es6 modules into cljs - but those dominate search results and are making it hard for me to find the opposite 🙂

samueldev15:12:36

i know maria was working on the es6 js->cljs side of things

rauh16:12:36

@samueldev Check out this repo: https://github.com/typeetfunc/datascript-mori They're doing that I think

Aron16:12:20

how do i write guards for loops so they don't block the whole browser and i don't have to restart even lein to be able to use anything?

dnolen16:12:46

@ashnur there’s no way to do that, that’s just how JavaScript works

anmonteiro16:12:28

@dbsgtk I commented in the ticket, but not sure CLJS-1872 is a bug

anmonteiro16:12:37

if you wanna use slurp you need to put it under a reader conditional

dnolen16:12:40

@samueldev doesn’t ES6 have story for loading plain JS libs

anmonteiro16:12:11

clojure.core is aliased to cljs.core by the ClojureScript compiler, which is why you get the undeclared Var warning

dnolen16:12:49

@anmonteiro he wrote a slurp macro

anmonteiro16:12:17

he's still requiring a .cljc file which calls clojure.core/slurp

anmonteiro16:12:35

when he :requires it, it's also evaluated in ClojureScript, which is why he's getting the warning

dnolen16:12:45

oh right heh

anmonteiro16:12:53

he probably just needs to put the macro under #?:clj

dnolen16:12:12

I missed the macro file was .cljc

anmonteiro16:12:23

that wasn't clear to me too until I saw CLJS-1872

pbostrom16:12:28

I'm seeing a weird error when trying to require cljs.repl.node:

user=> (require '[cljs.repl :as repl])
nil
user=> (require '[cljs.repl.node :as node])

ClassNotFoundException cljs.repl.IParseError  java.net.URLClassLoader.findClass (URLClassLoader.java:381)
user=>
this "just worked" last time I touched it, which was a few months ago, and as far as I can tell nothing in my project has changed

Aron16:12:52

@dnolen you misunderstand, i know javascript very well, and i know that's not possible to achieve in general, so when i work with loops or recursion, i always have a guard that when in javascript i just update normally with ++ and have a limit that's larger than the dataset but small comparatively (like 3000 or smth). I was asking how should I achieve the same thing in clojure?

dnolen16:12:54

@ashnur I don’t understand the question. That’s not idiomatic JS or anything. So just write a similar guard in ClojureScript if you like

darwin16:12:10

for some inspiration

dnolen16:12:23

but there are far more recursion patterns so you’re unlikely to come up with something that will work for all cases in Clojure(Script)

Aron16:12:45

@dnolen this is some silliness that is happening here, i am messing up the syntax probably or similar issue. seeing examples helps me personally a lot in this situations.

dnolen16:12:45

that core.async doesn’t seem related to what you want to me at least

fellshard16:12:50

It's going to be better for you to learn the idiomatic abstractions Clojurescript provides rather than trying to cram concepts from JS into CLJS.

Aron16:12:10

@fellshard i agree with that completely

darwin16:12:54

I was reacting to this part of the sentence "guards for loops so they don't block the whole browser”, didn’t understand the lein part 🙂

Aron16:12:10

i don't know why i have to reboot lein too

Aron16:12:25

maybe it doesn't clear the cache\

dnolen16:12:46

what’s happening is you’re probably spamming the REPL

Aron16:12:55

i am not touching the repl at all

dnolen16:12:58

so even if you kill the browser, the REPL is still trying to print

Aron16:12:05

i have figwheel and editing the file

Aron16:12:16

oh, yeah, that might happen completely right

dnolen16:12:23

figwheel is a REPL

Aron16:12:30

yes yes, i am not arguing 🙂

dnolen16:12:56

yes I know, I’m explaining that it’s going try to print whatever the browser had sent up to the point you killed it

dnolen16:12:02

it doesn’t matter that you’re not doing anything with it

Aron16:12:37

it's probably what's happening

Aron16:12:00

another thing why i sometimes ask for examples is that i can learn new functions

Aron16:12:15

what i am thinking is that i build something small, will share the code and then you will tell me how in clojurescript this is done differently. 🙂

Aron16:12:32

so i can refactor, probably better than try to get it right at the first time 🙂

samcf16:12:16

i usually just write the naive implementation first and scour the clojure docs for interesting library functions that do it better

samcf16:12:48

for me, a lot of the fun of clj/s is searching the breadth of the clojure std lib

darwin16:12:50

for me best works reading others’ people code, usually when I need/want to use it and start depending on it 🙂

Aron17:12:11

hmm, http://cljsfiddle.com is blocked by the company firewall

Aron17:12:24

prohibited security category

adamfrey22:12:05

Do anyone have links to explanation or examples for consuming a javascript react library like https://github.com/tomchentw/react-google-maps? Most React libraries have documentation examples in JSX, I’m trying to figure out how to translate that to something I can use in CLJS.

adamfrey22:12:38

I’m also interested in hearing anything to the effect of “it’s not worth it” If that’s your experience

jr22:12:31

if you're using reagent then you can "adopt" the class for direct use in hiccup-like templates

adamfrey22:12:28

I’m using Rum. Is “adopt” part of the reagent API?

adamfrey22:12:25

ok, I found adapt-react-class

jr22:12:57

yep. sorry meant "adapt" and not "adopt"

anmonteiro22:12:19

@adamfrey even if it's not, you can probably use js/React.createElement

anmonteiro22:12:23

that's what JSX translates to

anmonteiro22:12:21

<Foo x=42>
  <Bar/>
</Foo>
^ this is the same as:
(js/React.createElement Foo #js {:x 42}
  (js/React.createElement Bar))

adamfrey22:12:41

ok I’ll see if I can get something with that. Thanks

pld22:12:05

I’m trying to do something similar to a map destructure in CLJS, I was hoping

(let [[rows scroll-height style] ((juxt .-rows .-scrollHeight .-style) (.-target event))] …)
would work, but the closure compiler complains because the .- shortcuts aren’t proper methods, I should have seen that coming. Is there something else people do to destructure multiple JS properties at once?

dbsgtk22:12:16

@anmonteiro @dnolen I can certainly accept that's its not a bug, but can you help me understand what I did wrong?

dbsgtk22:12:46

FWIW, when I use clojure.core/slurp explicitly in the macro, I got an undeclared var on that.

dbsgtk22:12:24

Sorry for the long delay: i'm in Singapore and just woke up

anmonteiro22:12:26

@dbsgtk: the macro needs to be put under a :clj reader conditional so that ClojureScript doesn't see it

anmonteiro22:12:26

In ClojureScript macros are written in Clojure. By :requireing the file you're making it be compiled in ClojureScript too

jr22:12:32

pld: use goog.object/get to access the properties

dbsgtk22:12:28

I see, thank you

pld22:12:59

@jr ok thanks! I’ll try to write up a helper fn using that

pld23:12:31

cool, thanks @darwin

terje23:12:38

@adamfrey To use react-google-maps in cljs see the cljsjs package: https://github.com/cljsjs/packages/tree/master/react-google-maps

mikepjb23:12:01

$(function() {
   $('a.link').click(function() {
       $('a.link').removeClass('active');
       $(this).addClass('active');
   });
});
How do you write something like this in clojurescript? I'd like to add a css class to a href when clicked