Clojurians
#hoplon
<
2015-08-27
>

This page is not created by, affiliated with, or supported by Slack Technologies, Inc.

onetom15:08:36

what's going on if i get this from a hoplon (page ...)?

clojure.lang.ExceptionInfo: No reader function for tag js

onetom15:08:18

(clj->js ...) works

alandipert15:08:49

there is a boot.core/load-data-readers! function, perhaps it needs to be strategically called?

onetom16:08:06

I getting this error in the https://github.com/exicon/foreign-lib-with-cljs-init repo which is a super minimalistic repo. it doesn't have datomic, doesn't have boot-reload, nothing fancy, but the latest (boot-)hoplon. I hit this issue sevaral times in the past 2 weeks but I was always lazy to track it down.

data: {#object[clojure.lang.Keyword 0x38105db8 ":type"] #object[clojure.lang.Keyword 0x4ffa1257 ":reader-exception"]}
                             clojure.core/ex-info          core.clj: 4593
   clojure.tools.reader.reader-types/reader-error  reader_types.clj:  330
                                              ...
                 clojure.tools.reader/read-string        reader.clj:  788
       tailrecursion.boot-hoplon.util/read-string          util.clj:   31
      tailrecursion.boot-hoplon.compiler/as-forms      compiler.clj:   46
tailrecursion.boot-hoplon.compiler/compile-string      compiler.clj:  112
                                              ...
                               clojure.core/apply          core.clj:  632
  tailrecursion.boot-hoplon.compiler/compile-file      compiler.clj:  124
                                              ...
            tailrecursion.boot-hoplon.impl/hoplon          impl.clj:   46
                                              ...
                               clojure.core/apply          core.clj:  630
                            boot.pod/eval-fn-call           pod.clj:  184
                                boot.pod/call-in*           pod.clj:  191
                                              ...
                                boot.pod/call-in*           pod.clj:  194
       tailrecursion.boot-hoplon/eval374/fn/fn/fn   boot_hoplon.clj:   81
              cljsjs.boot-cljsjs/eval778/fn/fn/fn   boot_cljsjs.clj:   30
              pandeiro.boot-http/eval480/fn/fn/fn     boot_http.clj:   71
...
              clojure.core/binding-conveyor-fn/fn          core.clj: 1916

micha16:08:48

@onetom: that actually makes sense

micha16:08:03

since hoplon is using the clojure reader

micha16:08:18

when it parses

micha16:08:18

we no longer really have to parse the page actually

micha16:08:28

so we could modify the compiler to not do that anymore

micha16:08:37

and avoid those errors

micha16:08:11

hoplon just needs to parse the first expression, the page declaration

onetom16:08:24

i hope that brings some speed up too, because i was just working on our boot1/hoplon5 homepage today (hopefully for the last time) and it was compiling like lightning compared to boot2/hoplon6...

micha16:08:19

the hoplon compiler doesn't take much time

micha16:08:36

it's cljs compiler where it's spending most of its time i think

onetom16:08:22

sure, yet the old one was noticeably/obviously faster and when it comes to recompilations, then it was comparable to the cljs compilation time

onetom16:08:04

but i was working on the layout namespace which ~15 other hoplon pages depended on, so all of them were recompiled every time...

micha16:08:36

wait you're saying it's taking longer for hoplon to generate cljs namespace than it does for cljs to compiler them?

onetom16:08:36

so it's just our degenerate case magnifies all these things i guess

onetom16:08:01

not longer, but it was on par with the cljs incremental compilation

micha16:08:31

yes with the older versions of cljs, correct?

micha16:08:55

with newer versions of cljs hoplon compiler is still fast to generate cljs namespaces, but it takes the cljs compiler a long time to recompile them

onetom16:08:09

no. boot1+hoplon5 <-- fast boot2+hoplon6+cljs1.7.48-3 <-- slow

micha16:08:16

no understand

micha16:08:28

i mean i understand that you're saying something is being slow

micha16:08:48

but it's not clear which thing is slow

micha16:08:18

boot1 packages its own cljs compiler, and it's an old version

onetom16:08:20

i think i should just record a short work session for you to get a feel for it...

onetom16:08:44

so dont even worry about this now

micha16:08:27

it's possible that the stuff we did to accomodate hot reloading of test namespaces could be slowing down the cljs compiler, too

onetom16:08:10

sure, that's something i also felt when i was switching to 1.7.4x

onetom16:08:05

but what i was saying is the .cljs.hl -> .cljs was noticeable faster with hoplon5

micha16:08:32

that's interesting

micha16:08:43

it's doing less work now, which you'd think would make it faster

onetom16:08:55

that's why it's rather sad, not interesting simple_smile

micha16:08:19

maybe some judicious memoization is in order

onetom16:08:56

but still it mostly bothers myself only really. my other 6 colleagues seem pretty enduring in this regard, so no worries simple_smile

onetom16:08:33

how can i produce attributes without a value, like: <script async src="..."> ? (script :async true) produces <script async="async"> and i can see that in the code too, but is there a way not to provide a value? it's a purely aesthetic question though. eg if i do this in js:

s = document.createElement("script"); s.async = true; s
i get
<script async></script>

onetom16:08:25

i tried (script :async nil) and (script :async "") but none yields the "desired" result

mynomoto18:08:47

@micha: you need to read the hoplon file for multiline strings too right?

micha18:08:04

@mynomoto: hey man!

micha18:08:12

no i removed that

micha18:08:32

i think the best solution there is to use something like the haml preprocessor

micha18:08:48

a much more powerful way to achieve the same

mynomoto18:08:31

That makes me sad, but if it makes things easier I'm for it. I only need the multiline thing, don't want to use haml for it.

micha18:08:08

a preprocessor is i think still a good way to go

micha18:08:33

i think i have something that could almost work, i have the basis implemented already as an instaparse grammar

micha18:08:57

it's not fs copying, because filesets don't copy anything

micha18:08:05

the fileset only makes hardlinks

mynomoto18:08:06

We probably could have a task that only looks for something like multiline scripts and replaces it with the real clojure thing.

micha18:08:13

and all the cljs compiler stuff is cached

mynomoto18:08:31

I had problems with lein cljsbuild and wouldn't trade reliability for speed, but if those measurements are precise it's a pretty big difference.

micha18:08:53

i suspect it has something to do with that testing problem

micha18:08:57

and the fix for that

alandipert18:08:10

@mynomoto: that sounds ideal

xifi21:08:14

since I don't see any better docs I went through the http://hoplon.io docs and have a couple of questions: 1) there's :on-click and :do-class used. Is there a list of available events and what they do? 2) why are all castra requests POST? If you had a db and wanted to query it would you route it through castra? Wouldn't that be an example of a GET request? (as you might tell from these questions I'm still not sure what is castra's use case.) 3) does one first check for errors when calling through rpc? The doc says the state cell is only updated when the request is successful 4) since state, error and loading are cells, does one usually just hook up some code on top of that with cell=? This seems like you don't really need async channels and stuff like that 5) is there an example app like hoplon-minimal from @mynomoto that includes a server?

