clojure

New to Clojure? Try the #beginners channel. Official docs: https://clojure.org/ Searchable message archives: https://clojurians-log.clojureverse.org/
rossputin 2021-05-12T13:52:04.300Z

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!

NoahTheDuke 2021-05-12T13:57:24.300200Z

what have you tried?

NoahTheDuke 2021-05-12T13:57:42.300600Z

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

rossputin 2021-05-12T13:59:38.300700Z

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

NoahTheDuke 2021-05-12T14:20:37.300900Z

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

NoahTheDuke 2021-05-12T14:52:36.301100Z

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)

localshred 2021-05-12T15:06:52.301300Z

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

☝️ 1
rossputin 2021-05-12T16:11:52.301600Z

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

2021-05-12T17:07:32.303800Z

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)

emccue 2021-05-12T17:11:24.304100Z

@ivana Thread/sleep

emccue 2021-05-12T17:11:40.304400Z

if you block your thread you block your thread

emccue 2021-05-12T17:11:53.304700Z

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

emccue 2021-05-12T17:12:09.305100Z

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

2021-05-12T17:15:33.305800Z

Thanks. It's a pity, if so

dpsutton 2021-05-12T17:20:53.307200Z

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?

2021-05-12T17:26:59.311300Z

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.

2021-05-12T17:34:28.312500Z

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

haywood 2021-05-12T19:16:53.314800Z

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

alexmiller 2021-05-12T19:24:18.315400Z

which version of clojure CLI?

alexmiller 2021-05-12T19:24:46.315700Z

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

haywood 2021-05-12T19:25:59.316300Z

should be at least 😅

jdkealy 2021-05-12T19:28:35.317900Z

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 ?

jdkealy 2021-05-12T19:29:13.318Z

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

alexmiller 2021-05-12T19:29:58.318200Z

can you see the output of running the install there?

haywood 2021-05-12T19:30:43.318400Z

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

haywood 2021-05-12T19:30:48.318600Z

is that variable in scope?

haywood 2021-05-12T19:30:52.318800Z

what’s the error you get?

haywood 2021-05-12T19:31:04.319Z

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

jdkealy 2021-05-12T19:31:19.319200Z

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

jdkealy 2021-05-12T19:31:28.319400Z

yes the var is in scope

jdkealy 2021-05-12T19:31:39.319600Z

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.

jdkealy 2021-05-12T19:35:37.319800Z

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"}))

haywood 2021-05-12T19:38:39.320Z

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

seancorfield 2021-05-12T19:40:00.320200Z

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

seancorfield 2021-05-12T19:41:29.320400Z

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

seancorfield 2021-05-12T19:42:26.320600Z

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

jdkealy 2021-05-12T19:43:18.320800Z

right sorry i had just copy/pasted that.

jdkealy 2021-05-12T19:43:37.321100Z

i'll try to find the mysql equivilant if any

seancorfield 2021-05-12T19:43:55.321300Z

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.

jdkealy 2021-05-12T19:45:07.321500Z

that was it!

jdkealy 2021-05-12T19:45:17.321700Z

:useSSL false

seancorfield 2021-05-12T19:48:27.321900Z

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

p 2021-05-12T20:45:45.323200Z

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

alexmiller 2021-05-12T20:46:56.323600Z

probably 1 stack frame of difference :)

p 2021-05-12T20:51:39.324800Z

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

alexmiller 2021-05-12T21:03:21.325200Z

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

alexmiller 2021-05-12T21:04:00.325900Z

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

alexmiller 2021-05-12T21:06:42.328Z

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

alexmiller 2021-05-12T21:07:28.328500Z

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

jdkealy 2021-05-12T21:10:36.328600Z

i'm just importing a legacy db into datomic 🙂

p 2021-05-12T21:32:12.330800Z

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?

emccue 2021-05-12T21:36:54.331400Z

you probably want to trampoline at that point

emccue 2021-05-12T21:37:04.331700Z

which is recur but for mutual recursion

alexmiller 2021-05-12T21:45:37.332Z

yep

alexmiller 2021-05-12T21:50:39.332700Z

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

alexmiller 2021-05-12T21:51:33.332900Z

I think it should based on my mental model?

yunior 2021-05-12T21:53:44.333Z

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:

yunior 2021-05-12T21:54:10.333400Z

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"

yunior 2021-05-12T21:54:58.333800Z

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

yunior 2021-05-12T21:55:36.334Z

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