Fork me on GitHub
#beginners
<
2019-10-17
>
jlmr06:10:13

Hi all, I have found some Java code that I would like to use from Clojure. It does not appear to be in the Maven repo, nor is it clear to me how I could compile it into a jar. I came to Clojure without any prior knowledge about Java, what would be the best way to use this code from Clojure?

jumar07:10:51

It depends. many java projects uses maven. In that case you can just mvn install to build and install into your local maven repo. Then you can use it locally by adding a dependency on appropriate version (e.g. in leiningen's project.clj). If you want to share between devs/machines then you need to install into a shared remote maven repository like Nexus or http://deps.co/

jlmr07:10:36

Hi Jumar, thanks. This project does not include a pom file, so mvn install complains it cannot build it. Maybe I could add a pom file myself?

jumar07:10:40

Most probably yes; hard to yes without seeing it.

jumar07:10:56

maybe it's using build.xml (ant)? Or perhaps nothing, just build from IDE?

jlmr07:10:38

I think it’s supposed to build from Eclipse

jumar07:10:19

I'd just create a new maven project in my IDE and copy-paste that class. It doesn't seem to have any external dependencies

jumar07:10:14

perhaps just for tests (junit)

jlmr07:10:41

Ok, don’t have a Java IDE installed right now, but shouldn’t be that hard. Thanks for the pointers!

borkdude09:10:00

since it's just one class file and the lib seems unmaintained, I would just copy it over to my project and vendor it

jumar12:10:03

That's what @U56R03VNW is trying to do I guess πŸ˜‰

borkdude12:10:02

ok, fwiw, here's an example Clojure project using lein to compile the Java: https://github.com/borkdude/sci/tree/master/src-java/borkdude/sci

borkdude12:10:13

and fwiw, I wrote that Java completely in Emacs, no IDE πŸ˜›

jumar12:10:14

that must have been painful πŸ™‚ (ok it's really quite simple thing in this case)

borkdude12:10:04

yeah, it was just edit, compile, fix.

borkdude12:10:21

if I would vendor the Java code, I would maybe rewrite it in Clojure altogether

borkdude12:10:34

this might help if you're using tools.deps: https://github.com/EwenG/badigeon

Michael06:10:50

hi everyone, how could i write in clojure the following nested if statement?

int x = something
int y = something
if ( x * y < z ) {
   x++;
   if (x * y < z) {
      y++
   }
}

Michael06:10:50

hi everyone, how could i write in clojure the following nested if statement?

int x = something
int y = something
if ( x * y < z ) {
   x++;
   if (x * y < z) {
      y++
   }
}

sysarcher06:10:28

I just started with clojure 2 days ago but I think this mutation isn't good You might want to do (+ x 1) and (+ y 1) instead of x++ and y++

sysarcher06:10:59

for if, you can probably use case

sysarcher07:10:00

I haven't tried it (AND, I'm also a beginner) Just tried to translate this logic as-is... there probably exists a more functional way to solve this

Michael07:10:06

yeah i was thinking perhaps something like this:

(let [x #(if (< (* something something) z)
           (+ 1 something)
           something)
      y #(if (< (* x something) z)
           (+ 1 something)
           something)])

Michael07:10:51

i had an error in code above the initial values obviously are not 0 but anyway i was looking for something to avoid nesting let statements

Michael07:10:13

need to think about this a bit more

sysarcher07:10:20

nesting if statements are a smell in C anyway πŸ™‚

sysarcher07:10:21

you have to click Run at the top to get the function in your REPL

Michael07:10:22

yeah πŸ˜„

henrik10:10:04

(if (< (* x y) z)
  (let [new-x (inc x)]
    (if (< (* new-x y) z)
      [new-x (inc y)]
      [new-x y]))
  [x y])

chepprey13:10:13

So everyone is clamoring to re-implement that example Java logic in Clojure. Shouldn't we be asking, first and foremost: what on earth is that code trying to do?

