Fork me on GitHub
#clojure
<
2020-12-02
>
paul.legato00:12:44

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.

Alex Miller (Clojure team)00:12:15

there's a clj ticket for take-until with a function you can use

paul.legato00:12:04

This is for collections. Anything like that for core.async channels?

jjttjj01:12:50

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

jjttjj01:12:07

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

jjttjj01:12:29

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)

jjttjj01:12:45

(but actually at that point you might as well just use a go-loop and a predicate to direct the output)

jjttjj01:12:42

(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

hiredman02:12:43

Don't use put! Like that

hiredman02:12:57

When you use put! In a copying loop like that you are failing to communicate backpressure from out to in

👍 3
jaide00:12:26

Hmm cljs.analyzer/*cljs-file* is returning NO_SOURCE_PATH. Is there a way to get the current cljs file name in cljs?

jaide01:12:17

😅 Ended up figuring it out. Needed to be outside of the quoted forms in my defmacro, which makes sense

jaide01:12:11

(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#)))

jaide01:12:54

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.

noisesmith07:12:17

"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?

jaide07:12:14

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.

noisesmith18:12:04

oh - now I get it, the point of the code was to capture the source file, right

jaide00:12:27

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.

jaide01:12:12

Is there a way to trick it into returning the code to eval at runtime?

yuhan03:12:56

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)

rutledgepaulv03:12:34

imo 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.

rutledgepaulv03:12:41

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

yuhan04:12:21

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.

yuhan04:12:29

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.

yuhan03:12:46

eg.

(def my-hierarchy (make-hierarchy))
(alter-var-root #'my-hierarchy derive :dog :animal)
where the keywords :dog and :animal are not namespaced

jaide04:12:39

Was able to implement a working dbg! macro from Rust in Clojure & ClojureScript https://gist.github.com/eccentric-j/e7121b090957bab26b5843124917d101.

rutledgepaulv04:12:10

that's neat. reminds me of hashp (a tagged literal that does something similar): https://github.com/weavejester/hashp

jaide05:12:35

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.

Ronny Li22:12:43

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

noisesmith16:12:42

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

Ronny Li15:12:18

yup you guys are exactly right. I'll do that instead!