clojure

New to Clojure? Try the #beginners channel. Official docs: https://clojure.org/ Searchable message archives: https://clojurians-log.clojureverse.org/
2020-12-02T00:00:29.467Z

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 😄

dpsutton 2020-12-02T00:01:25.468Z

Rust will always have a file source location. This is not necessarily true when you’ve got a reader

2020-12-02T00:02:03.468200Z

I think I understand. This may not supply expected info when eval’d from a REPL right?

dpsutton 2020-12-02T00:04:37.470100Z

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

2020-12-02T00:06:09.470300Z

I see, well sometimes is better than nothing.

dpsutton 2020-12-02T00:06:30.470500Z

yeah totally

2020-12-02T00:13:44.472100Z

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.

alexmiller 2020-12-02T00:40:15.472500Z

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

alexmiller 2020-12-02T00:40:50.472700Z

https://clojure.atlassian.net/browse/CLJ-1451

2020-12-02T00:41:06.472900Z

Found it. Gotta reference cljs.analyzer/*cljs-file*

2020-12-02T00:48:37.473200Z

Oh, cool

2020-12-02T00:49:04.473400Z

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

2020-12-02T00:59:26.474100Z

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

2020-12-02T01:03:50.474200Z

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

2020-12-02T01:11:07.474700Z

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

2020-12-02T01:12:29.475Z

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)

2020-12-02T01:15:17.476Z

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

2020-12-02T01:18:45.476100Z

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

2020-12-02T01:27:11.476700Z

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

2020-12-02T01:27:54.477800Z

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.

2020-12-02T18:08:04.487900Z

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

2020-12-04T00:38:51.042400Z

Exactly

2020-12-04T00:39:27.042600Z

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.

2020-12-02T01:28:12.478200Z

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

2020-12-02T01:34:42.478300Z

(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

2020-12-02T02:40:43.478500Z

Don't use put! Like that

2020-12-02T02:41:57.478700Z

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

👍 1
yuhan 2020-12-02T03:29:56.481800Z

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)

yuhan 2020-12-02T03:32:46.482500Z

eg.

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

rutledgepaulv 2020-12-02T03:44:34.482600Z

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.

rutledgepaulv 2020-12-02T03:45:41.482800Z

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

yuhan 2020-12-02T04:00:21.483Z

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.

yuhan 2020-12-02T04:01:29.483200Z

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.

2020-12-02T04:34:39.483900Z

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

rutledgepaulv 2020-12-02T04:41:10.484Z

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

Renzo Tomlinson 2020-12-02T04:43:18.484400Z

i got lines solved. at least to a satisfactory answer 😄

Renzo Tomlinson 2020-12-02T04:44:13.484600Z

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

Renzo Tomlinson 2020-12-02T04:44:54.484800Z

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.

1
rutledgepaulv 2020-12-02T04:45:10.485Z

also debux: https://github.com/philoskim/debux

2020-12-02T05:05:35.485400Z

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.

Renzo Tomlinson 2020-12-02T05:19:10.485700Z

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

2020-12-02T07:09:17.485900Z

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

2020-12-02T07:36:14.486300Z

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.

Ronny Li 2020-12-02T22:47:43.489Z

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

2020-12-03T16:57:42.006600Z

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 Li 2020-12-05T15:02:18.064200Z

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