Fork me on GitHub
#clojurescript
<
2015-11-25
>
mudphone01:11:24

Anyone know why all the ClojureScript books are due out in February 2016? I think I count 3 (new books or 2nd editions).

Tim01:11:36

which ones?

Tim01:11:41

I’m not aware of them?

gabe01:11:42

@mfikes: thx. if i were doing node or native work i would. but would like to use advanced compilation.

mfikes01:11:06

@gabe: yep, that rules it out

gabe02:11:14

would be cool to be able to require namespaces at runtime and pull them in over the wire

gabe02:11:05

take advantage of advanced compilation and then pay as you go

gabe02:11:29

but then dependency management would be even more fun!

mudphone02:11:39

@tmtwd: Web Development with Clojure: Build Bulletproof Web Apps with Less Code 2nd Edition - (February 25, 2016)

mudphone02:11:16

ClojureScript: Up and Running: Functional Programming for the Web 2nd Edition - (February 25, 2016)

mudphone02:11:08

Learning ClojureScript, Rafik Naccache, February 2016

Tim02:11:37

not sure about Packt

mudphone02:11:51

and I can’t remember the last one

Tim02:11:00

Web Development with clojure should be on beta soon

mudphone02:11:27

Just curious while they’re all publishing at the same time.

mudphone02:11:37

Possibly waiting for something to be done on the code side?

mudphone02:11:45

Coincidence?

roberto02:11:47

are those all Packt?

Tim02:11:56

no just the last one

Tim02:11:34

also clojurescript up and running seems good

roberto02:11:38

you’ll have to ask the publisher why all the dates coincidie

Tim02:11:39

but its very short

Tim02:11:48

literally just to get you up and running

Tim02:11:59

if you already use cljs, I’m not sure its worth it

roberto02:11:19

I wish there was a cljs version of Applied Clojure

Tim02:11:42

I’m really looking forward to web development with clojure 2nd edition

Tim02:11:48

I hope it on beta soon

eyelidlessness03:11:45

cljs/goog closure by default requests deps with a relative path (e.g. js/foo/bar.js), is it possible to specify a base path, or require it use absolute paths?

eyelidlessness03:11:01

it breaks loading deps on a single-page app where arbitrary paths serve index.html, and i'd really prefer not to add <base href="/"> to the page (which breaks otherwise-intentional relative paths)

eyelidlessness03:11:10

i've tried googling this to no avail due to many false positives on the obvious keywords

eyelidlessness03:11:07

well, i feel a bit dumb. i was able to fix this in :cljsbuild :builds :app :compiler :asset-path

dvcrn08:11:47

hi cljs folks!

dvcrn08:11:03

I was wondering if it's possible to dynamically import / require / use a separate module?

dvcrn08:11:15

(doseq [module enabled-modules]
  (.log js/console (symbol (str "demo.contrib." (name module))))))
inside demo.contrib.{{ module-name }} are functions that I want to use

dvcrn08:11:54

hrm I guess I have to compile each module into a separate js file and require that through node. If anyone has a better idea, ping me

dvcrn09:11:29

(even dynamic ns/fx resolving and executing would work)

mike09:11:53

I have to suggest a clojurescript editor for for my team which I'm trying to pitch clojurescript to (vs es6). they have never written one line of lisp. any suggestions?

borkdude09:11:02

@mike: I would start with Cursive, if they don't know emacs or vim

mike09:11:48

no please do not suggest emacs and vim, it' difficult enough to get them into a new list language, set aside new editor designed for another species.

mike09:11:20

the most difficult part of convincing people into clojurescript is the editor.

mike09:11:59

looks like the authors of clojure did not really care the huge population and does not and never will adopt vim/emac based editors.

mike09:11:26

cursive is not free, and it is difficult to setup, and it is still in alpha?

cfleming09:11:38

@mike: I’m biased because I develop Cursive, but I think it’s a good fit for your needs. Doc for CLJS is a little sparse right now but feel free to DM me or ask in #C0744GXCJ if you have issues.

mike09:11:59

really, we should learn something from microsoft and visual studio code. this language needs an official editor.

cfleming09:11:04

It’s free for non-commercial work, but for commercial work you have to pay, right.

mike09:11:08

(not even a plugin, an editor)

cfleming09:11:52

I’m planning a standalone version of Cursive, but have not got to that yet.

mike09:11:56

@cfleming: didn't know it's free for personal, I had the impression that according to the webpage it will be payed for all in the future.

borkdude09:11:10

@mike I don't think Cursive is difficult to set up

borkdude09:11:32

@mike: just download/install Intellij, install the plugin, open a project.clj and you're good

cfleming09:11:49

@borkdude: @mike: It’s currently fiddly but will get better very soon (like a week or so)

cfleming09:11:10

There are a few things that trip people up along the way, like keybindings and SDKs

cfleming09:11:28

But it’s not a huge blocker, IMO

cfleming09:11:46

Anyway @mike, let me know if you need help.

juhoteperi09:11:53

IntelliJ Community Edition is free and it can be used for any kind of work

mike09:11:54

@borkdude: https://youtu.be/gsffg5xxFQI?t=26m8s this guy says it's a tough place to start for a noob (cursive)

borkdude09:11:36

@mike: ok, maybe you'd have to prepare the installation and walk them through it

malch09:11:04

@mike Have you actually tried Cursive? 😊

mike09:11:11

@cfleming: sure, will do simple_smile

borkdude09:11:14

@mike: first thing you'd have to teach them is how to use a REPL, so they don't start up a JVM every time they want to evaluate their code. This is the most important thing when teaching people Clojure in my opinion.

