beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
vinurs 2021-07-02T03:25:55.352300Z

hello, i hava a java file in src/java/vinurs/utils named http://hellojava.java and in lein project.clj i set :java-source-paths ["src/java"] :prep-tasks ["javac" "compile"] in my src/clj/app/core.clj i import it (:import (vinurs.utils HelloJava)) then when i in shell run lein repl, it output

Caused by: java.lang.ClassNotFoundException: vinurs.utils.HelloJava
then i have to comment the import (:import (vinurs.utils HelloJava)) in core.clj then run lein repl, this time it compile the java file to .class this time i restore the import , then run lein repl it works ok

vinurs 2021-07-02T03:26:55.353200Z

everytime i add a java file, i should do like this? comment the import?then lein javac, then import it?

2021-07-02T03:28:05.353800Z

It is because of the order of your prep tasks

vinurs 2021-07-02T03:28:57.354200Z

@hiredman how to resolve this problem?

Pradeep B 2021-07-02T03:30:37.354300Z

maybe by moving :prep-tasks first in the sequence.

2021-07-02T03:31:40.355300Z

No, sorry, I was misremembering but my guess is you have an issue like what is described here https://github.com/technomancy/leiningen/blob/master/doc/MIXED_PROJECTS.md#interleaving-compilation-steps

vinurs 2021-07-02T03:54:26.355500Z

thanks, this is what i need

olaf 2021-07-02T08:27:48.358900Z

Cljs+Reagent. A simple menu div that append an event listener to the document and decide if the document click is inside or outside the component. I expect the handler to be called first, but the output is "second" and then "first". Why? Is caused from the re-rendering that add the component on-click listener multiple times?

