Fork me on GitHub
#clojurescript
<
2017-05-31
>
tyler00:05:16

[org.clojure/clojurescript "1.9.562"]

tyler00:05:43

I don't see node_modules in the directory but I saw it downloading the module when I ran lein figwheel

rgdelato00:05:42

do you have a node_modules in any of the parent directories?

tyler00:05:30

yeah looks like it installed to my home dir

rgdelato00:05:16

if you need to keep that the way it is, you might be able to run npm init -y to generate a package.json in your project directory, then try again... though it'd be better to not nest directories that need their own npm dependencies

tyler00:05:12

ah that did it thanks :thumbsup:

anmonteiro00:05:38

^ just opened this

sophiago00:05:38

oops, sorry. meant that for the Om channel 😛

kaosko06:05:53

hey anybody here using D3? it drives me crazy... for example - how would I access scale.invert() - is there a static invert(scale) version of it somewhere? Or can anybody recommend a comparable but pure alternative for clojurescript/reagent?

mikethompson07:05:57

@kaosko this will help https://github.com/Day8/re-frame/blob/master/docs/Using-Stateful-JS-Components.md There's references to various D3s approaches towards the end.

cmal08:05:07

Hi, @thheller . I cloned the shadow-cljs project and lein install into my local repo, but the shadow-cljs --once seems not working, I also tried lein run -m shadow.cljs.devtools.cli/dev. What is the right step? Thanks.

10220 ± : shadow-cljs --once                                                                                             [5h13m] ✖ ✹ ✭
Could not find artifact thheller:shadow-devtools:jar:1.0.20170531 in central ()
Could not find artifact thheller:shadow-devtools:jar:1.0.20170531 in clojars ()
This could be due to a typo in :dependencies or network issues.
If you are behind a proxy, try setting the 'http_proxy' environment variable.
lein classpath generated successfully
shadow-cljs - using lein classpath
Exception in thread "main" java.lang.ExceptionInInitializerError
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:348)
	at clojure.lang.RT.classForName(RT.java:2168)
Here is my project.clj:
(defproject alpha "0.1.0-SNAPSHOT"

  :description "FIXME: write description"
  :url ""

  :dependencies [[org.clojure/clojure "1.9.0-alpha17"]
                 [org.clojure/clojurescript "1.9.542"]
                 [org.clojure/tools.cli "0.3.5"]
                 [org.clojure/tools.logging "0.3.1"]
                 [reagent "0.6.1" :exclusions [cljsjs/react cljsjs/react-dom]]
                 [reagent-utils "0.2.1"]
                 [re-frame "0.9.2"]  
                 [thheller/shadow-devtools "1.0.20170531"]
                 ]

  :min-lein-version "2.0.0"
  :source-paths ["src/cljs"]

  :dev
  {:source-paths ["src/cljs"]
   :dependencies [[thheller/shadow-devtools "1.0.20170531"]]}
  )

thheller08:05:35

haha doh thheller/shadow-cljs not thheller/shadow-devtools sorry 😛

cmal08:05:36

Ahh.. Thanks.

thheller08:05:21

don’t need to actually run lein yourself, just stick with shadow-cljs

cmal08:05:17

:thumbsup:

thheller08:05:57

@cmal also bump CLJS to 1.9.562 .. there is one important fix in that release

pesterhazy10:05:45

Is there a way to inspect the contents of an npm distribution package? If I know the filename, I can use unpkg: https://unpkg.com/[email protected]/README.md

pesterhazy10:05:37

But what if I want a directory listing? I can't seem to find a way to see the packages - or even download package bundles for specific versions here: https://www.npmjs.com/package/reactstrap

thheller10:05:33

@pesterhazy there is a “Browse Files” link on the right, see https://yarnpkg.com/en/package/reactstrap

thheller10:05:05

but unpkg is prettier

pesterhazy10:05:43

ah nice! http://npmjs.com seems almost deliberately unhelpful

