Fork me on GitHub
#clojure
<
2022-08-26
>
sheluchin02:08:23

Is there a way to get a project's Maven name (deps coord) from its source code?

dpsutton02:08:30

In general no. And jdbc.next is a great example. There's not really anywhere that has the group id

Alex Miller (Clojure team)02:08:57

there is no linkage between namespace/package names and Maven artifact coordinates, nor even conventions as such

seancorfield03:08:48

The ns is next.jdbc and the artifact ID just happens to be next.jdbc -- but there's no indication of the source code that the group ID is com.github.seancorfield (and it used to be just seancorfield -- and the name change had zero impact on the code).

sheluchin09:08:08

Okay, so no way to really figure out the full artifact coord from source. I find that kind of strange, but it's not the end of the world. Thanks, all.

sheluchin11:08:36

Ah, looks like Clojars provides some data that maps repos to their Maven artifact names.

phronmophobic18:08:50

@UPWHQK562, I'm curious what your use case is

sheluchin18:08:17

@U7RJTCH6J I'm building a Clojure code exploration tool.

šŸ†’ 3
phronmophobic18:08:27

very cool. I'm very interested in tools that work at the ecosystem level. If you're interested in git deps in addition to maven deps, you may find the data from my https://github.com/phronmophobic/dewey project useful.

šŸ‘€ 1
phronmophobic18:08:13

Is there a channel or otherwise that I can read about or follow your project?

sheluchin18:08:47

Thanks @U7RJTCH6J. I've been playing around with dewey a bit already šŸ™‚ This morning, even. I haven't yet published anything at all. I think I'm pretty close to putting up an initial alpha. It will probably have a few rough edges, but I'm curious to know if others will find the idea useful. I will keep you posted when something goes live.

šŸ‘ 1
Adam Helins10:08:31

What are the exact implications of eliding :arglists when compiling? E.g. I see a couple of type hints not working anymore.

Yogesvara Das12:08:21

Can you deserialize functions from edn?

magnars12:08:15

The short answer is no. Functions aren't serializable.

magnars12:08:40

The long answer is that you might be able to finagle it somehow, but I would try to avoid it if possible. Maybe you could represent your function call with some data, and then do your own dispatch.

p-himik12:08:38

In some cases, you could use eval. Serialization in this case would, of course, mean simply putting the function's source code into the EDN, as EDN.

skylize14:08:05

I recently showed an example of serializing a function in another thread. But that does not mean I actually suggest doing so. This is only on the JVM, so not compatible with ClojureScript.

(defn ->base64-str [x]
  (.encodeToString (java.util.Base64/getEncoder) x))

(defn serialize->str [object]
  (let [buff (java.io.ByteArrayOutputStream. 1024)]
    (with-open [oos (java.io.ObjectOutputStream. buff)]
      (.writeObject oos object))
    (->base64-str (.toByteArray buff))))

(def str-encoded-partial
  (serialize->str
   (partial + 1 2 3)))
then on another system
(defn <-base64-str [s]
  (.decode (java.util.Base64/getDecoder) s))

(defn deserialize<-str [string]
  (with-open [ois (java.io.ObjectInputStream.
                   (java.io.ByteArrayInputStream. 
                    (<-base64-str string)))]
    (.readObject ois)))

((deserialize<-str str-encoded-partial) 4)
;; --> 10
https://clojurians.slack.com/archives/C03RZGPG3/p1660230269966059?thread_ts=1659795506.163599&amp;cid=C03RZGPG3

šŸ¤Æ 1
walterl19:08:18

@U90R0EPHA That's fascinating! Do you know where that (de/)serialization is done? I see clojure.lang.AFunction implements Serializable, but I don't see a matching writeObject or readObject defined anywhere.

skylize20:08:42

The primary serializing step is done by java.io.ObjectOutputStream according to a given object's implementation of the Serializable interface. The primary work of reconstituting Objects is done by java.io.ObjectInputStream. The rest of the example is just converting the Object Stream to a static format you can send over the wire. See https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/io/ObjectOutputStream.html

reified Object -> ObjectOutputStream -> ByteArrayOutputStream -> ByteArray -> Base64 encoded String

Base64 encoded String -> ByteArray -> ByteArrayInputStream -> ObjectInputStream -> reified Object

dpsutton15:08:55

Does anyone know of a ordinal number formatter? Maybe in apache commons somewhere or some other common package that we might have on our classpath? Can handle locales as well?, (.f Ordinal 1) -> "1st", on 11 gives "11th""

Conor15:08:18

The only one I know of is RuleBasedNumberFormat from https://github.com/unicode-org/icu

Martin PÅÆda15:08:15

Dependency: [com.ibm.icu/icu4j "71.1"], (import com.ibm.icu.text.RuleBasedNumberFormat) :

(let [nf (RuleBasedNumberFormat. Locale/UK RuleBasedNumberFormat/ORDINAL)]
  (dotimes [i 10]
    (println i (.format nf i "%digits-ordinal"))))
(let [nf (RuleBasedNumberFormat. Locale/FRENCH RuleBasedNumberFormat/ORDINAL)]
  (dotimes [i 10]
    (println i (.format  nf i "%digits-ordinal"))))

dpsutton15:08:50

