Fork me on GitHub
#clojurescript
<
2016-04-05
>
lwhorton02:04:44

is there a way to use macros to change the way syntax is parsed? let’s say i wanted to write css in clojure within a macro…

[.class-name { :padding 1em 2em 1.5em 2.5em }]
is it possible to write a macro that can actually handle 1em without barfing? The easiest solution is just to wrap that in text: ”1em 2em 1.5em 2.5em”, but I don’t want easy, I want convenient 😛.

lwhorton02:04:14

I can think of a lot of alternatives such as def-ing each and every potential property .. (def flex “flex”) for example, but that sounds like a maintainability nightmare

tomjack02:04:55

> is it possible to write a macro that can actually handle 1em without barfing? no.

tomjack02:04:51

macros are given forms which have already been read. the reader will not read symbols starting with numbers

tomjack02:04:23

you could try to do something crazy with tagged literals, like #em 1... but strings seem fine to me

lwhorton02:04:12

Thanks @tomjack . I have read through a couple of macro tutorials but none of them touched on anything like changing the way tokens are parsed, so I wasn’t sure if that’s an impossibility or just rare.

tomjack02:04:55

you can look for discussion about "reader macros"

tomjack02:04:25

sounds like that's what you're asking for, and clojure doesn't have it

mikethompson03:04:21

@danielpcox Reagent patterns are described here: https://github.com/Day8/re-frame/wiki/Using-Stateful-JS-Components D3 links towards the end, under "Further Examples"

denik04:04:18

Thank you @isak !

fenton04:04:53

why is there the .- javascript property accessor in clojurescript when it breaks under advanced compilation?

raphael06:04:44

Hello I have a question on defrecord and how clojurescript compile it in javascript

raphael06:04:40

The code in javascript is:

raphael06:04:40

I don't understand the line 15

raphael06:04:16

what is "_" ? how can I enter in this case?

raphael06:04:04

why we don't have something like this

tomjack07:04:25

@raphael: that's for (extend-type default Fly (fly [this] ...))

raphael07:04:21

what is default?

raphael07:04:26

OOkkkkkkk I understand! thank you @tomjack thank you very much!! 😀😀😀

dm309:04:07

html* is also a macro

dm309:04:27

did you mean that?

jannis09:04:49

@dm3: Yes. Doesn't it have to be if it needs to be called from CLJS?

dm309:04:31

html has to generate code that cljs compiler can then compile

jannis09:04:53

And it can't compile code that refers to another macro?

dm309:04:35

it can, but html* being a macro means that gensymmed prefix# symbol is passed in, instead of its value

jannis09:04:43

Oh, yeah. That makes sense. Any idea how to avoid or to eval that?

dm309:04:15

you have to generate the prefix at compile time in order to make use of its value in a macro

dm309:04:33

for some reason I think you don't want html* to be a macro

jannis09:04:03

Yeah. But then it has to be a CLJS function, right? Which should work...

jannis09:04:12

Oh, yes, done.

jannis09:04:15

That works.

jannis09:04:54

I had it like that in the beginning but changed it to a macro for testing it using macroexpand. If html* is a function I can't test how it transforms its input because it'll evaluate it's body - and I need it unevaluated. All I want to achieve is annotate the data before I pass it down to sablono.

jannis09:04:19

Ah, yes, and that's why html* being a function still doesn't work.

jannis09:04:24

CLJS will evaluate the generated code (including for loops etc.) and will pass the evaluated data to html*. I need the unevaluated data.

jannis09:04:28

But I also can't generate prefix at compile time as it depends on js/this.

darwin10:04:56

@lwhorton: look for inspiration here[1], I’m using Garden[2] with some sugary macros[3] on top of it. Instead of 1em I would write (em 1) - brain can adapt easily simple_smile [1] https://github.com/darwin/faceboard/tree/master/frontend/styles/faceboard/css [2] https://github.com/noprompt/garden [3] https://github.com/darwin/faceboard/blob/master/frontend/styles/faceboard/lib/helpers.clj

dm310:04:27

@darwin: could you explain the >> macro vs default garden declarations?

darwin10:04:27

@dm3: haven’t touched it for more than a year, so I don’t remember the details, here is the code: https://github.com/darwin/faceboard/blob/master/frontend/styles/faceboard/lib/helpers.clj#L30-L39

darwin10:04:09

the goal was to make it more “DRY”, see my css files and usage of that macro

dm310:04:30

yeah, thanks

dm310:04:59

was looking for the motivation on doing things that way instead of the vanilla garden

dm310:04:38

seems like a few characters less to type

darwin10:04:05

also vectors maintain order

darwin10:04:30

so it behaves like css, not randomly when you re-declare some property within one block

vikeri11:04:26

Anyone who uses planck? How do I do to preload it with all my libraries in .m2? I tried planck -c ”~/.m2/repository” and then (require …) but it couldn’t find it.

mfikes11:04:00

@vikeri: Planck supports classpath semantics, so you'd have to provide a colon-delimited list of all jar files (same would be true for ClojureScript, I believe) http://planck-repl.org/dependencies.html

vikeri11:04:36

@mfikes: Alright, so when I go in to find the reagent jar and start it, I would also have to include every dep that reagent has?

vikeri11:04:36

Starting it with planck -c reagent-0.5.1.jar works but gives me this error when trying to require reagent.core: No such namespace: cljsjs.react, could not locate cljsjs/react.cljs, cljsjs/react.cljc, or Closure namespace ”cljsjs.react"

