Fork me on GitHub
#clojure
<
2021-05-12
>
rossputin13:05:04

hey all - bit of a lazyweb question really but I’m sure someone has posted about it sometime - I’m trying to build a transformation pipeline over a sequence based on a couple of query-params in an API call - there are a number of boilerplate and ‘ugly’ ways I can do it but I’m hoping there is something elegant/idiomatic that someone can point me to - thanks!

Noah Bogart13:05:24

what have you tried?

Noah Bogart13:05:42

or maybe, What does "boilerplate and ugly" mean to you?

rossputin13:05:38

Hey - I’ve put it together with a condp in the first go - works but does not feel right - was thinking about cond->> maybe next

Noah Bogart14:05:37

there's nothing wrong with using condp if that's what works for you. it's a solid function that's well understood

Noah Bogart14:05:36

another idea, as i'm thinking about it, is to move both the predicate check and the change to functions so you just use ->> and then can just list each potential change in a row, and the functions say (if (pred input) (apply-fn input) input). that's "cleaner" than cond->> but has other issues (like having to repeat/keep track of the if branches)

localshred15:05:52

May be checkout as->, it let's you set a binding name (usually $) and thread your calls, placing the result wherever makes most sense for the next fn call in the thread

☝️ 2
rossputin16:05:52

thanks all - I’ll have a play with some of this later on - good to crowdsource some methods 🙂

ivana17:05:32

Hello! Can I somehow start a delayed action in current (!) thread withiout blocking current thread? This way also evaluates action in another thread:

(def d (do
         (prn "initial thread" (.getId (Thread/currentThread)))
         (delay (prn "delay thread" (.getId (Thread/currentThread))))))

(future (Thread/sleep 5000) @d)

emccue17:05:40

if you block your thread you block your thread

emccue17:05:53

if you don't want to block your thread you need to work on another thread

emccue17:05:09

kinda as simple as that unless you want to make manual state machines

ivana17:05:33

Thanks. It's a pity, if so

dpsutton17:05:53

you'd need to make your own coordination. basically a loop look for tasks, which would block the thread. but this seems to be a necessity. consider if your thread went into an infinite loop calculating primes. how would this other unit of work interrupt that infinite loop and get its work done? What problem are you trying to solve though?

ivana17:05:59

Actually I tried to sole a problem with starting my own custom REPL when lein starts with its profile. But I just solved it - before I put code starting my REPL in :injections or :repl-options :init and it crashes leins Repl-y, I tried to make a delay without blocking current thread, or starting my REPL in another thread, but I found out that _:welcome_ calls after them all and put it here seems to be working.

ivana17:05:28

Looks like I found working configuration 🙂