pesterhazy10:05:35

unpkg allows you to inspect arbitrary previous versions of the package as well, whereas I don't think http://yarnpkg.com does

thheller10:05:03

dunno, I try to not look to closely at npm packages 😉

pesterhazy10:05:43

that's been my philosophy as well, but at some point you need to bite the bullet

pesterhazy10:05:21

I'm getting more and more convinced that the easiest way to use clojurescript today is to use the "double bundle" strategy, i.e. 1 webpack bundle with multiple global exports and 1 clojurescript bundle.

pesterhazy10:05:09

Especially when working with React, you'll eventually want access to those juicy prepackages components available as npm dependencies.

thheller10:05:19

one significant downside of the double bundle is code splitting though

thheller10:05:00

if you just want one single big file that is not an issue of course

thheller10:05:23

but yes access to npm is important since cljsjs does not scale well

pesterhazy10:05:26

yeah and a lot of cljsjs dependencies are a bit buggy

thheller10:05:50

and have harmful externs as well

pesterhazy10:05:42

yeah... w/r/t externs, I just use aget .. ahem .. goog.object/get, which is not too cumbersome for React components at least

thheller10:05:00

externs are not that hard … just misunderstood

thheller10:05:11

aget is annoying

pesterhazy10:05:53

can you explain how codesplitting works with cljs, and what advantages it brings?

thheller10:05:55

if includes 3 JS files

thheller10:05:14

all from one build

thheller10:05:56