mike09:11:03

@malch: no, I didn't try because I had the impression that it's not free even for personal use, I'm going to try it now.

mike09:11:44

also, the presenter of the above video says he had difficulty setting it up, and gave up, it's a new video.

cfleming09:11:03

I find it ironic that an Emacs user said that he tried Cursive for 20 mins and gave up.

borkdude09:11:15

@mike: just try and think for yourself simple_smile

mike09:11:29

> I spent 20 minutes and I couldn't figure it out.

mike09:11:39

that's what he said about cursive.

cfleming09:11:48

I’m sure he figured Emacs out in 15.

cfleming09:11:07

Anyway, I’m off to bed now, but let me know if you have issues and I’ll get back to you.

marvotron09:11:22

Im a long time Intellij user but very new to clojure so getting into cursive was easy, but I have the same problem where other devs dont use Intellij. Quickest / easiest sell for me was Atom + Parinfer : https://github.com/oakmac/atom-parinfer

mike09:11:02

how is parinfer helpful?

mike09:11:13

does it have code autocompletion?

marvotron09:11:20

it makes the brackets do things from indent

mike09:11:28

it looks like to me it's just a nice paren matcher.

marvotron09:11:49

well I found that was the biggest pain point

marvotron09:11:02

brackets, code completion comes quite a far 2nd

marvotron09:11:34

especially when learning I like to think about what I need, not what does the editor suggest from what it knows

mike09:11:39

doesn't cursive solve the problem that parinfer does?

marvotron09:11:56

im still a complete noob, so i'll defer that to someone else

marvotron09:11:20

but intellij often comes with the 'its a heavy tool' mindset

marvotron09:11:44

so the idea of projects and modules isnt something you can avoid, whereas with atom its more simple

marvotron09:11:49

point it at a folder and there's the code

marvotron09:11:07

for the initial part of 'what the hell are all these pieces and what do they do?' clojurescript, lein, figwheel, om, google closure, REPL etc.

marvotron09:11:18

not thinking about the tooling too much is a help

marvotron09:11:38

i got a terminal, i got a text editor. its got colours, it does brackets for me

martinklepsch09:11:47

@marvotron: is there a soliid setup for repl integration with atom?

borkdude09:11:52

you might be better off starting with only clojurescript and figwheel. The editor doesn't matter much as long as there's highlighting. They learn paredit later on.

marvotron09:11:52

i have no idea

borkdude09:11:23

and you can prepare a project for them, the only thing they'd have to do is: lein figwheel

marvotron09:11:28

im always happy in the terminal and fortunately so are my co-workers simple_smile

marvotron09:11:33

on a related note, just yesterday I put up a repo for me to learn this stuff and for my co-workers to clone and have something that runs with the basic set of stuff we're interested in

marvotron09:11:15

I think if you're trying to get others interested having something like that really helps

mike09:11:18

is this om next?

marvotron09:11:26

not my repo in particular,but the idea

marvotron09:11:36

its got a bit of om next

marvotron09:11:59

but again, im just starting, trying to get the pieces we're interested in developing with working. om-next, devcards

mike09:11:01

why still based on the old om?

marvotron09:11:11

isnt [org.omcljs/om "1.0.0-alpha22"] om next?

marvotron09:11:17

that's what its got in the om next quickstart

jaen09:11:20

A bit tongue in cheek: why not reagent? ; d Om was always too awkward to me.

marvotron09:11:00

for us we have quite a complicated data story, mixture of local and remote services everywhere

marvotron09:11:14

so the om-next reconciler concept is very appealing

jaen09:11:06

That makes sense, I suppose, there's nothing equivalent for reagent... yet.

mike09:11:54

@jaen: we're trying to pick btw om and reagent. how is om next compared with reagent when it comes to complexity and other downsides?

jaen09:11:24

