Fork me on GitHub
#clojure
<
2022-04-29
>
Brian Beckman01:04:55

? Spacemacs + clj-refactor problems ? Some documentation says that installing the clojure layer in Spacemacs automatically loads clj-refactor, but none of the cljr-blahblah functions show up in Meta-X. Then I read I should do (clojure :variables clojure-enable-clj-refactor t)) in the layer spec, but that sends Spacemacs into death-recovery mode. Then I tried installing the clj-refactor package in the Spacemacs place dotspacemacs-additional-packages and doing

(require 'clj-refactor)
(defun my-clojure-mode-hook ()
  (clj-refactor-mode 1)
  (yas-minor-mode 1)
  (cljr-add-keybindings-with-prefix "C-c C-m")
  )
(add-hook 'clojure-mode-hook #'my-clojure-mode-hook) 
and various permutations of that in dotspacemacs/user-config, but still none of the cljr-blahblah functions show up. any clues for me?

seancorfield01:04:05

Perhaps #spacemacs and/or #cider might be a better venue for this? You're more likely to get specific help there than in a general channel.

seancorfield04:04:16

Deleting the original now you've posted elsewhere (so no one duplicates effort). Good luck resolving it!

practicalli-johnny08:04:51

Replied in #spacemacs

zhuxun203:04:09

Is it okay to have a cljc file sharing the same namespace as a clj file? And if so, how to I access the variables defined in the cljc file from the clj file?

phronmophobic03:04:10

I'm not sure you can do that, but even if you could, I'm not sure that it's a good idea. Why not just move all the clj code into the cljc file or use two separate namespace names?

Alex Miller (Clojure team)03:04:09

no, you can't do this - the platforms load (only) the platform specific file or if not found, the cljc file

phill22:04:28

@U6SEJ4ZUH keep in mind that you can put clj-specific, or cljs-specific, things in a cljc file using reader conditionals

respatialized13:04:54

Are there any resources/guides on how to incorporate testing a library's public API for breaking changes into a project's test suite? I'd like to automate the process of enforcing the https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/Spec_ulation.md constraints on an external API as I refactor a project so I don't accidentally impose a breaking change on myself.

mccraigmccraig14:04:45

i've just uncovered an interesting issue in our codebase around some tagged-literals seemingly violating the principle of least surprise we have been returning defrecord objects from a custom tagged-literal reader, and having those defrecord objects participate in a protocol - it's all been working just fine until i ran across this issue someone had put a tagged literal into a def (which seemed like a reasonable thing to do at first blush): (def foo #ctx/event-path [:blah]) which was ok... until c.t.n.r/refresh was called, after which point everything broke it turns out that the defrecord object foo had a stale class (presumably because tagged-literal induced dependencies are not recognised by tools.namespace, and namespaces were therefore recompiled out of order), and so no longer participated in the protocol should tools.namespace be able to recognise tagged-literal induced dependencies ? or is that a step too far for it ?

Alex Miller (Clojure team)14:04:55

tagged literals are just tagged literals - they are only tied to classes via some context where reader fns are supplied

Alex Miller (Clojure team)14:04:59

in foo , would it make sense to call the record constructor instead there? that would make an explicit reference to the implementation

mccraigmccraig14:04:00

yeah, i have a data_readers.cljc

mccraigmccraig14:04:25

it wouldn't make sense to call the record constructor, because the objects are part of a serializable pure-data definition... i can stop using records+protocols though and just use plain maps and multimethods

Noah Bogart14:04:49

or maps with protocols with :extend-via-metadata true

mccraigmccraig15:04:21

@UEENNMX0T that works very nicely i'm now adding the :extend-via-metadata protocol method implementations to a defrecord object - so there are initially two available routes to protocol method satisfaction for the object after c.t.n.r/refresh the class-based protocol methods become stale, but the :extend-via-metadata implementations of the protocol methods are declared with namespaced symbols, so remain current, and the objects continue to work with the protocol and, since the print-method extensions declared for the stale defrecord class continue to work, i still get the full deserialise/reserialise roundtrips for the tagged-literals awesome!

Noah Bogart15:04:08

huh! that's very clever hah

mccraigmccraig17:04:08

lol, well that turned into some of the trickiest code ever... but i finally have a tagged-literal which works on both clj and cljs, has a full de/serialize roundtrip, and does not surprise with c.t.n.r/refresh

🎉 1
mccraigmccraig17:04:41

there are "here be dragons" comments all over it though 🙈

😂 1
Noah Bogart17:04:36

Ayyyy nicely done!

Alex Miller (Clojure team)14:04:27

I think you'd still potentially have the same issue of dependency tracking (but maybe it wouldn't actually break due to the class differences)

Alex Miller (Clojure team)14:04:48

I'm not sure whether it would make sense to change tools.namespace in this way, but would welcome an issue at https://ask.clojure.org so we can make a tns jira out of it

👍 1
JoshLemer17:04:58

I am thinking, what if clojure.lang.LongRange/`clojure.lang.Range` implemented clojure.lang.Reversible? I guess the only complication would be in the infinite case. In the finite case, the reverse range could be computed in O(1) space/time with some integer arithmetic.

👍 1
JoshLemer18:04:41

Motivation: this

(rseq (range (count xs))
is IMO much clearer than
(range (dec (count xs)) -1 -1)

apt18:04:37

Hi folks. Just to confirm, is there a better method of getting the str representation of a var other than these options? Example: The var is #'foo/bar Expectation: “foo/bar” method 1)

(str (subs (str my-var) 2))
method 2)
(let [var-meta (meta my-var)] (str (:ns var-meta) "/" (:name var-meta)))

p-himik18:04:11

(str (symbol my-var))

apt18:04:46

Much better. Thanks 🙂

👍 1
Noah Bogart20:04:23

if i have a function reference user$square , can I turn that into a var?

p-himik20:04:17

What do you mean by "turning into a var"?

lilactown20:04:40

you cannot turn a function reference into the var that contains it

👍 1
hiredman20:04:44

user$square is a class name

Noah Bogart20:04:02

yeah i know that user$square is a class name but that's what's printed in the error message i'm getting. i'm doing some shenanigans with alter-var-root in a function that accepts a function and i was hoping to do it with a plain function instead of a macro

seancorfield20:04:00

user=> (defn square [x] (* x x))
#'user/square
user=> (class square)
user$square
user=> (resolve (apply symbol (clojure.string/split "user$square" #"\$")))
#'user/square

👀 1
seancorfield20:04:05

(only works for simple functions in simple namespaces -- there are probably a lot of edge cases to handle for the general case)

didibus20:04:06

Would demunge work for this?

Noah Bogart20:04:36

lol i know we're all nerd sniped but i don't need y'all to spend a bunch of time on this

seancorfield20:04:06

That's probably safer than my hack, yes:

user=> (resolve (symbol (clojure.main/demunge (.getName (class square)))))
#'user/square

seancorfield20:04:25

I always forget about it, since it's in clojure.main which I rarely look at!

didibus07:04:26

Ya, I'm always confused because there's also demunge in clojure.repl, and I think I remember looking at their code and they're identical.