Fork me on GitHub
#clojurescript
<
2015-07-26
>
jonas08:07:13

cljs.core/declare seems to not work in the repl. Is this a known bug or perhaps somethings wrong with my environment?

jonas08:07:53

I found this old jira report http://dev.clojure.org/jira/browse/CLJS-445 but it’s closed as “Completed"

profil09:07:28

Is there something similiar to clojure.lang.PersistentQueue for cljs? I want to "rotate" a list efficiently, like using pop and conj on a queue

wagjo09:07:45

@profil there is PersistentQueue deftype right in the cljs.core

profil09:07:03

I just found #queue [1 2 3]

profil09:07:24

@wagjo: Thanks 😃

mfikes12:07:21

@jonas: FWIW, declare actually does affect the analysis metadata at the REPL. The problem is that the compiler doesn’t emit valid JavaScript (it is really a NOOP from that perspective).

mfikes12:07:56

You even get no evaluation warnings in a case like (do (declare g) (def x 5))

mfikes12:07:01

declare and def without an init form could probably be made to work at the REPL; we already have at least one thing in master that works differently to cater to the REPL: http://dev.clojure.org/jira/browse/CLJS-934

phil18:07:30

Where best can I catch up on the status of bootstrapped cljs?

phil18:07:55

@minimal: Ta.

onetom18:07:50

@phil: hi! 😉

phil18:07:06

@onetom: sup!

onetom18:07:47

nothing special. just joined here. got the hint on the freenode#hoplon channel

chancerussell18:07:04

@wildermuthn: Specifically the “Keeping utilities at hand with Vinyasa” section. It sounds like it’s implemented similarly to your idea of tossing things into .core though simple_smile

bbloom19:07:18

@dnolen: I noticed that numbers and ‘default’ yields sequential hash code values. I’ve got a map w/ dom nodes as keys & i’m wondering if a better distribution of hash values would perform better

casperc21:07:08

Anyone have any experience integrating Google maps into an Om project? I am getting alot of “Uncaught TypeError: Cannot read property 'x' of undefined” errors.

casperc21:07:32

This is what my code looks like: (defcomponent page [_ owner] (render [_] (dom/div {:class "maps_page" :ref "map-canvas" :style {:width "100%" :height "100%"}})) (did-mount [_] (let [map-div (om/get-node owner "map-canvas")] (google.maps.Map. (clj->js map-div)))))

casperc21:07:58

No idea if this is the right way (probably isn’t)

chancerussell21:07:49

You shouldn't need to call clj->js for that (get-node should return the native DOM node).

chancerussell21:07:40

I would step back and make sure you're getting the element and can manipulate it before bringing the google maps stuff into it

bbloom21:07:46

you’re missing #js

casperc21:07:50

Hmm yeah you are right. It does give me the element though.

bbloom21:07:51

which is a syntax-time clj->js

bbloom21:07:12

#js {:foo 1} is shorthand for (js-obj “foo” 1)

bbloom21:07:20

and om expects raw js objects for it’s prop maps

bbloom21:07:12

note that the transform is shallow, nested maps or arrays need their own #js tag

casperc21:07:30

@bbloom: Is the right syntax #js (google.maps.Map. (clj->js map-div)) then?

bbloom21:07:11

clj->js is a helper function that, at runtime, recursively converts a cljs map to a js object

bbloom21:07:31

#js is a reader literal which, at compile time, produces a js object in the output

bbloom21:07:44