Well, reagent is downright simple. You just write functions of type props -> hiccup or (initial-props -> (props -> hiccup) if you need to have some internal state to close over. It's also not prescriptive regarding the application structure. Has a nice flux-ish library in re-frame.

jaen09:11:56

Om always felt too complex and verbose to me and needlessly prescriptive. It was just awkward to use. So between reagent and old om, I don't think there's really any contest. (There's also rum that looks really interesting, but I didn't yet have an occassion to try it out)

jaen09:11:01

Om.next on the other hand

mike09:11:04

and om next? don't keep us hanging..

jaen09:11:15

It's still feels somewhat awkward when I'm reading the docs, but certainly less so than old om. And it's all secondary to the shiny synchronisation story that's inspired by Relay and Falcor; there's still precious few things that try to do that and om.next is one of them.

jaen09:11:37

So it's definitely worth knowing.

mike09:11:54

but how about complexity?

mike09:11:00

is it still complicated?

marvotron09:11:57

maybe a better question is, does it solve the problems you face?

jaen09:11:34

Well, it has to be more complex, since the problem it tries to solve is not trivial. But while om - disclaimer: to me - felt needlessly complicated, then om.next looks like it's no more complex than required by it's problem domain.

grav09:11:58

Imho as a React wrapper, I think Om and Om Next is a bit too opinionated and complex. They both want to do a bit too much for my likings.

jaen09:11:16

Neither reagent nor re-frame get you seamless synchronisation of data with pull queries defined in components.

mike09:11:24

@marvotron: redux, flux, falcor, relay,... all of these mushrooms can solve my problem, but with what complexity cost?

grav09:11:29

We went with Reagent at my company instead, since the first problem we wanted to solve was to write great components.

jaen09:11:48

@grav: I would agree with Om, but I don't think I would call Om Next just a React wrapper.

marvotron09:11:15

@mike, right. i agree. its a complex web of inter-dependent factors. team knowledge, app requirements, future development etc

grav09:11:17

No, both are definitely more than just wrappers. So if you just need a wrapper, which I think we did, I’d recommend something like Reagent.

marvotron09:11:09

watching david nolen's talks about om next really helps give an insight into what each of those has in terms of concepts

grav09:11:10

It just dawned upon our team that what we struggled the most with, was understanding React. If this is the main problem, then also trying to master Om just doesn’t help.

jaen09:11:12

What I mean, is I felt in Om's case that was gratuitous non-essential complexity on top of a wrapper. In Om.next it feels essential to the library.

jaen09:11:33

Of course YMMV

mike09:11:59

@marvotron: which talk , I tied https://www.youtube.com/watch?v=MDZpSIngwm4 and didn't understand a thing. (I'm a cljs noob)

grav09:11:07

@jaen agree. I think I understand the reasoning behind Om.next, and I think that it’ll be a cool thing. But maybe it shouldn’t have been a React wrapper. Maybe it should have been possible to compose the query and parser stuff with any React wrapper.

marvotron09:11:29

@mike there's one before that, that one goes very fast

marvotron09:11:42

and im a cljs noob too simple_smile

mike09:11:49

before that? link?

marvotron09:11:56

i'll find it. 1 sec

jaen09:11:04

@mike: if I were you I'd probably start with reagent, then pick up re-frame

jaen09:11:10

This one

jaen09:11:20

It's more focused on the concept

mike09:11:38

@jaen is reagent just the view?

mike09:11:54

so I'll need re-frame to fetch data from the server?

jaen09:11:37

Not re-frame, IIRC it also doesn't have anything to fetch the data for you, just makes following FLUXish patterns easier

jaen09:11:52

You'd want to look at cljs-http for example

jaen09:11:07

*cljs-ajax

jaen09:11:22

It's probably easier for starters, cljs-http deals in core.async channels

marvotron09:11:12

if you do watch it, you'll notice that during the demo you can't hear a thing, luckily i ripped the audio and processed it so you can hear it simple_smile. the audio is here : http://korisnamedia.com/audio/ClojureNYC_9-29-15.mp3

mike09:11:38

coming from the es6 + webpack + babel + react + redux + ... nightmare, I really am tired of mix n matching libraries. by the time I'm comfortable with my stack, it's already deprecated and the ship community has moved to the new shiny lib...

jaen09:11:04

You won't run escape from that here

mike09:11:17

I'm even surprised to learn that there is more than reaegent and om, so there is rum and quiescent

jaen09:11:24

Clojurescript is wholly mix&match to the point (at least for me) starting out the project is the hardest

mike09:11:26

even in this small community.

jaen09:11:35

But at least there's less libraries than in JS proper

mike09:11:45

what is it with the front end development, why does it have to be so fluid?

tord09:11:48

It's probably just because I'm stupid (I'm not even a real programmer, but a mathematician who somehow ended up writing code without having a clue what I'm doing), but i still struggle to see what is the fundamental difference between Om Next and Reagent + re-frame. In my mind, Om Next queries are analogous to re-frame subscriptions. What am I missing?

mike09:11:54

look at how solid closure library is.

marvotron10:11:01

@mike because we're still learning lessons from 50 years ago simple_smile

mike10:11:15

@jaen: mix n match is fine, as long as what you end up with is fairly stable and solid.

jaen10:11:10

@tord: the backend querying story is different. Re-frame basically has none and leaves it up to you - you can use cljs-ajax, cljs-http, whatever strikes your fancy and it's up to you to query and integrate new data in a handler. Om.next lets you associate queries with components and is written in a way in which it looks at what components need updating, builds a minimal query to get new state, queries the backend and then integrates the data back into application state, all for you

jaen10:11:13

More or less

mike10:11:21

does closure compiler advanced mode work out of the box with reagent + re-frame, or is it tricky?

jaen10:11:43

That is, I never played with the library itself, but I've seen the presentations, read about Relay and Falcor and that's how I understand it.

tord10:11:02

@jaen: Does "backend" here mean "server"? Does this mean that the difference is not really all that significant for client-only apps?

jaen10:11:43

Yeah, I imagine if you don't talk to anything other than the user, then it's quite probably an overkill.

malch10:11:16

@tord For client-only apps I'd go with re-frame+reagent (+ take a look at re-com)

jaen10:11:30

re-com is pretty cool, yeah

tord10:11:33

Thanks for the explanation, @jaen.

malch10:11:36

Since it's much simpler

tord10:11:04

@malch: Yes, Reagent+re-frame+re-com is what I'm currently using, but all the excitement about Om Next makes me feel like I'm missing something.

mike10:11:30

@tord that's called, errr hype simple_smile

jaen10:11:03

@mike: wouldn't know, I've only used architecture heavily inspired by re-frame, not re-frame itself, but I don't imagine it would have problems. In any case there's #C073DKH9P you can ask about that on.

mike10:11:09

@malch what if the app should talk to the server, our server is a rest api, not written in clojure.

malch10:11:52

Still re-frame, I suppose

jaen10:11:57

For REST API you can probably stay with re-frame, yeah

mike10:11:12

also, how about react-native support? do all/none of these libs support it?

mccraigmccraig10:11:17

@mike i was using closure advanced-mode compilation with reagent+re-frame for a while with no problems

jaen10:11:30

Om, reagent, om.next have been shown to work with native IIRC

malch10:11:51

Om.next need some customisation on the backend

mike10:11:52

@mccraigmccraig: great to hear that!! the whole js community is really missing the tree shaking part of closure compiler.

malch10:11:23

@mike Yes, no problems with advanced mode either

mike10:11:38

@malch so om next would not work with a standard rest api out of the box?

malch10:11:29

If my understanding is correct, it wouldn't

malch10:11:57

You have to resolve queries on the backend somehow

jaen10:11:46

Hm, I think you can resolve queries on the front as well if you need

mike10:11:52

any reagent/re-frame talks on youtube? there is a lot of om in clojure conferences, but couldn't find any of reagent/re-frame.

jaen10:11:59

It queries wikipedia REST API

malch10:11:15

@jaen may be wrong here 😊

jaen10:11:36

Me to, I only understand the general idea, not implementation details

malch10:11:38

@mike: Just read the docs, they are great

mike10:11:55

what about things like caching and normalization, does re-frame take care of those?

jaen10:11:38

Normalization? You mean if you have a user in REST responses and you want that user to be represented just once in your app?

jaen10:11:44

Then you have to write it by yourself.

jaen10:11:03

I kinda did something like that once, using reagent + datascript.

mike10:11:14

I meant an equivalent of https://github.com/gaearon/normalizr not sure if it applies here. (coming from redux)

jaen10:11:42

Yeah, something like that

jaen10:11:43

On your own

mike10:11:11

is that something that om next claims to do automatically?

jaen10:11:50

re-frame deals mostly with gicing you FLUX-like structure for you application, how you feed the app database is up to you.

jaen10:11:14

I don't think it's 100% automatically, but it gives you tools geared towards that I think.

jaen10:11:42

Then you have a nice store for normalised data on the client

mccraigmccraig10:11:03

@mike: re-frame doesn't have anything specifically aimed at caching... though you can just stuff api responses into your app-state, so it's easy enough. & normalizing is surely a server-side concern rather than client-side ?

jaen10:11:23

I basically inflicted writing something similar with reagent instead for my thesis on me, but I'm kinda in the woods : V

jaen10:11:20

@mccraigmccraig: well that depends if you control the backend for one

mike10:11:44

mccraigmccraig: I think normalizing on the server side could become expensive when having many clients of many different states.

mike10:11:26

you need to either keep each client state on the server side, or the client must send its state tree on the request.

mike10:11:46

it makes sense to normalize on the client side for this case.

mccraigmccraig10:11:22

hmm. i think i'm not getting something... i thought normalizing was about flattening object graphs in responses

mccraigmccraig10:11:59

though i can see you might want to do it client-side if you don't have control of the server-side

jaen10:11:24

Yeah, exploding entities into their constituent parts and de-duplicating them is how I would describe that in lay language. Well, maybe not-so-lay.

jaen10:11:43

But it still might be more strain on the server

jaen10:11:53

If it doesn't know what it can omit sending because client already knows it.

jaen10:11:16

If the client asks only for what it needs

jaen10:11:24

And gets pushes when something updates

jaen10:11:11

It's probably less demanding - you make less queries to the backend server, it has to fetch less from the db (or wherever it gets data from) and so on.

marvotron10:11:51

also there might not be just 1 'server' but a collection of data sources that have references to the same entity

marvotron10:11:42

so some kind of client side normalization is useful in that case (which also happens to be our case)

dnolen13:11:12

@mike: @jaen: it’s automatic in the sense that the queries themselves define the schema. You do have to provide a function that computes links from the visited node.

dnolen13:11:55

@mccraigmccraig: yeah it just depends, Om Next supports normalization client or server side

dnolen13:11:27

@malch @mike that’s a misinterpretation

dnolen13:11:50

Om Next can work perfectly fine with REST apis

dnolen13:11:09

you just have to do more work in your send function.

malch13:11:31

@dnolen: I see, sorry for that

dnolen13:11:42

i.e. you can pretend REST apis support graph queries trivially

dnolen13:11:11

Om Next has no backend requirements whatsoever

dnolen13:11:31

@tord except you can’t opt into sending re-frame subscriptions over the wire far as I know

dnolen13:11:02

Om Next doesn’t care if there is or there isn’t a backend that knows about query expressions

dnolen13:11:21

and therein lies its power - this is a Falcor idea

mike13:11:49

@dnolen: as a noob, these all sound like architecture level material. I have to yet see some pragmatic tutorials showing actually how to build an app with om next.

dnolen13:11:28

@mike there are developing application oriented tutorials coming from the community so I would look out for those

mike13:11:35

(1) lisp syntax (2) editor (3) flux/relay/falcor architecture, each of these single items are a noob killer, the unfortunate combination of these happens with clojurescript.

dnolen13:11:40

@mike can’t help you with 1). I don’t really understand 2), use whatever. No one says you have to use any of this stuff.

