Ooooh thanks! In a cross-lang discord someone mentioned how nice the dbg! macro\fn is in rust. I figured if we can get the file\line meta then the rest is a really easy macro 😄
Rust will always have a file source location. This is not necessarily true when you’ve got a reader
I think I understand. This may not supply expected info when eval’d from a REPL right?
That, if you eval it from the source buffer, or just call read-string or read ever. Basically only things that use the line numbering pushback reader when clojure requires and compiles things will have this information
I see, well sometimes is better than nothing.
yeah totally
Is there any (easy) way to do something like take-until
or take-while
on a core.async channel, where items are taken while (predicate item) is true, but the first non-true item is left on the channel for something else to take? I don’t see any peek
operation, so I’m not sure whether this can be implemented with just one channel.
there's a clj ticket for take-until with a function you can use
Found it. Gotta reference cljs.analyzer/*cljs-file*
Oh, cool
This is for collections. Anything like that for core.async channels?
Hmm cljs.analyzer/*cljs-file*
is returning NO_SOURCE_PATH
. Is there a way to get the current cljs file name in cljs?
I don't think there's a way to "peek" a core.async value. You can only consume something, there's no way to "say nevermind" or put a thing back at the front of a chan
But you could use the transducer version of that take-until
function, on a channel, and use core.async/into
to put the contents up to the item you want to peek into a vector, then just take the last item and put it on a seperate output channel
I believe take-upto
from the medley library is the same thing as that take-until
issue and has a transducer arity https://github.com/weavejester/medley/blob/1.3.0/src/medley/core.cljc#L320 (might just be a little easier to "borrow" than the patches)
😅 Ended up figuring it out. Needed to be outside of the quoted forms in my defmacro, which makes sense
(but actually at that point you might as well just use a go-loop and a predicate to direct the output)
(defmacro dbg!
[& forms]
(let [f# #?(:clj *file*
:cljs cljs.analyzer/*cljs-file*)
md# (meta &form)]
`(let [res# ~@forms]
(println (str res# " in " ~f# " line " (:line ~md#) " column " (:column ~md#)))
res#)))
If I manually inline the cljs conditional it works as expected, but it returns NO_SOURCE_PATH when run in that conditional. This suggests that the conditional is trying to eval it separately from the rest of the code.
oh - now I get it, the point of the code was to capture the source file, right
Exactly
The idea is you can wrap just about any form with it and it will log the code itself, the result, and the file, line, column that it’s in while returning the original value.
Is there a way to trick it into returning the code to eval at runtime?
(defn take-while-then-put [in pred out]
(go-loop [acc []]
(let [v (<! in)]
(if (pred v)
(recur (conj acc v))
(do (a/put! out v)
acc)))))
(def out (chan))
(go (println "out:" (<! out)))
(<!! (take-while-then-put (a/to-chan! [1 1 1 1 2]) odd? out)) ;;[1 1 1 1]
;; out: 2
Don't use put! Like that
When you use put! In a copying loop like that you are failing to communicate backpressure from out to in
Is it ok to derive
un-namespaced keywords when using a custom hierarchy? The docstring says all tags must be namespaced but the implementation only includes a namespace?
check when modifying the global hierarchy (arity 2)
eg.
(def my-hierarchy (make-hierarchy))
(alter-var-root #'my-hierarchy derive :dog :animal)
where the keywords :dog and :animal are not namespacedimo in a custom hierarchy this is definitely okay in the context of an application. the namespace stuff around the global hierarchy is to prevent people from stepping on each other when derivations get combined together into the default registry by various libraries + app code. a custom hierarchy provides protection against toe stepping by being opt-in when executing derive calls. However, if you were planning to distribute a library where you expect users to add additional derivations then it'd be wise to use namespaces just like clojure requires for the global hierarchy.
some people would say that you should always plan for the possibility that your "walled garden" eventually may have to integrate with things "outside the wall" and therefore just namespace everything all the time so that eventual integration is easy and you don't have to deal with conflict
I'm trying to a hierarchy to an existing multimethod which uses non-namespaced keywords, and would rather not refactor every defmethod and call-site to add namespaces.
I guess it's more a question of whether it's officially supported by the function spec? The way the docstring of derive
is worded suggests otherwise.
clojure.core/derive
[tag parent]
[h tag parent]
Establishes a parent/child relationship between parent and
tag. Parent must be a namespace-qualified symbol or keyword and
child can be either a namespace-qualified symbol or keyword or a
class. h must be a hierarchy obtained from make-hierarchy, if not
supplied defaults to, and modifies, the global hierarchy.
Was able to implement a working dbg! macro from Rust in Clojure & ClojureScript https://gist.github.com/eccentric-j/e7121b090957bab26b5843124917d101.
that's neat. reminds me of hashp (a tagged literal that does something similar): https://github.com/weavejester/hashp
i got lines
solved. at least to a satisfactory answer 😄
i still need to do words
but the process is making a little more sense and the flow of using the shrunken test input of a failing test to develop the code is coming together
i think i'm running into some memory issues with lein test-refresh
or maybe with using quick-check
in the repl but that's a different issue.
also debux: https://github.com/philoskim/debux
Oh yes very similar in concept. I would love to clean up the part for switching between cljs.analyzer/*cljs-file*
and *file*
but best I could do for now.
ah, i think it's because of recursion and i'm not spending any time on optimizing. because of the way clojure.test.check
does its expansion and shrinkage, it probably isn't too friendly with recursive functions
"NO_SOURCE_PATH" is part of the exception print out if you have an exception in code that was defined directly in a REPL rather than loaded from a file, do you mean it threw an exception?
Ended up fixing it. Turns out it was calling that var at macroxpansion instead of at runtime. Fixed version is at https://gist.github.com/eccentric-j/e7121b090957bab26b5843124917d101.
Hi there, has anyone tried running Clojure code from Google Cloud Functions? I found some articles where people https://medium.com/zero-one-group/having-fun-with-clojurescript-on-google-cloud-function-8434d5f94d25 but nothing about Clojure
yeah, in terms of deployment (not just for google cloud), it's more robust to treat your fat jar as a java application and follow instructions for that
yup you guys are exactly right. I'll do that instead!