:bb-repl {:dependencies [[bb-repl "0.0.1"]]
          ;;  :injections [(use '[bb-repl.repl :as bb])] or keep it here instead of :welcome
           :repl-options {:welcome (do
                                     (println "Welcome to bb-repl!")
                                     (use '[bb-repl.repl :as bb])
                                     (bb-repl.repl/start))}}

haywood19:05:53

Dockerfile:

FROM clojure:latest

RUN clojure -e "(clojure-version)"
but I get: /bin/sh: 1: clojure: not found Anyone run into this? Feel like I’m going mad, probably something stupid on my end. The latest tag does install Clojure

yunior21:05:44

I’m no sure if it’s going to be helpful for you but I was able to run an app using docker-compose like this:

yunior21:05:10

version: "3.8"

services:
  clojure:
    image: clojure:openjdk-8-tools-deps-1.10.1.536-buster
    working_dir: /app
    entrypoint: ["clojure", "-R:nREPL", "-m", "hello"]
    volumes:
      - ./code:/app
      - ~/.m2:/root/.m2
    ports:
      - "9500:9500"

yunior21:05:58

And later connect to the repl from my host OS using VS Code (Calva)

yunior21:05:36

I was using it to teach someone clojure and that person was able to replicate that in his computer.

Alex Miller (Clojure team)19:05:18

which version of clojure CLI?

Alex Miller (Clojure team)19:05:46

I guess maybe you can't run it to see :)

Alex Miller (Clojure team)19:05:58

can you see the output of running the install there?

haywood19:05:59

should be at least 😅

jdkealy19:05:35

I've been having trouble all day trying to connect to a mysql host in RDS. I'm able to connect to a local Mysql on my machine, I'm able to connect via the command line on the host I'm using, but when trying to use jdbc

(let [db-host "my-rds-host"
      db-port 3306
      db-name "lms"]
  (def mysql-db {:subprotocol "mysql"
                 :subname (str
                           "//"
                           db-host
                           ":"
                           db-port
                           "/"
                           db-name)
                 :user "admin"
                 :password "rootroot"}))
I've tried the above, and also using a :host parameter. Any advice on how to debug this ?

jdkealy19:05:13

I have [org.clojure/java.jdbc "0.7.12"] in project.clj

haywood19:05:43

are you trying to pass mysql-db map to the various j/* functions?

haywood19:05:48

is that variable in scope?

haywood19:05:52

what’s the error you get?

haywood19:05:04

what’s the value of the (println mysql-db)

jdkealy19:05:19

(defn get-schools [& [{:keys [limit]}]]
  (j/query mysql-db
           [(str  "select * from school "
                  (when limit (str "limit " limit)))]))

jdkealy19:05:28

yes the var is in scope

jdkealy19:05:39

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet successfully received from the server was 1 milliseconds ago.  The last packet sent successfully to the server was 1 milliseconds ago.

jdkealy19:05:37

also tried it like this

(let [db-host "rds-host"
      db-port 3306
      db-name "lms"]
  (def mysql-db {:dbtype "mysql"
                 :dbname "lms"
                 :host db-host
                 :user "admin"
                 :password "rootroot"
                 :ssl true
                 :sslfactory "org.postgresql.ssl.NonValidatingFactory"}))

haywood19:05:39

unless everything is inside that let form top level functions wouldn’t have access to it

seancorfield19:05:00

@U1DBQAAMB Feel free to ask in #sql — there may be folks there using RDS.

seancorfield19:05:29

I’d be a bit surprised if PostgreSQL was on port 3306 though — that’s normally MySQL.

seancorfield19:05:26

Given your :dbtype say "mysql" and your port is 3306, I’d say the :sslfactory attribute is wrong.

jdkealy19:05:18

right sorry i had just copy/pasted that.

jdkealy19:05:37

i'll try to find the mysql equivilant if any

seancorfield19:05:55

And I think for MySQL, it would be :useSSL true (or false), not :ssl, but it depends on what RDS is expecting in the connection string.

jdkealy19:05:07

that was it!

jdkealy19:05:17

:useSSL false

seancorfield19:05:27

Not recommended from a security p.o.v. 🙂

jdkealy21:05:36

i'm just importing a legacy db into datomic 🙂

p20:05:45

Hi, if I need to recurse when implementing a protocol function, is there a difference between calling recur or the protocol function by name?

Alex Miller (Clojure team)20:05:56

probably 1 stack frame of difference :)

p20:05:39

Thanks @alexmiller, good to know! Was initially worried calling recur wouldn't result in a type dispatch.

Alex Miller (Clojure team)21:05:21

it won't if I understand what you're suggesting

Alex Miller (Clojure team)21:05:00

in the recur case, I believe the type dispatch would happen once, after that it would just be a normal loop/recur back to function target

Alex Miller (Clojure team)21:05:42

so even if you recur'ed with a value of a different type, it's not going to "escape" the method body you're in

Alex Miller (Clojure team)21:05:28

if you want that, you need to re-call the protocol function (and you'll incur a stack frame)

p21:05:12

Interesting, thank you for pointing this out. In the case where I'm worried about incurring stack frames (and I need to re-dispatch on recur), would condp instance? be the better alternative for type dispatch?

emccue21:05:54

you probably want to trampoline at that point

emccue21:05:04

which is recur but for mutual recursion

Alex Miller (Clojure team)21:05:39

I'm not sure if that works through a protocol call, would have to try it tbh

Alex Miller (Clojure team)21:05:33

I think it should based on my mental model?