(dom/div {:class should be (dom/div #js {:class

bbloom21:07:58

which is shorthand for (dom/div (js-obj “class”

bbloom21:07:07

…. i hate slack’s insistence on smart quotes

casperc21:07:04

I am pretty sure that isn’t needed. I am using that syntax, without the #js in other components without any problems

bbloom21:07:59

if it does work, 1) i’d be surprised that dnolen changed that and 2) it’s definitely slower

bbloom21:07:45

and since #js is shallow, you also need it on the style map: #js {:style #js {:color “red”}}

casperc21:07:59

Ok, fair enough, and thanks for the pointer.

casperc21:07:23

Doesn’t make any difference though in terms of google maps though I am afraid.

bbloom21:07:14

do you only get errors in advanced compilation mode?

casperc21:07:32

No it’s in dev mode with figwheel

casperc21:07:44

I haven’t gotten the map to show up at all

chancerussell21:07:30

Can you try adding a logging statement to did-mount to verify it’s running correctly?

chancerussell21:07:00

(.log js/console “message”), etc.

casperc21:07:37

Yeah, just did and it is running fine.

casperc21:07:09

I am having some trouble with figwheel dropping the Google Maps dependency though

casperc21:07:27

Getting alot of “Required namespace not provided for my.maps.namespace"

chancerussell21:07:35

What does google.maps.Map eval to in the browser’s console?

casperc22:07:34

It evals to 'function Zk(a, b)'

bbloom22:07:29

…. are you sure you aren’t doing advanced compilation?

bbloom22:07:47

b/c the error you’re getting and the Zk(a, b) etc suggests to me name mangling issues

bbloom22:07:05

i don’t think you can’t mix advanced & not advanced, if the google maps stuff is already advanced compiled

casperc22:07:31

well I am in figwheel. I don’t think that even works with :advanced and my profile is set up for :none, but it is looking wierd

casperc22:07:54

I am using an externs file though: :externs ["google_maps_api_v3_20.js"]

bensu22:07:07

@casperc: the google.maps script is probably minified

casperc22:07:14

from the Google Closure compile github

bbloom22:07:19

are you sure that externs file correctly? what if you give it an invalid path, do you get an error?

bbloom22:07:32

s/file correctly/file is used correctly/

bbloom22:07:48

are you sure the versions match?

casperc22:07:22

yeah I was getting compile errors until i put it in the src directory

bensu22:07:26

@casperc: are you using schema/om-tools?

bensu22:07:55

@bbloom: that might explain why clj->js and #js are not needed

casperc22:07:13

Yeah I have prismatic/om-tools

bensu22:07:29

s/schema/prismatic yes

casperc22:07:45

Could be, I always had it in there simple_smile

bensu22:07:26

bbloom: is right, om.dom takes js objects while om-tools.dom takes whatever you give it.

bbloom22:07:02

@bensu: i didn’t even know that existed 😛

bensu22:07:19

also, are you importing goog.maps with cljsjs or by your own?

casperc22:07:29

Yup it is om-tools indeed i am using

casperc22:07:42

on my own, but I might try it from cljsjs

bensu22:07:49

@bbloom: it's nice sugar but probably not your thing.

casperc22:07:56

I only just found it by googling

bensu22:07:09

@casperc: consider using cljsjs it solves all this problems for you

bensu22:07:16

and adds no overhead

bensu22:07:23

s/this/these

casperc22:07:24

I’ll give it a try.

bbloom22:07:34

oh yeah, prismatic stuff. shrug

bensu22:07:18

@bbloom: haha I knew it wouldn't be for you, I like their libraries though.

bbloom22:07:28

they’re loaded with macros 😛

casperc22:07:07

I was just slightly put off by the fact that it was not completely up to date. It is at v3.18 for google maps, and the official current version is 3.20. And since it doesn’t actually include the js library, just the externs, it might cause trouble

casperc22:07:19

I’ll give it a look though

bensu22:07:24

yeah, but some of them won me over: schema.core

bensu22:07:52

@casperc: it does include the library, just not in the source, read the build.boot file.

bensu22:07:24

@casperc: if you want the latest one, packaging it is trivial, usually changing the version number somewhere in build.boot

casperc22:07:39

Yeah, guess that is the way forward next

casperc22:07:49

Thanks for the input all. Bedtime for me.

bensu22:07:28

@bbloom: how come I've never seen this before? Is there a way of using it with defn or one just writes {:pre (conforms ...)}

bbloom22:07:58

@bensu: you haven’t seen it before b/c there’s no venture back startup attempting to advertise themselves via it

bbloom22:07:24

but yeah, just use :pre

bensu22:07:16

@bbloom: don't be snappy! simple_smile it's not like they run invasive advertisements

bbloom22:07:19

language interpretation beats functional combinators every time

bensu22:07:36

I'll give it a go over the week.

kamn22:07:39

herbert clojure talk

bbloom22:07:50

i haven’t used it myself, but herbert’s approach is much preferable to me

bensu22:07:59

@kamn: thanks!

bensu22:07:38

@bbloom: I'll have to port it to cljs.

bbloom22:07:48

shouldn’t be hard

bbloom22:07:10

i bet you mostly just have to add c to the file names

bensu22:07:35

yeah, looking at it there are only a couple of namespaces that use java interop.

bensu22:07:05

but the dependencies might not be cljs.

bbloom22:07:33

give it a shot

bbloom22:07:27

anyway, this approach is seriously preferable b/c it doesn’t rely on an evaluator to build a schema object. instead it relies on an evaluator to interpret data… which means you can parse and manipulate schemas directly w/o special library support

bensu22:07:00

let's see if I follow: on other words, the schemas are closer to the language.

bbloom22:07:38

are you familiar with the idea of a functional combinator library?

lvh22:07:52

I hope core.typed integration becomes more of a thing, particularly for CLJS

lvh22:07:04

(it used to work, but CLJS changed and c.typed hasn’t kept up)

bensu22:07:27

@bbloom: not at all. but give me a week simple_smile whenever I talk to you 5 minutes I spend a week googling stuff.

lvh22:07:37

Herbert seems to like in band signaling though, which is a mixed bag

bbloom22:07:39

let’s imagine a library of “schema combinators” which have the function signature x => valid?

bensu22:07:59

@lvh: hi! never tried core.typed

bbloom22:07:14

you can take normal predicates like string? and use them as validators, or you can build up more complex ones

lvh22:07:26

the fundamental difference in implementation is that core.typed operates only as a compile-time linter

bbloom22:07:40

(defn both [f g] (fn [x] (and (f x) (g x)))

lvh22:07:48

so, I mostly just want them to share data so they add together simple_smile

bbloom22:07:11

@bensu: that both function is now a predicate factory, and many of those things will form a “combinator library"

bbloom22:07:33

but you could also have done this: (defn both [a b] (list ‘both a b))

bensu22:07:35

@bbloom: I see where your are going, that is why the error messages are so bad, fn closures are opaque.

lvh22:07:14

The latter is also amenable to optimization

bbloom22:07:15

if you do the list ‘both thing, you can now do (defmulti validate? (fn [schema subject] (first schema)))

bbloom22:07:30

now the validate? multimethod is an interpreter for the schema language

bbloom22:07:40

and you can also do: (defmulti compile first)

bbloom22:07:51

or, like @lvh, optimize

bbloom22:07:57

convert to english

bbloom22:07:19

don’t glue your records to your record player.

kamn22:07:24

@lvh so core.typed does not work with cljs currently?

lvh22:07:40

kamn: unless you use a very old version of both, no

kamn22:07:48

That's really too bad

bbloom22:07:07

schema internally has to have custom types for every “ast node"

bbloom22:07:29

and methods for all the different types of ways to use a schema

bbloom22:07:38

it’s very un-clojure

potetm22:07:58

@bbloom @bensu: I’ve not used the schema library much (or any combinator library really). Can you give an example of a bad error message?

bbloom22:07:32

schema goes out of it’s way to recover the input syntax to provide sensible error messages

bbloom22:07:42

if it didn’t do that work, it would just fail w/ like a memory address of the function

potetm22:07:43

@bbloom: Also, was that an arbitrary design decision, or were they limited by how they wanted the library to behave?

bbloom22:07:26

there’s nothing you can do w/ functional combinators that you can’t do better another way

bbloom22:07:38

functional combinators just save you some typing - it’s nice for prototyping

bbloom22:07:50

until you need a second interpretation, then you have to do that typing anyway

potetm22:07:51

Right, so they don’t know who gave them the function, just that it failed. The call stack should have some relevant info though, right?

bbloom22:07:09

potetm: either way the call stack will be the interpreter’s call stack

bensu22:07:13

@potetm: if you use (s/either SomeType AlmostThatType TheValidatedType) and it fails on AnotherThing the message explodes with descriptions of all the types, and nothing pointing to which of types in the either caused the failure.

bbloom22:07:22

but if you have the original syntax, you can use it as part of the error message

bbloom22:07:48

given: (defmulti validate (fn [schema subject] (first schema)))

bbloom22:07:40

(defmethod validate ‘both [[_ a b :as schema] subject] (when-not (and (validate a subject) (validate b subject)) (throw (ex-data “Validation failed” {:schema schema :subject subject}))))

bbloom22:07:06

if schema was a function or other opaque custom object, i’d have to do extra work to recover the syntax to report it in the error

bbloom22:07:37

my code is obviously wrong mixing validate and valid?

bbloom22:07:39

but whatever, you get the idea

potetm22:07:06

Right. So, point being, transmit the data, parse the data. Don’t build some arbitrary, opaque verification.

bbloom22:07:32

and then later when it’s too slow for a particular need, write a compiler 😉

potetm22:07:50

Thanks for the clarification simple_smile Much appreciated.

bensu22:07:10

@bbloom: cool, useful rant. I just watched @ztellman talk on macros (very good btw) so I'm ready to write some macros. I have ~3kLOC using prismatic/schema it would cool to redefine the s/defn macro to use herbert schemas and make a smooth transition.

bensu22:07:55

@bbloom: that PR explains a lot.

bbloom22:07:58

personally, i prefer handwritten validators

bbloom22:07:05

unless you really do have a need for generic validation

bbloom22:07:20

for all the same reasons why people still write parsers by hand

kamn22:07:59

Is there a way to have :pre and :post on functions enabled on a dev build and disabled on a production build?

kamn22:07:04

some compiler option?

bbloom22:07:13

yes, :elide-asserts true

bbloom22:07:16

it’s documented on the wiki

kamn22:07:11

Ah. perfect

bensu22:07:50

@bbloom: one other thing I forgot to ask you last time: after reading that cljs-vdom was not interested in providing cross browser compatibility I went and read React's synthetic event layer. It is not the greatest thing, but it doesn't change much. Do you think it would be a lot of work to extract it and apply it over cljs-vdom?

bensu22:07:14

@bbloom: ditto for goog.events

bbloom22:07:27

@bensu events need a tad more hammock time

bbloom22:07:06

i just pushed a change to cljs-vdom to enable reverse lookup (node -> vdom id), which is necessary for event routing. still trying to figure out how to use it

bbloom22:07:21

react.js also does some voodoo to make events faster in ways that only really seems to matter for mobile (eg fewer allocations) - i’m not interested in mobile

bensu22:07:56

@bbloom: agreed, I've been in that hammock for months now without good ideas. What I do know is that any event system (or whatever replaces it) could use the browser compatibility layer that those huge projects provide.

bbloom22:07:35

so i expect to achieve browser compatibility via a component library, not via low-level normalization & polyfill

bbloom22:07:55

eg a button component, rather than making onclick behave uniformly for everything

bensu22:07:40

I can see that, but what happens when you need to offer an escape latch for that person that needs the onclick, do they get the browsers onclick?

bbloom22:07:27

which, IMO, is preferable to what react.js does now

bbloom22:07:42

which is if you want to hook events that they don’t normalize, you need to manually addEventListener and removeEventListener

bbloom22:07:37

instead i want to provide dom virtualization separately from component event handling

bbloom22:07:54

delegation and such will be built in to the component system

bensu22:07:42

@bbloom: decomplecting for the win simple_smile

bensu23:07:01

ok, last question, do you have any opinions on FRP a la Elm?

bbloom23:07:51

elm is pretty neat, but i remain skeptical of FRP for UI

bensu23:07:33

ok, thanks! I'll leave you alone now.