Fork me on GitHub
#clojurescript
<
2016-03-14
>
jeffpamer00:03:10

I was just beginning to work through the Om tutorials, now I’m thinking I’ll have to look at Re-frame instead simple_smile

cky00:03:03

I recently used re-frame to implement a Minesweeper game. That’s my new frontend code kata. 😉

cky00:03:47

because 1. it’s dead simple to implement, and 2. I love playing Minesweeper. 😛

jeffpamer00:03:54

At work we have this sort of memory matching game we give to each prospective front-end developer as a test project. That’s my go to when I’m learning something new. I figure I should be able to come up with a convincing implementation if I’m asking anyone else to simple_smile

tomjack00:03:28

I am coincidentally just implementing a memory matching game while learning om.next simple_smile

tomjack00:03:56

oh, probably simpler than the "memory" game though

bwstearns04:03:57

@cky did you see the "MMO" minesweeper that was on hackernews the other day?

bwstearns04:03:57

oh, did not realize how late it was, that message was quite old.

cky05:03:47

@bwstearns I played that game a couple of years ago. It's quite fun!

zilvinasu06:03:02

Hey, anyone knows if there is some sort of track kept of all the CLJS videos in conferences ?

zilvinasu07:03:07

ah ok thanks, and one more question, any suggestions for making responsive layouts in CLJS based project ? does one just use SASS/LESS and related stuff, or there are some fancy CLJS style of things for that ?

rburns07:03:07

there's https://github.com/noprompt/garden though, I just use less, and figwheel's css loading for development. whatever you choose for css is rather orthogonal to chosing to use cljs

dm307:03:27

