This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2015-11-25
Channels
- # admin-announcements (3)
- # beginners (165)
- # boot (123)
- # cider (106)
- # clara (1)
- # cljsrn (20)
- # clojure (199)
- # clojure-canada (2)
- # clojure-dev (3)
- # clojure-poland (29)
- # clojure-russia (7)
- # clojure-taiwan (2)
- # clojurescript (487)
- # cursive (25)
- # datavis (89)
- # datomic (26)
- # gorilla (2)
- # hoplon (15)
- # ldnclj (12)
- # lein-figwheel (9)
- # leiningen (2)
- # liberator (1)
- # off-topic (25)
- # om (380)
- # onyx (26)
- # parinfer (52)
- # portland-or (12)
- # re-frame (28)
- # reagent (132)
Anyone know why all the ClojureScript books are due out in February 2016? I think I count 3 (new books or 2nd editions).
@mfikes: thx. if i were doing node or native work i would. but would like to use advanced compilation.
would be cool to be able to require namespaces at runtime and pull them in over the wire
@tmtwd: Web Development with Clojure: Build Bulletproof Web Apps with Less Code 2nd Edition - (February 25, 2016)
ClojureScript: Up and Running: Functional Programming for the Web 2nd Edition - (February 25, 2016)
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?
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)
i've tried googling this to no avail due to many false positives on the obvious keywords
well, i feel a bit dumb. i was able to fix this in :cljsbuild :builds :app :compiler :asset-path
I was wondering if it's possible to dynamically import / require / use a separate module?
(doseq [module enabled-modules]
(.log js/console (symbol (str "demo.contrib." (name module))))))
inside demo.contrib.{{ module-name }} are functions that I want to usehrm 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
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?
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.
looks like the authors of clojure did not really care the huge population and does not and never will adopt vim/emac based editors.
@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.
really, we should learn something from microsoft and visual studio code. this language needs an official editor.
@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.
@mike: just download/install Intellij, install the plugin, open a project.clj and you're good
@borkdude: @mike: It’s currently fiddly but will get better very soon (like a week or so)
IntelliJ Community Edition is free and it can be used for any kind of work
@borkdude: https://youtu.be/gsffg5xxFQI?t=26m8s this guy says it's a tough place to start for a noob (cursive)
@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.
@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.
also, the presenter of the above video says he had difficulty setting it up, and gave up, it's a new video.
I find it ironic that an Emacs user said that he tried Cursive for 20 mins and gave up.
Anyway, I’m off to bed now, but let me know if you have issues and I’ll get back to you.
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
especially when learning I like to think about what I need, not what does the editor suggest from what it knows
so the idea of projects and modules isnt something you can avoid, whereas with atom its more simple
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.
@marvotron: is there a soliid setup for repl integration with atom?
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.
and you can prepare a project for them, the only thing they'd have to do is: lein figwheel
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
I think if you're trying to get others interested having something like that really helps
but again, im just starting, trying to get the pieces we're interested in developing with working. om-next, devcards
for us we have quite a complicated data story, mixture of local and remote services everywhere
@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?
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.
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)
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.
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.
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.
Neither reagent nor re-frame get you seamless synchronisation of data with pull queries defined in components.
@marvotron: redux, flux, falcor, relay,... all of these mushrooms can solve my problem, but with what complexity cost?
We went with Reagent at my company instead, since the first problem we wanted to solve was to write great components.
@grav: I would agree with Om, but I don't think I would call Om Next just a React wrapper.
@mike, right. i agree. its a complex web of inter-dependent factors. team knowledge, app requirements, future development etc
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.
watching david nolen's talks about om next really helps give an insight into what each of those has in terms of concepts
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.
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.
@marvotron: which talk , I tied https://www.youtube.com/watch?v=MDZpSIngwm4 and didn't understand a thing. (I'm a cljs noob)
@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.
Not re-frame, IIRC it also doesn't have anything to fetch the data for you, just makes following FLUXish patterns easier
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 . the audio is here : http://korisnamedia.com/audio/ClojureNYC_9-29-15.mp3
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...
I'm even surprised to learn that there is more than reaegent and om, so there is rum and quiescent
Clojurescript is wholly mix&match to the point (at least for me) starting out the project is the hardest
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?
@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
does closure compiler advanced mode work out of the box with reagent + re-frame, or is it tricky?
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.
@jaen: Does "backend" here mean "server"? Does this mean that the difference is not really all that significant for client-only apps?
Yeah, I imagine if you don't talk to anything other than the user, then it's quite probably an overkill.
@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.
@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.
@malch what if the app should talk to the server, our server is a rest api, not written in clojure.
@mike i was using closure advanced-mode compilation with reagent+re-frame for a while with no problems
@mccraigmccraig: great to hear that!! the whole js community is really missing the tree shaking part of closure compiler.
At least that's how it looks here - https://github.com/omcljs/om/wiki/Remote-Synchronization-Tutorial#code
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.
Normalization? You mean if you have a user in REST responses and you want that user to be represented just once in your app?
I meant an equivalent of https://github.com/gaearon/normalizr not sure if it applies here. (coming from redux)
re-frame deals mostly with gicing you FLUX-like structure for you application, how you feed the app database is up to you.
I don't think it's 100% automatically, but it gives you tools geared towards that I think.
https://github.com/omcljs/om/wiki/Components,-Identity-&-Normalization#normalization
Also you can use datascript with it - https://github.com/omcljs/om/wiki/DataScript-Integration-Tutorial
@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 ?
I basically inflicted writing something similar with reagent instead for my thesis on me, but I'm kinda in the woods : V
@mccraigmccraig: well that depends if you control the backend for one
mccraigmccraig: I think normalizing on the server side could become expensive when having many clients of many different states.
you need to either keep each client state on the server side, or the client must send its state tree on the request.
hmm. i think i'm not getting something... i thought normalizing was about flattening object graphs in responses
though i can see you might want to do it client-side if you don't have control of the server-side
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.
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.
also there might not be just 1 'server' but a collection of data sources that have references to the same entity
so some kind of client side normalization is useful in that case (which also happens to be our case)
@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.
@mccraigmccraig: yeah it just depends, Om Next supports normalization client or server side
@tord except you can’t opt into sending re-frame subscriptions over the wire far as I know
Om Next doesn’t care if there is or there isn’t a backend that knows about query expressions
@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.
@mike there are developing application oriented tutorials coming from the community so I would look out for those
(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.
@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.
Speaking as a non-programmer, I'd say Lisp syntax is the most newbie-friendly syntax there is.
@mike: Not sure, but I think it would be like that for most non-technical people. Less syntax means less to learn and remember.
@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
@mike I cannot explain why you would want to use ClojureScript But a lot of people like Clojure the language, and for them ClojureScript + jQuery gave them something they didn’t have before.
@grav I take it you haven’t actually tried Om Next, the parser stuff is actually a la carte
@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"
@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.
@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.
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)
@mike: sometimes I think Clojurescript isn't all that interested in the Javascript crowd ; d
@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!
@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.
@angusiguess: I have to say I've found clojurescript community very helpful + friendly so far.
@mike Getting into lisp takes some effort but most of us are here because we're super into it.
@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.
@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.
@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.
At $WORK we've found we can get most devs up and running in ~2 weeks.
@angusiguess: is clojurescript not a a subset of clojure? is reading a clojure book the right place to start?
I'd be a bad person to talk to about literature specific to clojurescript, but the vast majority of the information maps.
it's like someone absolutely new to javascript, I wouldn't ask them to start with the book on the left
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.
given that a clojure book probably has nothing to do with frontend development, and might come with some scary jargons.
I like Chas Emerick's book, but also Living Clojure just came out and it looks like a fantastic introduction.
@mike: there's probably no Clojurescript book because it used to move really fast (and still does to a degree)
@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
and the tooling landscape has transformed thanks to Figwheel & growing editor/IDE support
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
anecdotally the community also feels much larger - it’s now pretty much impossible to really know what’s going on
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.
boot is rad, but once I stopped trying to make lein do everything I started to feel better as well.
but sure Google Closure Library & Compiler has always been and always will be a big part
the funny thing is it is not really possible to mix closure library goog.require and es6 modules in javascript itself.
the ClojureScript rationale really is "Clojure for places where you can’t run the JVM"
@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.
@mike lein is great because it does about 20 things. boot is great because you snap together pieces to build and run your stuff.
It's just simpler to get up and running than lein (for Clojurescript, if you're doing just Clojure then either is fine)
boot is modular and has fewer dependencies, lein is config-heavy.
@mike: example projects - https://github.com/martinklepsch/tenzing, https://github.com/Deraen/saapas
I like the lein setup that the om.next tutorials use but it pretty much exclusively uses lein for deps.
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.
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
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.
That probably uses lein to create a template.
It's probably not necessary.
@mike: install instructions - https://github.com/boot-clj/boot#install
lein handles: dependencies, building, running, minification, tests, deployment, linting, whatever else you want to plug into it.
If you take look at saapas (or the result of lein new tenzing
) you'll see it just uses boot
@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.
for example the most popular way to build ClojureScript is still a plugin to Lein. ClojureScript dependency resolution is just Maven same as Clojure.
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..
@marvotron: ha, usually if you say JVM you’ve already lost them. But I don’t think anyone’s interested in that problem anyway.
you can compile ClojureScript into JavaScript now and there’s some community interesting around that
@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.
jvm is only used for compilation.
@angusiguess: isn't the pain with lein that it might fire up multiple jvm's?
@mike Yeah, but you have one lein or boot session running the entire time rather than like.
@mike you’re saying things that have no correspondence to anything I’ve ever experienced with the JVM on modern hardware.
@mike: possibly isn't, but IMO line still has quite finnicky Clojurescript build setup, and that's where boot helps.
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?
Or build scripts.
@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).
@marvotron: there are so many obstacles to fast startup time and not enough people care to fix it
@angusiguess: and who manages deps then : V
@jaen Always deps :x
@marvotron: startup times are similar across the board..
I love Clojure(Script) but there’s just not much interest in fixing this fixable problem
@marvotron: get involved in Lein / Boot / cljsbuild
@marvotron: keep in mind that this is just for first builds, i.e. incremental builds are much faster
@marvotron: or, work on scala compiler!
@marvotron: yes none of these problems exist for up and running stuff
but its quite a common pain point because when you're new you have to add dependencies all the time
It doesn’t require a restart with boot 😛
@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.
@martinklepsch: do tell more, I wasn't aware of that.
@mike: there's one linked in the readme it seems - https://github.com/madvas/fractalify/ - not sure how big it is though.
You can just call (boot.core/merge-env! :dependencies ‘[[your-dep “0.1.0”]])
and it’s available.
Yeah, without AOT it certainly might be even slower, read, compile, emit classes and so on.
@mike: I have been going through this online book on ClojureScript it's been really helpful so far. https://funcool.github.io/clojurescript-unraveled/
Clojurescript Unraveled looks like a pretty good starter, but doesn't touch on React and whatnot unfortunately.
@arronmabrey: thanks!
@dnolen when you say 'nothing can fix..' is that an absolute nothing or 'no-one is inclined to fix'
@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.
@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
@marvotron: I imagine it's "nothing can fix" as in "no one would want to rewrite lein from scratch"
@marvotron: yeah “impossible” is probably too strong a word, but I suspect working on the problem would require everyone to re-sync.
@jaen similar stuff exists for lein (think its part of something called vinyasa) but it’s a bit more “native” in boot
@dnolen: is it (still) true that =
might not work well for comparing two keywords? and one must use keyword-identical?
@marvotron: maybe, maybe not - but someone would need to sit down and work it out.
@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
@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
@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.
Well there is no server thing in Boot yet, that’s just something “within reach” w/ Boot … I think 😄
@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?
No one's fighting. I just sincerely think it will be simpler for beginners if that's your goal.
@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.
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
now, when I do js/goog.global will it survive advanced compilation? is some default extern handling it?
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?
@camechis check out ClojureScript Unraveled
it's an online book that is more up to date
@camechis: figwheel to get started is very beginner friendly too
http://cljs.info/cheatsheet is a good quickref of funcs and concepts
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.)
@mfikes: yeah I believe we fixed browser REPL some time ago to support that. Of course nREPL has always supported that
I remember the first time I connected to an SBCL process on Slicehost over SSH from SLIME … the power!
given that clojurescript is not strongly typed, when it comes to refactoring, where does it fall in the spectrum of javascript to typescript?
core.typed offers gradual typing but I've never used it so ymmv.
Prismatic offers a library called schema which helps to annotate types, it can validate types in tests (or even running code) as well.
sorry, core.typed offers optional typing with an eye towards gradual in the future.
I don't really know the details, I just know that core.typed has recognized some limitations and are working to solve them.
are collections in clojurescript transpiled form clojure to javascript, or are they based on closure library collection?
@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
is the compiled javascript code, from clojurescript, also annotated for closure compiler?
if so, that could bring some type safety, which could provide refactoring safety to some extend.
@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.
there are a couple of issues for it, for example http://dev.clojure.org/jira/browse/CLJS-1412