Fork me on GitHub
#clojurescript
<
2018-06-01
>
michael.heuberger05:06:34

hello folks, anyone knows how to print a function name in clojurescript for browser? name and var won’t work.

michael.heuberger05:06:13

interestingly, (.toString function-x) prints the whole function code whereas i’m only interested in its name (for logging)

lilactown05:06:34

(defn fn-name [f]
  (demunge (.-name f)))

metacritical05:06:47

@michael.heuberger if you just want to log it then why not just quote the function. (.toString (quote func-name))

michael.heuberger05:06:57

thanks guys, will check out both suggestions after the weekend (new zealand here)

djwelch66607:06:18

Hello, just wondering if there was some article I could read about best practises around where to put files in your clojure/clojurescript project. Like where do I put cljs, cljc, clj. I just want to read an article because I'm bad at making up my mind 🙂

thheller07:06:30

@djwelch666 I just keep everything in src/main which already "group" everything by namespace. no need to group by extension.

joelsanchez07:06:51

@djwelch666 I do have src/cljs, src/clj and src/cljc, because the frontend and backend don't have much code overlap. mixing them is not impossible but not very positive either (in my case)

djwelch66608:06:53

I have seen src/cljs, as well as src-cljs. I guess there is no real difference

thheller08:06:43

personal preference really

djwelch66608:06:42

yeah, cheers

bendlas12:06:55

Does anybody else develop a shared react / react-native app here? How do you handle differences? reader - features seem to be out for this use case ...

troglotit13:06:16

I haven’t developed anything, but I’m pretty sure that https://github.com/necolas/react-native-web is the best shot at that

pesterhazy13:06:36

@bendlas you may not be able to share that much actual UI code

pesterhazy13:06:07

Sharing actual functions between react-dom and react-native is not a primary goal of RN AFAIK

pesterhazy13:06:17

But of course you can share all the helper libraries

pesterhazy13:06:55

Chances are your native UI will be different from the Web UI

bendlas13:06:10

OK, please get me right, I'm not looking for basic answers, I've been developing with Cljs for several years, and I think I had one of the first commercial applications out with it ...

bendlas13:06:35

my current application is in production already ..

bendlas13:06:50

with web and native developed separately

pesterhazy13:06:02

Yeah as I see it the question poses itself for React (JS) as well as for CLJS

bendlas13:06:38

our primary use case is sharing sharing functionality. sharing ui code is a secondary / non - goal

pesterhazy13:06:51

The answer will be pretty similar — separate code into platform-specific and shared business logic

bendlas13:06:34

that's what we've been doing

pesterhazy13:06:43

I've been working on shared react-native and react-dom code bases for a few years, so if you have more specific questions lmk

bendlas13:06:21

but i want a solution for almost-equal namespaces, that have different :require clauses. everything else is pretty much taken care of

bendlas13:06:50

the best, I've been able to do, is create separate source folders

pesterhazy13:06:58

possibility 1: two source directories with different classpaths

bendlas13:06:59

but it just sucks being back to pre-cljs for this

bendlas13:06:38

@dnolen has declined my ticket due to missing previous discussussion: https://dev.clojure.org/jira/browse/CLJS-2396

pesterhazy13:06:57

possibility 2: write code in such a way that it doesn't blow up at NS init time

pesterhazy13:06:30

e.g.: (def react (if (on-react-native?) (js/require "react-native") (js/require "react-native-web")))

pesterhazy13:06:16

avoid things like (def platform-specific-comp (r/adapt-react-class js/PlatformSpecificComp))

bendlas13:06:17

@pesterhazy I'm doing 2) as much as possible, but it's not for require clauses

dnolen13:06:44

@bendlas nothing was missed in declining that ticket

dnolen13:06:56

if Clojure doesn’t support that we’re not going to support it, end of story 🙂

bendlas13:06:23

@dnolen it was a statement of fact, not an accusation ...

pesterhazy13:06:35

if the "require"s in the ns declaration blow up because of missing npm deps, avoid those in favor of using js/require directly