dnolen13:11:51

people started out writing ClojureScript + jQuery

mike13:11:17

that's not helpful.

mike13:11:28

I come here to look for a solution for SPA.

tord13:11:32

Speaking as a non-programmer, I'd say Lisp syntax is the most newbie-friendly syntax there is.

mike13:11:44

if I wanted to use jquery, why would I even touch clojurescript?

mike13:11:29

@tord maybe because you're a mathematician?

tord13:11:00

@mike: Not sure, but I think it would be like that for most non-technical people. Less syntax means less to learn and remember.

darwin13:11:05

@mike: I don’t want to disappoint you, but I think ClojureScript community does not offer “frameworks” in general, only “libraries” you have to compose together. There is no Angular or Ember or Rails in ClojureScript ecosystem

dnolen13:11:55

@mike I cannot explain why you would want to use ClojureScript simple_smile But a lot of people like Clojure the language, and for them ClojureScript + jQuery gave them something they didn’t have before.

mike13:11:58

@darwin I did not have a framework in that list. libs are more than fine.

dnolen13:11:37

@grav I take it you haven’t actually tried Om Next, the parser stuff is actually a la carte

dnolen13:11:47

how could it work on the backend if it wasn’t?

darwin13:11:11

@mike: my point was, composing libraries expects some knowledge and is not noob friendly, full-stack frameworks are more noob friendly because they make architectural decisions on behalf of the user and do some hand-holding to keep people on “the right path"

