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)

jason35813:02:35

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

joshkh13:02:48

my hero! thanks @jason358

doby16215: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!

jkr.sw15:02:00

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

k.i.o15:02:32

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

doby16215: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?

doby16215:02:16

It was supposed to be the thing you're suggesting but I clearly didn't quite understand ๐Ÿ˜

jkr.sw16: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 @ said above, you need to think through be dependencies between namespaces

doby16216: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"!

doby16216: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

alexmiller16: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.

alexmiller16: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.

mark54016: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.

mark54016: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

k.i.o17: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

k.i.o17:02:29

is that cursive pretty-printing goes wild?

thheller17:02:36

react elements can't be printed

k.i.o17:02:12

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

k.i.o17:02:22

whats going on here, i'm really confused

stebokas17:02:53

how to convert byte var to char

k.i.o17:02:24

(char 2r1000001)

stebokas17: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?

k.i.o17:02:48

can't you just sum them?

stebokas18:02:13

I beliewe I should shift first var by 8 first

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 :)

clementhamon20: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.

tkjone20: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)

michael.e.loughlin13: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

michael.e.loughlin13: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.

hindol.adhya14: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!

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

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 @!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

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

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!

michael74021: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})

michael74005:02:20

oh no kidding! thanks @

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?