dnolen13:06:45

@bendlas sorry I think I misread what you were saying

pesterhazy13:06:57

you can build shared RN / react-doc namespaces that way

dnolen13:06:01

I see now you were saying that you had missed the Clojure discussion on this matter

bendlas13:06:37

ah, i see now how that could be misread

bendlas13:06:43

@pesterhazy yeah, that's what I'm doing anyway, since too much read-cond gets confusing as well

bendlas13:06:56

but at least the entry point still needs to be overlayed from separate source directories then ...

bendlas13:06:50

@dnolen how do you feel about making the reader in cljs swappable? that's not something we would need to wait on clojure for ...

dnolen13:06:02

I think we should just leave reading alone

bendlas13:06:26

so you're telling me, that I would, in fact, need to do significant development work, in order to feed data structures to a lisp compiler (and cover all the tooling cases)?

bendlas13:06:00

that's easy to say, if you don't have a need ...

dnolen13:06:11

I’m not suggesting anything except not interested reader stuff

dnolen13:06:26

whatever problem you’re trying to solve I do not have context for

dnolen13:06:51

but I also know other people have likely encountered this problem and worked around it without futzing with reader capability

pesterhazy13:06:38

multiple source-dirs for multiple entry points has worked well for me in the past

dnolen13:06:05

which probably what JS people do

dnolen13:06:11

different builds - it’s not a big deal

bendlas13:06:47

I'm doing different builds, and probably every "best practice" for clojurescript

bendlas13:06:53

this still is a real need

dnolen13:06:16

I suggest taking this to #cljsrn and collecting more information

dnolen13:06:33

I don’t really have anything more to say on this for now

Alex Miller (Clojure team)13:06:25

re the reader, the concern from Rich from the beginning was to avoid creating Clojure(Script) code that is unreadable by other users. Being able to swap out the whole reader would open that scenario so I don’t think Rich would be on board with that.

Alex Miller (Clojure team)13:06:57

same reason we don’t have reader macros

bendlas13:06:16

Yep, I'm aware of that concern

dnolen13:06:48

@bendlas the goal here should be distill the problem and not jump to the solution

dnolen13:06:54

futzing with reading is one way

bendlas13:06:55

I still think it could be easier to use just the compiler (with a custom reader) without making that problem worse

dnolen13:06:09

but I’m not really hearing other options - so it’s easy to be disinterested

dnolen13:06:31

I understand the pain people are encountering here - but it’s same pain in any programming language

dnolen13:06:45

when you’re trying to target multi-platform in some generic way

dnolen13:06:24

anyways far as I’m hearing this is only about imports

dnolen13:06:34

so why such a big hammer for such a well defined problem

dnolen13:06:39

I cannot understand this at all

bendlas13:06:47

> it’s same pain in any programming language

bendlas13:06:11

this is (one of) the reason(s), I like using clojure over other languages

bendlas13:06:20

because it's less pain

dnolen13:06:27

anyways Slack is not the place for this - come up with a proposal with multiple ideas

dnolen13:06:42

and suggest it on the usual channels instead of pursuing only reading as the way

bendlas13:06:05

> so why such a big hammer for such a well defined problem to be fair, what other problem did read-cond solve for clojure?

Alex Miller (Clojure team)13:06:30

cross-platform portability

bendlas13:06:18

.. which is exactly what I'd like to use it for. only with extensible definition of platform

Alex Miller (Clojure team)13:06:51

well it’s the extensibility that caused a lot of complexity in the implementation which is why we backed down to just platform level.

bendlas14:06:15

The design page lists something very complex indeed under the label extensibility. Also boolean combinators. I'm not interested in the former one and only slightly in the latter. The thing I'm interested in, configurable compiler :features, doesn't seem that complex besides those ...

dnolen13:06:32

I will certainly look it over such a proposal, provide feeback and see if I have further comments/ideas

dnolen13:06:51

but I agree w/ your assessment that I’m not worked about it because I don’t need it