mike13:11:19

@dnolen: that's starting from the wrong demographic, people who already know clojure do not need convincing about clojurescript. the problem is convincing people who do not know what clojure is. I find many points in https://www.youtube.com/watch?v=gsffg5xxFQI very valid.

jaen13:11:33

@tord: maybe it's simpler in that it has few rules, but the more I use Clojure the more I think LISP syntax feels "too dense" and it's regularity lets you easily trip up by things like putting something that's not a function in a function call position. It's not a deal breaker by any stretch of imagination, but Haskell syntax feels more readable than LISP to me for example. Sure, it's less regular, but it's also less dense and protects you from such slip-ups.

darwin13:11:53

from this discussion I have a feeling, that you are looking for some kind of SPA framework in clojurescript, already bundled with tooling and IDE (ideally) simple_smile

jaen13:11:06

@mike: sometimes I think Clojurescript isn't all that interested in the Javascript crowd ; d

angusiguess13:11:24

@mike Well I'm glad you're here, if you were working through clojurescript and had concerns with syntax or what have you we'd be happy to help!

mike13:11:21

@jaen closure library is also not interested in js crowd, they're oldschool, and I like their way. the thing is, I could start with closure library easily and 'feel at home'. it's a different story with clojurescript.

mike13:11:16

@angusiguess: I have to say I've found clojurescript community very helpful + friendly so far.

angusiguess13:11:49

@mike Getting into lisp takes some effort but most of us are here because we're super into it.

mike13:11:16

@angusiguess: exactly! lisp people feel at home with clojurescript.. the problem is, people like me and my team who are not lisp people (and do not hate lisp or anything, it's just that we never wrote lisp) and we want to look for a sound SPA solution.

dnolen13:11:29

@mike “wrong” demographic. It’s the demographic that the easiest to reach out to and makes the most sense to pursue in terms of time/cost. Yes that’s a great video, but it hand waves the time/cost of reaching out to other communities especially ones that would require more effort to evangelize to for network effect reasons.

angusiguess13:11:32

@mike Depending on the amount of time you have to invest, a couple of weeks working through a clojure book should give you an indication if it's the direction you want to go.

angusiguess13:11:58

At $WORK we've found we can get most devs up and running in ~2 weeks.

mike13:11:49

@angusiguess: is clojurescript not a a subset of clojure? is reading a clojure book the right place to start?

jaen13:11:00

It's quite a big subset.

mike13:11:12

(and why is there only one (outdated) book on clojurescript?)

angusiguess13:11:31

I'd be a bad person to talk to about literature specific to clojurescript, but the vast majority of the information maps.

mike13:11:41

it's like someone absolutely new to javascript, I wouldn't ask them to start with the book on the left

jaen13:11:31

Well, it is true that Clojure doesn't have as much "canned" solutions as Ruby or Javascript world has. The closest thing server-side has to it is probably Luminus. For frontend it's certainly less clear cut. For frontend reagent + re-frame is probably the closest to the sound SPA solution you'd want right now. Though in the near future om.next will probabyl be a neat alternative.

mike13:11:56

given that a clojure book probably has nothing to do with frontend development, and might come with some scary jargons.

angusiguess13:11:59

I like Chas Emerick's book, but also Living Clojure just came out and it looks like a fantastic introduction.

jaen13:11:59

@mike: there's probably no Clojurescript book because it used to move really fast (and still does to a degree)

mike13:11:21

@jaen makes sense.

dnolen13:11:39

@mike @jaen yes Stuart Sierra & Luke Vanderhart were working on a second edition but over the past 2 years there’s been a massive upheaval

dnolen13:11:54

unlike JavaScript, ClojureScript switched to React overnight

dnolen13:11:21

and the tooling landscape has transformed thanks to Figwheel & growing editor/IDE support

jaen13:11:40

Basically if it has domina or jayq it's severely outdated and even then are things that showed up after introduction of React (like re-frame) that totally should be in an introductory material

dnolen13:11:16

anecdotally the community also feels much larger - it’s now pretty much impossible to really know what’s going on

jaen13:11:00

And - but that's my view - if a tutorial uses lein instead of boot, then it's probably a bit out of touch as well.

mike13:11:08

IMO the best long term investment of clojurescript is closure library, not react simple_smile

mike13:11:26

there is google's incremental dom coming soon to closure library.

angusiguess13:11:39

boot is rad, but once I stopped trying to make lein do everything I started to feel better as well.

dnolen13:11:46

except ClojureScript doesn’t care about DOM

dnolen13:11:57

and React Native covers iOS and Android

dnolen13:11:18

but sure Google Closure Library & Compiler has always been and always will be a big part

mike13:11:18

you're right about the native side.

mike13:11:16

the funny thing is it is not really possible to mix closure library goog.require and es6 modules in javascript itself.

mike13:11:24

but this is trivial in clojurescript.

dnolen13:11:28

the ClojureScript rationale really is "Clojure for places where you can’t run the JVM"

dnolen13:11:33

all the other stuff is secondary

jaen13:11:05

@angusiguess: I remember that when I first tried Clojurescript with lein-cljsbuild & co. and it was a really big pain to have it working well, a pain I never experienced using boot.

mike13:11:38

@jaen is boot an alternative for lein?

mike13:11:48

how is it better?

jaen13:11:06

It doesn't hurt ; d

jaen13:11:09

But more seriously

angusiguess13:11:21

@mike lein is great because it does about 20 things. boot is great because you snap together pieces to build and run your stuff.

jaen13:11:42

It's just simpler to get up and running than lein (for Clojurescript, if you're doing just Clojure then either is fine)

