Fork me on GitHub
#clojurescript
<
2017-02-28
>
tmayse00:02:10

I'm (trying to) create an app in re-frame and I'm vexed by subscriptions

tmayse00:02:36

I think I'm creating them correctly but one of my subs doesn't seem to exist when I go to use it

tmayse00:02:37

^^ nm fixed it

qqq02:02:12

the last paragraph of https://github.com/omcljs/om/wiki/DataScript-Integration-Tutorial states: That's all there is to it! Due to its support for Datomic Pull Syntax, DataScript is a natural fit for Om Next applications especially if they do not or cannot have significant remote service integration. Contact GitHub API Training Shop Blog About This seems to imply that for remotes, plain Om Next Db works better than datascript -- what is the reasoning behind this?

hkjels09:02:23

Tomorrow I’m having a session with my colleagues on Clojure(Script). Do you have any ideas of what would be cool to present or dabble with?

hkjels09:02:06

My initial thought is to show them figwheel

hkjels09:02:31

perhaps clone the flappy-bird-demo

hlolli09:02:41

has someone experience or example code of creating priority queue in clojurescript, like described here? http://jsperf.com/js-priority-queue-queue-dequeue

hlolli09:02:07

I'm already familiar with #queue [] not sure if it's doing similar things.

qqq09:02:37

binary heap priority queue is not hard to impelment; you just need perc-up/perc-down

rauh09:02:22

90% sure that goog.* has some

hlolli09:02:29

ok, didn't think about looking there. Of course goog.* should have been my first (latest second) place to look. Well, my question is bit unformulated, I'll explore more before asking again. Thanks.

moizsj14:02:01

i have been a career backend programmer (java and clojure). and cljs seems to me like just the right vehicle for me to explore frontend dev. i’ve never done any html/css/js work. anyone here got advice for what’s the bare minimum learning of html/css/js I need before i can start using cljs to build decent frontends. i’d like to be in a position where i use cljs for everything and step into html/css/js only if i have to. how do i go about my journey, any learning resources you’d like to point to if you’ve gone through a similar journey. thanks for your time!

mccraigmccraig14:02:00

@moizsj you could do worse than start with a template, like https://github.com/martinklepsch/tenzing , perhaps use it to initialise a basic reagent or rum app and kick its tyres

moizsj17:02:34

@U0524B4UW thats an eye opener. #nobackend sounds fab

rauh14:02:29

@moizsj I was in a similar position. I'd say HTML isn't the hard part, but CSS is. (Especially the box model etc). The spec is actually really good and has tons of examples as well. For example: , better than most online tutorials.

nico15:02:04

@moizsj I'm i nthe opposite situation and from what I know of clojurescript you still need to know the names of native js functions, and yeah css can be a pain sometimes

borkdude16:02:56

Is there anything against dynamically requiring a namespace in clojurescript, e.g. are we missing out on some advanced compiler feature there?

bostonaholic16:02:26

dead code elimination among others I’m sure

borkdude16:02:33

We introduced this macro:

borkdude16:02:40