dnolen13:06:13

but even if I did, I don’t have issues w/ managing the classpath, writing some redundant files or whatever

bendlas13:06:04

@dnolen I'll try to come up with something, but there are only so many eyelet to hook into

bendlas13:06:21

and classpath overlaying just sucks. not least because of the confusion it causes

dnolen13:06:35

fwiw I already had this discussion with Rich and our conclusion was that managing the classpath was fine in many cases

bendlas13:06:37

That got massively better with cljc

dnolen13:06:39

I don’t really believe that

dnolen13:06:46

since you need to manage the classpath all the time already

dnolen13:06:59

build vs dev vs test vs whatever

dnolen13:06:31

which suggests this case is not really different in any meaningful way

bendlas13:06:52

all the cases i've been finding could be solved with distinct namespaces. the best solution for this one seems to be overlaying namespaces ...

bendlas13:06:36

well, I guess I'll be looking into shadow-cljs, until more users become vocal on this, and / or someone on the core team has a personal need 😉

dnolen14:06:37

yes, shadow-cljs does lots of cool things we’re not necessarily interested in (yet) - so this seems like a perfectly fine solution to me!

bendlas14:06:42

yep, maybe there's a chance to enhance its tooling support as well ...

bendlas14:06:05

@dnolen @alexmiller I'm just looking at the latest State of Clojure, because I want to know, how many people are doing what I'm doing (shared web/native). Didn't find anything about that ... do you have any idea about that?

dnolen14:06:30

no we might want to start asking that question

dnolen14:06:51

I do suspect shadow-cljs usage to get a huge boost in the next survey given the large influx of JS users

dnolen14:06:05

and the fact that Google Closure NPM integration is challenging / slow going

bendlas14:06:50

hah, that's a whole separate chapter ... am I right with my perception, that the main problem seems to be gclosure lacking the ability to apply :simple to npm deps, while compiling the rest with :advanced?

Alex Miller (Clojure team)14:06:25

there was one question about targeting React Native I think ?

dnolen14:06:55

that may very well trigger us adopting a similar strategy but with our own spin

Alex Miller (Clojure team)14:06:10

yeah, 19.5% said they were targeting React Native

dnolen14:06:11

but just not feeling rushed - there’s already tons of users and legacy code bases doing things the previous way

hlolli14:06:48

I can see this being dirty the solution bendlas is suggesting with the reader. Offering no solution, but I could see how seperating native platforms would be nice. I'm now working with Samsung Tizen and Amazon FireTv, they both offer custom chromium browsers that can do some custom stuff. Never did rn, so not sure if it's comparable 🙂

bendlas14:06:51

well, most platform differences can easily be handled by :closure-defines + if. I'm concerned about the remaining cases, where you want to :require different namespaces based on platform ...

hlolli14:06:30

ah good point. The cordova mess would be a good example.

hlolli14:06:58

(the cordova plugins specifically)

bendlas14:06:18

An example for what?

hlolli14:06:31

requireing platform specific plugin, geolocation in cordova-toast will only work on Tizen platform.

hlolli14:06:12

but this isn't a problem for me, just thinking out loud about potential cleaner code in the future.

hlolli14:06:14

all in all this was bit badly thought comment, don't do React Native, just React, so don't know how this applies. Support for reader macros on various native platforms sounds good. But I have no slightest idea what implications that has from the bigger picture, so I stay out of it.

leongrapenthin16:06:06

I'm trying to compile a minimal program with the cljs.main and target node. It does not work. Am I doing something wrong? https://github.com/lgrapenthin/cljs-main-node-problem

bhauman16:06:15

@leongrapenthin you need to specify "-re node"

bhauman16:06:10

And you can skip the --output-to

pesterhazy16:06:12

This is what I use