mike13:11:48

I cannot find anything about boot in clojurescript wiki.

angusiguess13:11:50

boot is modular and has fewer dependencies, lein is config-heavy.

jaen13:11:08

And Clojurescript setup with boot is less error prone

angusiguess13:11:59

I like the lein setup that the om.next tutorials use but it pretty much exclusively uses lein for deps.

tord13:11:57

I haven't personally tried boot, but my impression is that Leiningen would be easier in practice, simply because that's what everybody else is using. Easier to get help or google for solutions.

jaen13:11:41

But with lein the errors tend to be more arcane in my experience, and boot has an active channel here - #C053K90BR - if you need to ask questions

marvotron13:11:47

what would be handy, and maybe this is something i'll have a go at is a kind of mapping between the usual js ecosystem tools and the closurescript stuff.

marvotron13:11:03

grunt / gulp -> lein / boot ?

jaen13:11:19

Someone compared boot to broccoli here recently, I think

mike13:11:39

lein new tenzing your-app

mike13:11:46

you need lein to get boot?

angusiguess13:11:07

That probably uses lein to create a template.

jaen13:11:07

No, you don't. Tenzing just uses lein's template system

angusiguess13:11:12

It's probably not necessary.

marvotron13:11:32

so lein is kind of like yeoman, grunt and bower and npm rolled into one

angusiguess13:11:05

lein handles: dependencies, building, running, minification, tests, deployment, linting, whatever else you want to plug into it.

jaen13:11:17

If you take look at saapas (or the result of lein new tenzing) you'll see it just uses boot

mike13:11:38

@jaen I guess lein new tenzing your-app installs boot too? no?

jaen13:11:05

No, I don't think it does

jaen13:11:13

It just creates the project structure

jaen13:11:21

You have to follow the instructions I linked

jaen13:11:28

Just like you did with lein when you installed it

mike13:11:37

you're right.

dnolen13:11:59

@marvotron: something like that. one thing to understand is that Clojure existed before ClojureScript and over time the community and core just embraced the pre-existing tooling.

dnolen13:11:40

for example the most popular way to build ClojureScript is still a plugin to Lein. ClojureScript dependency resolution is just Maven same as Clojure.

marvotron13:11:10

best not mention maven to js developers. the colour drains from their cheeks

marvotron13:11:06

but i'll have a go at a rough mapping of tools because it'll be useful for me and my colleagues as well as everyone else. dependency resolution, building, testing etc..

dnolen13:11:17

@marvotron: ha, usually if you say JVM you’ve already lost them. But I don’t think anyone’s interested in that problem anyway.

mike13:11:02

is there a plan at all to move clojure/clojurescript out of jvm?

dnolen13:11:15

@mike: never going to happen

mike13:11:25

like Elm is written in haskell, and no overhead there.

dnolen13:11:35

“no overhead"

mike13:11:57

vm warm up etc.

dnolen13:11:09

you can compile ClojureScript into JavaScript now and there’s some community interesting around that

dnolen13:11:11

“vm warmup"

marvotron13:11:17

'drip' helps with startup times

mike13:11:20

why are you keep quoting me?

roberto13:11:41

because he didn’t understand how you were using that term, I guess.

roberto13:11:16

“vm warmup” isn’t a thing for cljs

angusiguess13:11:20

@mike A lot of people who write cljs for the browser are using figwheel etc, so you keep one jvm running for your whole session, then maybe spin one up when you build for production.

angusiguess13:11:31

jvm is only used for compilation.

roberto13:11:48

maybe you meant “vm startup"

mike13:11:11

@angusiguess: isn't the pain with lein that it might fire up multiple jvm's?

roberto13:11:23

and “vm startup” isn’t an issue if you are using figwheel

jaen13:11:33

Which is even better

jaen13:11:39

Because it keeps everything in a single process

angusiguess13:11:41

@mike Yeah, but you have one lein or boot session running the entire time rather than like.

jaen13:11:43

So less memory overhead as well

dnolen13:11:44

@mike you’re saying things that have no correspondence to anything I’ve ever experienced with the JVM on modern hardware.

roberto13:11:47

I didn’t like boot, I found it too slow to compile cljs

dnolen13:11:01

write HelloWorld.java, running this program takes 80ms

mike13:11:02

@jaen if figwheel solves that problem with lein, is there a benefit to use boot?

roberto13:11:04

what is bad about having a repl running all the time?

dnolen13:11:09

so much for VM startup

jaen13:11:33

It's not VM startup, it's Clojure startup

roberto13:11:37

do you close your editor everytime you want to open a new file?

jaen13:11:38

Clojure is just relatively slow to boot