(defmacro require* [ns-prefix]
  (let [namespaces
        (map #(symbol (str ns-prefix "." %))
             ["views" "events" "subs" "db"])]
    (cons 'do
          (map (fn [ns]
                 (list 'require `(quote ~ns)))
               namespaces))))

borkdude16:02:56

which we use at the top of a namespace. Just checking if this could cause problems

tbaldridge16:02:30

@borkdude I don't think that is dynamic require though...that's just a macro that emits a require

borkdude16:02:51

Well yes, but can it hurt optimizations?

tbaldridge16:02:23

Don't think so (unless there's something about CLJS's require outside of a ns I don't know)

tbaldridge16:02:31

But I have to ask "why?"

tbaldridge16:02:49

Macros like that will break tools, and make the code harder to understand

tbaldridge16:02:10

If those things are always going to be used together, why not just put them in the same namespace?

thheller16:02:13

also seems like something your editor could type for you

bronsa16:02:10

uh, does clojurescript even have require?

jdeisenberg16:02:13

@hjkels Definitely use figwheel. Perhaps a simple example relevant to the business you are in would be the best thing to convince people that ClojureScript is worth using.

thheller16:02:33

@bronsa it was added recently 😕 with the restriction that it must be a top level form, essentially modifying the ns form

borkdude16:02:20

@tbaldridge Good point. Why not put those namespaces together? Well, shorter files are sometimes easier to work with and it’s a standard structure of re-frame apps I believe

borkdude16:02:16

@tbaldridge This is used in some initial namespace where we have a map of keywords to pages/components

anmonteiro16:02:21

@borkdude that's not gonna work

borkdude16:02:15

It does work in development though

anmonteiro16:02:40

Try requiring a namespace not required anywhere else in your project, and the compiler won't be able to find/sort deps

anmonteiro16:02:04

This has nothing to do with optimizations

anmonteiro16:02:32

It's about ClojureScript's compilation model

borkdude16:02:43

ok, I kind of had a hunch this was a bad idea, I’ll just roll this back

dnolen16:02:20

really this is how about Closure Compiler works

dnolen16:02:27

requires are static

isak17:02:20

@borkdude I had been wondering about that. They use a similar concept in Phoenix, where you have a place you can specify a set of requires/imports, then pull a group of those in with one call. Works out quite well for views/controllers - standard things that you need a lot of

anmonteiro17:02:49

@borkdude sorry was on phone, I can expand on my reasoning now. Basically the way we compute dependencies in the ClojureScript compiler is we analyze just enough of either a namespace declaration or a set of requires

anmonteiro17:02:14

this is why they need to be at the top of the file - to prevent us from analyzing the entire thing and slowing down compilation

anmonteiro17:02:26

they also need to be static, due to Closure Compiler requirements

dnolen17:02:29

remember that dynamic require and whole program optimization are not particularly compatible things

anmonteiro17:02:15

@borkdude so your macro would probably work fine if it sit at the top of a file (which has no NS declaration)

anmonteiro17:02:31

but that’s not particularly useful, is it?

Aron17:02:32

i spent the last 4 minutes trying to think of a reason why i would need dynamic requires

anmonteiro17:02:53

@borkdude now I can imagine why you’d want to require things dynamically

borkdude17:02:55

nope, I’ll rollback to normal ns

anmonteiro17:02:18

you wanna ship the least amount of code possible in a first route, and async load dependencies based on some heuristic

anmonteiro17:02:28

the Closure Compiler supports this via Closure modules

anmonteiro17:02:49

so if that was your goal, it is possible, just not with require

isak17:02:55

this is phoenix, in case anyone is insterested. still static

dnolen17:02:43

@isak as @anmonteiro mentioned you’re probably talking about code splitting

dnolen17:02:48

and Google Closure already does that

isak17:02:24

@dnolen no, @borkdude was trying to think of a way to reduce boilerplate in ns forms, i was just showing some prior art

dnolen17:02:47

I missed that part of the backlog

dnolen17:02:01

and no we don’t care about those kinds of conveniences 🙂

isak17:02:15

i figured

anmonteiro17:02:26

@borkdude if you were actually looking for how to do code splitting this is a good primer https://rasterize.io/blog/cljs-dynamic-module-loading.html

borkdude17:02:57

I’m not looking for code splitting, just eliminate some boilerplate because a colleague asked for it. Not a major issue.

borkdude17:02:08

He was referring to this though, not sure if that is relevant here? http://stackoverflow.com/a/30171851/6264

bostonaholic17:02:12

if you have namespaces that are always needing the same namespaces, you might have a code structure problem

bostonaholic17:02:22

and writing a macro to solve it is going to hurt

joelkuiper17:02:49

yeah that’s what I figured, we ended up with this due to re-frame where each “page” has a db, events, subs, and views namespace

joelkuiper17:02:12

but that means every page has 4 namespaces that need to be included in the “main” file each time we add one

joelkuiper17:02:24

which is tedious and error prone, just looking for a way to restructure it

joelkuiper17:02:41

then I remembered the trick cljs.test uses, but I guess that will break things

dnolen17:02:08

right, sounds like a inconvenient code structure

dnolen17:02:17

any macro-ology is just papering over the real problem

joelkuiper17:02:46

guess we’ll have to rethink it, anyone with a large-isch re-frame app that can give insight into how they do it 😉 ?

dnolen17:02:16

why can’t you just have one namespace for each logical component

dnolen17:02:24

I don’t see the value of breaking down one component into so many namespaces

joelkuiper17:02:58

that’s a good point, not sure why re-frame proposed this, we were just following the example as @borkdude says

dnolen17:02:08

sounds ill-advised to me for anything large

joelkuiper17:02:27

we could just squash them all into one namespace, files would be significantly longer, but that might be a trade-off to consider

anmonteiro17:02:36

definitely sounds easier to reason about your code if every thing that belongs to the component’s behavior is co-located with the component definition

anmonteiro17:02:47

but I’m probably biased when it comes to co-location 🙂

joelkuiper17:02:15

I guess the re-frame decision comes more or less from the MVC model, where the M, V, C have different files

anmonteiro17:02:42

but re-frame is not really about MVC AFAICT

joelkuiper17:02:08

true, but just saying that’s probably where the file layout comes from

isak17:02:03

its just a standard thing in a lot of frameworks/libraries across languages - separate things out into tons of files. A little less convenient in clojure than other langs, but not a huge deal. Can combine things of course, but it isn't an obvious improvement, other than the import stuff

isak17:02:28

especially in UIs

borkdude17:02:52

The reason we need to require the subs and events namespaces are because they are decoupled in re-frame: you don’t need to require a namespace to be able to dispatch an event, but you have to load the namespace at some point of course. We could merge everything related to one page/component in one file, but I’m not sure if that’s easier to work with.

shaun-mahood17:02:12

@joelkuiper: For re-frame development, the structure is really flexible - you can do it as in the todomvc, put your whole project in one file, or split components up into their own file - it really doesn't matter as far as functionality. My general approach has been to start with one file for each "section", and then refactor into separate namespaces as it fits your application. There's not any real refactoring support outside of find and replace, but if you are using uniquely named elements with namespaces that make sense to you it's pretty straightforward.

gklijs17:02:24

As I’m using re-frame now, I have one ‘main’ file, and one for each page, I don’t really see the point in breaking it up even further for components, or for each layer of a component

shaun-mahood17:02:15

The structure in the todomvc app is pretty well suited for an application where each of your "sections" is a reasonably complex application in itself - not great for components though. But one of the very nice things about re-frame is that it makes very few decisions for you outside of the essential trade-offs that come with it. If you want to go into detail on your specifics we can take it to the #re-frame channel as well.

mruzekw19:02:22

Does my target platform need to be node in order to use node_modules?

shaun-mahood19:02:21

I'm trying to translate a JS example to CLJS for OpenLayers, which uses Google Closure, and I suspect I'm doing something wrong with my require or import - the generated JS code works when pasted in to the original example but the CLJS is giving me an error. Apologies for the length, code snippets don't seem to be working.

(ns hello-world.core
  (:require [ol.proj]
            [ol.layer.Tile]
            [ol.source.OSM])
  (:import [ol.Map]
           [ol.View]))

(def my-map
  (ol.Map. #js {"target" "map"
                "layers" #js [(ol.layer.Tile. #js {"source" (ol.source.OSM.)})]
                "view"   (ol.View. #js {"center" (.fromLonLat ol.proj #js [37.41 8.82])
                                        "zoom"   4})}))