{:deps {org.clojure/clojurescript {:mvn/version "1.10.238"}}
 :aliases
 {:prod
  {:main-opts ["-m" "cljs.main"
               "--optimizations" "simple"
               "-o" "compiled-prod.js"
               "--compile" "foo.prod"]}
  :watch
  {:main-opts ["-m" "cljs.main"
               "--target" "node"
               "-o" "compiled-dev.js"
               "--watch" "src"
               "--compile" "foo.devserver"]}
  :repl
  {:main-opts ["-m" "cljs.main"
               "--repl-env" "node"
               "--repl"]}}}

bhauman16:06:17

you dont' need -re

leongrapenthin16:06:22

@bhauman But I don't want a repl environment

bhauman16:06:28

yeah my mistake

bhauman16:06:48

it was the http error that was throwing me

pesterhazy16:06:15

I'm not using clojurescript to pull in NPM deps. Instead I just add them to package.json (and yarn install). To make that work from the repl I use NODE_PATH="$PWD/node_modules" clj -M:repl

leongrapenthin16:06:34

since i'm using exactly the command line from the quickstart i'm wondering if I'm doing sth. else wrong

dnolen16:06:37

@leongrapenthin not sure if that will work without master

dnolen16:06:50

there was a bug about requiring Node.js core modules that was addressed if I recall

leongrapenthin16:06:06

@dnolen thanks, I'll try master

leongrapenthin16:06:47

@dnolen can confirm its working on master

bhauman16:06:08

I could use some field use feedback

dnolen16:06:10

@bhauman just playing around with it myself

dnolen16:06:20

I get Exception in thread "main" clojure.lang.ExceptionInfo: Couldn't read the file:figwheel-main.edn {:figwheel.main/error true}

dnolen16:06:24

what’s in your README

dnolen16:06:29

nothing different

dnolen16:06:43

clj -Sdeps "{:deps {com.bhauman/figwheel-main {:mvn/version \"0.1.0-SNAPSHOT\"}}}}" -m figwheel.main

bhauman16:06:53

oh cool thanks

bhauman16:06:49

need high level testing which is much easier now

dnolen16:06:18

I’m looking forward to taking this for a serious spin

dnolen16:06:45

being able to compose dev stuff in ~/.clojure with project local stuff is so much better

bhauman17:06:12

oh yeah it is

pesterhazy17:06:33

@bhauman looks cool, I'll check it out

bhauman17:06:38

another thing is it's even better in leiningen

dnolen17:06:51

the main stuff?

dnolen17:06:54

yeah I believe that

bhauman17:06:06

no dynamic loading of plugins so its faster

bhauman17:06:47

but also much more expressive

pesterhazy17:06:29

for node I'm just using doall clj -M:watch -- nodemon dev-compiled.js, where doall is https://gist.github.com/pesterhazy/9020617ade9c93c3cccd9748f76dbe01

pesterhazy17:06:17

it just restarts the node process whenever the cljs compilation produces a new output file

pesterhazy17:06:18

it's useful to bundle everything into a single script that you can ask people to run

bhauman17:06:45

whereas figwheel hot loads it into the running program

bhauman17:06:07

depends on what you are developing

pesterhazy17:06:00

right for the browser where you have a lot of state hotloading is obviously superior. I'm excited to give it a try next week

mattly17:06:34

can anyone recommend a library for dealing with in-memory graph-like data in clojurescript?

mattly17:06:21

basically i have a list of nodes and and edge descriptions, and need to run some simple queries on it, such as “how many steps from node A to node E”

mattly17:06:47

most of what I’m finding via google or clojars requires the JVM

mattly17:06:39

maybe I can use datascript for this

bhauman17:06:37

@mattly tree-seq is an interesting tool for this

bhauman17:06:01

a tad challenging to initially get used to but makes for some concise solutions

mattly17:06:38

thanks – man core is huge

tristefigure18:06:40

@mattly: I use ubergraph (datastructure for various types of graphs + some algorithms). https://github.com/Engelberg/ubergraph Not sure it runs on clojurescript

mattly18:06:30

I looked at that one already, it doesn’t. thanks though

mattly18:06:51

it turns out my data structure has circular directed references as well

mattly18:06:06

