This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-03-29
Channels
- # admin-announcements (1)
- # announcements (20)
- # babashka (43)
- # beginners (134)
- # calva (2)
- # clerk (7)
- # cljdoc (9)
- # clojars (8)
- # clojure (91)
- # clojure-europe (21)
- # clojure-nl (1)
- # clojure-norway (13)
- # clojure-uk (1)
- # clojurescript (5)
- # datahike (3)
- # docker (2)
- # emacs (6)
- # fulcro (7)
- # graphql (9)
- # honeysql (24)
- # improve-getting-started (5)
- # introduce-yourself (1)
- # lambdaisland (1)
- # luminus (3)
- # malli (3)
- # nbb (19)
- # off-topic (22)
- # pathom (1)
- # portal (3)
- # practicalli (1)
- # rdf (26)
- # reagent (29)
- # reitit (9)
- # shadow-cljs (15)
- # spacemacs (3)
- # sql (4)
- # tools-build (30)
- # xtdb (41)
(defn foo ^long [^long n] (unchecked-inc n))
(:bases (clojure.reflect/reflect foo))
;; => #{clojure.lang.IFn$OL clojure.lang.AFunction}
Shouldn't it be IFn$LL
?How can I uuencode/uudecode files in clojure ? clojure.data.codec only does base64 and my google-foo skills haven't even surfaced an obvious java implementation to use.
Not sure how up to date this is, but I found https://javadoc.io/static/com.sun.mail/javax.mail/1.6.2/com/sun/mail/util/package-tree.html
So my searching so far seems to indicate that there used to be a sun.misc
UUEncode class, but unless you're still on Java 8 you probably don't have access to it.
The only other implementation of it that I'm finding is in apache geronimo, but that's a whole lot of stuff to bring in just for this.
I would probably recommend that you just shell out to the uuencode and uudecode utilities directly.
Decoder, but not an encoder: https://github.com/biagioT/java-uudecoder
Chad's suggestion is also a bit heavy as my use case is not mail related. I have no java / interop experience and yes I am targeting java 11.
There's also this: http://docs.groovy-lang.org/docs/ant/api/org/apache/tools/ant/util/UUEncoder.html
Chad's suggestion I think is also tied to the sun packages that are built into the JDK. It's a question of which JDK you're using, not of bringing in a library.
shelling out feels like defeat... and a loss of deployment options (e.g. what if I want to make an AWS Lambda)
Well the encoding itself doesn't seem like it would be that much of a challenge
Maybe you could just implement it yourself?
It's just taking a sequence of bytes, splitting it up into groups of 6 bits, and then adding 32 to each value
You have a lot of choices for Lambdas as well. For example, you could take the Clojure approach, but there's a https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/lambda-optimize-starttime.html (could use Lambda SnapStart for Java). There are some folks using ClojureScript in Lambdas to utilize Node. Other examples use babashka for very fast and small lambdas (in which shelling out is pretty simple).
actually this looks like a fun project, I might make a version myself in clojure
I think Joshua is right. not too bad to make. Q: is a PR to clojure.data.codec the right place to add it? i.e. is that the "go-to" for base-64 decoding?
yeah, just releasing a community library and then making a PR against the clojure toolbox website is probably the better bet.
@U0472B45003 that apache.tools.ant Encoder was a nice suggestion but odd that there is no Decoder. dunno wassup with that.
decoder and encoder; stream-based (untried): https://codeberg.org/marc.nause/uuencode
I've got a :path ["src" "resources"]
in my deps.edn
, a resources folder containing a file foo.txt
, yet when I do (io/resource "foo.txt")
it returns nil, in spite of (slurp "resources/foo.txt")
returning the content of the file. The file exists before I start the repl, if that matters. It's probably silly, but not sure what I am missing
what does (.contains (System/getProperty "java.class.path") "/resources")
return in the repl?
user=> (.contains (System/getProperty "java.class.path") "/resources")
false
user=> (.contains (System/getProperty "java.class.path") "resources")
true
that’s a great check. But looks like it wants a relative path and not an absolute oneIs the best way to re-use an existing record with a new implementation of a protocol, to just create a new record using the old one? (example below):
(defrecord r [a]
x (f [_] (str a 0)))
;; => #<Class@5733099 record2.r>
(def r0 (->r "r"))
;; => #'record2/r0
(f r0)
;; => "r0"
(defrecord r [a]
x (f [_] (str a
;; update call
1)))
;; => #<Class@6793616b record2.r>
(f (map->r r0))
;; => "r1"
And yes, doing this probably indicates something dubious about my approach to the larger task at hand.
seems like a fine approach to me
What is the best practice for exposing data readers to clients of a namespace if you expect all clients will want the them in *data-readers*
? Options I could imagine include:
1. Provide the readers as public functions in the namespace. Do nothing else.
2. Provide a add-data-readers!
function that calls alter-var-root
on #'*data-readers*
.
3. Have the namespace itself call alter-var-root
on #'*data-readers*
at the top-level.
in the context of a lib?
the provided facility for this is to include a data_readers.clj[c] file, is there some reason that's not an option?
I didn’t realize that including a data_readers.clj[c]
file would work in the context of a lib, is all.
that's the whole reason for it :)
I’m finding that clojure.tools.namespace.repl/refresh
doesn’t seem to play well with data_readers.clj
in that refreshing seems to blow away the vars in *data-readers*
. After refreshing, the next usage of the tag triggers a Attempting to call unbound fn
exception.
One workaround that seems to work is option (3) above, but is there a better way to handle this? Is the answer to simply not use c.t.n.r/refresh
in projects that have a data_readers.clj
?
Perhaps disable-unload!
or disable-reload!
(https://github.com/clojure/tools.namespace#disabling-refresh-in-a-namespace) are other options?
data_readers.clj is generally expected to be a resource, not a source file.
A correctly-configured t.n will only reload sources (`src` , test
etc), not resources
I think what’s happening is that it’s unloading and re-evaluating the namespace that contains the vars that are referenced in data_readers.clj
.
> Is the answer to simply not use c.t.n.r/refresh
That would certainly be my answer. I think refresh is sufficiently problematic that it should be avoided in general.
Here’s what I’m seeing:
(-> *data-readers*
(get 'gen/choice)
(symbol))
;; => gen.dynamic.choice-map/choice
@#'gen.dynamic.choice-map/choice
;; => #function[gen.dynamic.choice-map/choice]
(-> *data-readers*
(get 'gen/choice)
(deref))
;; => #object[clojure.lang.Var$Unbound 0x55330604 "Unbound: #'gen.dynamic.choice-map/choice"]
> That would certainly be my answer. I think refresh is sufficiently problematic that it should be avoided in general. That can be debated ad nauseam, a large cross-section of devs opt to use t.n. It also has seen some interesting updates lately. I haven't faced this issue because I rarely use data readers. Maybe check/report in the issue tracker?
clojure/tools.namespace
doesn’t use GitHub’s issue tracker, and there doesn’t appear to be anything in Jira about this.
> a large cross-section of devs opt to use t.n. They use it because it's listed in a lot of old tutorials and books and old Leiningen project templates -- but I don't think they understand how it really works: they're using it "by default" rather than out of any informed sense of choice.
@U050CT4HR If I had to guess about your problem, maybe some file that 'consumes' the data reader does not have a formal (`:require`) dependency on the file that 'produces' it (there's https://clojure.atlassian.net/jira/software/c/projects/TNS/issues/?filter=allissues in case you didn't notice that project)
If there is an existing ticket, it'll get linked into an answer there, otherwise a new ticket will get created and linked, if this can be repro'd
> maybe some file that ‘consumes’ the data reader does not have a formal (`:require`) dependency on the file that ‘produces’ it That’s the first thing I checked, unfortunately.
> They use it because it's listed in a lot of old tutorials and books and old Leiningen project templates -- but I don't think they understand how it really works: they're using it "by default" rather than out of any informed sense of choice. People may want automation. t.n provides automation. If you don't like it that's fine but it doesn't mean that anyone using it simply doesn't know any better.
"People may want easy. t.n provides easy." FTFY 🙂
Simple can be made easy. There are people trying, why not let us instead of FUDing the project?
Knock yourself out... I just think it's important to let people know that c.t.n is not required and that there are other options.
I work in a 130k line code base and just eval every change as I make it, while the code is running.
No refresh needed. Just "clean REPL" habits.
> just eval every change as I make it, while the code is running
@U04V70XH6 That’s certainly what I try to do, but there are a few situations where I run into trouble. Here are some examples:
1. Find / replace across the entire project.
2. Applying a patch that touches many files.
3. Switching branches in git.
4. Deleting or renaming a function.
In cases 1-3 it’s possible to create an exhaustive list of all the touched files and eval every namespace in that list, but it’s time consuming. In case 4 I could ns-unmap
the old name, but that adds friction that I’d like to avoid if possible. In all of the cases above I could simply restart the REPL, but again, that adds friction.
@U050CT4HR What I do: (require '[some-namespace] :reload-all)
I think maybe you've glossed over finding the actual problem above, not sure if you want to go back to that
> not sure if you want to go back to that @U064X3EF3 Would be happy to if you have thoughts! Or I can try to make a minimal repro.
I'd be happy to work through it with you at some point, and it may have some solution in t.ns, but I'm unlikely to have any more time today
the way data readers works it resolves the name of the function to a var once, and then just uses that var to handle the tag
yeah, and maybe you can just tell t.ns to not do that, or to proactively fix up afterwards
there's no mystery on what those vars are
I mean t.ns could do this automatically
> you can give refresh callback to call afterwards if I recall I don’t think this would work because the error occurs during the refresh when the tagged literal is first encountered and re-evaluated.
@U050CT4HR, if you're looking for an alternative to using c.t.n.r/refresh
I have rolled my c.t.n. workflow into https://github.com/zalky/runway that, at least for me, has made using c.t.n.r/refresh
unnecessary. You get automatic code reloading, without every having to manually refresh. Only those files that have changed will be reloaded, so if your namespace that contains the data readers vars has not changed, your reader bindings in *data-readers*
should stay valid.
(i removed my question so i could stew on it a bit longer, i hit enter by accident..)
I had trouble with that a lot until someone told me it's a setting you can change in Slack's preferences. Now it's cmd/ctrl enter to send and enter for newline.
Yeah. I consider swapping to Ctrl+Enter to send a vital must-do settings change. If for some reason you choose not to do that, you can use Shift+Enter to add newlines without sending.
I’m finding that clojure.tools.namespace.repl/refresh
doesn’t seem to play well with data_readers.clj
in that refreshing seems to blow away the vars in *data-readers*
. After refreshing, the next usage of the tag triggers a Attempting to call unbound fn
exception.
One workaround that seems to work is option (3) above, but is there a better way to handle this? Is the answer to simply not use c.t.n.r/refresh
in projects that have a data_readers.clj
?
hello everyone, following @zalky’s https://clojurians.slack.com/archives/C06MAR553/p1679410576104599 of https://github.com/zalky/cues (low-latency persistent blocking queues, processors, and graphs via ChronicleQueue) and their push to ask here too, I wanted to ask for relevant resources/docs/books/links/real-projects on how queues are used in practice (both in code and when designing/architecting an app). Are there people talking about an approach where queues are considered and used to decouple components and build apps?
This is probably a little bit better suited to #C03RZGPG3. I don't know if moving it there might help you get more activity on your question?
I will do that, thanks 😉 PS: pointer: https://clojurians.slack.com/archives/C03RZGPG3/p1680344641297949