(defn menu [mouse-pos]
  (r/with-let [!menu-ref (atom nil)
               handler   (fn [evt]
                           (console-log "first")
                           (when (and @!menu-ref
                                      (not (.contains @!menu-ref
                                                      (.-target evt))))
                             (console-log "outside")))
               _         (.addEventListener js/document "click" handler)]
    [:div.UI-menu {:style {:top  (:y mouse-pos)
                           :left (:x mouse-pos)}
                   :ref #(reset! !menu-ref %)
                   :on-click #(console-log "second")}
     "Adjust Diameter"]
    (finally
      (.removeEventListener js/document "click" handler))))

lepistane 2021-07-02T10:29:33.362500Z

Hello, i've got general question about security. So i have a website and i would like traffic to be encrypted/hidden even for the client. Basically web app will know how to de-crypt it. I've never done this, i never heard about this, i dont think this is practice. Basically i want website to be usable but all traffic that it receives is hidden/unreadable/encrypted Is there a way for this to be done?

2021-07-02T10:31:01.362600Z

Typically using https protocol should be enough.

dgb23 2021-07-02T10:41:47.362800Z

I was thinking of https too but: > So i have a website and i would like traffic to be encrypted/hidden even for the client.

dgb23 2021-07-02T10:41:58.363Z

makes me suspcious

dgb23 2021-07-02T10:43:20.363200Z

Either the client can read the data or not. A web application is open to the client.

lepistane 2021-07-02T11:35:49.364200Z

Yeah that makes sense. Like even if i do some voodoo JS functions that will decrypt that voodoo are still available for reading. Oki guys thanks

Apple 2021-07-02T11:35:59.364400Z

what's the point of communication, perhaps you mean client(human) cannot read but client(program) can read?

max minoS 2021-07-02T11:47:51.366300Z

I'm trying to multiply all digits in a number together (e.g. 729 => 7 2 9), and so far I have

(->> digits
    str
    seq
    (map Integer/parseInt)
    (reduce *))
but I see that I cant do those functions to a sequence, which returns (\7 \2 \9), what does this mean?

dgb23 2021-07-02T11:49:09.366500Z

@zengxh that would have been the idea it seems. However, simply not sending the data they shouldnt be able to read is the only robust solution and is typically less work than trying to obfuscate. The visibility (authorization) logic has to live somewhere anyways.

tws 2021-07-02T11:51:00.366800Z

those are literal chars. try doing (map #(Character/getNumericValue %) s)) instead

tws 2021-07-02T11:51:44.367Z

also, you don’t need to seq a string. they have that abstraction on them already.

👍 1
max minoS 2021-07-02T11:53:51.367300Z

is the Character/ a default library that I can always call without requiring?

pithyless 2021-07-02T11:56:14.367500Z

Integer and Character are both classes from java.lang (which is available by default in CLJ)

pithyless 2021-07-02T11:57:12.367700Z

you're actually calling a static method in this example: https://docs.oracle.com/javase/8/docs/api/java/lang/Character.html#getNumericValue-char-

🙏 1
pithyless 2021-07-02T11:57:59.368Z

there's also a different way of splitting a string you should be aware of:

user=> (seq (str 123))
(\1 \2 \3)

user=> (clojure.string/split (str 123) #"")
["1" "2" "3"]

pithyless 2021-07-02T11:58:54.368200Z

In the first example you get back java Characters (the slashes are the giveaway); in the latter you get back strings (where you can then call Integer/parseInt )

max minoS 2021-07-02T12:02:27.368400Z

thank you so much, I've used the clojure.string/split before but I seq being used a lot when I google so I thought it might be better

lepistane 2021-07-02T12:05:23.368600Z

weirdly i just want client to see the data they way i present it but not be able to read the data from response in json.

lepistane 2021-07-02T12:06:33.368800Z

maybe obfuscate route is the way to go since authorization is solved. client won't see what i don't want him to see, but i want him to see data only via website if he calls api directly to receive jiberish that only website can read

lepistane 2021-07-02T12:07:26.369100Z

hopefully it makes sense what i am asking

pithyless 2021-07-02T12:08:40.369300Z

The two are semantically different (and both have their place). When you split a string, you're saying split this one string into a collection of smaller, disjoint strings. When you seq you are iterating over a sequence (iterating over a string returns it's characters one-by-one).

pithyless 2021-07-02T12:10:44.369500Z

I think Brave Clojure probably gives a much better explanation :) https://www.braveclojure.com/core-functions-in-depth/

🙏 1
dgb23 2021-07-02T12:28:14.371Z

well you can use something like messagepack or some other binary format. but those things wont help if they are technically adept. a CSRF token can at least give you some control over who can read from your API. I guess if you are just worried about cosmetics, then just put your stuff into a binary format, they typically have some good performance characteristics too.

lepistane 2021-07-02T13:16:57.371300Z

makes sense, thanks

practicalli-john 2021-07-02T13:29:30.375100Z

I have a project that will use AWS Dynamo to hold some key-value pairs, so wondering what recommendations people had on using it from Clojure. The value can be a string and I guess I can map between a keyword and what ever AWS Dynamo uses. https://github.com/Taoensso/faraday seems to be a common choice to access the AWS Dynamo API It seems pretty straightforward. Any thumbs up for this approach or other alternatives people have found useful. Thank you.

bigos 2021-07-02T15:40:08.378500Z

I use clj to create a library jar. how do I use that jar in and based java project?

bigos 2021-07-02T15:40:52.379300Z

i tried to copy generated jar but do not know how to use it on java side. the documentation is a bit confusing

alexmiller 2021-07-02T15:41:54.380100Z

Java only runs bytecode, so you need some hook into compiled Clojure. there are several ways to do this:

alexmiller 2021-07-02T15:43:38.382100Z

• pre-compile your Clojure code into bytecode with classes with static methods, then call into those • use the https://clojure.github.io/clojure/javadoc/clojure/java/api/Clojure.html to start the Clojure runtime, load vars, and invoke them (compiles dynamically from Clojure source) • other variants of the above, but those are the most common

bigos 2021-07-02T15:44:56.383200Z

i do not understand such vague details, my apologies. i use deps.edn https://github.com/bigos/Pyrulis/blob/master/Clojure/deps.edn

bigos 2021-07-02T15:45:17.384Z

clj -X:jar :jar csvreport.jar

bigos 2021-07-02T15:45:54.385100Z

then i copy the jar file to the libs folder of netbeand based project and add the jar in netbeans properties

bigos 2021-07-02T15:46:23.385600Z

i do not know how to import the code and use it on java side

bigos 2021-07-02T15:47:14.386Z

you say precompile clojure into bytecode

bigos 2021-07-02T15:47:40.386600Z

looking into the jar file doe not show similar content to other java jars

bigos 2021-07-02T15:47:52.386900Z

it just contins raw clojure files

alexmiller 2021-07-02T15:48:54.387600Z

yeah, if you read the depstar docs, you need to AOT compile the jar as well by specifying :compile-ns etc

alexmiller 2021-07-02T15:50:56.388Z

what code do you want to run?

bigos 2021-07-02T15:52:58.388600Z

i want to run simple clojure hello world and point it on java side

bigos 2021-07-02T15:53:28.389300Z

I have noticed the deps.edn that i follow has changed, should I update it?

alexmiller 2021-07-02T15:56:31.389600Z

sorry, don't know the answer to that

alexmiller 2021-07-02T15:56:59.390300Z

what existing function do you want to run? I'm trying to be less vague for you

bigos 2021-07-02T15:57:22.390800Z

thank you for being honest 🙂 it is complex and requires patience

bigos 2021-07-02T15:58:05.391700Z

i have updated deps.edn and will try compiling again keeping your suggestions in mind. I may have more specific questions later

bigos 2021-07-02T15:58:39.391900Z

(ns sgs.lidlcsvreport) (defn foo "I don't do a whole lot." [x] (prn x "Hello, World!"))

bigos 2021-07-02T15:59:03.392400Z

this is my clojure code that i want run on java side

bigos 2021-07-02T15:59:31.392900Z

hopefully it will let me escape from the insanity of java type system

alexmiller 2021-07-02T16:00:02.393400Z

if you don't want to aot compile, you can use the Clojure Java API to load and compile this on the fly

bigos 2021-07-02T16:01:55.395300Z

jacekp@EID6043:~$ clj --help| grep Version Version: 1.10.1.727 jacekp@EID6043:~$ java -version java version "1.8.0_162" Java(TM) SE Runtime Environment (build 1.8.0_162-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, mixed mode)

bigos 2021-07-02T16:02:15.395800Z

for the old java i use, which one is better?

alexmiller 2021-07-02T16:03:17.396600Z

import clojure.java.api.Clojure;
import clojure.lang.IFn;
...

// (require 'sgs.lidlcsvreport)
IFn require = Clojure.var("clojure.core", "require");
require.invoke(Clojure.read("sgs.lidlcsvreport"));

// (sgs.lidlcsvreport/foo "HI")
IFn foo = Clojure.var("sgs.lidlcsvreport", "foo");
foo.invoke("HI");

alexmiller 2021-07-02T16:03:38.396900Z

on the Java, doesn't matter, anything ≥ Java 1.8 is fine

alexmiller 2021-07-02T16:04:05.397300Z

(that version is pretty old and missing a lot of security fixes though fyi)

bigos 2021-07-02T16:06:27.398Z

there is nothing I can do about the decade of compromise 🙂

bigos 2021-07-02T16:06:48.398500Z

hopefully, it that works we can gradually make progress

bigos 2021-07-02T16:08:13.399Z

if I import clojure, how do I add clojure to the project?

bigos 2021-07-02T16:08:54.399700Z

i can copy a jar file in the project lib folder and add the jar to project proprties

alexmiller 2021-07-02T16:09:16.400Z

if I understood correctly, you're building an uber jar that will include clojure

bigos 2021-07-02T16:09:44.400500Z

ah, so how do i import that uberjar into clojure?

alexmiller 2021-07-02T16:10:27.401300Z

an uberjar is the code from a project + all the code from its dependencies. in this case, the dependency includes clojure (which is just pulled in as a library)

alexmiller 2021-07-02T16:10:43.401700Z

so the uberjar you build in your project includes your project's code and clojure itself

alexmiller 2021-07-02T16:11:28.402500Z

if you did need to include clojure, it's on Maven Central like everything else - groupId= org.clojure, artifactId = clojure, latest version = 1.10.3

bigos 2021-07-02T16:12:41.402700Z

clj -X:uberjar :jar ./lidlcsvreport.jar :main-class sgs.lidlcsvreport

bigos 2021-07-02T16:13:27.403100Z

now the sgs has 'lidlcsvreport$fn__140.class' lidlcsvreport.clj 'lidlcsvreport$foo.class' lidlcsvreport__init.class 'lidlcsvreport$loading__6738__auto____138.class'

bigos 2021-07-02T16:14:06.403400Z

how do i import that on java side

bigos 2021-07-02T16:14:09.403600Z

?

alexmiller 2021-07-02T16:15:58.403900Z

the code I posted above

bigos 2021-07-02T16:18:27.404600Z

i will try it, we are on something because java ide tries to be helpful about the package

bigos 2021-07-02T16:19:19.405100Z

ide complains saying class interface or enum expected

alexmiller 2021-07-02T16:21:57.405400Z

are the Clojure classes in your jar?

alexmiller 2021-07-02T16:22:19.405900Z

if not, then you have a jar, not an uberjar and you will need to include Clojure as a dependency

bigos 2021-07-02T16:24:09.406400Z

clj -X:uberjar :jar ./lidlcsvreport.jar :main-class sgs.lidlcsvreport i have tried that, what options i am missing

bigos 2021-07-02T16:25:22.406800Z

the project deps.edn has alias for deploy

bigos 2021-07-02T16:25:29.407Z

should i try that?

alexmiller 2021-07-02T16:26:55.407200Z

I don’t think so

alexmiller 2021-07-02T16:27:11.407600Z

Sorry, I need to step away for a bit

bigos 2021-07-02T16:28:51.408Z

no problem 🙂

bigos 2021-07-02T16:36:17.408300Z

import clojure.java.api.Clojure; now ide says it is unused import

bigos 2021-07-02T16:36:44.408500Z

IFn require = Clojure.var("clojure.core", "require"); has the error

bigos 2021-07-02T16:36:52.408700Z

IFn require = Clojure.var("clojure.core", "require");

bigos 2021-07-02T16:44:21.408900Z

code compiles

bigos 2021-07-02T16:44:31.409200Z

import clojure.java.api.Clojure; import clojure.lang.IFn; import sgs.lidlcsvreport$foo;

bigos 2021-07-02T16:44:52.409500Z

what do I do about the foo?

bigos 2021-07-02T16:58:46.410Z

i think I am making progress now. than you very much for your help

bigos 2021-07-02T16:58:55.410200Z

🙂

2021-07-02T17:43:22.412200Z

in terms of security, the client has full access to the js vm, and controls that vm implementation, there's nothing you can do that actually hides anything reliably in client code

2021-07-02T17:43:39.412400Z

obfuscation is possible but can't be relied on

2021-07-02T17:45:05.412800Z

seq is called implicitly many places in clojure, including map and reduce

2021-07-02T17:45:27.413Z

user=> (map str "hello")
("h" "e" "l" "l" "o")

2021-07-02T17:46:42.413400Z

> you don’t need to seq a string. they have that abstraction on them already @tws almost - any clojure.core sequential function calls seq for you

2021-07-02T17:47:25.413900Z

usually, you only need to call seq in your own code when using interop with something outside clojure, or when you need the behavior of empty meaning nil which means false

👍 1
2021-07-02T17:49:27.414700Z

what you do about the foo is you remove the import, use Clojure.var to reference it like alex has above

Yosevu Kilonzo 2021-07-02T18:58:57.418200Z

Hello! Is there an idiomatic way to thread data through converging functions similar to https://ramdajs.com/docs/#converge?

// JavaScript

const data = { a: 3, b: 4 }

pipe(
  converge(add, [prop('a'), prop('b')]),
  fn2,
  fn3
)
This is what I have:
(+ (:a data) (:b data)) // 7
And I want to do something like:
;; Clojure

(def data {:a 3 :b 4})

(-> data
    (something :a :b +)
    fn2
    fn3)

indy 2021-07-02T19:08:11.419800Z

Something like (apply converge-fn ((juxt f g h) input))

dpsutton 2021-07-02T19:08:47.420500Z

(defn something [x fns f] (apply f ((juxt fns) x))

1
2021-07-05T15:33:38.497Z

that should be (apply juxt fns) in there I think

dpsutton 2021-07-05T15:41:21.499500Z

Ah yeah. Good point

Yosevu Kilonzo 2021-07-02T19:11:33.421500Z

Ah, thanks indy and dpsutton. I'll experiment with that!

sova-soars-the-sora 2021-07-02T19:43:44.421900Z

apply and juxt seem to be super powerful

tws 2021-07-02T20:03:36.422200Z

how do people perform benchmarking?

tws 2021-07-02T20:04:16.422300Z

I see

Aliases in the deps.edn file can also be used to add optional dependencies that affect the classpath:

{:aliases
 {:bench {:extra-deps {criterium/criterium {:mvn/version "0.4.4"}}}}}
Here the :bench alias is used to add an extra dependency, namely the criterium benchmarking library.

You can add this dependency to your classpath by adding the :bench alias to modify the dependency resolution: clj -A:bench.
from https://clojure.org/guides/deps_and_cli but do you just run clj -A:bench and do stuff from a repl? Not sure how to integrate this from my REPL driven approach. right now it seems easier to require criterium and have some rich comment forms. (using CIDER/emacs)

seancorfield 2021-07-02T20:05:49.422700Z

Yes, criterium's README should show examples of how to run from a REPL -- which you could do from a Rich Comment Form in a source file.

seancorfield 2021-07-02T20:08:21.423Z

(! 738)-> clj -A:bench
Downloading: criterium/criterium/maven-metadata.xml from clojars
Clojure 1.10.3
user=> (require '[criterium.core :refer [bench quick-bench]])
nil
user=> (bench (reduce + (range 10000)))

seancorfield 2021-07-02T20:09:36.423200Z

(time passes)

Evaluation count : 549420 in 60 samples of 9157 calls.
             Execution time mean : 107.444260 µs
    Execution time std-deviation : 5.941988 µs
   Execution time lower quantile : 101.784873 µs ( 2.5%)
   Execution time upper quantile : 125.506758 µs (97.5%)
                   Overhead used : 8.115184 ns

Found 6 outliers in 60 samples (10.0000 %)
	low-severe	 2 (3.3333 %)
	low-mild	 4 (6.6667 %)
 Variance from outliers : 40.1884 % Variance is moderately inflated by outliers

phronmophobic 2021-07-02T20:13:17.423400Z

I've found the clojure-goes-fast blog posts generally helpful, http://clojure-goes-fast.com/blog/

tws 2021-07-02T20:14:46.423700Z

sorry, @seancorfield i wasn’t clear. i know how to do it, but my execution feels clunky, so wondering how others run any periodic benchmarks.

tws 2021-07-02T20:15:28.423900Z

thanks, I’ll stick with RCF for now.

seancorfield 2021-07-02T20:18:51.424100Z

Yup, RCFs in the code is how I'd deal with this.

tws 2021-07-02T20:20:27.424300Z

is it weird to have criterium in your deps.edn :deps if it’s only used for RCF? Or is there another way to get it on the classpath?

ghadi 2021-07-02T20:25:48.424500Z

put it in an alias and add the alias when you are developing or benchmarking

1
seancorfield 2021-07-02T20:43:59.424800Z

I think a lot of folks have a :dev alias that adds in all sorts of dev-only tooling (Polylith encourages that approach: :dev for dev-only stuff, :test for test-only stuff, so you start your REPL with clj -A:dev:test or similar)

greg 2021-07-02T20:50:42.428500Z

It looks like it is possible to have a multi-arity anonymous function. How to call anonymous fn with 1 arg from the one with no args?

(defn fun []
  (fn 
    ([] :call-anon-with-random)
    ([x] {:x x})))

; expected:
((fun))    ; => {:x :random}
((fun) :A) ; => {:x :A}

alexmiller 2021-07-02T20:52:56.428900Z

I think you mean def there (or you don't need the fn part)

greg 2021-07-02T20:54:25.430800Z

This is simplified example, I want to use higher-order function and create a (fn) with optional argument

alexmiller 2021-07-02T20:54:43.431Z

there is no magic here - if you want to invoke a thing, you either need the instance or a name to refer to it

greg 2021-07-02T20:55:00.431300Z

oh, ok

alexmiller 2021-07-02T20:56:26.432200Z

you can use & to make optional arguments and then parse the args and handle both cases

phronmophobic 2021-07-02T20:57:36.432900Z

What about?

(def fun
  (fn my-fn
    ([] (my-fn :random))
    ([x] {:x x})))

(fun) ;; {:x :random}
(fun 42) ;; {:x 42}
(my-fn) ;; Unable to resolve symbol: my-fn in this context

👍 1
greg 2021-07-02T20:58:54.433200Z

this is it

1
greg 2021-07-02T21:00:05.433500Z

actually I realised that I can call defn from another defn as well

(defn fun []
  (defn anon
    ([] (anon :random))
    ([x] {:x x})))
but yours way is better. I didn't know that fn can have a name 😄

😁 1
tws 2021-07-02T21:29:18.433900Z

defn is just shorthand or the long-form fn invocation. ps. that’s a first for me, seeing a todo in the source.

Clojure 1.10.3
user=> (source defn)
(def
...
defn (fn defn [&form &env name & fdecl]
...
;;todo - restore propagation of fn name
...

Elias Elfarri 2021-07-02T21:44:13.437900Z

Hello, I need help with using the chestnut template. I've been able to develope in re-frame and cljs with figwheel and i wanted to take it a step further and try to connect it to some sort of backend. So i setup a chestnut project, how ever i am very unexperienced with compojure/ring and everything todo with server side stuff. So i really need help with setting up extra routes with compojure in said environment. There is a route.clj that has the following code in it:

(defn home-routes [endpoint]
  (routes
   (GET "/" _
     (-> "public/index.html"
         io/resource
         io/input-stream
         response
         (assoc :headers {"Content-Type" "text/html; charset=utf-8"})))
   (resources "/")))
I would like to add extra routes to it and thought that i could just do that by adding another GET just like this:

Elias Elfarri 2021-07-02T21:45:28.439200Z

(defn home-routes [endpoint]
  (routes
   (GET "/" _
     (-> "public/index.html"
         io/resource
         io/input-stream
         response
         (assoc :headers {"Content-Type" "text/html; charset=utf-8"})))
   (GET "/bar" [] ("Please Work"))
   (resources "/")))
But this, does unfortunately not work. Does anyone here know why or what i am doing wrong here? I basically want to be able to access a link "localhost:10555/bar", but nothing really shows up when i do this.

sova-soars-the-sora 2021-07-02T21:52:02.441700Z

Hi @moelfarri good job so far. You need to return a "ring response map" from your server which takes the form

{:status 200
 :headers {"Content-Type" "text/html"}
 :body "Your string or HTML here."
}
In the GET above yours that works already, you can see it is threading together index.html and a function called response and associating into that map the key :headers You can rearrange this a bit so it's more convenient to write new routes. There is a defroutes macro that you can use to define new routes rather than operating each one as a new io/resource. Let me see if I can find a brief example for you.

sova-soars-the-sora 2021-07-02T21:55:23.442300Z

This page might help (and hopefully not confuse you) https://github.com/ring-clojure/ring/wiki/Concepts#requests This page about using Compojure ought to be very helpful to you @moelfarri https://learnxinyminutes.com/docs/compojure/