Fork me on GitHub
#clojure
<
2023-01-29
>
Takis_00:01:00

i use leiningen in mixed java/clojure project, and my main is in a java class, can i run it with lein? for example with lein run

Takis_00:01:52

i tried using this java class on project.clj :main but it was complaining that java class not found

phill00:01:21

I think lein run inalterably uses clojure.main as the main class from Java's point of view. Lein's :main is an argument to clojure.main. You can run a different main Java class from a command line, using Leiningen only to compose the classpath: java -cp $(lein classpath) some.other.Main

Takis_00:01:16

oh ok,i do lein compile, and then i run the java class from the IDE and works fine, i just wondered if i could do something to run with lein run or something

Takis_00:01:02

thank you for helping me

didibus02:01:25

What do people normally do when they need to use a function that takes the coll as first argument inside a chain of ->> ? Do you do:

(-> (->> [1 2 3 4]
         (map inc)
         (filter odd?)
         set)
    (conj 10))
Or
(->> [1 2 3 4]
     (map inc)
     (filter odd?)
     set
     (#(conj % 10)))
Or something else?

dpsutton04:01:13

(-> [1 2 3 4]
    (->> (map inc)
         (filter odd?))
    set
    (conj 10))

Max05:01:50

I wrote a “dual” to as-> for this called as->>, it’s made it into a few of my projects:

(->> [1 2 3 4]
     (map inc)
     (filter odd?)
     set
     (as->> $ (conj $ 10)))
Here’s the code:
(defmacro as->> [& form]
  `(as-> ~(last form) ~@(butlast form)))
It’s not as common knowledge as it should be, but as-> https://clojuredocs.org/clojure.core/as-%3E#example-568eeddae4b0f37b65a3c280.

didibus05:01:34

Hum, you're making me think switching entirely to as-> is also an option:

(as-> [1 2 3 4] $
      (map inc $)
      (filter odd? $)
      (set $)
      (conj $ 10))

Max05:01:58

FYI https://clojurians.slack.com/archives/C03S1KBA2/p1571756579470800?thread_ts=1571741026.454500&amp;channel=C03S1KBA2&amp;message_ts=1571756579.470800 about not using as-> outside of thread-first forms. I kind of agree? But not strongly enough to really argue for it. At the very least I think it’s preferable to use as-> and as->> for small exceptions to an otherwise thread-first or thread-last operation.

didibus06:01:21

That use of as makes sense in a one off, but if you end up doing say 2 or three things in a row, would seem weird to me to do:

(->> [1 2 3 4]
     (map inc)
     (filter odd?)
     set
     (as->> $ (conj $ 10))
     (as->> $ (conj $ 11))
     (as->> $ (conj $ 12)))
For example. You could:
(->> [1 2 3 4]
     (map inc)
     (filter odd?)
     set
     (as->> $ (conj $ 10))
              (conj $ 11))
              (conj $ 12)))
As well, but at that point, why not switch the whole thing to as? Also, as-> kinds of annoy me a bit, it's similar to using a lambda, you have to put the position. I find as-> maybe makes more sense if you need an argument in the middle? I think I'd like a -> and ->> where they can both safely nest in one another. That be my ideal.

p-himik09:01:37

I'd use let.

💯 6
Ed17:01:43

(into #{10} (comp (map inc) (filter odd?)) [1 2 3 4])
???

vemv21:01:23

didbus' first example is perfect to me. the 'trick' (or insight) is that you don't thread inside your head ->> and -> - doing that mental computation can be a bit confusing Instead, you read the ->> and -> parts separately. When reading the -> , you regard the whole (->> ,,,) as single thing, which could be as well something that doesn't use ->> at all, like :foo or x So in my head this is what I see:

(-> x
    (conj 10))

vemv21:01:07

IIRC the opposite pattern (`->>` then -> ) does require more mental gymnastics, so I'd reach for let in those cases

didibus23:01:59

Ya, I think I'm leaning on that one as well, basically when a mix of -> and ->> have -> be the outer threading, and use ->> inside it. I guess it also helps making you realize you're likely switching between a lazy sequence context and an eager collection based context.

DFST02:01:19

I have a macro question that I asked elsewhere but didn't quite get an answer. I'm working on a re-frame app and it's the first time I've felt the itch to use a macro, but I'm running into some issues and I don't know if it's a limitation from the macro system or my ability. Basically, I'd like to define the shape of my app-db with a malli schema, and use the schema to compute the various paths to the data I want to access based on properties that I embed in the schema for various subscription and event functions. The idea is so that I can make refactoring the db easier so that I don't have to re-enter the path to each piece of data in every subscription and event that points to it. Essentially, the macro needs access to the schema itself in order to be able to know how many parameters the subscription function is going to take. Ideally, I'd like to do this: (def app-schema (malli/schema ...)) (my-macro app-schema "player-name"). The problem is that app-schema gets passed into the macro as a schema, but I'd like to pass in the actual data so the macro can actually do computations based on it before spitting out a subscription function. Is that possible, or do I need to create one macro that takes the definition statement itself as an argument and all of the subscriptions/events I want to write?

didibus04:01:21

You know functions can also define functions, are you sure you even need a macro?

2
didibus04:01:59

(defn define
  [name]
  (defn hello [] (println "Hello " name)))

(define "John")

(hello)
;;> Hello John

didibus04:01:52

You'd need a macro if you wanted the functions names to be dynamic

didibus04:01:36

Otherwise, for what you're asking, you can call eval on the schema definition to evaluate it. You can also evaluate it first, then call the macro and refer to the schema

DFST16:01:15

That's interesting, I wouldn't have expected the code you entered to work. But how do I do it where sometimes it needs to return a function like (fn [db] (get-in db [:a :b])...), and some other times it needs to look like (fn [db arg1] (get-in db [:a :b arg1])...) I got stumped when the higher function needs to return a function (or a form that contains functions) that have different arities based on the inputs.

didibus02:01:06

You'd need a macro for that if you wanted it fully dynamic. If you know there's a bound, like between 1 to 3 arguments, you could do something like:

(case arg-count
  1 (fn [db] ...)
  2 (fn [db arg1] ...)
  3 (fn [db arg1 arg2] ...))

didibus02:01:43

(defn define [x]
   (case x
      1 (fn [a] (+ a))
      2 (fn [a b] (+ a b))
      3 (fn [a b c] (+ a b c))))

((define 2) 10 10)
;;=> 20

didibus02:01:05

If you want to dynamically define the name of the function, the number of arguments, or the implementation, then you will need a macro to do so.

didibus02:01:07

If you take a malli schema, you can call eval on it to get it evaled. But also the macros don't all get evaluated first, it's all in order as they appear in the namespace. So if you define a malli schema above the macro, in some def, you can then call resolve on it in the macro to get it.

didibus04:01:58

I'm seeing some behavior I'm a bit baffled by, it's a bit tricky to follow though:

(defmacro test2
  [& body]
  (println (keys &env) (map meta (keys &env)))
  `(do ~@body))

(defmacro test
  [sym & body]
  `(let [~sym 10]
     (test2 ~@body)))

(let [a 10]
  (test
   ^:a a
   (test
    ^:b b
    (test
     ^:c c
     (test
      ^:d d
      "hello")))))
It seems for some reason, the surrounding let binding overrides the local binding generated from the test macro, you can see that by the fact it's meta is nil, where it should have the meta :a true

didibus04:01:50

Oh, I see, inner let that shadow outer let somehow they don't replace the binding so you get the meta from the outer one only:

(let [^:1 a 1]
  (let [^:2 a 2]
    (let [^:3 a 3]
      (test2 "hello"))))
;;=> (a) ({:1 true})

didibus04:01:26

Ok, you can grab the meta but you need to get the sym on the LocalBinding object and then get the meta for that. The sym in the map from &env on the key is the first one.

p-himik09:01:26

Is there a chance it's a bug? Might be worth an "ask", if so.

didibus02:01:22

I'm not too sure, but I could ask. I think it' probably because when they build up the &env, they don't replace the key, but only the value, as things get shadowed.

Clojuri0an12:01:44

flycheck-clj-kondo for emacs linting? Is it outdated?

borkdude12:01:54

Why would it be outdated?

Chris Clark12:01:45

There’s an #C099W16KZ channel if you want some help working through any emacs troubles you’re having

borkdude12:01:36

And there's also a #CHY97NXE2 channel. flycheck-clj-kondo is not outdated, I'm using it daily

Clojuri0an12:01:54

ty, idk, sometimes tooling changes

borkdude12:01:33

clojure #CPABC1H61 is also a popular way to use clj-kondo in emacs nowadays

Clojuri0an15:01:25

What's the state of machine learning on clojure?

practicalli-johnny16:01:55

There is a lot of data science related info at https://scicloj.github.io/

Ben Sless16:01:26

I guess I'll take advantage of the opportunity and ask if data science should be counted as ML and vice versa

skylize17:01:40

Machine Learning is a subset of Data Science, right? More specifically, I think "... is a field of..." would be acceptable terminology. For analogy, this would be logically equivalent to your question as asked: > ... and ask if biology should be counted as botany and vice versa.

Carsten Behring19:01:25

Most ML libraries in Clojure cover a subset of machine learning (same as in Python + R) To answer your questions, it is useful to know what subset of ML you are interested in.

Takis_17:01:13

i am using the java stream api, is there a functional java library that makes the code looks more like Clojure? Something like Mori that we have for Clojurescript, so we can use them from javascript.

jjttjj18:01:03

You could call .iterator on the stream then iterator-seq it. Then just use it like any clojure sequence

Takis_23:01:23

i am writting java code, so i wanted a java-functional-library, that is similar to clojure functions

borkdude09:01:23

you can use clojure from Java :)

👍 2
Takis_00:02:56

i could use only clojure also ; ), i wish, but i decided to learn java also for job safety so i try to make java as clojure like as possible 🙈

jjttjj01:02:11

What sort of functional looking operations are you looking for? They already have map/filter/reduce etc that let you use lambdas right? In what way do you want it to look more like clojure? https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html

Takis_14:02:23

yes they have, i was just wondering if we had something better to write java in more clojure way, i saw Mori also(provides clojurescript data structures from javascript), so i thought if we have something similar for java

Takis_15:02:11

i think i will just use clojure data structures from java as borkdude suggested thank you : )

Takis_17:01:40

even if not immutable, to have similar names and similar places to put the arguments etc, java stream api seems so limited and not clojure like