Error Message Uncaught TypeError: Cannot read property 'getExtent' of null at Object.ol.tilegrid.extentFromProjection (tilegrid.js:149) at [as constructor] (xyz.js:37) at new ol.source.OSM (osm.js:34) at core.cljs:11 Any ideas? Original JS example can be found at https://openlayers.org/en/latest/doc/quickstart.html

anmonteiro19:02:14

@shaun-mahood just looks like you’re not importing enough stuff

anmonteiro19:02:18

e.g. ol.layer.Tile and ol.source.OSM

anmonteiro19:02:08

@shaun-mahood actually is looks like there’s more stuff wrong with your example

anmonteiro19:02:17

you’re using a namespace as if it were an object?

anmonteiro19:02:23

(.fromLonLat ol.proj #js [37.41 8.82])?

anmonteiro19:02:29

I don’t think this will mean anything to CLJS

anmonteiro19:02:03

you actually want ol.proj/fromLonLat there, for example

anmonteiro19:02:36

just like when you require goog.string and you use goog.string/includes or something

shaun-mahood19:02:39

On the import vs require question, my understanding is a bit vague there - based on how it's used and the API definituon at https://openlayers.org/en/latest/apidoc/ol.layer.Tile.html I expected it to require an import, but if I move it from require to import I get the error Uncaught TypeError: Cannot read property 'Tile' of undefined - I don't need to have it in both, do I?

anmonteiro19:02:10

@shaun-mahood the rule of thumb is, require namespaces, import objects classes

anmonteiro19:02:37

you probably need to (require ol.layer) and then import ol.layer.Tile

shaun-mahood19:02:20

They don't seem to actually have an ol.layer namespace...

jaydeesimon19:02:07

I'm writing a command-line utility using ClojureScript and targeting Node as the runtime. I have a few dependencies that I’m pulling in from npm. Is it possible to compile my application into one js file using :optimizations :advanced and have it pull the npm dependencies into that one js file as well? So far, it doesn’t seem like that’s the case but maybe I’m doing something wrong.

jr19:02:09

that site is down 😕

jaydeesimon19:02:40

it probably relies on s3 🙂

jaydeesimon19:02:10

i think i’ve read that page though

jaydeesimon19:02:36

is it about how google closure now understands nodejs modules?

jr19:02:52

yes and cljs has experimental support

jaydeesimon19:02:56

so there is a path to doing this. that’s good news

ag19:02:17

hey guys, if I want to have a namespace called test-helpers, I can’t seem to be able to put it in ../test/cljs/my-proj folder? even if it’s added to :source-paths?

ag19:02:43

does it really have to be in ../src/cljs/my-proj?

jr19:02:46

are you packaging it as a lib?

anmonteiro19:02:38

@ag you just need to follow the directory structure. if it’s a single segment namespace it needs to be at the root of the classpath

jaydeesimon20:02:18

@jr thank you, btw

jr20:02:35

I forget how it works 🙂

jaydeesimon20:02:50

the javascript-modules page is up. i’m going to walk through the example now

anmonteiro20:02:07

@jaydeesimon hopefully what you’re trying to achieve will be even easier in the very short term http://dev.clojure.org/jira/browse/CLJS-1960

jaydeesimon20:02:48

whoa that would be so sweet

jaydeesimon20:02:10

i’ve just started to play around with clojurescript on nodejs and i am amazed by the possibilites

shaun-mahood20:02:44

@anmonteiro: I think I've narrowed down the code to an obvious difference. The JS code var projections = ol.proj.projections.cache_ returns null in my CLJS version - I think I'm going to try and make an intermediate version which is JS using the Closure Compiler since my grasp of how it works is pretty shaky. Thanks for the help!

jaydeesimon20:02:08

i’m surprised i don’t see more clojurescript+node apps

tankthinks20:02:10

is this the right opts construct for clojure.spec.test/check in clojurescript?

(stest/check `specced-fn {:clojure.spec.test.check/opts {:num-tests 1}})

Alex Miller (Clojure team)20:02:22

I think it’s slightly different (s/clojure/cljs) ?

tankthinks20:02:17

ok ... i wasn't sure because

(:require [clojure.spec :as s])
magically works in clojurescript

dnolen20:02:40

@tankthinks we auto-alias namespaces not keywords

anmonteiro20:02:03

@tankthinks I think @alexmiller is right. you can use ::stest/opts and it’ll work

dnolen20:02:28

clojure.spec is an alias for cljs.spec

dnolen20:02:35

clojure.spec doesn’t actually exist

anmonteiro20:02:59

sorry I’m wrong above. needs to be cljs....

dnolen20:02:41

::s/foo will work of course

tankthinks20:02:48

so

(stest/check `specced-fn {:cljs.spec.test.check/opts {:num-tests 1}})

anmonteiro20:02:50

@tankthinks OK found your issue

anmonteiro20:02:06

clojure.test.check/opts, not clojure.spec.test.check/opts

Alex Miller (Clojure team)20:02:24

oh, yeah. sorry I didn’t see that.

tankthinks20:02:30

ah ... thank you!!!

anmonteiro20:02:33

from the docstring:

The opts map includes the following optional keys, where stc
aliases clojure.test.check:
::stc/opts  opts to flow through test.check/quick-check

tankthinks20:02:29

the clojure docstring is:

The opts map includes the following optional keys, where stc
aliases clojure.spec.test.check: 

anmonteiro20:02:38

@tankthinks that’s the difference between Clojure and ClojureScript

tankthinks20:02:52

thanks ... i was working in a cljc file so was using the clojure docs ... everything has magically worked in clojurescript, which is amazing! thanks for the heads up

campeterson21:02:11

Hey friends, got a question regarding JS interop and the compiler. My CLJS needs to call:

(js/window.webkit.messageHandlers.authStatus.postMessage status)
but when it’s optimized :advanced I get:
window.webkit.messageHandlers.vq.postMessage()

anmonteiro21:02:06

@campeterson add an extern, e.g.:

var webkit = {};
webkit.messageHandlers = {};
webkit.messageHandlers.authStatus = {};
webkit.messageHandlers.authStatus.postMessage = function(msg) {};

campeterson21:02:00

@anmonteiro Thanks. will give it a go

darwin22:02:21

or (gcall “window.webkit.messageHandlers.authStatus.postMessage” status) with cljs-oops: https://github.com/binaryage/cljs-oops

mikepjb23:02:06

Hey guys, I'm trying to translate some javascript into clojurescript - does anyone know how to call the | operator? e.g 2 & 0x3 | 0x8