mfikes11:04:55

@vikeri: Right. One approach is to use lein to generate the classpath to feed to Planck. (Having said that, I'd be surprised if Reagent works in self-hosted ClojureScript).

vikeri11:04:48

Alright, well my use case that I want to go in and fiddle with functions in different libraries without starting a project with them. Maybe this is not intended use for planck?

mfikes11:04:20

Speaking of fiddling, I suppose that http://cljsfiddle.com works with Reagent with self-hosted ClojureScript so… with Planck the issue would be the lack of browser capabilities (perhaps top-level window object etc.)

mfikes11:04:31

@vikeri: Sure, you should be able to use Planck to explore functions in libraries—the trick would be loading them. Planck doesn’t attempt to solve the dependency problem and just supports classpath.

vikeri11:04:46

@mfikes: Hmm ok, if I get time I might look at doing something to more easily browse the libraries already loaded in ~/.m2 would be awesome to have something like planck —libraries=reagent:foo:bar:doo where those libs have to be present in your ~/.m2 folder.

slipset11:04:07

@vikeri I was toying playing with the same ideas wrt planck and project-files

slipset11:04:15

One could imagine using lein the first time just to download the deps and generate the classpath, and then apply magic to make subsequent planck startups quick

mfikes11:04:45

Right, you could use Planck itself to form the classpath via something like https://gist.github.com/mfikes/9503aa2555aac1cafaf4#file-cljs-cli-md

vikeri12:04:35

@slipset: Would be great!

mfikes12:04:47

@vikeri: This might get you by for now, if you want to just fool around and not use lein and project.clj: https://gist.github.com/mfikes/39be3c7d966f6910bc72b1d0fc929ea7

mfikes12:04:19

(It uses Planck to form its own classpath from JARs in the local Maven repo.)

mfikes12:04:15

I created a #C0Y3CSPHQ channel so chats like the above can occur in there for people who are interested in Planck.

fasiha12:04:03

Wishing there was a native-JS port of partition that included stepping and padding…

lwhorton12:04:44

thanks @darwin. I did write a 3-arity version of ems to support num, topbottom left right, and t r b l like normal css. those sugar macros look nice, though.

denik14:04:10

I have an om.next app using sablono that throws react key warnings only the first time a certain component is mounted and then never again regardless of how many times it’s mounted/unmounted. Any ideas?

numberq14:04:07

Yesterday I was asking about reading a file in cljs ( https://clojurians.slack.com/archives/clojurescript/p1459785461002876 ), and I realize now that there was some confusion in my understanding of some of the help I was getting. I was asked if the value I was passing to a macro was known at compile time, and I said yes, but that was wrong. For testing purposes that value currently is hardcoded at compile time, but at some point I will be moving to building the filepath string at runtime, since it will always follow the same pattern and there will be a lot of them. Sorry about that misunderstanding :P So is there a way to pass variables at runtime to a macro from cljs?

darwin14:04:09

@numberq: macro expands at compile time, it has no chance to know what value the symbol will have at runtime, so you cannot slurp file at compile time with a path taken from the runtime-value of passed-in symbol

darwin14:04:47

in other words: macro can just rewrite code using information known at compile time

numberq14:04:23

Hmm I was afraid of that. So my only bet is to either hardcode every filepath or to use Node.js like you suggested yesterday?

darwin14:04:04

you can still “compute” file paths, if that computation can be performed at compile time

darwin14:04:29

so the question is, if you will be building file paths at runtime, does it really need to be at runtime? don’t you have all inputs known at compile time?

numberq14:04:03

I have all inputs known at compile time, but I don't know when they'll be used. Essentially, when an event is triggered, a random map will be loaded. The filepath will look something like "/assets/maps/map#.txt", where # identifies which map it is.

numberq14:04:55

So load-map could be called with whatever map is randomly chosen, and I was hoping to do that in one or two lines with something like (def map-file "whatever/map.txt") (load-map map-file)

numberq15:04:53

Or rather I should say, I'd rather not have all inputs known at compile time. Unless I'm mistaken, wouldn't that mean having a separate call to (load-map) for everything single map there is?

darwin15:04:08

Let’s see if I understand your problem: You have quite small set of map files in some folder. And you want to use those files dynamically during runtime (in reaction to some events). You cannot access filesystem during runtime. My solution would be: 1) write a macro load-maps which lists all maps in the folder and slurps them into a clojure map key-ed by their filenames (when called this happens during compile-time executed by clojure) 2) in cljs (def maps-in-memory-cache (load-maps)) 3) in cljs write a function, which can lookup a requested map in the cache, something like (defn load-map [name] (get maps-in-memory-cache name))

jr15:04:53

you can try serving the maps over http where the network becomes your filesystem

darwin15:04:56

long-story-short: load-map is dynamic, load-maps is static macro which runs at compile-time and builds a static map of file contents for you

numberq15:04:18

That sounds like a good idea. The number of maps will be a bit larger than "quite small" eventually, but I don't think it will get into performance or memory affecting numbers. Thanks! parrot

darwin15:04:19

if it is “too big to embed into js source” then you have to come up with some dynamic method how to retrieve those files on demand at runtime

numberq15:04:05

I'll keep that in mind, but based on current plans I don't think it should get to that point. You never know, though