chepprey13:10:41

Is there a real-world problem being solved? If there is, the great failing of that Java code is: I cannot muster enough effort to figure out what it might be, not because I'm too dumb (although I might be), but because that code is ANNOYING.

chepprey13:10:01

It gives no indication as to the meaning of anything.

chepprey13:10:10

If we knew, in plain english, what we were looking for (and/or WHY we were looking for it), I wonder how we might express that idea more idiomatically in Clojure.

sysarcher14:10:42

no I think (as is the case with myself) we were both trying to get familiarity with the syntax of Clojure more than anything else

chepprey14:10:50

Fair enough. The spirit of my rant I think still does apply here though. The above Java sample is very typical of how one thinks to solve problems in Java: it's all about the "mechanics" of computing, rather than the "meaning".

chepprey14:10:28

The lambdas/streams they added in Java 8 do make it possible to get closer to meaning and farther from mechanics, which is nice (my day job is still Java unfortunately, so I take what I can get).

chepprey14:10:03

So as a Java hostage, with jealous eyes, I would just implore you (and anyone coming to Clojure) to think about the meaning of things, about expressing code that actually illustrates the meaningful solution to real problems. Clojure is really really good at this.

Manu09:10:04

How to enable println function in re-frame

danielneal10:10:47

(enable-console-print!) I think will do it

Raziyeh Mohajer11:10:24

Hi everyone How can I take the current system time in nanoseconds and store it in postgresql? (I heard that system.nanoTime is not accurate and it doesn't have fixed reference point)

jaihindhreddy13:10:30

Just like as->, are cond-> and some-> designed to be used within ->?

jaihindhreddy13:10:43

Not saying they can't be used by themselves.

Cas Shun13:10:01

I writing a macro where I wish to check for a value, if the value exists output (foo bar ~baz)`, if the value does not then '(foo bar). Is it there a value for baz that would not affect the arity of the function foo?

Cas Shun13:10:17

essentially a value that when unquoted would disappear from the list

Cas Shun13:10:30

otherwise I assume I have to branch and 'write out' both forms fully

Cas Shun13:10:04

I guess I can assemble (foo bar) and splice baz if it exists?

jaihindhreddy13:10:00

yup. splicing-in nil or an empty seq should preserve the arity.

Cas Shun13:10:31

empty seq doesn't work, let me try nil

hansbugge13:10:21

You could splice it in like this

`(foo bar [email protected](when baz (list baz))) 

Cas Shun14:10:20

that does work, awesome. Thank you

noisesmith17:10:18

also I'd always use [baz] in place of (list baz) - there's no context where the list version is better

Vachi17:10:18

hi guys , I have a defined a multimethod

(defmulti product-list-view (fn [kw lang-id]
                              (identity kw)))
 
and then implemented it with
(defmethod product-list-view :local [_ lang-id]
  (product/product-list-view lang-id)) 
but when calling it
(product-list-view :local 1) 
I get this error
No method in multimethod 'product-list-view' for dispatch value: :local 

Vachi17:10:59

If I run in the REPL , and reload the file, it works fine, but when running from lein run , same issue

hiredman17:10:59

is the implementation in another file?

Vachi17:10:14

@hiredman yes

hiredman17:10:43

are you loading (or causing to load via require, use, etc) the file with the implementation?

Vachi17:10:56

thank you! that was the problem

sysarcher17:10:57

How did you do it??? I've been writing everything in a single file up until now πŸ™‚

bfabry17:10:22

defmulti in file a.clj, defmethod in b.clj, call to the defined multimethod in c.clj. something in c.clj’s list of required files should cause both a.clj and b.clj to be loaded (for instance, just requiring both of them works)

hiredman17:10:22

the problem most people then run in to is they decide they want the namespace with the defmulti to require all the implementation namespaces (with the defmethods)

hiredman17:10:55

which creates a cyclic dependency which is verboten

walterl17:10:51

@U050MP39D must b.clj load a.clj for the defmethod to be recognized as an implementation of the multimethod?

Vachi17:10:24

@UPEGYT4G4 well I have a interface.clj where i put the defmulti, then implementation1.clj and implementatio2.clj where I define the defmethod, and then I have a service.cljs which requires the interface.clj and the implementantion1.clj and implementation2.clj

bfabry17:10:06

yes. a must be required in order to use the multimethod at all. b must be loaded in order to get to that implementation but it doesn’t necessarily have to be required

bfabry17:10:31

requiring is an easy way to ensure load though πŸ™‚

Vachi17:10:01

yep, thats what I did , what is the other way to load?

alexmiller17:10:38

call load or load-file

walterl18:10:21

Heh. I didn't even know about load/`load-file`. I meant "load" as a general term for require/use. What I was getting at is this: if b requires a, then surely it's not necessary require a in c, since c requires b and b requires a, right?

alexmiller18:10:28

require and use ultimately call load so these are all the same thing eventually

alexmiller18:10:37

re abc, no it's not necessary - b will ensure a gets loaded if you load b in c

walterl18:10:41

Thanks for confirming πŸ™‚

alexmiller18:10:28

I'm assuming based on prior discussion you care primarily about the load side effects

alexmiller18:10:46

if you're actually calling functions in a directly from c, then I'd say you should explicitly require it in c

walterl18:10:21

Hmmm... you just made me realize that I was going about it the wrong way: since client code of a multimethod is agnostic about the defmethods of said multimethod, it means that c should be agnostic of b, and only require a (where the multimethod is defined). Therefore it's the larger system's responsibility to make sure that b was loaded before c calls the multimethod. Does that make sense?

walterl18:10:24

Thanks! :levelup: πŸ˜›

alexmiller18:10:07

I may have misunderstood what was in a/b/c before :)