micha21:08:57

@xifi: ok the first question first simple_smile

xifi21:08:14

ka-boom, right simple_smile

micha21:08:29

the :on-* and :do-* convention has been dropped in h6 for efficiency reasons

micha21:08:36

did you see the do! multimethod?

micha21:08:04

so consider the following

micha21:08:21

(div :foo bar "this is some text")

micha21:08:29

div here is a function

micha21:08:53

or it could be a DOM element, since hoplon makes DOM elements into functions by implementing IFn on them

micha21:08:45

the function application semantic on DOM elements denotes setAttribute and appendChild, as it does in HTML markup

micha21:08:52

tracking so far?

xifi21:08:11

I think so

micha21:08:34

ok so the IFn implementation knows certain things about which arguments make sense

micha21:08:52

like for instance only text nodes, comments, and elements can be children of a DOM element

micha21:08:06

this is a restriction imposed by the DOM in the browser

micha21:08:28

likewise attributes on DOM elements must have string keys and values

micha21:08:58

so hoplon elements can parse the arguments by using these constraints,

micha21:08:08

like for example a keyword can't be a child of a DOM element

micha21:08:26

so what happens in the example is the element takes its arguments

micha21:08:40

and when it sees a keyword it knows that that's an attribute key

micha21:08:23

it continues to iterate over all keyword/value pairs in the arglist until it gets to something that could be a child, like a DOM element or a string

micha21:08:46

for each attribute it can determine what to do by looking at the type of value associated with it

micha21:08:52

bar in the example above

micha21:08:34

if bar is a function then we know how to interpret the attribute

micha21:08:53

it must be an event handler, because attributes can't be set to functions in the DOM

micha21:08:30

if it's not a function then the attribute is interpreted as either setting an attribute (in the case where the value is a string)

micha21:08:22

or if the value is a javelin cell it wires up the attribute reactively such that the attribute will be updated wenever the cell changes

micha21:08:39

so for example:

micha21:08:06

(button :click #(js/alert "click!") "click me")

micha21:08:23

this creates a button that calls the handler when you click on it

xifi21:08:42

I still don't see how does this relate to my question 😄 But go on

micha21:08:55

(a :href (cell= (str "" some-cell)) "go somewhere")

micha21:08:17

that craetes an anchor whose href attribute changes as some-cell changes

micha21:08:48

ok so now for a list of events

micha21:08:13

when you do something like the button above, what actually happens is the on! method is called on the element

micha21:08:41

(on! elem :click #(js/alert "click!"))

micha21:08:33

if you haven't yourself defined a dispatch for :click in the on! multimethod it will end up here: https://github.com/tailrecursion/hoplon/blob/master/src/tailrecursion/hoplon.cljs#L560-L562

micha21:08:02

notice it simply delegates to jQuery, setting up a jQuery event handler for "click"

micha21:08:27

so to finally answer your question: the list of available events is the same as the list of available jQuery events

micha21:08:45

you can add your own by implementing a dispatch for the on! multimethod

micha21:08:28

how do we feel? simple_smile

xifi21:08:54

I see, so I have to look into jQuery (remember I'm new at this)

xifi21:08:06

I'll be afk for a long while now but keep writing I'll read it later simple_smile

mynomoto21:08:59

Almost all demos are converted to hoplon 6 on that branch.

micha21:08:13

@mynomoto: metal 👑 metal

micha21:08:20

!m mynomoto

xifi22:08:52

@micha forgot to say - thanks!

xifi22:08:07

@mynomoto: thanks too, will check the examples

micha22:08:10

@xifi: anytime!

xifi22:08:06

@micha: cool! I'll set up a call tomorrow simple_smile

micha22:08:28

haha sure

micha22:08:49

seriously though we could probably do a workshop or something

micha22:08:04

http://tmate.io and google hangouts or something

xifi22:08:12

(= we ?)

micha22:08:27

whoever is interested

micha22:08:42

alan might be able to join, too

xifi22:08:50

wouldn't mind that if it was during my work hours simple_smile I don't have much time after that, you know, family

xifi22:08:49

reading docs or source code is nice but having an education/workshop is great

xifi22:08:05

think about it simple_smile Bedtime here, bye guys and thanks