This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-03-08
Channels
- # aws (3)
- # beginners (126)
- # boot (19)
- # cider (31)
- # cljs-dev (324)
- # clojure (96)
- # clojure-boston (2)
- # clojure-denver (9)
- # clojure-dusseldorf (2)
- # clojure-greece (4)
- # clojure-italy (5)
- # clojure-losangeles (1)
- # clojure-spec (18)
- # clojure-uk (59)
- # clojurebridge (1)
- # clojurescript (184)
- # community-development (29)
- # cursive (2)
- # datascript (2)
- # datomic (5)
- # emacs (1)
- # figwheel (6)
- # fulcro (270)
- # hoplon (2)
- # jobs (1)
- # jobs-discuss (1)
- # keyboards (2)
- # leiningen (2)
- # london-clojurians (2)
- # luminus (10)
- # mount (1)
- # off-topic (26)
- # onyx (8)
- # other-languages (1)
- # parinfer (1)
- # protorepl (6)
- # re-frame (23)
- # reagent (61)
- # reitit (5)
- # shadow-cljs (100)
- # spacemacs (3)
- # sql (19)
- # unrepl (90)
- # vim (25)
Hi, is there a uri predicate for clojurescript?
@wvelezva Yes, but you need 1.9.946 See https://github.com/clojure/clojurescript/commit/35ad08e6728d83d0e7e1cce1d724f080eb5abce4
thanks! @mfikes
This is maybe kind of crazy but has anyone tried using ClojureScript as the scripting language for a Mac app? I'm building a Mac Cocoa app and have resigned myself to using JavascriptCore as the scripting engine since its out of the box and they make the integration laughably easy. But I grimace slightly at the idea of using the language. I wondered how plausible it might be to actually use ClojureScript in there.
I can’t answer your question directly, but if I were trying to implement an in-app scripting language for Cocoa, my first stop would definitely be to have a look at planck https://github.com/mfikes/planck
http://genedavis.com/articles/2014/01/10/blazing-fast-clojure-command-line-tools/
shadow-cljs … does anyone (ok does @thheller) know how to watch test files and have them run automagically?
@raymcdermott chokidar 'out/test.js' -c 'node out/test.js'
via https://github.com/kimmobrunfeldt/chokidar-cli
I have something in the works so you don't need external tools but its going to take a bit of time till its done
I can wait a little while … just wanted to make sure that I wasn’t missing some existing feature
@thheller Here it is https://github.com/google/closure-compiler/issues/2841 - Thanks again. /cc @dnolen
I’ve you’ve been trying the ClojureScript pre-release train, beta 1.10.145 is available now. Give it a shot, nearly all bugs have been addressed and it very close to release now!
Hmm. There is this failed attempt https://github.com/mfikes/planck/issues/122 But, if you want to just script up reading and writing files, Planck is already set up to drive the JavaScriptCore that ships with macOS.
Yeah, Ambly could be used to drive any macOS app that embeds JavaScriptCore, and that app can do anything (drive JavaScript for Automation, perhaps)
Say, I have a macro in a cljc
file that I want to call from a cljs
file.
1) Does the macro have to be in a reader conditional block?
2) Do I use refer-macros
or plain refer
in cljs for referring macros from a cljc
file?
I had the macro without a reader conditional and used refer. Sometimes we got error message (not on all machines). Changing the refer
to refer-macros
solved it. The macro was:
(defmacro ->map
"(->map a b) ;;=> {:a a :b b}"
[& symbols]
(assert (every? symbol? symbols))
`(hash-map
~@(interleave (map keyword symbols) symbols)))
and the error we sometimes got is from the assert. But not always, sometimes it just worked.
Example call:
(->map a b) ;;=> {:a a :b b}
When we changed :refer
to :refer-macros
it worked as expected.@borkdude afaik, 1) no, 2) normally you'd use refer-macros
, but if you're using a fairly recent version of cljs, you can use :refer
with implicit macro loading (see https://gist.github.com/mfikes/40b634b1ef8e317d8d5a)
also, you'd have to wrap the :require-macros ...
part in a reader conditional since that does not exist in clj
ok, but apparently this could still contain bugs, why else would switching from refer to refer-macros solve our problem…
if I don’t wrap it inside a conditional, it would be as if I also put it in a cljs file right…
@borkdude One thing that might help get to the bottom of it is to see how the ns
forms desugar when you employ :refer-macros
or :refer
. But then again there is implicit infer behind :refer
now.
One way to desugar is to use Lumo or Planck and "Desugaring in the REPL" at http://blog.fikesfarm.com/posts/2016-03-01-clojurescript-macro-sugar.html
@borkdude If you don't put the macro in a reader conditional, it won't matter to the JVM ClojureScript compiler: It loads that file and it is processed by Clojure
does anyone know what this tweet is referring to? i'm pretty curious. maybe something about interop and clojars? https://twitter.com/functionalcave/status/971438971648692225
@mfikes This is the desugared form:
(ns
dre.ticker.events
(:require
[ajax.core :as ajax]
[dre.api.articles.search :as asa]
[dre.coll :refer [->map]]
[dre.config :refer [config]]
[dre.document-util :refer [new-article article->id]]
[dre.search.query :as q]
[dre.search.util :refer [normalized-blunt]]
[dre.ticker.db :as db]
[re-frame.core :as re-frame :refer [path reg-event-db reg-event-fx]]
(taoensso.timbre))
(:require-macros (taoensso.timbre :refer [info debug warn])))
This is the original one:
(ns dre.ticker.events
(:require [ajax.core :as ajax]
[dre.api.articles.search :as asa]
[dre.coll :refer [->map]]
[dre.config :refer [config]]
[dre.document-util :refer
[new-article article->id]]
[dre.search.query :as q]
[dre.search.util :refer [normalized-blunt]]
[dre.ticker.db :as db]
[re-frame.core :as re-frame :refer
[path reg-event-db reg-event-fx]]
[taoensso.timbre :refer-macros [info debug
warn]]))
@joshkh I have a strong hunch it is referring to the new ability of ClojureScript 1.10.x to cache artifacts compiled from code in JARs in a shared cache on your box (in ~/.cljs
)
@borkdude Another hunch, perhaps some code is setting *assert*
and the loading order affects whether it is enabled
The 1.10.x cache feature is nice because you can't put AOT ClojureScript artifacts in JARs (because they won't necessarily valid for all ClojureScript versions), so the shared AOT cache effectively solves that problem. Thus perhaps the tweet is showing ClojureScript 1.10.x "embracing" Clojars in a sense.
@mfikes The weird thing is that we didn’t get this as a compile time failure, but as a failure in the browser console:
router.cljc:203 Uncaught Error: Assert failed: (every? symbol? symbols)
at Function.dre.coll.__GT_map.cljs$core$IFn$_invoke$arity$variadic (coll.cljc:563)
at dre$coll$__GT_map (coll.cljc:560)
at events.cljs:64
Normally when I do this:
(->map "foo")
I get a compile time assert error, not something from the browser consolethat’s why I thought maybe putting the macro itself in a #?(:clj ...)
block would help
Or perhaps ->map
is being compiled to a runtime function... making it into your JavaScript, and :refer-macros
forces the issue, making it be treated as a macro
Perhaps macro inference is failing if you :refer [->map]
. Is there a ->map
function in the runtime namespace?
Ahh, if you (:require [dre.coll :refer [->map]])
and it is in a .cljc
file then it will be processed as ClojureScript
You can fix that though, I think. If you add a coll.cljs
file that does nothing more than :require-macros
on itself.
Here is an example of what I'm describing https://github.com/clojure/clojurescript/blob/master/src/main/cljs/cljs/core/specs/alpha.cljs
If you wrap it with #?(:clj ...)
then it won't be available at all (not as a function nor a macro)
By adding a core.cljs
you are enabling Implicit macro loading
as described in (doc ns)
what is odd is that it used to work for months. we changed some unrelated part of our code base and this popped up
By having it sitting there by itself as a .cljc
file, it is all to easy for it to be eligible for processing as a runtime ClojureScript namespace
Maybe I should look at https://github.com/cgrand/macrovich for this problem?
If you add a .cljs
file, then it would break code that wants to load the .cljc
file as ClojureScript.
Trying the new 1.10.145
:
when I build (with figwheel)
Figwheel: Starting server at
Figwheel: Watching build - dev
Compiling build :dev to "resources/public/javascript/main.js" from ["src" "test" "dev"]...
WARNING: preload namespace user.cljs does not exist
Successfully compiled build :dev to "resources/public/javascript/main.js" in 11.747 seconds.
On repl
=> nil
(require '[user.cljs])
ClojureScript 1.10.145
=> nil
(in-ns 'user.cljs)
ClojureScript 1.10.145
=> nil
(dir user.cljs)
ClojureScript 1.10.145
---- Compiler Warning on <cljs form> line:1 column:2 ----
Use of undeclared Var user.cljs/dir
1 (dir user.cljs)
^---
---- Compiler Warning ----
#object[TypeError TypeError: user.cljs.dir is undefined]
=> nil
(user.cljs/on-js-reload)
ClojureScript 1.10.145
=> #object[HTMLDivElement [object HTMLDivElement]]
Really odda ClojureScript REPL and the ability to call clojurescript functions from Cocoa and vice-verca
@mfikes if I understand the macrovich docs right, putting my macro inside a macros/deftime
would solve my problem right?
#{@mfikes, @cgrand}
why would cljs compile a macro in a cljc file to a function though?
Right; there was discussion of making the compiler balk, but it wasn't deemed necessary to prevent that
But, a repro is pretty simple, you just want (defmacro foo [])
to fail in ClojureScript code (in a cljs
file, or in a REPL, or in a cljc
file not being processed as a macro namespace)
There are interesting things that are allowed in self host, this one for example https://dev.clojure.org/jira/browse/CLJS-2015
@cgrand works like a charm now. What is use case for usetime
, this is not clear to me from the docs. What problem does it solve? Example would help.
1/ in cljs/clj, avoiding some cljs code to be compiled by clj (can be solved by a reader conditional) 2/ in cljs/cljs avoiding double compilation (between the real namespace and the pseudo namespace where macros live)
my recommandation is to wrap all defs (that are not support defs for the macros) in m/usetime
thus you are sure they won’t be evaluated in the wrong existence plane 🙂
Hi, I'm having issues when using :require
on a namespace which needs to be a string (due to special character):
Assert failed: cljs.analyzer/foreign-dep? expected symbol got "@0xproject/connect"
(symbol? dep)
Repository that reproduces the problem (reproduce for example with lein figwheel dev
):
https://github.com/district0x/cljs-0x-connectI suspected there was a MacOS performance tax: my builds under MacOS always seemed "slow". So I checked: installed a hackintosh system on my Linux machine. Building a sizable clj+cljs project: 90s (Linux) vs 125s (MacOS). Same hardware. That's a 30% difference! More that I'd expect. Thought this might be of interest to some of you.
same hardware though?
in my experience mac hardware was much more powerful than any linux hardware I had so the "perf tax" wasn't really a thing. MBPs have PCIe SSDs these days, last I checked that's still pretty rare in non-mac machines.
That also applies to hackintosh systems, realize you're running benchmarks on hardware the OS wasn't designed to work with.
Exact same hardware. Yes, I know there are caveats, but still, it's the best you can do to compare, short of installing Linux on a Mac (worth trying, too). This isn't entirely #off-topic — I'm pretty sure I'm not the only one for whom compile/build times are becoming a problem…
my point is that the times I've run Linux on a mac I've been completely disappointed in how badly it runs. I find it really hard to believe that anyone could get a 30% perf improvements in compile times simply by switching OSes
I suppose it's possible if the compiler is doing something really nasty with IO and the filesystem is optimized for something else.
i gave my mac when i got 1.5 hours of battery on fedora. been enjoying my x1 carbon thinkpad
query about go blocks in core.async: when something goes wrong, the stack trace is often inscrutable. is there something i’m supposed to be doing to get better diagnostics or is this just something you have to deal with?
@tbaldridge Well, these are the numbers I get. But this isn't Linux on Mac hardware, it's Mac OS on a PC (a good one, with identical SSDs for both OSes). Frankly, I don't like developing on Linux because of the abysmal copy&paste and different keyboard shortcuts in every app. But — a 30% difference… This is very noticeable in ClojureScript work.
I'd submit that that's your problem. You're using unsupported hardware with OS X, hardware that probably isn't optimized. All macs have PCI-e SSDs these days, so they may have removed optimizations for SATA drives. In addition all macs are Intel processor based, so that can add another level.
So perhaps the wording needs to be "hackintosh tax"?
@lee.justin.m this is an almost unavoidable aspect of async, unless somebody does bookkeeping about the flow of things you get lost, because stack traces don't reveal channel interaction (lazy sequences cause the same problem, to a lesser degree)
@lee.justin.m something like core.async, or any other cooperative multitasking or channel based abstraction, is effectively replacing the stack with a more flexible custom structure (usually driven by some mechanism the underlying platform doesn't understand, like channel queues), so bad stack traces seem hard to avoid
I wonder if there are good alternatives for stack traces, and what kind of design you would need to accomodate them
message tracing?
@lee.justin.m some things I wanted to do: https://github.com/binaryage/dirac/issues/36
@noisesmith i get that generally. it would be nice if there was a way to keep track of the top-level call, at least. just being able to see the top-most and bottom-most invocation would be great, but somehow the entire stack gets sheared off of my source code (sometimes)
Also this was another idea: https://bugs.chromium.org/p/chromium/issues/detail?id=622506
@lee.justin.m once you call go, the async channel driver is now the top of the stack
(for all code inside that block)
there's no stack relationship between code in that block and what launched it
but that's incoherent
@tbaldridge That's possible. I'm just trying to find a way to get a faster machine than my MacBook Pro 15" for Clojure+ClojureScript development. Benchmarks show that in single-core perf most latest Macs are slower than this machine.
well i don’t know. there’s this newer thing where you can see previous async events now in javascript
I wonder how that works - I'd be afraid of fake stacks causing more trouble than they solve
maybe hard to implement, but it is a godsend. hell if the go macro could just pick up a file and line number and store it, that’d be enough. or if it had an option to manually register an identifier. but getting an error sheared from any context sure is a bummer 🙂
@lee.justin.m you should be able to achieve something like this with latest Chrome Canary: https://box.binaryage.com/core-async-long-stack-traces.png
oh, cljs core.async doesn't even give you line numbers in errors? that's worse than I thought
@noisesmith no it does, but the problem is that bottom of the stack isn’t in my code
cljs-devtools used to help with previous versions: https://github.com/binaryage/cljs-devtools/blob/master/docs/faq.md#what-is-the-async-feature
@lee.justin.m right, because a go block is rewritten to callbacks that get called by channels, it's all trampolined, it's not actually a stack
or, equivalently, the stack is only an implementation detail of the dispatch channels are doing
okay well thanks for your help. i mostly wanted to make sure i wasn’t misunderstanding something. i’ll either have to deal with debugging difficulties or think about not using go blocks
@lee.justin.m a pattern that's helped me with weirdly abstracted control flows is to have an atom (def debug (atom []))
and inside relevant code do (swap! debug conj {:where "here" :when (timestamp) :relevant {... ...}})
and then puzzle through the contents in a repl
if you make it an optional callback you can even unit-test that things happen in some general order
that’s a cool trick in general. sad part here is that what i’m doing isn’t particularly complicated--i’m really just using go blocks to avoid callback hell. i’m thinking that maybe just using js native promises is easier. all i really want is to find which of my many go blocks caused the error without doing a bunch of prints. once i find it, it’ll be easy to figure out what the issue is.
shouldn't the source line of the go block be unambiguous? maybe I'm misunderstanding
the callback that async is calling should have been created inside your go block though, and that should be in there... somewhere
@lee.justin.m just a wild idea, write your own go macro, which will emit go wrapped in a function which gets immediately invoked, this way I believe you get that function on your callstack, you can assign a name to anonymous function in a way which works in chrome devtools
@darwin my understanding is that the go macro generates a series of callbacks, that are attached to the channels used in that block
calling it inside something else shouldn't change the call stack when those cbs are invoked
and if you want the stack trace to be useful (beyond showing the line of the file in which this go block callback was created), you'd need to generate fake stack data, because the go mechanism trampolines between channel callbacks, they don't invoke each other (you'd run out of stack for busy channels otherwise)
@noisesmith I was assuming enabled async callstacks feature in devtools
OK - I have no idea how that works
@darwin do you have any insight as to why the choice for nextTick was made instead of a promise-based implementation?
@noisesmith normally you get this: https://box.binaryage.com/core-async-normal-traces.png, with async call stack you get this https://box.binaryage.com/core-async-long-stack-traces.png
fascinating
@darwin so they must be instrumenting the promises to chain call stack information?
nice!
@noisesmith yes, they are “remembering” parent call stacks on on async-call boundaries and reconstruct them in devtools stacktrace view: https://bugs.chromium.org/p/chromium/issues/detail?id=272416
@lee.justin.m yes, nextTick has different timing characteristics than promises (micro-tasks vs. tasks)
@lee.justin.m some code could rely on it: https://github.com/binaryage/cljs-devtools/issues/20#issuecomment-257399432
@darwin and @noisesmith if you are curious, it turns out I was hitting a known issue in cljs-http: https://github.com/r0man/cljs-http/issues/110. This behavior seems so obviously wrong to me I think I must not get it.
Is there a way to generate JS output for a Reagent project, say, and then serve the index.html via NodeJS and Express in that container?
pretty nice summary of what’s coming in the next ClojureScript release https://www.youtube.com/watch?v=WyISHu0JFpg
Please try 1.10.145, we’re collecting the last few issues to sort out before we cut a new version hopefully early next week
Our app has problems again, this time with cljs.spec. Reported here: https://dev.clojure.org/jira/browse/CLJS-2641
my goodness how is it I’ve never heard of https://github.com/swannodette/mori until right now? this is exactly what i’ve been looking for as an alternative to immutablejs for those horrid times I cannot use cljs