dnolen13:11:56

this also isn’t true

dnolen13:11:06

the entire Clojure ecosystem is what makes everything slow to start

dnolen13:11:19

my Clojure REPL starts in under second in Cursive

jaen13:11:54

@mike: possibly isn't, but IMO line still has quite finnicky Clojurescript build setup, and that's where boot helps.

marvotron13:11:18

so for us newer users who type in 'lein fighweel' and have to wait a fair few seconds, whats the quickest route to quicker startup? simple_smile

angusiguess13:11:33

Or build scripts.

jaen13:11:34

@mike: I've just pushed something I'm working on so if you want to compare how a boot project looks - https://gitlab.com/jaen/clj-cljs-presentation/tree/master. It has some nice things (like being able to use Ruby's middleman to manage assets).

dnolen13:11:46

@marvotron: there are so many obstacles to fast startup time and not enough people care to fix it

jaen13:11:47

@angusiguess: and who manages deps then : V

dnolen13:11:57

for example ClojureScript provides AOTed JARs

dnolen14:11:03

but they are impossible to use in Lein

martinklepsch14:11:07

@marvotron: startup times are similar across the board..

dnolen14:11:23

so you have to eat 4-8 seconds of ClojureScript compile time just to start Figwheel

marvotron14:11:24

so its all recompiled

dnolen14:11:18

I love Clojure(Script) but there’s just not much interest in fixing this fixable problem

marvotron14:11:37

what would be the general approach to fixing it? can i read about it somewhere?

marvotron14:11:47

i love optimising build times and that kind of thing 😄

dnolen14:11:57

@marvotron: get involved in Lein / Boot / cljsbuild

martinklepsch14:11:11

@marvotron: keep in mind that this is just for first builds, i.e. incremental builds are much faster

marvotron14:11:35

i know once figwheel is up and running its all very fast

mike14:11:39

@marvotron: or, work on scala compiler!

dnolen14:11:47

@marvotron: yes none of these problems exist for up and running stuff

marvotron14:11:13

but its quite a common pain point because when you're new you have to add dependencies all the time

marvotron14:11:19

and that requires a restart, right?

marvotron14:11:18

its not easy being a noob simple_smile

mike14:11:41

any open source real world app based on reagent/re-frame, to study?

mike14:11:10

(something like docker for golang)

martinklepsch14:11:16

It doesn’t require a restart with boot 😛

jaen14:11:41

@dnolen: I didn't mean it as Clojure-the-REPL, but how Clojure the language works (as in here http://blog.ndk.io/2014/02/25/clojure-bootstrapping.html). And the less trivial the application is, the longer boot time will be. Lein and boot aren't trivial.

jaen14:11:58

@martinklepsch: do tell more, I wasn't aware of that.

jaen14:11:37

@mike: there's one linked in the readme it seems - https://github.com/madvas/fractalify/ - not sure how big it is though.

martinklepsch14:11:49

You can just call (boot.core/merge-env! :dependencies ‘[[your-dep “0.1.0”]]) and it’s available. simple_smile

dnolen14:11:57

@jaen yes but those graphs don’t include how long it takes for non-AOTed code

dnolen14:11:09

those graphs would go far off to the right

jaen14:11:38

Yeah, without AOT it certainly might be even slower, read, compile, emit classes and so on.

dnolen14:11:01

Clojure has been binary compatible since 1.4 if I recall

arronmabrey14:11:06

@mike: I have been going through this online book on ClojureScript it's been really helpful so far. https://funcool.github.io/clojurescript-unraveled/

dnolen14:11:34

yet popular libraries don’t provide aot :classifier

dnolen14:11:48

and nothing can fix Lein’s insistance on doing everything dynamically

jaen14:11:50

Clojurescript Unraveled looks like a pretty good starter, but doesn't touch on React and whatnot unfortunately.

mike14:11:17

@jaen: fractalify is very close to what I had in mind. thanks!

marvotron14:11:39

@dnolen when you say 'nothing can fix..' is that an absolute nothing or 'no-one is inclined to fix'

jaen14:11:18

@martinklepsch: so you say I just do that from boot.user and it downloads the dep and puts in on classpath? If so then - whoa, magic.

arronmabrey14:11:38

@jaen: that's true but it does touch on some of the tooling which has been hard for me to grok thus far. Also it's a nice concise overview of the Clojure(Script) language simple_smile

jaen14:11:44

@marvotron: I imagine it's "nothing can fix" as in "no one would want to rewrite lein from scratch"

dnolen14:11:54

@marvotron: yeah “impossible” is probably too strong a word, but I suspect working on the problem would require everyone to re-sync.

martinklepsch14:11:58

@jaen similar stuff exists for lein (think its part of something called vinyasa) but it’s a bit more “native” in boot

marvotron14:11:59

so architecturally prohibitive

darwin14:11:52

@dnolen: is it (still) true that = might not work well for comparing two keywords? and one must use keyword-identical?

dnolen14:11:58

@marvotron: maybe, maybe not - but someone would need to sit down and work it out.

dnolen14:11:15

@darwin: that’s never been true

marvotron14:11:30

i got enough to chew on for now simple_smile

dnolen14:11:37

@darwin keyword-identical? is a performance thing

martinklepsch14:11:07

@marvotron: @dnolen in boot there is this concept of pods which are isolated clojure runtimes. technically it should be possible to turn this into a “server” type of component and all newly invoked things would just create new pods within "the server”. I think drip was conceptually similar but don’t remember exactly

darwin14:11:41

