This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-08-27
Channels
- # aleph (1)
- # announcements (5)
- # babashka (13)
- # beginners (68)
- # brompton (7)
- # calva (10)
- # cider (1)
- # clara (15)
- # cljsrn (2)
- # clojure (63)
- # clojure-austin (1)
- # clojure-europe (44)
- # clojure-france (2)
- # clojure-nl (5)
- # clojure-norway (1)
- # clojure-poland (1)
- # clojure-uk (8)
- # clojurescript (8)
- # clojureverse-ops (7)
- # conjure (13)
- # core-async (27)
- # cryogen (10)
- # cursive (17)
- # datomic (13)
- # deps-new (1)
- # events (1)
- # fulcro (3)
- # gratitude (4)
- # helix (6)
- # honeysql (6)
- # introduce-yourself (1)
- # jobs (2)
- # malli (13)
- # meander (9)
- # music (1)
- # news-and-articles (2)
- # off-topic (8)
- # pedestal (1)
- # reitit (4)
- # sci (25)
- # shadow-cljs (13)
- # spacemacs (2)
- # tools-build (5)
- # tools-deps (20)
- # vscode (50)
- # xtdb (2)
I am looking for cron/quartz like functionality that is idiomatic to the datomic cloud environment. Any suggestions? Thanks!
other than Clojure, are there JVM langs which .jar artifacts are primarily distributed as sources?
(I mean for their ecosystems - .jars representing arbitrary libraries from their users. I'm less interested in .jars representing the compilers themselves)
i.e. langs for which AOT distribution is less common, and a :classifier "sources"
artifact will be quite redundant
is there a library or plugin that will change a [X.Y :refer :all]
into a [X.Y :as xy]
and then qualify all of the referred symbols to qualified symbols?
i have a project that exports a lot of symbols and it’s now reached the point where [game.core :refer :all]
throws a MethodTooLarge error when compiling lol
no, but i’m not sure how else this is happening
either way, seems like it’s better to qualify all of these symbols than try to refer them without thought, you know?
better for readability and clarity
can you start a new repl and do (require 'game.core)
and see if you get the method too large error?
and yes i agree with you. i consider :refer :all
an antipattern apart from clojure.test
I don't get how :refer :all could cause that error
looking at it again, i think it’s actually my use of import-vars
being too big (61 namespaces, 570 vars)
sadly, slamhound isn’t actively maintained anymore and fails on my project
that seems far more likely
also, don't use import-vars
Well, I'm not sure if the dislike is conceptual, or its because how Potemkin does it is unreliable (which it is), and doesn't play super well with tools
The issue with "put vars where you want them", is that overtime, there comes reasons to move a var elsewhere, and that's a breaking change, unless like with URLs, you could make the old-var a redirect. Potemkin lets you do that nicely. You can do (def a #'new/a)
as well, but its at the Var level, so if you move a whole namespace, you kind of have to remember to keep going back and adding more vars into it.
It's no a super big issue. Its come up with me where our team has a big library of Clojure functions, and we want to expose part of it as a lib for other teams to consume, but don't want them to need to pull in the big one we use. So you'd want to be able to create a separate lib that includes a selection of the namespaces from the big lib.
If refactoring to maintain compatibility was the use case, then I’d feel more amenable to it, but almost every use of import-vars I’ve seen was not that but a priori to make an api that collected things from elsewhere
That's possible, I guess Potemkin's readme kind of talks about using it for that. But I've personally only wanted it in the scenario I described 🤷
hi, please advice if I need to implement something like this in clojure:
import java.sql.SQLData;
class Address implements SQLData {
public String street;
public String city;
public String state;
public String zip;
public String getSQLTypeName() {
return "address";
}
public void readSQL(SQLInput stream, String typeName) throws java.sql.SQLException {
street = stream.readString();
city = stream.readString();
state = stream.readString();
zip = stream.readString();
}
public void writeSQL (SQLOutput stream) throws SQLException {
stream.writeString(street);
stream.writeString(city);
stream.writeString(state);
stream.writeString(zip);
}
}
i should look into the defrecord?
not sure tho how i can specify fields with typesWhy is it that this code works:
(repeatedly #(let [files-in-dir nil]
(prn "new iteration")
(Thread/sleep 1000)))
Whereas if I actually try to read files in a directory like so:
(repeatedly #(let [files-in-dir (scan-files-in-dir "./")]
(prn "new iteration")
(Thread/sleep 1000)))
I get a error:
"class clojure.lang.Atom cannot be cast to class clojure.lang.IFn"The scan-files-in-dir
function does not use any atoms. It only iterates over the result of (.list (io/file directory))
How do people typically use sente in webapps with many components when the sente handlers need access to those other components (such as a db)? Do you just have a routing function that assoc's into the sente event message all the needed components?
I had a component that depended on sente (as the sink / source of data) plus all the components needed to implement the handlers, and it used a router
For some reason log libraries seem to love using macros. They also seem to rely on & args
a lot. That makes me want to apply
them. Am I an evil person? Do I dare revive apply-macro
?
why do you want to apply them?
they love macros because because java logging libs all tell you which method is logging the call, and if you called the logging lib from a function it would always report that function's .invoke
method instead of your actual call site
so in practice when I use logging libs I usually end up writing macros to extend the logging macros
@marcus.rydberg what do you mean by "revive" - did apply-macro exist somewhere? a macro only sees the literal form to expand so I fail to understand how apply would help
Because I have what I want logged in a neat collection, but the loggging macro always seem to want it destructed, unrolled, whatever it's called. "listed without a surrounding collection". Sorry for Friday-evening aphasia.
of course if the macro you wrap uses & args
you use ~@
to splice the args into the call in your macro
@noisesmith found it in some dark corners of the deprecated contrib package. 🙂
(defmacro apply-macro
"This is evil. Don't ever use it. It makes a macro behave like a
function. Seriously, how messed up is that?
then surely the solution is to use the accessing code for the data you want to log and call it in the macro invocation?
perhaps you'd be interested in the subject of structured logging - it's a whole thing and it's oriented to serializable data structures (usually via json) rather than strings
I agree (if I understand you correctly) that the answer is a macro. But I've been deeply instilled with irrational macro-fear so I was hoping to avoid having to learn new things but it seems it has caught up with me.
or if the access patterns are predictable, you write another macro that unwraps the data in the way you want and calls the logging macro on the result
presumably that log macro calls some log function - can you just call that directly?
@alexmiller I thought that it usually doesn't because that pollutes the underlying log lib functionality of showing class / method
so you end up with a macro that generates an interop form
That's the other option @alexmiller, but it would be stepping in beside the intended public boundary of the library. I think.
I could be misremembering though it's been a while
Thank you both for input. Still laughing about the docstring of the apply-macro
. Gotta love this community.
double checking, I see that tools.logging at least does use a function underlying the macro - there must be some other layer taking care of the call site reporting(?)
a lot of Java things use stack introspection for that I think
OK, that makes sense, and what I saw was every time I wrote a function to wrap a logging macro I'd end up seeing my function falsely reported as the location
Isn't the macro wrapper in tools.logging
at least partly to get *ns*
correct?
https://github.com/clojure/tools.logging/blob/master/src/main/clojure/clojure/tools/logging.clj#L74
So that gets *ns*
at compile time rather than runtime, where it's bound to the top-level calling ns or something?
and there must be something else eliding the tools.logging log*
function and going up to your own caller in the impl somewhere...
Is there a better way to get the source code for a function’s var than slurping the file, line, and column number and read-stringing it?
@escherize You mean when (source fn-name)
doesn't work?
Or are you asking for an alternative to the implementation of source
which, yes, reads the source file and finds the var at that location?
The source isn't retained in the compiled code so there's nothing else out of the box that you could do.
source
had slipped my mind, I was going to roll my own source
. But maybe I will simply use it directly
The underlying source-fn might be more useful than the macro
It be interesting to see a decompiler for Clojure. There are some for Java, but it be neat to go byte-code -> Clojure code, or byte-code -> java code -> clojure code (mostly for educational purpose)