Fork me on GitHub
#clojurescript
<
2017-01-17
>
futuro05:01:20

@pupeno you're creating a vector that starts with a function as it's first element, but it needs to be wrapped in parens to be a function call

Pablo Fernandez08:01:59

@futuro: reagent will call those functions at rendering time: https://reagent-project.github.io/

Pablo Fernandez08:01:33

Otherwise, why is tabs being called?

dottedmag08:01:15

I have noticed that any evaluation in CLJS REPL (in CIDER) is visibly non-instantaneous: it takes ~0.1s to read-eval-print (+ 1 1) for example. What might be a bottleneck? The target is V8 environment.

pesterhazy08:01:37

it needs to be compiled in Java code, then sent over a socket and the added as a script tag to the head (or eval'd?)

dottedmag09:01:53

@pesterhazy Sockets and JS part ought to be blazing fast. So the most likely culprit is compiler, is it?

dottedmag09:01:02

I'd like to debug further, but I don't know how to crack open this "put this string here and get result out of it" construction. I know how to test times of read, eval and print in Clojure separately, but CLJS is still a black magic for me.

pesterhazy09:01:50

cljs repls are more complicated than they seem

pesterhazy10:01:30

I'm integrating with a React fn, which calls a callback in my code. To that code it passes a js Object. If I used .-width and such, advanced compilation breaks access.

pesterhazy10:01:39

What's the solution in such a case?

pesterhazy10:01:48

- externs? (but what would I specify there)

pesterhazy10:01:55

- aget (woe is me)

dottedmag10:01:03

@darwin Thanks! And "The Ultimate Guide to Clojure REPLs" linked from it is even more useful.

pesterhazy10:01:03

- darwin's oops?

pesterhazy10:01:12

- dnolen's gist style ^Class specifier?

schmee10:01:14

I think aget is the way to go

pesterhazy10:01:24

haha that's what I went with too, but it's the way of the devil 🙂

dnolen10:01:38

width should be fine. goog.object is the right answer

pesterhazy10:01:13

@dnolen, is there special casing for some attributes, like width?

dnolen10:01:32

It's CSSOM

dnolen10:01:50

So extern already provided for

pesterhazy11:01:22

does that work only for dom objects or also for arbitrary JS objects?

dnolen11:01:00

Arbitrary JS objects doesn't sound like a published browser standard to me :)

pesterhazy11:01:21

to clarify, I'm not working with the DOM directly

rovanion11:01:25

Bah, I can't for my life get cljs-devtools injected into my chromium 55 and I feel that my project.clj is out of controle. http://paste.ubuntu.com/23815705/ All that should be needed is for me to add devtools to my :profiles :dependencies and then add devtools.preload into the :preloads array of the :clsjbuild :compiler options, right?

dnolen11:01:43

@pesterhazy: it doesn't matter

dnolen11:01:05

The standard externals always apply

pesterhazy11:01:16

I use a react component that calls my function, passing me Objects with attribute like "width", "rowData", "index", "dataKey" etc

dnolen11:01:47

If it's a standard property name you don't need externs

pesterhazy11:01:49

so width works, by accident, because it also happens to be a common DOM attribute, but rowData won't

dnolen11:01:05

Won't work as implied by what I said

pesterhazy11:01:05

didn't mean to imply you were being unclear, just trying to make sure I understood

pesterhazy11:01:57

the best thing to do, then, is just to use gobj/get always

pesterhazy11:01:13

as this is super common, it would be nice if that didn't require an additional require

pesterhazy11:01:56

or Object destructuring (let [#js {:rowData} m] ...)

pesterhazy11:01:24

though I realize that was brought up before and decided against

pesterhazy11:01:11

couldn't we just alias gobj/get to clojure.core/oget?

pesterhazy11:01:45

it's helpful if a function is "blessed" by virtue of being included in clojurescript's core

dnolen11:01:21

@pesterhazy anything in Closure Library is already blessed

dnolen11:01:09

and there’s no significant benefit to putting one function from goog.object in core since all the other stuff there is also useful

pesterhazy11:01:40

auto-require goog.object maybe?

pesterhazy11:01:10

actually goog.object/get always seems to work even if it's not required

dnolen11:01:03

@pesterhazy yes because core uses it. For the record we’re not taking any ideas here 🙂

pesterhazy11:01:28

We understand 🙂

pesterhazy12:01:08

The fact that goog.object/get works out of the box is news to me, so I learned a lot. Thanks!

dottedmag13:01:50

I can use doc macro when in cljs.user namespace. How do I see in which namespace this macro is defined?

dnolen14:01:10

@dottedmag all the REPL helpers are from the cljs.repl namespace

dottedmag14:01:46

@dnolen How do I figure it out in the general case? There is no reification, so I can't query it in runtime, or can I?

dnolen14:01:29

(doc some-macro) will tell you

dottedmag14:01:39

I see (doc) itself prints

cljs.user> (doc doc)
-------------------------
cljs.repl/doc
, so it can be done.

nikki16:01:24

@tbaldridge: hey! :D so yeah the idea atm is to have each obj have full access to a cljs env and an interpreter locally, and msgs you send to it replace the interpreter with that

nikki16:01:10

The rendering paradigm im looking at is based on raymarching distance functions, but can get to that later

nikki16:01:41

Im still a noob at clj(s) so this is me looking ahead a bit and just brainstorming tbh

nikki16:01:04

The key is the universe starts with one obj

nikki16:01:14

Which can send msgs to other objs to recode them

nikki16:01:20

And can instantiate new ones

nikki16:01:26

That obj is called "me"

nikki16:01:30

It is you

nikki16:01:56

And you live dev the universe into whatever you want it to be

nikki16:01:49

Composing with old state at an obj is possible cuz when you send a msg you can close over old code

tbaldridge16:01:21

@nikki you can get most of that at a repl by re-deffing functions. I'm not sure what your end-goal is.

nikki16:01:43

End goal is to have async actor msg passing oo, and then let complex systems evolve over time

nikki16:01:20

Just an env for creation like Smalltalks

nikki16:01:04

But yeah, it's possible since a repl is such a thing, i guess the model is just to have many repls

nikki16:01:29

But they can repl to each other or something

tbaldridge16:01:42

the problem you will encounter is that Clojure runtimes are not reified. I.e. you can't go and create a new Clojure runtime without starting a new process.

tbaldridge16:01:03

In CLJ process=JVM process, in CLJS process = browser thread.

nikki16:01:21

Right, for now i was thinking each obj's interpreter is just a pure function of the previous interpreter and the msg

nikki16:01:31

So no need for isolated processes

dnolen17:01:26

@nikki Clojure & ClojureScript aren’t interpreters - not sure if it matters for your goals

dnolen17:01:01

however for ClojureScript note this also means a very large payload - which is often impractical (might not be for you)

mf18:01:11

Hi, Hoping someone can advise on a ClojureScript core.async question. If I understand correctly core.async in ClojureScript doesn't have the <!! macro. In the following contrived Clojure example I'm using <!! to effectively wait for a go block to finish so that the greet-user function can return the value on the msg channel returned from the go block:

(ns scribble
  (:require
   [clojure.core.async :as a :refer [<! <!! chan put! go]]))

;; imagine this is an asynchronous task
(defn get-name []
  (let [c (chan)
        _ (put! c "Joe")]
    c))

(defn welcome-message [name]
  (str "Hello " name))

(defn greet-user []
  (let [name-chan (get-name)
        msg (go (welcome-message
                 (<! name-chan)))]
    (<!! msg)))

(greet-user) ;; "Hello Joe"
How can I achieve similar functionality in ClojureScript without <!!?

tbaldridge18:01:58

@mf, you have to wrap the next form in a (go ..) as well. Async code is infectious

tbaldridge18:01:52

But that's a good thing, since if you think about it, <! and >! are IO, so any function that interacts with channels is an impure function

mf18:01:52

@tbaldridge that makes sense, but the problem I have is that greet-user needs to return the msg not a channel

tbaldridge18:01:17

It's not possible in CLJS

mf18:01:30

ok, because it's single threaded?

tbaldridge18:01:43

even in JS its not possible

mf18:01:49

@tbaldridge looks like some refactoring is in order. Thanks for your help

tbaldridge18:01:52

@mf, some food for thought, It's super easy to get into a situation with core.async where everything is a go block, and everything is async. Been there, and it's not pretty. So although I don't have any perfect solutions, I'd recommend trying to find ways to keep the use of core.async to a minimum in a CLJS app (or any app really). It can't always be done, and in those cases, core.async can be awesome. But it's also pretty easy to over-use.

mf18:01:20

@tbaldridge sounds like good advice. My example is very contrived. In reality I'm trying to avoid callback hell!

miikka18:01:49

Is it a bug or feature that (s/from (s/nilable ::whatever)) differs for clojure.spec and cljs.spec`? For clj, it's (s/nilable ...) and for cljs it's (s/or ...).

miikka18:01:40

(I don't think that's the only form that differs, but I'm not aware of any other examples right now)

miikka18:01:05

Okay. I'll open an issue at CLJS JIRA, then

dnolen18:01:13

@miikka and attach a patch 🙂

miikka18:01:49

Heh, I'll see if I'll have the time to try fixing it

pre19:01:47

@anmonteiro I tried lumo over the weekend—worked out of the box and started fast. Where's the cljs repl server running, and how can I connect to it from emacs?

anmonteiro19:01:40

@pri you can create a socket server with -n port or -n ip:port, and connect to it from inf-clojure for example

anmonteiro19:01:48

also make sure to drop by #lumo if you need any help

pre19:01:41

So I have to create another server on Jvm to talk to Lumo?

anmonteiro19:01:32

there's no JVM needed in either side

anmonteiro19:01:52

Lumo runs on Node, no JVM needed

anmonteiro19:01:04

it starts a (Node) socket server

pre20:01:54

I started lumo -n 7777 and cider-connect worked but threw the error: “Sync nRepl request timed out (op clone id 1).

anmonteiro20:01:19

@pri right, which is why I mentioned inf-clojure

anmonteiro20:01:25

Lumo doesnt implement nREPL

anmonteiro20:01:00

or rather, nREPL doesn't run in ClojureScript (yet)

futuro20:01:40

Yeah, working on that :)

pre20:01:16

Given my dependency on Cider, I can't switch to any other repl. So fighwheel/nrepl is still going to be my current workflow

pre20:01:43

I spent 15 minutes reading the docs of inf-clojure and it’s not clear how to connect to a socket repl. Would you, by chance, know how?

anmonteiro20:01:09

I actually never tried, my time has been very limited these days

anmonteiro20:01:25

I did test Lumo out with a simple telnet

futuro20:01:48

I can't remember the specifics, but start the server then probably something like inf-clojure-connect and you give it the hostname and port, then it should connect

mahinshaw21:01:45

If you look at the usage section of the inf-clojure readme, you will see what you need to connect to a socket repl. Basically, you (setq inf-clojure-program '(”localhost” . 7777)).

mahinshaw21:01:35

This works from planck as well. Basically, comint takes a cons pair for tcp connections.

mahinshaw21:01:01

And since cider isn’t based on comint, the solution is quite so simple.

pre21:01:44

Thanks, @mahinshaw I tried adding your snippet and still can't connect. @anmonteiro what editor do you use and how do you connect to your lumo’s socket repl?

mahinshaw21:01:06

do you already have the repl running in the command line?

pre21:01:37

Lumo 1.0.0
ClojureScript 1.9.293
 Docs: (doc function-name-here)
 Exit: Control+D or :cljs/quit or exit

Lumo socket REPL listening at localhost:7777.
cljs.user=>

mahinshaw21:01:18

I just got it working. I started the repl. Then in emacs M-: (setq inf-clojure-program '("localhost" . 7777)) RET then M-x inf-clojure RET

pre21:01:25

wrong type argument: stringp, (”localhost” . 7777)

mahinshaw22:01:52

Is your version of inf-clojure up to date?

pre22:01:58

I just installed one from stable branch

pre22:01:09

emacs 24.5.1

mahinshaw22:01:55

yeah. not sure about that then. you could just set inf-clojure-program to ”lumo”