thank you for the example. Thatā€™s very helpful

dpsutton15:08:28

and if in french, 1er, 2e, etc

Alex Miller (Clojure team)15:08:52

I think the built-in clojure.pprint/cl-format has ordinal support with ~:R (is there anything it can't do?), but not localized

didibus17:08:31

The only thing it can't do is my biggest missing feature from it, it doesn't take a map of variable, just a list of them. If it did, I could use it as a template. I also think it doesn't support custom functions if I remember.

dpsutton15:08:08

what a swiss army knife that code is

Alex Miller (Clojure team)15:08:22

user=> (run! #(clojure.pprint/cl-format true "~:R\n" %) (range 1 20))
first
second
third
fourth
fifth
sixth
seventh
eighth
ninth
tenth
eleventh
twelfth
thirteenth
fourteenth
fifteenth
sixteenth
seventeenth
eighteenth
nineteenth

šŸ˜Ž 12
Martin PÅÆda15:08:16

You even don't have to use run! : (clojure.pprint/cl-format true "~{~:R~%~}" (range 1 20))

dpsutton15:08:04

ha nice. I just need the 1st style ordinal and not fully in words. But thatā€™s super useful. Iā€™ve never dug around in cl-format before.

Richard Bowen18:08:38

What's recommended for social login for Meta, Google, Twitter and other providers?

Jeongsoo Lee18:08:52

Itā€™s not a Clojure library per se, but Iā€™ve found a Java library: https://developers.google.com/api-client-library/java/google-oauth-java-client

Jeongsoo Lee18:08:10

Also, this link might help, too: https://oauth.net/code/java/

Richard Bowen18:08:05

For some reason I sometimes forget about Java when searching for libs. Thanks.

šŸ‘ 1
erwinrooijakkers19:08:47

In Inside Transducers (2014) https://youtu.be/4KqUvG8HPYo?t=1859 Rich Hickey states that the 3-arity function of transduce, that differs from reduce in that it calls (f) as init , is the reason the 4-arity of transduce is not ā€œslappedā€ onto reduce as a 4-arity function. I donā€™t understand this reasoning. What is the benefit of the 3-arity transducefunction and why not just have`(defn reduce ([xform f init coll])`?

hiredman19:08:19

It would be a change in behavior of reduce, which could break existing code

erwinrooijakkers20:08:10

I meant only adding the 4-arity function of transduce to reduce, that would not break existing code. Why not do this? And how does it relate to the 3-arity function of transduce that I do not see the use case for?

hiredman20:08:18

oh, that is because the behavior of reduce when not given an init value is considered to be a mistake

hiredman20:08:40

reduce takes the first element of what is passed in as a init

hiredman20:08:32

but that is too restrictive on the kind of thing passed in

hiredman20:08:17

transduce doesn't just add xform, it also rectifies that behavior by having the reducing function supply the init if it is missing

erwinrooijakkers21:08:43

Thanks, I see now this example from the transduce documentation:

(def xf (comp (filter odd?) (take 10)))
(transduce xf + (range))
;; => 100
with reduce xf + (range) this fails because of calling take initially on two elements. The init step of reduce applies the reducing function (when there is no init) to the first two elements, thatā€™s considered the mistake.

erwinrooijakkers21:08:52

With the logging function of https://youtu.be/TaazvSJvBaw:

user=> (defn logging [f] (fn [& args] (prn args) (apply f args)))
#'user/logging
user=> (reduce (logging +) [1 2 3])
(1 2)
(3 3)
6

erwinrooijakkers21:08:07

And yes reimplementing reduce sarity-2 would break existing code

erwinrooijakkers21:08:09

Thanks! šŸ™‚

sheluchin23:08:09

> oh, that is because the behavior of reduce when not given an init value is considered to be a mistake @U0NCTKEV8 Hmm, what? Considered to be a mistake? Could you explain that part of your message please?

hiredman23:08:30

it causes issues on two fronts: 1. it limits what can be reduced over, because it implies a seq like model of traversing data 2. the most useful thing to reduce with are monoids. moving the init into the reducing function allows you to define the entire monoid there, and easily swap it around

erwinrooijakkers10:08:35

@UPWHQK562 Rich Hickey explains it here: https://youtu.be/4KqUvG8HPYo?t=1765 > Who knows what the semantics of reduce are when you call it with a collection and no initial value? > [Audience response] > No one, right. No one knows. Itā€™s a ridiculous, complex rule. Itā€™s one of the worst things I ever copied from Common List was definitely the semantics of reduce. Itā€™s very complex. If thereā€™s nothing, it does one thing. If thereā€™s one thing, it does a different thing. If thereā€™s more than one thing, it does another thing. Itā€™s much more straightforward to have it be monoidal and just use f to create the initial value. Thatā€™s what transduce does, so transduce says, ā€œIf you donā€™t supply me any information, f with no arguments better give me an initial value.ā€

sheluchin11:08:16

Thanks. The differences beween reduce vs. transduce when given no init are pretty confusing indeed. So if it's considered a mistake, should I always provide reduce with the init value in my code?

erwinrooijakkers14:08:10

I donā€™t think so for trivial cases where it does do the right thing mostly, I think itā€™s more a mistake in the sense that the behaviour could not be used for transduce