Fork me on GitHub
#beginners
<
2020-02-15
>
joshkh12:02:25

i don't know much quoting and splicing. how can i make the following return unqualified symbols?

(let [v 99]
  `(?entity :item/stock ~v))
=> (myproject.core/?entity :item/stock 99)
but instead return
(?entity :item/stock 99)

jsn13:02:35

@joshkh like this? (let [v 99] ('?entity :item/stock v))` ?

joshkh13:02:48

my hero! thanks @jason358

Michael J Dorian15:02:57

Hey friends, if namespace A requires namspace B, how do I get access to namespace A's symbols in namespace B without a cyclical dependency error? I'm using namespaces to separate concerns in my project, so namespace B isn't some sort of stand alone library. Thanks!

Jan K15:02:00

You have to avoid cyclical dependencies. Try refactoring your code, perhaps by making a 3rd shared namespace.

Ivan Koz15:02:32

isn't clojure skips require if it's already loaded?

Michael J Dorian15:02:52

So there are actually 4 namespaces, and the purpose of namespace A, core, is supposed to be to hold the symbols that are needed in every namespace, and then to require all of the "specific" namespaces. How would I restructure that so all I have access to certain symbols in every namespace?

Michael J Dorian15:02:16

It was supposed to be the thing you're suggesting but I clearly didn't quite understand 😁

Jan K16:02:23

You just can't have "certain symbols in every namespace" unless the namespace with those symbols doesn't depend on anything. Try to keep your dependencies minimal and explicit.

mbjarland16:02:03

without seeing your code it is hard to say, but usually in a situation like yours I have ended up breaking out the common/shared/whatever functions into a separate namespace, say common or utils or tools or something which des not depend on anything. Then you can use common from all your other namespaces and still tie everything together in say core

mbjarland16:02:42

but like @UCPGSBNQ4 said above, you need to think through be dependencies between namespaces

Michael J Dorian16:02:00

it sounds like the two things that core does, (define common behavior and load all of the files) are actually seperate tasks that should have separate namespaces. Thanks, I'll make "core" just be a bunch of requires and nothing else and move all it's code into "common"!

Michael J Dorian16:02:23

That worked!! Thanks a bunch simple_smile My "core" namespace is literally 8 lines of code now which bothers me a bit but I can get over it 😁

mbjarland16:02:42

Well if your core really is empty, perhaps you don't need it?

mbjarland16:02:44

I tend to see core as the place to stick my "central logic", at least for smaller projects.

mbjarland15:02:01

I have a question, I find myself writing first a lot in front of reduce calls where I keep some multi-value-state. I.e.:

(first
  (reduce
    (fn [[a i] x] [...])
    [[] state]
    coll))
I thought I saw a pattern once which made this cleaner than first, but can for the life of me not remember or find it. One way I guess is (let [[result _] (reduce …)]), but I thought I saw something better. Might seem nit-picky, but this shape has been bothering me for a while so figured I would ask

Alex Miller (Clojure team)16:02:01

seems fine to me, but another option might be to write it as a loop/recur and just return the value you need when you get to the termination condition - that lets you separate out the collection and the state more cleanly.

Alex Miller (Clojure team)16:02:26

(loop [a nil, i nil, state state, [x & xs] coll] (if x (...(recur a i state xs)) [a i]))

mbjarland16:02:23

Thank you @alexmiller - I think I have harboured some subconscious resistance to the loop construct, but now that I think about it I can't come up with any actual reasoning behind it...,perhaps time to let it go. Thanks for the pointer, on the spot as usual.

jumpnbrownweasel16:02:16

To avoid an explicit loop (which is often recommended when practical) another way is to keep using reduce but use reduced to short circuit and return the first value when it is found.

jumpnbrownweasel16:02:41

Here's an example.

(defn limited-sum [limit]
  (reduce
    (fn [acc n]
      (let [acc' (+ n acc)]
        (if (>= acc' limit)
          (reduced acc)
          acc')))
    (range)))

(limited-sum 1000)
=> 990

Ivan Koz17:02:36

can somebody explain what's up with that error, i'm running cursive and shadow-cljs nrepl, calling hello-world constructor generated by rum which should return ReactElement instance https://i.gyazo.com/53285d3705fc2decb3fae02baf387499.png

Ivan Koz17:02:29

is that cursive pretty-printing goes wild?

thheller17:02:36

react elements can't be printed

Ivan Koz17:02:12

in java every object has a toString method, in js every object is a dictionary as far as i know

Ivan Koz17:02:22

whats going on here, i'm really confused

Old account17:02:53

how to convert byte var to char

Ivan Koz17:02:24

(char 2r1000001)

βœ”οΈ 4
Old account17:02:31

how to conbine two bytes into int? I am getting 8 bytes from

(let [in (DataInputStream. (BufferedInputStream. (FileInputStream. "/dev/input/js0")))
        data (make-array Byte/TYPE 8)]
    (while true
      (let [result (.read in data)
data that is there documented in here https://www.kernel.org/doc/Documentation/input/joystick-api.txt So how to combine (nth data 4) (nth data 5) into an signed integer?

Ivan Koz17:02:48

can't you just sum them?

Old account18:02:13

I beliewe I should shift first var by 8 first

🎯 4
Jakob Durstberger18:02:34

I am using spacemacs with CIDER and clj. I pull the okhttp mockwebserver dependency and import it in a test file. Running the test from clj works fine, but when I eval ns from spacemacs it fails with a ClassNotFoundException. Any idea what I am doing wrong?

{:paths ["src"]
 :deps {org.clojure/clojure {:mvn/version "1.10.1"}
        amazonica {:mvn/version "0.3.152"}}
 :aliases
 {:test
  {:extra-paths ["test"]
   :extra-deps {org.clojure/test.check {:mvn/version "0.10.0"}
                com.cognitect/test-runner {:git/url ""
                                           :sha "f7ef16dc3b8332b0d77bc0274578ad5270fbfedd"}
                com.squareup.okhttp3/mockwebserver {:mvn/version "4.3.1"}}}

  :all
  {:main-opts ["-m" "cognitect.test-runner"
               "-d" "test"]}}}
test-file
(ns myproj.e2etests.rss-server-driver
  (:import [okhttp3.mockwebserver MockWebServer]))
Any help is appreciated :)

clement hamon20:02:37

Hi guys, quick question. Do you think it's mandatory to have a good Java experience before trying to find a career in Clojure? In fact, most of the "Clojure" jobs' description ask for a good understanding of Java and the JVM. I guess there is very few 100% Clojure jobs out there and the programmer will probably have to work with other technology based on the JVM.

athomasoriginal20:02:19

No. You can be good at Clojure and not know Java. There will be a point where you will want to lvl up and when this happens knowledge of Java will be an asset, but you can build to this knowledge.

jumar07:02:09

I’d say that at least a shallow understanding is quite useful but you can get very far without deep knowledge. It also depends a lot on the context (company, team, project)

mloughlin13:02:03

I've found that there are certain areas where you'll need to be able to understand the Java l;anguage's docs. Specifically in my case, working with File IO for more than what's available in

mloughlin13:02:23

I don't know Java at all. Sometimes there's something weird I can't immediately figure out but Java has so much info out there on Stack Exchange that it's hard to go too far wrong.

hindol14:02:34

I thought that's because it's so hard to find Clojure devs that companies are willing to hire Java devs and then train them.

tjb20:02:06

hey team i have a quick question regarding the Component lib. I was able to get a web server up and running and i am now trying to hook up a database. I have the following DB component file

(def pg-db
  "Connect map we will use to connect to PostgreSQL"
  {:dbtype "postgresql"
   :dbname "patentfitness"
   :host (System/getenv "DATABASE_HOST")
   :user (System/getenv "DATABASE_USER")
   :password (System/getenv "DATABASE_PASSWORD")})

(defn connect-to-database [config]
  (jdbc/get-datasource config))

(defrecord Database [config connection]
  component/Lifecycle
  (start [this]
    (println "Starting database...")
    (if conn
      this
      (let [conn (connect-to-database config)]
        (assoc this :connection conn))))
  (stop [this]
    (println "Stoping database...")
    (dissoc this :connection)))

(defn setup-database []
  (map->Database pg-db))
my question is how would i pass the DB as a constructor? assume i have something like this
(defn my-query [db]
  ;; do work)
when i call my-query what should i be passing into the db param?

Lennart Buit20:02:41

some people would pass the Database component itself, from which you can access to the connection via destructuring

tjb20:02:03

so something like (my-query database/Database) where Database is the defrecord?

Lennart Buit20:02:25

well an instance of that defrecord, which is typically part of the system and the component that is trying to reach the database got via its dependencies

tjb20:02:39

hmmm sorry i am not following. im pretty new to clojure 😞 if i access the defrecord it should just return the instantiated component, right?

Lennart Buit20:02:04

Oh no don’t apologize! Let me take one step back and explain more thoroughly!

❀️ 4
Lennart Buit20:02:55

In the component libraries, you have components and systems. You defined your database component, and a function to create that component. You did not yet specify a system

πŸ‘ 4
Lennart Buit20:02:20

This system defines the dependencies between components

Lennart Buit20:02:21

Lets say we have a system of a database connection and a webserver, then we could say that we have a system of two components: database and webserver, on which the webserver component depends on this database

tjb20:02:27

ah ok! yes this

(defn new-system
  "Set up our system map"
  ([port]
   (component/system-map :database (database/setup-database)
                         :web-server  (server/web-server port))))

Lennart Buit20:02:56

yes! thats your system definition, but you currently don’t have any dependencies between your components

Lennart Buit20:02:15

you can specify them using component/using

tjb20:02:15

hmmm, should there be in this web server and db case?

tjb20:02:30

im my web server function i have this

tjb20:02:31

(defn web-server
  "Map web server to component"
  ([port]
   (component/using (map->WebServer {:port port}) [])))

Lennart Buit20:02:34

well I can imagine that as part of handling a web request, you may want to access the database

tjb20:02:45

correct i do!

tjb20:02:56

so this web server should depend on the db

Lennart Buit21:02:29

I’d say yes

tjb21:02:17

gotcha which per this skeleton git repo and component repo should look like this

tjb21:02:18

(defn web-server
  "Map web server to component"
  ([port]
   (component/using (map->WebServer {:port port}) 
                    [:database])))

Lennart Buit21:02:22

I would specify that in my system map tho, to maintain overview of which components depend on what

Lennart Buit21:02:36

(defn new-system
  "Set up our system map"
  ([port]
   (component/system-map 
    :database (database/setup-database)
    :web-server (component/using (server/web-server port)
                                 [:database]))))

tjb21:02:57

ohhhhhhh i see

Lennart Buit21:02:00

(formatting went weird on slack)

tjb21:02:04

bringing the function to the top level for visibility

tjb21:02:17

awesome! that makes sense

tjb21:02:20

thank you so much!

Lennart Buit21:02:31

now, the component library promises you that the database component runs its start function before the web-server component, and assocs the database component into the web component

Lennart Buit21:02:55

the components are started in dependency order

tjb21:02:10

thats so awesome

tjb21:02:30

ok this is perfect thank you so much for explaining things to me @UDF11HLKC!this all makes sense now

Lennart Buit21:02:01

Don’t be afraid to ask for advice ^^! People hanging out in #beginners are probably here because they like helping

πŸ‘ 4
tjb21:02:06

another probably dumb question πŸ˜› cross post from #sql https://clojurians.slack.com/archives/C1Q164V29/p1581800277208200

Lennart Buit21:02:38

sounds like you are passing in a nil that should be something else

tjb21:02:43

hmmm from my example above the config param is nil

tjb21:02:55

but i thought i was passing it in because of (map->Database pg-db)

tjb21:02:08

ahhh but i guess since the 2nd param is nil it blows up?

Lennart Buit21:02:36

which function are you calling, the error doesnt say

tjb21:02:59

interestingly if i do this it works

tjb21:02:00

(defn setup-database []
  (map->Database {:config pg-db}))

tjb21:02:06

vs

(defn setup-database []
  (map->Database pg-db))

tjb21:02:23

the error was happening in the defrecord

tjb21:02:26

(defrecord Database [config connection]
  component/Lifecycle
  (start [this]
    (println "Starting database...")
    (if connection
      this
      (let [conn (jdbc/get-datasource config)]
        (assoc this :connection conn))))
  (stop [this]
    (println "Stoping database...")
    (dissoc this :connection)))

Lennart Buit21:02:00

defrecords have two constructors

tjb21:02:11

yeah thats where i messed up

Lennart Buit21:02:28

map->Database which takes a map and gives you a record instance, and ->Database which takes a positional list of arguments

‼️ 4
βœ”οΈ 4
tjb21:02:32

it is cool if i do

(defn setup-database []
  (map->Database {:config pg-db}))
clojure is smart enough to set config to pg-db and leave connection nil

Lennart Buit21:02:05

(actually there is a third, but you can forget about that for now)

tjb21:02:09

i think im getting the hang of things

tjb21:02:22

sorta πŸ˜›

tjb21:02:23

thanks again for rubber ducking with me Lennart!

Michael Stokley21:02:14

I'm writing an http server that uses the clj-http library. I'd like to pass in the post and get functions as parameters explicitly so I can pass in mocks when testing. I have two questions - 1) does that seem like a good design? 2) If so, is the most idiomatic way to accomplish that to wrap up clj-http.client/get and clj-http.client/post into a map and pass it around, like this?

(def my-http-client-wrapper {:get clj-http.client/get :post clj-http.client/post})

Michael Stokley05:02:20

oh no kidding! thanks @USGKE8RS7

Kamuela23:02:59

Let, when defining promises, allow those promises to leak into global scope?

seancorfield23:02:17

@kamuela Not quite sure what you're asking -- can you share code that relates to the question?