so most libraries probably wouldn’t be of help anyway

lilactown18:06:27

I was super impressed with blessed at first but ran into a few bugs that were kinda dealbreaks 😕 specifically made it hard/impossible to use lists in react-blessed

borkdude19:06:32

@lilactown cool, I’ve only been playing around with simple examples so far

borkdude19:06:37

@lilactown this project seems pretty active though: https://github.com/yaronn/blessed-contrib it lists blessed as a dev-dependency, wonder why it isn’t a normal one

johanatan20:06:05

does anyone know if with-open is supported on clojurescript?

johanatan20:06:01

any other way to get the same functionality if not?

borkdude20:06:12

@johanatan it doesn’t seem so, but you can include the macro in a .clj file and then use it from clojurescript?

johanatan20:06:04

@borkdude do you have an example of that? I generally avoid macros in cljs due to not having successfully pulled that off before

borkdude20:06:34

@johanatan in which context do you use cljs?

johanatan20:06:59

lumo repl + src and jar classpaths

borkdude20:06:13

this is using self-hosted cljs. I don’t know in detail how it works with macros, but this one worked…

johanatan20:06:28

hmm, so the only diff is the file extension?

johanatan20:06:33

lumo processes clj files as clojure?

borkdude20:06:44

> We currently only look for macros in .cljc and .clj files (see

borkdude20:06:13

I think that’s a good choice, principle of least confusion

johanatan20:06:06

@selfsame i'm looking particularly for the resource cleanup/finalization. with-open just calls .close() on its target (which could be impl as a protocol method)

borkdude20:06:03

@johanatan transducers are maybe even better for closing stuff when you’re done reading. with-open doesn’t play nice with laziness

johanatan20:06:01

@borkdude in my case, the cleanup would be: (fs.unlinkSync temp-file) (the resource acquisition is the equivalent of mktemp from bash).

johanatan20:06:25

ah, good to know but doesn't really apply in my case. the file is created in one fell swoop via output redirection to a temp file and it's read in its entirety on the very next line via readFileSync

borkdude20:06:21

what should your code look like?

johanatan20:06:37

(with-open [f (mktemp!)]
    (sh (str "some-process >" f))
    (do-stuff-with (fs.readFileSync f "utf-8")))

johanatan20:06:48

[assuming that sh exists and does what one would expect

johanatan20:06:56

likewise for mktemp

borkdude20:06:57

so it should be something like with-temp which deletes the temp file?

borkdude20:06:18

I have one of those in JVM clojure laying around

borkdude20:06:31

note that regular with-open is not what you want here

johanatan20:06:53

well, i was thinking that i could use with-open to implement with-temp

selfsame20:06:08

probably just a (try (do-stuff) (finally (.close f)))

johanatan20:06:18

i.e., with-open according to docs doesn't call .open and only just calls .close() when finalized

borkdude20:06:49

(defmacro with-tmp-dir
     "Evaluates body while binding `tmp-dir-bind` to a fresh temporary
  directory and returns evaluated value. Cleans up directory
  afterwards, if no exception happens. Else, leaves it there for
  inspection."
     [tmp-dir-bind & body]
     `(let [~tmp-dir-bind (new-tmp-dir)
            res# (do ~@body)]
        (org.apache.commons.io.FileUtils/deleteQuietly
         ~tmp-dir-bind)
        res#))
Convert to nodejs and you’re done 😉

johanatan20:06:51

@selfsame yea, i could implement it that way

johanatan20:06:04

like so:

(defn with-temp [callback]
  (let [tmp (mktemp)]
    (try
      (callback tmp)
      (finally
        (fs.unlinkSync tmp)))))

johanatan20:06:39

if with-open existed, i could have implemented it via defining a close however

johanatan20:06:52

[in probably 1-2 lines]

borkdude20:06:34

@johanatan I wouldn’t try to retrofit things into with-open if you can do it more simple

johanatan20:06:58

yea, i'm inclined to agree since it isn't readily available. if it were [easily] available however, it would be tempting 🙂