alexmiller18:10:06

consumers only care about method definition (defmulti) implementers (defmethod) must depend on the defmulti the system should ensure implementations are loaded before consumers invoke

alexmiller18:10:47

sometimes system == consumer, but it depends

walterl18:10:36

Sure, that make sense :+1:

bfabry18:10:47

I hugely regret my choice of names πŸ˜†

alexmiller18:10:24

welcome to software :)

walterl18:10:07

It is, after all, the second of Dijkstra's Phil Karlton's two "hard problems in computer science" 😝

sb17:10:18

(mount/defstate sass-server
  :start (future (sh "bash" "-c" "nohup npx sass --watch sass/main.scss:public/css/main.css & echo $! > pid.txt"))
  :stop (sh "bash" "-c" (str "kill " (clojure.string/trim (slurp "pid.txt")))))
how to solve this nicer in clojure, if the future-cancel not works and the npx script need to run in the background? (that is in the user / dev environment mount part / ns)

hiredman17:10:37

don't use clojure.java.sh, use processbuilder or exec on runtime and call destroy on the process object

sb17:10:02

Ok, I check it, thanks!

tjb20:10:08

this may be much to ask but would someone be willing to pair program with me for 1 hour this weekend? im having some issues with ring cors and i could use some mentorship if anyone is feeling charitable πŸ™‚

seancorfield20:10:58

Yeah, I could probably do that @tjb -- My wife's away in China so some interaction would make a nice change πŸ™‚ I'm West Coast and not a morning person tho'...

tjb20:10:53

that would be awesome! i am CST (Chicago) but honestly whatever time works for you i can bend my schedule to

seancorfield20:10:13

Just DM me when you're around -- I've no idea what kind of hours I'll be keeping, with only the cats for company. My schedule kind of goes to hell when my wife's away (I WFH 100% so I'm used to having her around my "office" nearly all the time).

tjb20:10:53

no worries Ill get online mid day to see if you are online and i will DM you then! @U04V70XH6

seancorfield20:10:15

We have Ring-based CORS running in production.