@dnolen: ok, thanks for clarification, I was under impression that it was documented somewhere, but it is true that I never encountered any problem personally (when I forgot to use keyword-identical?), good to know

dnolen14:11:40

@martinklepsch: having tried a few of the server process things in the past - they never worked well enough for me. Perhaps the Boot thing is better, haven’t tried Boot yet.

martinklepsch14:11:32

Well there is no server thing in Boot yet, that’s just something “within reach” w/ Boot … I think 😄

jaen14:11:18

@martinklepsch: out of curiosity, from your description I understand I do that manually. Would theoretically boot be able to watch build.boot and inject new dependencies when it noticed those?

mike14:11:22

fine. I'll go with boot. you can stop fighting now.

jaen14:11:02

No one's fighting. I just sincerely think it will be simpler for beginners if that's your goal.

martinklepsch14:11:03

@jaen you can have a task that looks at resources/deps.edn and makes sure all deps in there are satisfied. you could also parse build.boot but I don’t think that’d end up being very clean.

jaen14:11:27

That deps.edn suggestion sounds cool, I'll try it.

darwin14:11:41

I’m writing a library which does some js interop, can anyone point me in direction how to safely reference “root" javascript object from clojurescript, I can do js/window, but I’m not sure if “window” object will be always present, also I saw “js/self” but I’m not sure how this expands, any explanation appreciated

thheller14:11:19

@darwin: js/goog.global might work

darwin14:11:42

@thheller: thanks, will google more about it

thheller14:11:14

doubt there is much to google about it simple_smile

thheller14:11:43

it is goog.global = this;

darwin14:11:43

I see, looking at the goog source code, it looks good to me, thanks

thheller14:11:49

this is whatever is the global object

thheller14:11:04

ie window or actual global in node

darwin14:11:25

now, when I do js/goog.global will it survive advanced compilation? is some default extern handling it? simple_smile

thheller14:11:46

goog.global will survive, but whatever comes after that won't simple_smile

darwin14:11:00

good enough for me

darwin14:11:03

thanks a lot

thheller14:11:38

@darwin I'd be vary careful with global though, it is not intended for direct use

Travis18:11:29

Hey guys, I am getting ready to get up to speed with clojurescript and I haven’t done UI side of things in awhile. Is the Clojurescript up and running book still pretty relevant?

Travis18:11:38

minus tools I am sure

shaunlebron18:11:57

@camechis check out ClojureScript Unraveled

shaunlebron18:11:35

it's an online book that is more up to date

Travis18:11:44

cool I will check it out

shaunlebron18:11:58

@camechis: figwheel to get started is very beginner friendly too

Travis18:11:49

yes, I definitely will be looking at figwheel

shaunlebron18:11:56

http://cljs.info/cheatsheet is a good quickref of funcs and concepts

mfikes18:11:20

Socket REPL is mind bending. :) I'm not used to the idea of having multiple REPL sessions into a JavaScript engine. (I never do any browser-based ClojureScript dev—if that's already common in that world.)

dnolen19:11:53

@mfikes: yeah I believe we fixed browser REPL some time ago to support that. Of course nREPL has always supported that

dnolen19:11:05

and the swank stuff before that

mfikes19:11:21

Cool. So it is just me. Well my mind is blown anyway. :)

dnolen19:11:26

(I mean the general idea of Lisp process w/ multiple clients)

dnolen19:11:36

I remember the first time I connected to an SBCL process on Slicehost over SSH from SLIME … the power!

mfikes19:11:28

It is like stereo, quadrophonics, after listening to one of those cheesy mono radios.

mike20:11:20

given that clojurescript is not strongly typed, when it comes to refactoring, where does it fall in the spectrum of javascript to typescript?

dnolen20:11:16

it’s like JavaScript minus all the coercion stuff and the mutability

dnolen20:11:33

so assertions, testing etc. are important

mike20:11:04

would optional typing be there at some point?

angusiguess21:11:18

core.typed offers gradual typing but I've never used it so ymmv.

angusiguess21:11:57

Prismatic offers a library called schema which helps to annotate types, it can validate types in tests (or even running code) as well.

angusiguess21:11:17

sorry, core.typed offers optional typing with an eye towards gradual in the future.

mike21:11:27

how is optional typing different to gradual typing?

angusiguess21:11:11

I don't really know the details, I just know that core.typed has recognized some limitations and are working to solve them.

dnolen21:11:20

@mike there’s already experimental support for Closure type annotations

dnolen21:11:32

but somebody needs to spend a little more time on it to see it through

mike21:11:02

are collections in clojurescript transpiled form clojure to javascript, or are they based on closure library collection?

jaen21:11:02

Clojurescript has it's own immutable collection types IIRC

thheller21:11:47

@mike the collections are entirely implemented in cljs

arohner22:11:02

@mike optional typing is compile-time only, enforces no contracts at runtime. If something slips through, you have no guarantees. gradual typing is optional typing + runtime validation

mike23:11:32

is the compiled javascript code, from clojurescript, also annotated for closure compiler?

mike23:11:28

if so, that could bring some type safety, which could provide refactoring safety to some extend.

bensu23:11:48

@mike that is what David was talking about earlier. Parts of the cljs is annotated and those annotations are passed along to Closure. The remaining work is to allow for annotation of new (and some existing) types.

bensu23:11:35

there are a couple of issues for it, for example http://dev.clojure.org/jira/browse/CLJS-1412

mike23:11:03

@bensu I meant, would clojurescript compiler generate any annotations?

bensu23:11:18

@mike: yes, look at :jsdoc metadata