but other pages (ie. http://www.smartchecker.de/) do not include the other 2 files only the common file

thheller10:05:35

that /assets/smartchecker/js/calc-foreign-CF6E1081CE98A4F91DAC14940B4E9F0F.js file is react+react-dom

thheller10:05:49

since that changes muss less frequently the other code

pesterhazy10:05:07

seems like a pretty advanced optimization though

pesterhazy10:05:18

micro-optimization even

thheller10:05:11

well … you can either have every page download 200KB JS and not use half of it

thheller10:05:17

or just download the code you want 🙂

pesterhazy10:05:18

smartchecker feels really fast by the way

thheller10:05:48

thx, it should be … I optimized a ton of it

pesterhazy10:05:06

no ads either.... chapeau

thheller10:05:50

code-splitting is the latest JS hype I feel

thheller10:05:16

I started shadow-build/shadow-cljs 3+ years ago since I think its super useful

pesterhazy10:05:21

yeah along with js modules

thheller10:05:34

yeah but same idea in CLJS really

thheller10:05:44

just split at the namespace level

manu10:05:17

Hi all! I'm developing a mobile app with re-natal. I need to draw a curved line chart, (and maybe animate it). what is the best API to do it? I saw d3 and ART, but d3 is most for the web.. I alsodiscovered Victory https://formidable.com/open-source/victory/docs/native and React-native-Chart https://github.com/tomauty/react-native-chart. What do you think? thanks 🙂

deas11:05:51

@pesterhazy @thheller The webpack bundle part might also help with compilation performance issues introduced by tons of npm-deps.

thheller11:05:36

@deas can’t really compare the two .. one tries to make the code go through the closure compiler

thheller11:05:40

which is always going to be slower but in theory provide better optimized code

thheller11:05:10

but yeah webpack is an alternative for that which be way easier to get going

pesterhazy12:05:58

webpack is very quick too

thheller12:05:32

hmm I think its quite slow actually

deas12:05:46

@thheller Got the suspicion that npm-deps can make things really slow. Especially when tons of deps come into play.

thheller12:05:29

yes definitely … it is going to be painfully slow without heavy caching

thheller12:05:47

@deas is :npm-deps working well for you or do you have to work around many issues?

deas12:05:28

@thheller Compiliation performance may be an issue. Will look into that in a second. Other than that, I am not using :npm-deps literally bc it does not yet play with modules which don't map to packages. Hence, I build up the dependencies vector myself.

dvingo12:05:26

thheller, thanks for the work on shadow-cljs, very cool stuff. just wanted to hear your thoughts on consuming JS to include in the modules. is there a way to get the JS code included in the closure bundles?

thheller12:05:02

@danvingo thanks. I have only implemented the part where the CLJS code is bundled together by webpack not the other way around yet

dvingo12:05:32

a guess the shorter way of saying it, is do you still use foreign-deps?

thheller12:05:52

yes but not for much longer

thheller12:05:39

the real issue is that I want code splitting to work

dvingo12:05:30

yea, i see. thanks for the info

thheller12:05:35

but webpack works well for now. even if you don’t have any JS it can package CLJS code just fine

thheller12:05:07

:advanced still works so no real downside other than webpack adding a little boilerplate code

dvingo12:05:07

so webpack builds your final bundles - including split modules?

dvingo12:05:03

is this using shadow-devtools?

thheller12:05:02

all *my* builds have been shadow-cljs for years

thheller12:05:36

the webpack stuff I’m not using yet in production no but might soon

dvingo12:05:04

i see, i haven't played with it yet, so i'll do that first and get a better sense of how all the pieces fit

thheller12:05:06

but yes you can use webpack to create a bundle now, including code splitting

dvingo12:05:23

great, thanks for your help!

thheller12:05:10

working on the documentation and examples to make things easier to understand

dvingo12:05:30

thanks, much appreciated

thheller12:05:46

I really only struggle with the webpack configs, they are so different from the way the closure compiler handles splits

deas13:05:53

@thheller How come you are pushing things from the JS side? Personally, I'd be happy to see JS land "disappearing" when working with cljs.

thheller13:05:08

@deas been thinking about it for a while, this was the final push I guess https://groups.google.com/d/msg/clojurescript/HNuYCfPRtQw/OGbMQWH9CQAJ

thheller13:05:25

I didn’t want to deal with JS land at all .. just like you … but :foreign-libs doesn’t scale so something needed to be done

thheller13:05:12

I was against :npm-deps when it was introduced and still am .. so exploring what the alternative would look like

deas13:05:35

Very interesting. Thanks for picking me up here. 🙂

thheller13:05:05

I really want to be able to dump everything into the closure compiler and get nice optimized output

thheller13:05:42

but given the state of the JS world that is probably going to take some time to work reliably

thheller13:05:18

meanwhile other interesting things are happening in things like create-react-app that ship a service worker by default

thheller13:05:33

CLJS isn’t well suited for writing these since they would be too big

deas13:05:55

Hehe, I am also closely paying attention what's happening around create-react(-native)-app. Guess that's what cljs has to compete with.

thheller13:05:47

yeah I’m using it as the basis for all my experiments which is why shadow-cljs work with those with almost zero config

deas13:05:17

If we wan't to pitch cljs at react devs, we will have to look at the tooling facebook is coming up with.

thheller13:05:11

if you haven’t seen it … just drop in CLJS with zero config

thheller13:05:31

but using things like reagent still requires config

thheller13:05:38

working on a written guide

thheller13:05:26

really the only reason reagent or others require config is due to :foreign-libs

qqq14:05:12

anyone know of sample code for cljs + apple pencil (via mobile safari)? I have googled; but can not find such info.

michaellindon15:05:32

Hi Guys, I have memory issues, I'm running out of memory doing (take 1000 (iterate update-state initial-state)), this is because state is pretty large. If i were to thin the iterates, by doing say, (take 100 (take-nth 10 (iterate update-state initial-state))) do I use 1/10 of the memory space? Or does it still store the whole 1000 iterations in memory and return every 10'th one

Roman Liutikov15:05:47

I have a macro which appends to file and clears the file initially when macro ns is loaded. So if I use the macro twice, build, it would write twice. Then when I build again it creates a replaces file's contents which is expected. But this doesn't work so during incremental compilation, because macro ns is loaded only once when process is started. Is it possible to achieve same behavior during incremental compilation?

Roman Liutikov16:05:31

One solution I can think of would be to setup global timeout to detect subsequent compilations. But that's super unsafe :)

dnolen16:05:57

@michaellindon what are you actually trying to accomplish?

dnolen16:05:02

do you need the 1000th only?

dnolen16:05:03

@roman01la stateful macros are a bit icky - there’s no good answer to a problem like that

captainlexington16:05:48

@dnolen @michaellindon sent the above message to the wrong chat - he meant to send it to the clojure channel, and it's being discussed over there now.

Roman Liutikov16:05:14

@dnolen I’m doing co-located css which writes everything into a file after some processing via macro

dominicm18:05:08

Is there any reason that Scrum, Re-frame, etc. are tied to a particular component framework (rum & reagent), instead of being agnostic state managers which have a notification capability built in (with helpers for particular component frameworks)

mihaelkonjevic18:05:18

@dominicm I can’t answer for Scrum or Re-frame, but I can answer for Keechma. The reason why Keechma is coupled to reagent is that I’m using reagent every day, and it’s just simpler to fully embrace the platform and use it’s advantages. Any other integration would take serious effort and you end with the lowest common denominator of features. I don’t think it would be too hard to integrate Rum and Keechma but until someone has a real need for it, it could be a wasted effort

dominicm18:05:34

@mihaelkonjevic What are the sorts of features you really need to take full advantage of? Isn't the gist of it that eventually you update a "super atom" & cause a re-mount (which diffs & so on)

mihaelkonjevic18:05:42

for Keechma, it’s super atom and the fact that components are simple functions that can be partially applied (which I’m using to pass in the state to each component)

dominicm18:05:17

@mihaelkonjevic But I would think that should make it easy to use with rum, brutha, etc. ? (I'm probably not grasping the state passing!) In Rum you'd pass into the root component the resolved state & re-mount rum. Same for Brutha.

mihaelkonjevic18:05:37

@dominicm you might be right, I’ll definitely take another look

dominicm18:05:23

@mihaelkonjevic I'd love to know if there's a really good technical reason for it. If you do come up with something, I'd really appreciate a note back. I feel like there's a slight trend of complecting [Particular React Library] to State management. Possibly because they cannot be untangled, but I'd love to know why 🙂

mihaelkonjevic18:05:03

I think it’s mostly related to people building frameworks for themselves first, so it makes sense to integrate with the view layer that you use every day. But, it would be an interesting exercise to see how hard it is to integrate with a diff layer

dominicm18:05:26

I suspect so too.

dominicm18:05:17

@shaun-mahood I've seen! There's also https://github.com/Day8/re-frame/pull/107 / https://github.com/binaryage/pure-frame which is in a similar vein of attempting decoupling.

rauh19:05:29

@roman01la As somebody who's gone down the rabbit hole of writing stateful macros: Avoid it all cost. Absolutely make the macros pure or you're gonna have a bad time. They should even be pure among Clojure compiler restarts. I solved the issue with writing some DB file that get's written on macro expansion and loaded from the file system once the macro namespace gets loaded the first time.

qqq19:05:29

non-stateful-macros, lol, had not even considered them until now

michaellindon20:05:42

@dnolen @captainlexington yes sorry about that, I sent to the wrong chat 😞 Feel free to chip in though David. My question is about memory and garbage collection. When I do (take 100 (take-nth 10 (iterate update-fn initial-state))) I do not need the iterates which are not divisible by 10, so I am wondering if those iterates are garbage collected incrementally as the iteration process, or whether first the 1000 iterates are performed and stored in memory, and then the unwanted iterates are garbage collected in one large batch after the iteration has completed

adamvh20:05:43

back in my common lisp days i wrote a macro that parsed c header files and defined ffi structs 😄

adamvh20:05:52

guess you guys would consider that a no-no

noisesmith20:05:03

@adamvh that sounds fine. Now if it had an internal state that modified its output based on other times it ran, that would be iffy.

adamvh20:05:46

oh yeah i don't think i ever did that

adamvh20:05:00

didn't bang on the headers at all

adamvh20:05:14

although now that i think about it i probably should have given it an internal state tbh

adamvh20:05:27

to only parse the headers if it hadn't already

adamvh20:05:08

and to just like read from some dump otherwise

dnolen20:05:13

@michaellindon there’s no real skipping involved here and we do not control GC

dnolen20:05:48

@michaellindon given the small size of N here, I suspect your state is really big

michaellindon20:05:32

@dnolen I see, yes this is a computationally intensive machine learning application, sadly one which cannot be summarized by the final state. I need some in-between values. I do not have enough memory to store all 1000 iterates, yet I would have enough memory to store every 10th iterate. I figured (take 100 (take-nth 10 would be one way to achieve this, but it looks like I am still running out of memory. I feel like clojure is still constructing the full 1000 iterates in the background.

dnolen20:05:01

right because that’s just how it works

michaellindon20:05:13

ok, thats good to know, thank you for clarifying

dnolen20:05:09

my suspicion is your memory issues are pretty much in update-fn itself

dnolen20:05:44

without being able to see behind that opaque thing hard to say if your algorithm is benefitting at all from structure sharing or if you have lazy sequence or other memory related issues elsewhere

michaellindon20:05:30

I expect the state on each iteration to be different from the state on the previous iteration, so I don't think I can exploit any structural sharing of the datastructure sadly

dnolen20:05:32

it’s a typical user mistake to write code around lazy seqs deep in some algorithm and run out of memory

michaellindon20:05:33

state is quite big

captainlexington20:05:48

You could write a tail-recursive function that's like a reducer with a passed index that could calculate them in chunks of ten at a time

michaellindon20:05:07

@captainlexington yeah I'm thinking this is probably the way to go

captainlexington20:05:10

I usually hate writing code that has to take hardware limitations into account, but it sounds like you have no other choice

wiseman20:05:20

i don’t quite follow. it will construct 1000 states but it shouldn’t hold them all in memory, right?

captainlexington20:05:24

Oh I forgot that Clojure doesn't have tail-recursion optimization

captainlexington20:05:31

So you'd have to use recur

dnolen20:05:46

@michaellindon chrome support heap snapshots so you can easily find the issue

dnolen20:05:27

when you say run out of memory I mean state has to be really big, at least 2mb at each iteration

dnolen20:05:58

assuming your just gobbling 2gb of ram after 1000 steps

dnolen20:05:39

sounds unusual to me, but like I said hard to say without seeing behind update-fn

dnolen20:05:59

@wiseman yes assuming you’re not assigning the result to a def

dnolen20:05:45

@michaellindon ah right this is Clojure though the same basic principles apply

michaellindon20:05:52

so my understanding is that as the iteration procedes, it stores all the iterates in memory, until it completes, at which point the unwanted iterates are presumably GC'd

michaellindon20:05:08

is that right?

dnolen20:05:50

not quite we should rewind here

dnolen20:05:07

you will in fact compute all 1000 states here via iterate, but take 100 will only take 100 of them

michaellindon20:05:07

sorry for being slow

dnolen20:05:34

the ones that were skipped will be GCed whenever the VM decides to do that

captainlexington20:05:04

@dnolen The issue is that he's running out of memory while the process is still running - so he wants to know whether the GC would have to wait until the take 100 was done before it could spring into action

michaellindon20:05:24

exactly, and i think that is whats happening

dnolen20:05:40

I doubt it

dnolen20:05:11

take-nth uses drop

dnolen20:05:16

nothing will hold onto the dropped value

michaellindon20:05:21

i would have expected that after the 9th state was used to compute the 10th state, that the 9th state gets GC'd?

ag20:05:30

hey guys… can someone who’s done enough CSS can tell me. I’ve been told to use BEM, now our elegantly looking Hiccup markup looks like an abomination. It just… doesn’t feel right… So, maybe there’s better way? I can’t use Garden, have to use SASS. do you think it really makes sense to use BEM in a Clojurescript project?

Roman Liutikov20:05:31

@ag we have plenty of it at work, looks fine in Hiccup for me

ag20:05:14

yeah, but it feels it was created to simplify certain problems that seem to be less in React based apps. no?

Roman Liutikov20:05:15

it depends on how you manage styles: usual CSS (maybe with preprocessors) or css-in-js

Roman Liutikov20:05:15

the latter is at the very early stage

ag20:05:35

Garden is much more matured

ag20:05:59

although ain’t perfect, still way better IMO than any of known pre-processors

dominicm20:05:50

@ag I hugely prefer to use SASS over Garden. BEM is really useful. I'd read anything by Harry Roberts on the topic of css organization

ag20:05:32

dominicm: BEM still does feel like a thing that’s trying to solve problems, by creating problems of different sort. Maybe it’s just my uninformed perception. I don’t know

dominicm20:05:56

@ag which problems are they?

ag20:05:16

huge amount of repeated patterns required to express even seemingly simple things

dominicm20:05:26

@ag BEM is supposed to reduce duplication. What do you mean repeated?

ag20:05:26

well, again - it feels to me like that. Haven’t you ever feel that BEM and pre-processors not the answer?

dominicm21:05:39

Inline react styles are a real tarpit. Examples: - No media queries - Overriding arbitrary points is impossible If you're talking about some alternative to the "cascading" part of CSS that is.

dominicm21:05:23

If I understand correctly, your issue is with the cascading part :thinking_face:. I think it's a blessing & a curse. It's a global namespace. So ensure you namespace your CSS (BEM!)

ag23:05:29

@dominicm my problem is the following: I have a component that included in a parent component (it's a React based app), by looking at the code I can already see the hierarchy. But now, to appease gods of CSS I have to spell all the classes and explicitly explain that indeed this is main-menu__menu-item_active

ag23:05:11

I feel that BEM made sense before the dawn of React. Yet again, I can't emphasize this enough - this maybe my biased uneducated opinion. Which might be 100% wrong.

dominicm07:06:11

You could also see the hierarchy before react, in the HTML. It's common that a component isn't only use one CSS class though. You usually compose several together. In which case it's very useful to know the origin of the class. Your example provides many benefits: - no collision with active for any other kind of thing - that part of styling related to main menu block - no collision with menu item for other kind of thing (non main bar) - if in the future I add Special-item block that is supposed to work anywhere and it breaks here, I can see the groupings of classes clearly and know what belongs to who - with multiple classes on, if the main menu block was unstyled, but content still wanted, you know which classes to remove (they all start the same!) - if you want to extend all main menu items, it's very easy to ensure you get the exact right class (thinking here of a menu item with classes like main-menu__menu-item dropdown)

rgdelato20:05:21

Even if you don't use BEM, you should probably have -some- pattern for your CSS classnames. In a magical future, I'd love to see some CLJS library rip off CSS Modules and let us do something like:

(ns example.core
  (:require [app.css :as styles]))

(defn app-component []
  [:div {:class (styles/app)} "Hello there!"])
...but in lieu of auto-generated classnames, we have BEM.

john20:05:41

@michaellindon Could you combine your post-iteration step into your iteration? So that you don't need the whole result set?

Roman Liutikov20:05:29

@rgdelato I’m actually close to release cljs port of this js lib https://github.com/threepointone/glam

rgdelato20:05:05

I've also ported over a variant of styled-components: https://github.com/rgdelato/styled-classnames

rgdelato20:05:41

but I'd like for there to be a CSS classname auto-gen solution that -isn't- CSS-in-JS for people who aren't into that

Roman Liutikov20:05:47

this perfectly shows how there’s no standard for managing CSS 😄

rauh20:05:30

Yeah I have one as well! 🙂