Fork me on GitHub
#clojurescript
<
2015-07-21
>
spiralganglion00:07:24

@wei Did you check out the Reagent channel?

wei00:07:57

@ivanreese: I didn’t know there was one, thanks

wei00:07:45

how do I test whether empty? will operate on something? I thought it was coll? but (empty? “”) => true (coll? “”) => false

wei00:07:04

@nullptr (seq? “”) => false

spiralganglion00:07:24

Yeah, it looks like empty? does a little more than its docstring implies.

wei00:07:54

I’m trying to avoid (empty? 777) => Exception, 777 not seq-able. That’s why I’m looking for this test

dnolen01:07:10

@wei: (satisfies? IEmptyableCollection 777)

wei01:07:50

@dnolen: is there a function where (f “") => true and (f 777) => false. (satisfies? IEmptyableCollection “”) => false

wei01:07:04

if not, it’s alright, I think I found a workaround

dnolen01:07:51

@wei: there isn't

wei01:07:13

cool, thanks anyways for taking a look

danielcompton02:07:15

I’m getting false returned from (instance? js/String "hi”). I’m pretty confused by this, is it expected?

danielcompton02:07:48

This happens in a figwheel REPL, http://clojurescript.net, and from within the runtime of my project

danielcompton02:07:00

There’s http://dev.clojure.org/jira/browse/CLJS-98 but that was resolved years ago

dnolen02:07:07

@danielcompton: why are you doing that instead of string?. JS primitives will return unexpected instanceof checks.

danielcompton02:07:17

@dnolen: I was converting some code from Clojure to Cljc, and it was using instance?. I forgot all about string?

dnolen02:07:22

@danielcompton: those tests may or may not fail, they aren’t failing for me, but that’s really besides the point.

dnolen02:07:32

we test engines only at the command line.

danielcompton02:07:47

cool, string? it is

dnolen02:07:02

I know this probably won’t make that much sense but this is really cool:

dnolen02:07:58

shows that ns forms can be compiled and that custom eval & load can be supplied

kahunamoore03:07:14

At the risk of being redundant… has anyone been able to get Om to work within Electron?

kahunamoore03:07:56

My app compiles but at runtime it is telling me that ‘React’ is not defined… and yet I can see the (minified) react code in the generated main.js

kahunamoore03:07:16

I’m guessing there may have been a symbol rename that is making it unresolvable.

kahunamoore03:07:06

I tried using :optimizations :none but that didn’t help… so maybe not.

emil0r07:07:03

@kahunamoore: have you checked that it's in the correct order?

grav08:07:37

does putting a script tag after the html tags ensure that the dom is ready when the script is executed? (not cljs specific)

grav08:07:29

eg <html><div>hello</div><script src=“js/foo.js”></script></html>

Pablo Fernandez08:07:24

@grav: as far as I remember, yes, but inside <body>, you are missing <body> there.

grav08:07:37

so it’s important that it resides inside <body>? that’s puzzling, since body can be omitted. but it might be some legacy thing, regarding IE or something, I don’t know?

Pablo Fernandez08:07:05

@grav, body can be omitted? That’s news to me, so ignore what I said.

Pablo Fernandez08:07:31

Oh… the good old days of HTML 3… and the promise of XHTML and XHTML 2.0! Good? who am I kidding… it sucked.

grav08:07:28

well, not that I’m omitting it on purpose 😉

grav08:07:34

Anyways, I’ve always been using something along the lines of jquery’s document.ready, or the DOMContentLoaded event, but I guess that’s not necessary

Pablo Fernandez08:07:46

I am converting my Luminus generated web app from secretary to silk, and as I follow ks-front-routing-example I notice it uses an atom to store the current route (https://github.com/metosin/ks-front-routing-example/blob/master/src/clj/ks_front_routing/ui/routing.cljs#L10) while Luminus uses the session (https://github.com/luminus-framework/luminus-template/blob/master/src/leiningen/new/luminus/cljs/src/cljs/core.cljs#L53). What are the implications of one vs the other?

domkm08:07:53

@pupeno: I was writing up an answer about how in-memory atoms differ from sessionStorage and why for routing it is probably preferable to use an atom when I decided to look at the source for reagent.session. Turns out it's just named poorly and uses an atom as well! https://github.com/reagent-project/reagent-utils/blob/master/src/reagent/session.cljs

Pablo Fernandez08:07:27

@domkm: yeah… I actually ended up finding that same information. Based on the description of reagent-utils, it seems to be designed so that you can run code intended to work with lib-noir on the client. Maybe @yogthos can shed some light here.

Pablo Fernandez10:07:42

Any ideas what’s going on here: https://github.com/luminus-framework/luminus-template/blob/master/src/leiningen/new/luminus/cljs/src/cljs/core.cljs#L42 why are the functions being interpreted as vars? is this something ClojureScript releated?

curtosis12:07:00

@pupeno I was wondering the same thing. also here:

(defn mount-components []
  (reagent/render-component [#'navbar] (.getElementById js/document "navbar"))
  (reagent/render-component [#'page] (.getElementById js/document "app")))

curtosis12:07:22

I haven't seen that as idiomatic in other reagent apps (yet).

Pablo Fernandez12:07:29

@curtosis: I think the reason is to have a fresh copy of navbar and page when they get reloaded… but that doesn’t make sense in my brain anymore… it did some time ago.

Pablo Fernandez12:07:34

Let me try it empirically.

Pablo Fernandez12:07:33

Nope… it works just fine without it.

curtosis12:07:43

interesting. I assume by default that there must be a reason for it, so am curious as well.

Pablo Fernandez12:07:07

Yeah, me too… but I can’t find any difference in behaviour.

curtosis12:07:11

(also, because I'll have to explain it to my not-yet-clojurian colleagues 😉)

Pablo Fernandez12:07:35

curtosis: oh, it seems we are having similar challenges then.

yogthos12:07:14

@pupeno: reagent-utils aren't related to lib-noir, just the session API is taken from it that's all

yogthos12:07:52

the #' syntax is just a workaround for live reloading

Pablo Fernandez12:07:55

@yogthos: I just tried it without it and it auto reloading works fine… not sure if that’s due to other changes I made to the file.

yogthos12:07:28

it won't work if it comes from a different namespace though

yogthos12:07:01

what happens is that the old symbol will be referenced, and when the file is reloaded then a new symbol with the same name will be provided

yogthos12:07:11

the original namespace ends up still referencing the old one

curtosis12:07:01

hmm.. so it would work fine if you don't mount components across namespaces?

yogthos12:07:41

there still has to be some entry point

curtosis12:07:08

the mechanics of live reloading still hurts my brain.

Pablo Fernandez12:07:46

I wonder if this example, which doesn’t use var, then, suffers from reloading issues: https://github.com/metosin/ks-front-routing-example/blob/master/src/clj/ks_front_routing/ui/routing.cljs

jrychter12:07:47

I'm browsing through the routing discussion from yesterday and today — I tried using React (Reagent and later Rum) with silk and bidi and it just didn't fit for me. The problem was that I noticed that I ended up introducing yet another translation layer (URLs to symbols to component configuration).

jrychter12:07:50

What worked well for me was a solution that couples the component hierarchy to URL hierarchy. That might not work for everyone, but for new apps it's very nice. You get the benefits of composability: the same component with internal nav structure can exist in multiple places in your app and its nav structure will work without changes to the global "routing table".

jrychter12:07:48

I think I need to write a blog post about that.

Pablo Fernandez12:07:02

@jrychter: I’m experiencing some of those issues too… the truth is that routing has three components if the route is to be bidirectional: the path, the identifier and the code to run.

jrychter12:07:42

I don't like the whole idea of "routing". I think it's something we brought in without much consideration, mostly from the Ruby on Rails world.

Pablo Fernandez12:07:19

@jrychter: I don’t think connecting to the code through the identifier of the route is that bad, it’s just such a central component of the app and deciding on how to do it when you are new to the language, the library, the framework, etc is hard, as at least me, I don’t know the implications of my decisions.

jrychter12:07:19

URIs were designed to be hierarchical. We now have hierarchical componentized apps. Why stick to the idea of "routing"?

dnolen12:07:33

I’ve created a new channel #C07UQ678E for discussing development on ClojureScript itself so to avoid flooding this channel with information that may only be of passing interest to application developers simple_smile

dnolen12:07:40

of course anyone and everyone welcome!

jrychter12:07:59

@pupeno: It becomes really bad once you try using a single component it two different parts of your app. What do you do? Duplicate the route entries and create another set of keywords?

Pablo Fernandez12:07:19

jrychter: what you build sounds similar to EmberJS, did you have any experience with it?

jrychter12:07:52

@pupeno: No. The ideas come from weblocks, a common lisp framework I used to contribute to.

Pablo Fernandez12:07:04

jrychter: well, I have no idea, I’m new to building components for UI in the browser, which is why I don’t like having to make this architectural decisions, I don’t have enough information about it yet.

jrychter12:07:21

You can see what I'm talking about here: https://partsbox.io/demo/part/1c265b6d-18f8-11e5-957e-9bcf9dabe7b7/ and here: https://partsbox.io/demo/parts/1c265b6d-18f8-11e5-957e-9bcf9dabe7b7 — this is the same component in two different places, with local navigation.

jrychter13:07:12

The component has no idea where it sits in the hierarchy and there is no global "routing table". I would end up tearing my hair out if I had to specify all the nav entries for this menu multiple times.

jrychter13:07:42

By "component" I mean the electronic part display with the local menu on the left. That's the local nav.

Pablo Fernandez13:07:11

it requires logging in to view it.

Pablo Fernandez13:07:44

So, how are you handling URLs then?

jrychter13:07:51

@pupeno: sorry. Click on https://partsbox.io/instant-demo first, this will log you in.

jrychter13:07:31

What I do is use pushy to get history events, then split the URL into "tokens". These are passed down the component tree as props/args (nav-state), containing consumed tokens and remaining tokens. Any component is free to "consume" a token, by passing it from remaining to consumed. It then passes the new nav-state down to its children.

Pablo Fernandez13:07:39

Are you using html5 history to handle the URL changing?

jrychter13:07:42

The only drawback is that you do have to pass another parameter down your component tree. But it isn't that bad. And it means that local navigation is encapsulated within the component and is composable.

Pablo Fernandez13:07:46

On the server side, are you using compojure? compojure-api? liberator?

jrychter13:07:07

In a larger app there is still a "global" part, but it's not a routing table, but code that can generate global links. You will need those for certain parts of your app. In my case, that's 6 one-line functions.

jrychter13:07:10

I don't use a framework. I do use compojure for server-side routes and hate it, I plan to remove it eventually. The app uses Sente, Ring, and RethinkDB for data storage.

Pablo Fernandez13:07:00

@jrychter: RethinkDB + Sente sounds like you have data that changes on the server and want the client to automatically update. Is that true?

ordnungswidrig13:07:01

you should have a look at bidi for routing. Pretty desing, composable, routes are data etc.

jrychter13:07:42

@pupeno: Yes, that's the plan. But even if you don't, sente is great for writing apps.

profil13:07:54

@jrychter: Why do you hate compojure?

jrychter13:07:01

@ordnungswidrig: I did, it isn't much different from silk. It's the same concept, a "routing table".

domkm13:07:17

Linking components directly to routes in a hierarchy leads to a lot of complication, speaking from personal experience with React + ReactRouter (which I think is very similar to Ember)

jrychter13:07:25

@profil: Oh, it's just that my brain has problems dealing with routes being ring handlers. Functions returning functions, generated by macros — I always end up with a mess that barely works and is very hard to debug. I'm sure it's fine for people who can conceptualize all this in their heads. I can't.

jrychter13:07:52

@domkm: I think this depends on the application. I can see how it could be a huge problem if you have externally-mandated URL structure that you have to adhere to.

domkm13:07:37

@jrychter: Even basic things like authentication (which should be easy to handle with a parent auth component) becomes very complicated in ReactRouter. All of the examples work when used individually but it's absolute hell when you have to combine them.

jrychter13:07:55

@domkm: Well, I don't know ReactRouter, so I can't speak for that. What I do know is that I encountered no problems writing PartsBox, which isn't such a small app (and it does have authentication). I am very happy with the results so far.

jrychter13:07:53

One thing: I'm not sure what "Linking components directly to routes in a hierarchy" means. I don't link them that directly. A component doesn't have to consume any tokens — it just needs to pass the nav-state map down the tree to its children. So not every component in the tree is reflected in the URI structure.

domkm13:07:43

@jrychter: Oh, yeah passing routes down the tree is my preferred way as well. It's far superior (less complicated) than ReactRouter and Ember routing in my experience.

Pablo Fernandez13:07:32

jrychter: where’s your blog? I’ll be interested in that post.

jrychter13:07:23

@pupeno: http://jan.rychter.com/enblog/ — but I have to write it first. Which might take several days.

bhagany15:07:42

ugh for some reason I can't install Replete

bhagany15:07:55

I don't suppose anyone else is having App Store problems?

akiva15:07:16

Yeah, it seems to be suffering currently.

mfikes17:07:24

@bhagany: Did things get sorted out with the App Store?

jonas17:07:50

@bbloom: I’ve continued studying you vdom implementation (it’s a great read, highly recommended!). I was wondering about child diffing. The implementation ( https://github.com/brandonbloom/cljs-vdom/blob/master/src/bbloom/vdom/patch.cljc#L58-L76 ) seems to imply that if you remove the first item all the rest are rerendered. Is this correct? I think that React uses a more efficient algorithm?

bhagany17:07:09

@mfikes - just tried again and it worked. all good!

denik18:07:10

@mfikes: can Planck be used to write shell scripts to be run from the command line?

bbloom18:07:01

@jonas: if i understand your question, correctly: No, changing one child will not cause the rest to need updating. The overall approach treats property sets separately from parenting

bbloom18:07:47

@jonas the code you highlighted essentially works by re-arranging all the nodes via a virtual DOM .insertBefore method. Then virtual .removeChild for the remainders. This models that when a node is moved to one place, it’s removed from the previous place.

bbloom18:07:02

@jonas My experiments showed that insertBefore tends to perform surprisingly well, suggesting that browsers use decent data structures for node children and/or it doesn’t matter for small numbers of children. For larger numbers of children, my code should behave well b/c it uses rrb vectors for cheap splicing. Slow part in rendering may be the search for a node, not the insertion of a node, but i figure that for a few thousand children tops it should perform just fine & in that case you should use a virtualized scroll panel or canvas or whatever other non-dom thing, since humans can’t really look at / click on more than a few thousand boxes on a screen

bbloom18:07:44

that reduce loop is sorta the moral equiv of an insertion sort

bbloom19:07:38

but insertion sort performs pretty well if the data is mostly sorted and stable over time, which UI elements are… up until you do something like totally change the sort order by like clicking on a column header or something in a table view. but you do that ONCE not like 60 frames per second

bbloom19:07:41

so ultimately it should be fine

bbloom19:07:56

anyway, hope that clears it up. lmk if you have more questions or if you discover my assumptions don’t hold simple_smile

mfikes19:07:24

@denik: Planck is really just a small PoC right now, but it sounds like there is interest in seeing it grow into such a thing.

coyotespike19:07:08

Quick question: I transferred a jar from my Mac to an Ubuntu. On one page, I used if to display one div or another, based on a boolean (it's a Reagent SPA). This doesn't work on the Ubuntu, with the same jar, and Java 8 installed. Everything else works though. My google-fu reveals nothing helpful. Is there some Ubuntu-ClojureScript gotcha I should be aware of?

roberto19:07:32

log to the console and try debugging

Petrus Theron19:07:27

I'm having a look at RethinkDB and the clj-rethinkdb client. Has anyone used this from ClojureScript for real-time updates, perhaps through sente?

danielcompton19:07:07

@petrus I’m working on this as we speak

Petrus Theron19:07:36

How do I send you cupcakes?

danielcompton19:07:38

Just pushed cljs support to master yesterday

danielcompton19:07:44

for generating queries

curtosis19:07:15

@coyotespike: which Java 8 on Ubuntu? IIRC there are differences between OpenJDK and OrclJDK.

Petrus Theron19:07:28

:thumbsup: glossing over commits now. If I wanted to "subscribe" to a table and get a callback when data changes, is that possible? Others say to use the JavaScript driver.

curtosis19:07:19

rephrasing: are they both using the same Java 8. at least a starting point for diagnosing.

danielcompton19:07:06

@petrus RethinkDB doesn’t support direct connections to the browser so you need something on the server running the queries and proxying them back to the user

Petrus Theron19:07:42

ah, I misunderstood. Thought there was a direct connection ala firebase.

coyotespike19:07:01

@curtosis: They are both using SE, Oracle.

danielcompton19:07:05

or the rethink proxy that I’m building at the moment

Petrus Theron19:07:26

Are there any reference impl. around? Ah, sweet. How do you feel about progress so far? Is there something I can test drive for you? simple_smile

curtosis19:07:28

oh well. worth a shot. simple_smile

coyotespike19:07:41

Yeah, good starting point simple_smile

coyotespike19:07:52

I'll keep poking around, I understand the JVM runs a bit differently in each environment. Might have to start developing via ssh...

danielcompton19:07:23

Mikemintz work is probably closest thing to a reference impl

danielcompton19:07:53

The stuff I’m working on is beta quality, and not well suited for the public internet as the query whitelisting is still quite basic

danielcompton19:07:20

It works for our authentication and threat model, but not for a general consumer facing website

danielcompton19:07:06

I’m not sure what I’m able to share, or how valuable it would be to an outsider, I’ll have a think

roberto19:07:24

@coyotespike: if you are using source maps, I would try to debug in the browser and compare the differences between both deployments.

coyotespike19:07:30

@roberto: looks like I'm using source maps in dev, but not in production. I'll monkey with enabling source-maps and using them to debug.

mfikes20:07:44

@lazy-lambda: Another place we can link in Replicator, once available: https://github.com/clojure/clojurescript/wiki#learning-tools

dnolen20:07:23

@mfikes: thanks for adding that!

lazy-lambda20:07:45

BTW does creating a shared cljs runtime for Android will be any good, for apps that want to execute cljs.

lazy-lambda20:07:28

So that not every app has to bundle their own versions of cljs

shaun-mahood21:07:31

@mfikes: Since there's so many fun rules for the app store, what kind of things are possible for Replete as far as saving files/namespaces for later, or synchronization with dropbox and loading existing files into the repl? 2 things I would love to be able to do - save code for later so I can work through a whole textbook or problem over days/weeks, and pass files between my computer and iPad.

mfikes21:07:54

Nothing in the App Store rules precludes any of that AFAIK.

shaun-mahood21:07:05

Oh that is super cool.

bsvingen21:07:55

@shaun-mahood: You can already do “open in” from other apps, including Dropbox.

shaun-mahood21:07:35

@bsvingen: Whoa. That didn't even cross my mind.

shaun-mahood21:07:17

That would be an amazing way to explore things.