Fork me on GitHub
#clojure
<
2021-08-27
>
Lucas Jordan01:08:40

I am looking for cron/quartz like functionality that is idiomatic to the datomic cloud environment. Any suggestions? Thanks!

vemv07:08:35

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

Noah Bogart15:08:29

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?

Noah Bogart15:08:33

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

dpsutton15:08:16

are you sure just requiring it is the cause of this?

Noah Bogart15:08:34

no, but i’m not sure how else this is happening

Noah Bogart15:08:41

either way, seems like it’s better to qualify all of these symbols than try to refer them without thought, you know?

Noah Bogart15:08:47

better for readability and clarity

dpsutton15:08:58

can you start a new repl and do (require 'game.core) and see if you get the method too large error?

dpsutton15:08:20

and yes i agree with you. i consider :refer :all an antipattern apart from clojure.test

Alex Miller (Clojure team)15:08:37

I don't get how :refer :all could cause that error

Noah Bogart15:08:45

looking at it again, i think it’s actually my use of import-vars being too big (61 namespaces, 570 vars)

Noah Bogart15:08:24

sadly, slamhound isn’t actively maintained anymore and fails on my project

Alex Miller (Clojure team)15:08:58

that seems far more likely

Alex Miller (Clojure team)15:08:01

also, don't use import-vars

didibus22:08:28

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

didibus22:08:50

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.

Alex Miller (Clojure team)23:08:21

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

didibus23:08:28

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 🤷

lread23:08:36

The use case I have seen is exposing an API from implementation namespaces.

kirill.salykin15:08:57

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 types

Asko Nōmm20:08:18

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

Asko Nōmm20:08:52

The scan-files-in-dir function does not use any atoms. It only iterates over the result of (.list (io/file directory))

jjttjj20:08:59

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?

noisesmith20:08:17

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

Marcus Rydberg21:08:16

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?

Alex Miller (Clojure team)21:08:34

why do you want to apply them?

noisesmith21:08:50

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

noisesmith21:08:25

so in practice when I use logging libs I usually end up writing macros to extend the logging macros

noisesmith21:08:25

@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

Marcus Rydberg21:08:21

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.

noisesmith21:08:33

of course if the macro you wrap uses & args you use ~@ to splice the args into the call in your macro

Marcus Rydberg21:08:59

@noisesmith found it in some dark corners of the deprecated contrib package. 🙂

Marcus Rydberg21:08:13

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

noisesmith21:08:40

then surely the solution is to use the accessing code for the data you want to log and call it in the macro invocation?

noisesmith21:08:25

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

Marcus Rydberg21:08:25

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.

noisesmith21:08:34

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

Alex Miller (Clojure team)21:08:47

presumably that log macro calls some log function - can you just call that directly?

noisesmith21:08:28

@alexmiller I thought that it usually doesn't because that pollutes the underlying log lib functionality of showing class / method

noisesmith21:08:43

so you end up with a macro that generates an interop form

Marcus Rydberg21:08:50

That's the other option @alexmiller, but it would be stepping in beside the intended public boundary of the library. I think.

noisesmith21:08:53

I could be misremembering though it's been a while

Marcus Rydberg21:08:09

Thank you both for input. Still laughing about the docstring of the apply-macro. Gotta love this community.

noisesmith21:08:57

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

Alex Miller (Clojure team)21:08:26

a lot of Java things use stack introspection for that I think

noisesmith21:08:09

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

seancorfield21:08:11

Isn't the macro wrapper in tools.logging at least partly to get *ns* correct?

seancorfield21:08:32

So that gets *ns* at compile time rather than runtime, where it's bound to the top-level calling ns or something?

noisesmith21:08:56

and there must be something else eliding the tools.logging log* function and going up to your own caller in the impl somewhere...

escherize23:08:15

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?

seancorfield23:08:08

@escherize You mean when (source fn-name) doesn't work?

seancorfield23:08:11

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?

seancorfield23:08:42

The source isn't retained in the compiled code so there's nothing else out of the box that you could do.

escherize23:08:29

source had slipped my mind, I was going to roll my own source . But maybe I will simply use it directly

Alex Miller (Clojure team)23:08:43

The underlying source-fn might be more useful than the macro

didibus23:08:28

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)

dpsutton23:08:02

bronsa made one and released the source a week after his talk with the fun challenge to decompile it if you were interested

didibus23:08:49

That's actually awesome!

dpsutton23:08:05

is the talk