@zilvinasu: I use garden (with https://github.com/martinklepsch/boot-garden) which has a very nice benefit of having access to all the normal Clojure abstractions when composing stylesheets

zilvinasu07:03:57

I see, thanks! simple_smile

martinklepsch08:03:40

@zilvinasu: I find http://basscss.com to have some overlap with functional programming thinking and really enjoy using it

urbanslug09:03:36

What’s this #_ for in cljs or clj?

akjetma09:03:35

tells the reader to ignore the next form, often used for comments

urbanslug09:03:35

akjetma: Instead of ; why so? Just read that comment macro causes a form to return nil

urbanslug09:03:40

This is interesting.

urbanslug09:03:51

"The form following #_ is completely skipped by the reader. (This is a more complete removal than the comment macro which yields nil)."

akjetma09:03:10

one thing about the comment macro is that the body is still read (so it has to be syntactically valid)

urbanslug09:03:07

What is reading comments good for? Better developer tools? I would’ve expected the two to be semantically equal.

akjetma09:03:10

it is pretty interesting! they all have valid use cases imo

urbanslug09:03:01

Well yeah I guess it could be used by certain DSLs but that’s unexpected which doesn’t necessarily mean bad.

dm309:03:58

it's much easier to comment out a form with #_ than ;. You'd need editor support to move trailing parens to a newline otherwise in some cases

martinklepsch10:03:27

> one thing about the comment macro is that the body is still read (so it has to be syntactically valid) I think this is equally true for #_

rauh10:03:10

@urbanslug: #_ is useful since it will also work properly with multi-line forms where ; would not. Also, you can have multiple #_#_ and ignore two form. #_ can also stand alone on the line preceding the form to ignore (and then you can comment the #_ with a ; to disable it. Possibly cursive specific: I have my code littered with #_ since I can eval the form with a keypress (not possible with ;), you also still get proper paredit functionality within a #_ commented form.

urbanslug10:03:24

martinklepsch: I don’t think so "The form following #_ is completely skipped by the reader. (This is a more complete removal than the comment macro which yields nil).” from http://clojure.org/reference/reader

nha10:03:53

Well it still has to see that it is a form so at least the parenthesis have to match I guess.

urbanslug10:03:12

@rauh: Comment #_ with ; to disable it?

rauh10:03:03

#_
(xyz)
vs
;#_
(xyz)

martinklepsch10:03:29

> The form following #_ is completely skipped by the reader. For that to be possible it has to correctly identify the form as @nha noted

ul12:03:18

is ns special form in CLJS in contrast with CLJ?

ul12:03:32

can't find by simple search where it is defined in source

ul12:03:40

the problem is that i want to include or not some namespaces depending on compile-time known environment variables

ul12:03:54

in :require

lvh13:03:43

I like reagent, but om next is looking pretty snazzy. ratoms + hiccup syntax by default are pretty cool simple_smile

edbond14:03:16

help me with Html5History

clojure
(def history
  (doto (Html5History.)
    (.setEnabled true)
    (.setPathPrefix "")
    (.setUseFragment true)))

edbond14:03:39

when I (.replaceToken "zxc") it eats last part of the path

edbond14:03:15

/admin/abc becomes /admin/zxc not /admin/abc#zxc

thheller14:03:20

@ul yes ns is special .. not possible to do what you describe

daan14:03:20

Hi everyone! I'm have a problem that I hope someone here can help me with. I'm building a Clojurescript + Reagent frontend and I want it be split into 2 different (frontend) apps, served from within 2 different HTML pages: the main app, and a login page. Both should be built using Clojurescript, and ideally I want the source code to be in the same project, and both should be handled by the same lein-figwheel. Is this possible?

thheller14:03:00

@daan with figwheel no .. at least I don't think it supports :modules

bhauman14:03:39

@daan are you trying to do modules?

thheller14:03:58

based on that description you should be 😉

daan14:03:11

I'm not trying anything yet, because I have no idea how to go about it. But I have heard of Google Closure modules support

thheller14:03:26

you basically want 3 javascript files

thheller14:03:32

one that is shared between the 2 pages

thheller14:03:35

one for the main

thheller14:03:38

one for login

daan14:03:47

sound exactly what I want yes

thheller14:03:55

yes that is :modules

bhauman14:03:00

@daan you can also just simply have 2 builds

bhauman14:03:12

that share code

daan14:03:17

@bhauman: 2 figwheel builds?

bhauman14:03:33

yes two clojurescript buidls

thheller14:03:43

@bhauman: 2 builds mean the user will download stuff twice if he visits both pages

thheller14:03:48

that is uncool

bhauman14:03:12

@thheller: the question was how to have two builds with figwheel

thheller14:03:21

no that is not 2 builds

thheller14:03:42

that is one build split into 3 modules .. well at least it should be

thheller14:03:46

2 builds works as well

bhauman14:03:18

yes 2 builds works for dev and if you want you can then have a deployment builds that splits things into modules

bhauman14:03:59

there is no big deal here

thheller14:03:02

well ... that works too

daan14:03:03

so I could have a production build that uses Google Closure modules to so I can split out the common code. And for dev I would have 2 builds, one for each page?

thheller14:03:20

or use shadow-build and just use modules 😉

thheller14:03:37

but figwheel has more features

thheller15:03:11

I don't like it when things are too different in dev vs. prod

thheller15:03:26

thats why I dislike the 2 builds in dev but modules in prod

bhauman15:03:38

@thheller: building modules during dev takes much more time per iteration

thheller15:03:04

well if you use cljs.build.api yes

thheller15:03:19

shadow-build does things quite a bit differently in that regard

daan15:03:14

Let's say that for the moment I want to keep using Figwheel (I'm new to most of this, and I've just learnt this tool chain), would I be able to run the 2 dev Figwheel builds simultaneously?

bhauman15:03:54

lein figwheel dev1 dev2

daan15:03:08

okay, thanks for all the info guys!

daan15:03:13

I'm gonna try it out

chrisoakman15:03:19

@daan: Something else to consider, ClojureScript works well when you are producing a single output JS file. Google Closure Advanced mode optimizations can do amazing things to reduce your overall codebase.

chrisoakman15:03:56

My default approach is to go for producing a single file until it gets too big that I feel like it needs to be split.

karolmajta15:03:24

Hi guys, this is my first time here, so please don’t be too harsh on me simple_smile I have a question regarding the outfile, which is the result of compiling clojurescript targeting :nodejs. The resulting file looks like this:

#!/usr/bin/env node
if(typeof Math.imul == "undefined" || (Math.imul(0xffffffff,5) == 0)) {
    Math.imul = function (a, b) {
        var ah  = (a >>> 16) & 0xffff;
        var al = a & 0xffff;
        var bh  = (b >>> 16) & 0xffff;
        var bl = b & 0xffff;
        // the shift by 0 fixes the sign on the high part
        // the final |0 converts the unsigned value into a signed value
        return ((al * bl) + (((ah * bl + al * bh) << 16) >>> 0)|0);
    }
}

var path = require("path");
try {
    require("source-map-support").install();
} catch(err) {
}
require(path.join(“.”,”target”,goog","bootstrap","nodejs.js"));
require(path.join(“.”,”target”,"cljs_deps.js"));
goog.global.CLOSURE_UNCOMPILED_DEFINES = {"cljs.core._STAR_target_STAR_":"nodejs"};
goog.require("server.core");
goog.require("cljs.nodejscli");
I am concerned with the calls to require:
require(path.join(“.”,”target”,"goog","bootstrap","nodejs.js"));
require(path.join(“.”,”target”,"cljs_deps.js"));
Long story short, this code depends on the CWD, therefore this node program can only be run from leiningen project root. Is this on purpose? Changing to:
require(path.join(__dirname,"goog","bootstrap","nodejs.js"));
require(path.join(__dirname,"cljs_deps.js"));
would make it runnable independently of the process cwd.

chrisoakman15:03:36

You might want to try that first - which would simplify your build setup - and then have something like initLoginPage() and initOtherPage() functions to act as entrypoints on your different pages.

daan15:03:42

I get your point, but in this case it's not about size or code-management, it's more that I feel the login code should be on a completely different page, apart from the SPA main page

chrisoakman15:03:48

Right; there are many ways to skin this cat 😉 Just thought I would add that idea.

daan15:03:55

thanks for the input! simple_smile

thheller15:03:27

@karolmajta: there is an open ticket for that somewhere I think .. not sure if there is a patch

karolmajta15:03:49

ok, i’ll search for it

karolmajta15:03:34

@theller it seems there is no clear conclusion on this one, do you guys have any thoughts? I’ve commented, that current behaviour makes clojurescript hard to use for commandline and desktop applications (for servers, the CWD can be usually set to match the expectation). Do you guys have any thoughts on this? We’re currently doing electron application and this is a real pain when packaging the app.

darwin15:03:57

@karolmajta: I think you could just use your own modified copy of that file, I guess it won’t be changing much, or wrap it with your own helper script which will change current directory to the one expected by that file

karolmajta15:03:41

Changing a CWD of a process is just bad (but this is what i do now), what if i wanted to write a script for listing current directory? Surely not a good long time solution. Using custom shim file surely might be better. One thing i don’t like is the fact that if i change the :output-to i would have to modify the shim too, but i think i could live with that.

thheller16:03:53

@karolmajta: I don't use node but I agree that the bootstrap should just use __dirname. I see no reason why it shouldn't.

karolmajta16:03:41

In the jira issues there are some concerns about breakage, but to be honest, I don’t fully understand them.

thheller16:03:22

well to be honest I don't agree with how paths are handled in cljs at all

thheller16:03:32

so that applies to this situation as well

thheller16:03:46

but breakage is bad, so not sure what the best course of action is

rundis16:03:33

Does anybody know if there is a hidden gem somewhere that allows you to print a js regex object to include modifier flags. Ex:

(print (re-pattern "(?i)RUN")) => #"RUN"
I'd love to get the original string back somehow (I could always use
.toString
and reconstruct manually but was hoping for some symmetry in the core api simple_smile

nha17:03:13

What would be the structure/function to make this go-loop run in parallel with core.async ? : https://gist.github.com/nha/2003f3a5b738e72cb75e

noisesmith17:03:58

nha: how would you propose making parallelism ever happen in js?

darwin17:03:23

and, by the way, that channel wrapping in sample-async-fn is not needed - go returns a channel, which will receive the result value of the go body expression and then closes: `(go (<! (timeout t) s)` should be equivalent (except for closing)

kspear18:03:26

Anyone know a good method for pretty printing edn so that it can be rendered on the page? I was looking at cljs.pprint/pprint, but it seems to only want to output to the js console.

nberger18:03:57

@kspear: what about (with-out-str (cljs.pprint/pprint ...))

kspear19:03:33

@nberger: I'll give that a try when I'm back at my terminal. Ty =]

symfrog20:03:34

The performance of syntax-quote seems to degrade on nested structures in Safari. For example, the following expression will hang on Safari 9.0.3 (OS X 10.11.3) using clojurescript 1.7.228: `[({:person [:db/id :name {:address [:street]}]} {:id '?id})] whereas the following works: [(list {:person [:db/id :name {:address [:street]}]} {:id '?id})] Firefox and Chrome does not have this issue. Is anyone else experiencing this on Safari?

nberger20:03:44

@symfrog: I think it's a known issue in safari, and there's a ticket in jira about it, and the workaround involves using :static-fns true for cljsbuild... but I can't find the ticket right now

symfrog20:03:57

@nberger: Thanks, I searched jira earlier for a possible known issue, but did not find one, will keep on searching now that I know that one exists.

cmcfarlen20:03:45

@symfrog: I ran into that performance issue with safari. I just went with using the list form. Actually eliminates a source of bugs with ` vs ' and missing ~

cmcfarlen20:03:17

You could also render markdown and use code blocks

symfrog20:03:18

@nberger: thanks, passing :static-fns true to the compiler opts solved the issue, out of interest the jira issue suggested this occurs only with :optimizations :whitespace, but I was also experiencing it with :simple

cmcfarlen20:03:54

There is a downside to :static-fns true if you eval fns in the repl.

cmcfarlen20:03:36

I think you'll see the slowdown with everything but :advanced, but I haven't explored that yet at all

symfrog20:03:50

@cmcfarlen: thanks, in the end I will probably use the list form instead as you suggested, what are the downsides with using :static-fns true and function eval in the repl?

cmcfarlen20:03:49

@symfrog: I think it would eventually bite me (or a coworker) when I least expect it so I decided to not set it

bwstearns22:03:36

Any recommendations on where to start for mapping in cljs?

shaun-mahood22:03:07

@bwstearns: Like google maps type mapping?

bwstearns22:03:21

yes, sorry I should have clarified.

bwstearns22:03:43

@shaun-mahood: like the geographic kind not the conceptual or data-correspondance kind

shaun-mahood22:03:11

@bwstearns: I've not looked into anything clojurescript specific, but if you can't find anything openlayers is written with the Closure compiler so I assume it might play nice with cljs http://openlayers.org/en/v3.7.0/doc/tutorials/closure.html

bwstearns22:03:48

Thanks, I'll take a look.

george.w.singer23:03:56

Here is a sample clojurescript repl.clj config file:

(require '[cljs.repl])
(require '[cljs.repl.node])

(cljs.repl/repl 
  (cljs.repl.node/repl-env)
  :watch "src"
  :output-dir "out-repl"
  :repl-requires '[[cljs.nodejs :as node]
                   [cljs.core.async :refer [put! chan <! >!]]])
Notice the part that :repl-requires some useful cljs.core.async functions. Question: How does one :repl-require macros? In particular, how would one :repl-requires the go macro from cljs.core.async.macros (i.e., so that when one loads up a nodejs repl, the go macro is immediately usable)?