beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
2021-04-13T01:19:10.461500Z

I'm trying to programmatically create a union type out of an existing spec and a new spec. i understand this is a complete hack, but i've tried many variations of the following:

(defonce spec-ledger (atom {}))

(defn add-to-ledger!
  [k spec]
  (swap! spec-ledger update k (fnil conj #{}) spec))

(defn union-spec
  [k spec]
  (let [existing (get @spec-ledger k)
        options  (->> spec
                      (conj existing)
                      (map-indexed (fn [i p] [(keyword (str i)) p]))
                      flatten)]
    ;; return quoted form instead of evaluating because this evaluates to an
    ;; object, which can't be "embedded in code"
    `(s/or ~@options)))

(alter-var-root
 #'clojure.spec.alpha/def-impl
 (fn alter-sdef-impl [sdef-impl]
   (fn register-union-spec-instead
     [k _form spec]
     (add-to-ledger! k spec)
     (let [union              (union-spec k spec)
           ;; can't seem to call `s/def` directly here
           ;; but in order to call `s/def-impl`, need to need to generate
           ;; updated `form` and `spec` (which `s/def` would otherwise
           ;; accomplish)
           [_ _ form' spec'] (macroexpand `(s/def ~k ~union))]
       (sdef-impl k (eval form') (eval spec'))))))
this ultimately fails when it sees the output of, for example, s/or presumably because it's an object. (`Can't embed object in code, maybe print-dup not defined: clojure.spec.alpha$and_spec_impl$reify__2193@34633d03`)

2021-04-13T01:21:32.463200Z

are there other strategies (other than getting rid of my existing specs or getting rid of my non-conforming data) that jump out at folks?

Eric Ihli 2021-04-13T01:22:35.464200Z

What's a good way to track down what line of my code is causing a stackoverflow? I'm only getting it when I work with a really big data set. So I don't think it's an infinite loop as part of some calculation. The biggest problem I'm having debugging it is that the lines in the error are all from clojure namespaces.

LazySeq.java:   42  clojure.lang.LazySeq/sval
              LazySeq.java:   51  clojure.lang.LazySeq/seq
                   RT.java:  531  clojure.lang.RT/seq
                  core.clj:  137  clojure.core/seq
                  core.clj: 2927  clojure.core/drop/step
                  core.clj: 2932  clojure.core/drop/fn
              LazySeq.java:   42  clojure.lang.LazySeq/sval
              LazySeq.java:   51  clojure.lang.LazySeq/seq
The function that I call that triggers it is about 100 lines long and kind of ugly but it's got a top-level loop/recur and I don't recur by calling the function. My best guess now is to keep placing Thread/sleeps and printlns and step through the code. But with a sleep of 10ms I just watched it run for about 5 minutes and all of the output looked fine. If I uncomment the commented out sexp below, that's when I get the stackoverflow.
(def tightly-packed-trie
  (let [tight-ready-trie
        (->> trie
             (map (fn [[k v]]
                    (let [k (map #(get trie-database %) k)]
                      [k v])))
             (into (trie/make-trie)))]
    #_(tpt/tightly-packed-trie
     tight-ready-trie
     encode-fn
     decode-fn)))
That function in it's current state is at https://github.com/eihli/clj-tightly-packed-trie/blob/main/src/com/owoga/tightly_packed_trie.clj#L225

2021-04-13T01:23:12.464400Z

with lazy stuff like this, try mapv instead of map

2021-04-13T01:23:52.464600Z

i've had good experiences getting better stack traces doing so

Eric Ihli 2021-04-13T01:26:03.464800Z

Hm. I'm iterating over a custom datatype and I guess I'm not implementing what I need to in order to use mapv yet. Method com/owoga/trie/Trie.iterator()Ljava/util/Iterator; is abstract

2021-04-13T01:28:47.465Z

there are other ways to realize a lazy sequence

2021-04-13T01:29:04.465200Z

doall

Eric Ihli 2021-04-13T01:42:57.465400Z

Thanks for the idea. I think it's a good lead. I haven't made any progress with it yet though. I noticed http://clojure.github.io/clojure/clojure.stacktrace-api.html and thought I could get all traces rather than just what my editor was showing me. But that's still not showing anything other than core clojure code.

Eric Ihli 2021-04-13T01:44:25.465600Z

Ah ha ha... -XX:MaxJavaStackTraceDepth=-1

2021-04-13T01:52:39.465800Z

folks are suggesting s/form to go from an object to a form

Eric Ihli 2021-04-13T01:55:10.466Z

Bingo. You were right. Adding a doall to a concat fixed it I think. And that stacktrace pointed straight to the line.

🙏 1
Edward Ciafardini 2021-04-13T02:05:15.467800Z

newb question: Just getting my feet wet with clojure....every time I run any lein commands, I get this warning: OpenJDK 64-Bit Server VM warning: Options -Xverify:none and -noverify were deprecated in JDK 13 and will likely be removed in a future release. 1. Does this matter? && 2. How do I make it stop?

2021-04-13T02:05:20.467900Z

i've heard folks say never to use concat instead of into for that reason

2021-04-13T02:11:55.468100Z

It doesn't matter a ton at the moment, upgrading your lein version might make it go away

2021-04-13T02:13:12.468200Z

Lein passes (passed?) those options to speed up jvm launching, lein because of the way it works usually ends up launching two

seancorfield 2021-04-13T02:16:43.468300Z

https://stuartsierra.com/2015/04/26/clojure-donts-concat

seancorfield 2021-04-13T02:17:21.468600Z

All of https://stuartsierra.com/tag/dos-and-donts is worth reading.

🙏 1
Sebastian Ohlsson 2021-04-13T07:30:25.472100Z

Hi there! How do I run a python script with sh ?

Sebastian Ohlsson 2021-04-14T15:12:28.091Z

I will take a look into this, thank you

👍 1
Sebastian Ohlsson 2021-04-20T09:03:04.266100Z

So I finally got back to this. Turns out that I had to type "python.exe" and not just "python3". Rookie misstakes were made 🙂 As you mentioned python3 just takes me to the windows store. Maybe there are different installation ways. Its solved, thanks for all the help.

zackteo 2021-04-20T10:42:43.267500Z

Nice :D glad you managed to get it working!

👏 1
sb 2021-04-13T07:46:00.472600Z

https://github.com/clj-python/libpython-clj is not better in this way?

sb 2021-04-13T07:46:17.473300Z

I dont know what is the goal at your side, maybe wrong idea

Sebastian Ohlsson 2021-04-13T08:10:12.474200Z

Thanks for the feedback! Due to only calling a python script one time I think its overkill to add another library and would rather try to learn to sh it. I tried the second suggestion

(use '[clojure.java.shell :only [sh]])
(sh "python3" "helloworld.py")
But I got the following result:
(sh "python3" "helloworld.py")
=>
{:exit 9009,
 :out "",
 :err "Python hittades inte. Kör utan argument för att installera från Microsoft Store eller inaktivera den här genvägen från Inställningar > Hantera alias för körning av program.\r
       "}
The error is essentially "python wasnt found."

sb 2021-04-13T08:14:49.474500Z

I don’t have experience w/ Windows. On mac, works fine:

user=> (use '[clojure.java.shell :only [sh]])
nil
user=> (sh "python3" "hello.py")
{:exit 0, :out "hello world\n", :err ""}
user=> (sh "python" "hello.py")
{:exit 0, :out "hello world\n", :err ""}

zackteo 2021-04-13T08:16:11.475600Z

Hello! How do I do something like

(take 100 (cycle [{:type :invoke, :f :write, :value (rand-int 5)}
                         (repeat 10 {:f :read})]))
But make the rand-int run again

zackteo 2021-04-13T08:17:02.475700Z

@sebastian.ohlsson.198 have you looked at https://clojuredocs.org/clojure.java.shell/sh ? 🙂

zackteo 2021-04-13T08:18:33.475900Z

Whoops, I realised you want to specifically call python are you on windows or linux?

Sebastian Ohlsson 2021-04-13T08:22:00.476200Z

Hello! Yes I started looking at the docs but sadly I am no wiser. I am on windows

zackteo 2021-04-13T08:23:22.476400Z

is your helloworld.py the right path? Perhaps you might want to run (sh "pwd" to check

sb 2021-04-13T08:28:25.476600Z

Bad file location case: different the error message (exit 2). I think, he need to config python3 (maybe alias setup problem) on Windows. Or simply try with `

"python file.py"
python --version (could helpful)

zackteo 2021-04-13T08:29:10.476800Z

Right python might not even be on the path ... :thinking_face:

👍 1
raspasov 2021-04-13T08:31:31.477200Z

(sequence
 (comp
  (take 100)
  (mapcat identity))
 (repeatedly
  (fn []
   [{:type :invoke, :f :write, :value (rand-int 5)}
    (repeat 10 {:f :read})])))

sb 2021-04-13T08:33:02.477400Z

@sebastian.ohlsson.198 I found an answer: error 9009 “The python.exe you are using isn’t a real Python executable. It’s just a link to Microsoft Store to download it from there.” maybe true?

zackteo 2021-04-13T08:34:49.477700Z

Right right! I should use a function and repeatedly

1
zackteo 2021-04-13T08:35:49.478Z

Thanks 🙂

👌 1
yuhan 2021-04-13T08:43:15.478400Z

You could also use recursion~

((fn rec []
   (lazy-cat
     [{:type :invoke, :f :write, :value (rand-int 5)}
      (repeat 10 {:f :read})]
     (rec))))

raspasov 2021-04-13T08:45:18.478600Z

As presented atm, the above is an infinite loop. Also, if you can solve your problem in straightforward way without recursion, you should.

yuhan 2021-04-13T08:46:23.479Z

yup, don't use recursion in normal circumstances - I think it's just an interesting thing for beginners to encounter

👍 1
raspasov 2021-04-13T08:46:55.479200Z

Also, on the JVM direct recursion can blow up the stack, so be careful with recursion.

zackteo 2021-04-13T08:48:14.479500Z

If I want to inc the value instead, would recursion be good for that then?

zackteo 2021-04-13T08:50:09.479700Z

Like

(take 100 ((fn rec [x]
             (lazy-cat
               [{:type :invoke, :f :write, :value x}
                (repeat 10 {:f :read})]
               (rec (inc x)))) 0))

raspasov 2021-04-13T08:50:30.479900Z

@zackteo Probably not:

(sequence
 (comp
  (take 100)
  (mapcat identity))
 (map
  (fn [n]
   [{:type :invoke, :f :write, :value n}
    (repeat 10 {:f :read})])
  (range)))

yuhan 2021-04-13T08:52:34.480100Z

If each value depends on the previous ones, you can also look at iterate or reductions

zackteo 2021-04-13T08:52:57.480300Z

right right :thinking_face:

raspasov 2021-04-13T09:10:36.480500Z

(do
 ;bad - avoid
 #_(let [f-bad (fn inc-inc [x]
              (if (< 100000 x)
               x
               (inc-inc (inc x))))]
  (f-bad 0))

 ;OK to use
 (let [f-good (fn inc-inc [x]
                (if (< 100000 x)
                 x
                 #(inc-inc (inc x))))]
  (trampoline f-good 0)))

raspasov 2021-04-13T09:11:12.480700Z

Notice that inc-inc returns a fn in the second case.

zackteo 2021-04-13T09:13:55.480900Z

so the point is to use trampoline when doing recursion?

raspasov 2021-04-13T09:23:24.481100Z

Yes… I believe in the example above, you might be able avoid the problem because the recursion is from within lazy-cat… But I am not 100% sure.

zackteo 2021-04-13T09:27:03.481700Z

Will look into it 🙂 thanks

2021-04-13T09:44:38.484300Z

is their a way to do destructuring but give unique names to the keys, or should I just use a let? e..g

(defn is-left [{:keys [x y]} {:keys [x y]} {:keys [x y]}]
   ;; takes 3 parameters, all 3 have x and y key. BUt I'd like it to be like:
   ;; {px py} {x0 y0} {x1 y1}
)
Should I just do this?
(defn is-left [pxy xy0 xy1]
  (let [px (:x pxy)
        py (:y pxy)
        x0 (:x xy0)
        y0 (:y xy0)
     ... so on...]))

2021-04-13T09:47:05.484500Z

There is a way to do destructuring on maps, without using :keys, where you get to pick the local names for the value. See examples here: https://clojure.org/guides/destructuring#_associative_destructuring

2021-04-13T09:47:29.484700Z

:keys is unnecessary, but a nice shorthand when you want the local names to be the same as the keyword without the :

2021-04-13T09:48:49.484900Z

Thank you, that looks like that I want. TIL!

raspasov 2021-04-13T09:51:44.485100Z

I recently wrote this REPL utility to solve this “problem” 🙂 It will print the destructure form for you (for one map): https://github.com/raspasov/alexandria-clj/blob/main/src/ss/auto_let/core.cljc#L112

(ss.auto-let.core/de
 {:user/id    42
  :message/id 52
  :data       {:comment/id 62}})
[{:user/keys [id], message-id :message/id, :keys [data]} your-map {comment-id :comment/id} data]

raspasov 2021-04-13T09:52:04.485500Z

(it’s not a library atm, but you can copy the namespace…)

raspasov 2021-04-13T09:52:59.485700Z

It should do the “right thing” and avoid shadowing of locals for that map.

Milan Munzar 2021-04-13T11:34:25.489400Z

Hello, do you guys have any tips on how to debug the 'pending puts errror' in core.async for ClojureScript? It happens after several days running on our server on nodejs platform. I understand what is happening, but have trouble identifying the code which is throwing the assertion. Thank you.

Dave Suico 2021-04-13T14:13:14.494200Z

Hello guys, I'm trying to make a move file function that is done by copying the file to the new destination and removing the source after copying. However, I get a strange behavior since the io/delete-file function says "Couldn't delete" error so I'm checking the file manually and tried to rename it and it says it's locked since another program is using the file. Is the io/copy function not being able to release the lock to cause this such state? What should I do if so?

dpsutton 2021-04-13T14:16:02.494500Z

(let [input (io/file "foo")]
    (println "contents: " (slurp "foo"))
    (io/copy input (io/file "bar"))
    (io/delete-file input)
    (println "contents: " (slurp "bar")))

dpsutton 2021-04-13T14:16:24.494700Z

returns

contents:  hello

contents:  hello
and deletes foo after copying to bar

2021-04-13T14:16:27.494900Z

io/copy doesn’t close any streams have a look at this example - https://clojuredocs.org/clojure.java.io/copy#example-5e008f1ce4b0ca44402ef7fe

dpsutton 2021-04-13T14:16:44.495100Z

i suspect that you are holding two references to the file which is what your problem is

dpsutton 2021-04-13T14:17:20.495300Z

notice i io/copy and then io/delte the same io/file. you make an io/file for the copy, and then make another one for the deletion

2021-04-13T14:18:30.495800Z

and btw, consider using let instead of def withing defn. The difference that def creates global var and let is for making localy scoped references.

Dave Suico 2021-04-13T14:24:17.499600Z

@dpsutton am I having a race condition? I can't think of any ways to copy and delete the source file the clojure way

Dave Suico 2021-04-13T14:24:35.499800Z

@delaguardo I stand corrected, thank you!

2021-04-13T14:29:00.002900Z

(defn move-file [source destination]
  (with-open [in (io/input-stream source)
              out (io/output-stream destination)]
    (io/copy in out))
  (io/delete-file source))

(spit "/tmp/foo" "lalala")              ; => nil

(slurp "/tmp/foo")                      ; => "lalala"

(move-file "/tmp/foo" "/tmp/bar")       ; => true

(slurp "/tmp/foo")                      ; throws FileNotFoundException

(slurp "/tmp/bar")                      ; => "lalala"

❤️ 1
dpsutton 2021-04-13T14:29:02.003200Z

i don't think its a race condition. io/copy loops until it is done. i'd guess you're doing other stuff to the file

❤️ 1
Eric Ihli 2021-04-13T14:30:34.004500Z

I get a lot of help from this channel and just wanted to give a big thank you and show what your help has led to. I just released my first package on Clojars: https://clojars.org/com.owoga/tightly-packed-trie It's an implementation of a https://www.aclweb.org/anthology/W09-1505.pdf and helped me reduce the memory footprint of a language model from several gigabytes to several megabytes (a savings of $15 per month since I can use a $5/mo server rather than a $20/mo server; not a great return on time spent to be fair, but it was fun!). Sending encouragement to those of you new to Clojure and a big shout out to everyone in this channel providing so much help. Special thanks to @seancorfield for https://github.com/seancorfield/depstar and @andy.fingerhut for https://github.com/jafingerhut/cljol.

👏 1
1
🎉 6
2021-04-13T14:34:19.005200Z

There is no requirement to do so, but you are certainly welcome to announce your library in the #announcements channel on this Slack if you wish.

🙏 1
Dave Suico 2021-04-13T15:21:33.006600Z

@delaguardo I'm still having the issue, the program using the file is OpenJDK Platform binary. I'm using Calva + VSCode how come OpenJDK be using this file?

dpsutton 2021-04-13T15:28:52.006800Z

openjdk is the jvm. clojure runs on the jvm. openjdk is the vm that executes clojure code.

Dave Suico 2021-04-13T15:33:13.007Z

@dpsutton I have followed @delaguardo’s implementation but still no luck :(

dpsutton 2021-04-13T15:33:52.007200Z

can you restart your repl and only execute this code? i'm guessing you've got some open file handlers to it somewhere

Dave Suico 2021-04-13T15:34:09.007400Z

sure

Dave Suico 2021-04-13T15:42:54.007700Z

nah still the same.. here's what I did: -killed the current repl -started new repl via Calva jack-in -loaded the file and its dependencies -called the function

dpsutton 2021-04-13T15:44:09.007900Z

can you evaluate *e at the repl? I wonder if the stacktrace has more information

dpsutton 2021-04-13T15:44:27.008100Z

seeing that its on the desktop i'm wondering if permissions might come in to play here

Dave Suico 2021-04-13T15:45:08.008300Z

:cause "Couldn't delete C:\\Users\\Dave Suico\\Desktop\\desktopCSV3.csv"  :via  [{:type http://java.io.IOException    :message "Couldn't delete C:\\Users\\Dave Suico\\Desktop\\desktopCSV3.csv"    :at [http://clojure.java.io$delete_file invokeStatic "io.clj" 434]}]  :trace  [[http://clojure.java.io$delete_file invokeStatic "io.clj" 434]   [http://clojure.java.io$delete_file doInvoke "io.clj" 430]   [clojure.lang.RestFn invoke "RestFn.java" 410]   [gmaven.csv.main$move_csv_file invokeStatic "main.clj" 43]   [gmaven.csv.main$move_csv_file invoke "main.clj" 36]   [gmaven.csv.main$read_and_move_csv invokeStatic "main.clj" 51]   [gmaven.csv.main$read_and_move_csv invoke "main.clj" 49]   [gmaven.csv.main$eval8153 invokeStatic "NO_SOURCE_FILE" 27]   [gmaven.csv.main$eval8153 invoke "NO_SOURCE_FILE" 27]   [clojure.lang.Compiler eval "Compiler.java" 7177]   [clojure.lang.Compiler eval "Compiler.java" 7132]   [clojure.core$eval invokeStatic "core.clj" 3214]   [clojure.core$eval invoke "core.clj" 3210]   [nrepl.middleware.interruptible_eval$evaluate$fn__960$fn__961 invoke "interruptible_eval.clj" 87]   [clojure.lang.AFn applyToHelper "AFn.java" 152]   [clojure.lang.AFn applyTo "AFn.java" 144]   [clojure.core$apply invokeStatic "core.clj" 665]   [clojure.core$with_bindings_STAR_ invokeStatic "core.clj" 1973]   [clojure.core$with_bindings_STAR_ doInvoke "core.clj" 1973]   [clojure.lang.RestFn invoke "RestFn.java" 425]   [nrepl.middleware.interruptible_eval$evaluate$fn__960 invoke "interruptible_eval.clj" 87]   [clojure.main$repl$read_eval_print__9086$fn__9089 invoke "main.clj" 437]   [clojure.main$repl$read_eval_print__9086 invoke "main.clj" 437]   [clojure.main$repl$fn__9095 invoke "main.clj" 458]   [clojure.main$repl invokeStatic "main.clj" 458]   [clojure.main$repl doInvoke "main.clj" 368]   [clojure.lang.RestFn invoke "RestFn.java" 1523]   [nrepl.middleware.interruptible_eval$evaluate invokeStatic "interruptible_eval.clj" 84]   [nrepl.middleware.interruptible_eval$evaluate invoke "interruptible_eval.clj" 56]   [nrepl.middleware.interruptible_eval$interruptible_eval$fn__991$fn__995 invoke "interruptible_eval.clj" 152]   [clojure.lang.AFn run "AFn.java" 22]   [nrepl.middleware.session$session_exec$main_loop__1058$fn__1062 invoke "session.clj" 202]   [nrepl.middleware.session$session_exec$main_loop__1058 invoke "session.clj" 201]   [clojure.lang.AFn run "AFn.java" 22]   [java.lang.Thread run "Thread.java" 832]]}

Dave Suico 2021-04-13T15:45:58.008500Z

will check if I could run this in other drive

Dave Suico 2021-04-13T16:15:12.008800Z

oh my apologies, this function actually works

dpsutton 2021-04-13T16:15:30.009Z

was it just lacking permissions to delete files from the desktop?

Dave Suico 2021-04-13T16:17:45.009200Z

@dpsutton actually the move-csv-file works by itself when called alone but now when I call read-and-move-csv the error happens. Your suspicion of 2 handles was right.

dpsutton 2021-04-13T16:18:22.009500Z

don't use def like that. use let

Dave Suico 2021-04-13T16:18:38.009700Z

yes yes, I'm still refactoring things

dpsutton 2021-04-13T16:19:01.009900Z

no worries. it's possible that that's preventing garbage collecting since it's still defined and that prevents deletion

Dave Suico 2021-04-13T16:21:38.010100Z

done refactoring with let, still the error persist when -reading csv to a variable -moving the csv to another path should I be wrapping these using with-open?

dpsutton 2021-04-13T16:22:15.010300Z

can you post the source of move-csv-file as it currently is?

dpsutton 2021-04-13T16:22:51.010500Z

and i'd restart your repl since you probably still have some defs around

Dave Suico 2021-04-13T16:23:01.010700Z

Alright, I'm posting 2 functions

Dave Suico 2021-04-13T16:23:40.010900Z

no more defs and I'm restarting my reply every time I call it

dpsutton 2021-04-13T16:24:05.011100Z

oh where did the input streams come from? if you use (io/file source-file) you don't need to worry about the inputstreams

Dave Suico 2021-04-13T16:25:16.011300Z

I just copied @delaguardo’s snippet silly me

dpsutton 2021-04-13T16:27:11.011600Z

no worries. the docstring of io/copy says it doesn't close any streams that it didn't open itself. If you provide the file, it will do the stream opening and closing so you don't need to worry about it

Dave Suico 2021-04-13T16:30:24.011800Z

so in my case, my csv reader isn't closing my stream?

dpsutton 2021-04-13T16:32:36.012Z

can you restart your repl and post the source of these two functions again?

dpsutton 2021-04-13T16:32:50.012200Z

and make sure no code is running at startup, no top level forms do work, etc

Dave Suico 2021-04-13T16:34:19.012400Z

sure

Dave Suico 2021-04-13T16:34:42.012600Z

Dave Suico 2021-04-13T16:35:18.012800Z

nevermind the defs, i'll refactor as we speak

Dave Suico 2021-04-13T16:38:25.013Z

I've refactored move-csv-file to this and it is working. Now to test read-and-move-csv

Dave Suico 2021-04-13T16:43:31.013300Z

read-and-move-csv doesn't work

dpsutton 2021-04-13T16:48:14.013500Z

ok. so that means one of the two branches csv-to-vector or read-csv must be interacting in a way to prevent it. do you know which branch is taken?

Dave Suico 2021-04-13T16:49:59.013700Z

the read-csv function is doing the file reading, the csv-to-vector is only for converting the rows from read-csv if the user opts to

dpsutton 2021-04-13T16:50:20.013900Z

and which branch is being taken?

Dave Suico 2021-04-13T16:51:46.014100Z

uhm a library called ultra csv does the actual reading

dpsutton 2021-04-13T16:52:57.014300Z

(if (true? as-vector?) (csv-to-vector source-file) (read-csv source-file)) only one of these two branches is taken. which branch is being taken?

Dave Suico 2021-04-13T16:55:27.014500Z

my apologies I may have misled you, allow me to correct. both csv-to-vector and read-csv reference to the same library (ultra-csv)

dpsutton 2021-04-13T16:57:14.014700Z

when you are calling the function read-and-move-csv you are passing in as-vector?. this influences the expression (if (true? as-vector?) (csv-to-vector source-file) (read-csv source-file)) . this form has two branches. which branch is being taken?

Dave Suico 2021-04-13T17:01:35.014900Z

the as-vector parameter is a boolean variable. It depends on the client what value to assign in that variable when true, it will take you to csv-to-vector when false, just plain read-csv

dpsutton 2021-04-13T17:02:21.015100Z

i completely understand that

dpsutton 2021-04-13T17:02:47.015300Z

when you are invoking this function and saying that it doesn't work, what value are you passing in for as-vector? and therefore which branch is being taken?

Dave Suico 2021-04-13T17:03:11.015500Z

uhm both false and true and both fails

dpsutton 2021-04-13T17:04:35.015800Z

ok. well let's just stay with false and diagnose how read-csv will interact with deleting the file

dpsutton 2021-04-13T17:05:08.016100Z

so we know that we are trying to delete the file after reading it. can you post the docstring for csv-reader/read-csv?

Dave Suico 2021-04-13T17:10:25.016300Z

my bad, I should've known this earlier. I am rereading my tasks spec and I just realized that read-csv and move-csv are separate functions and they shouldn't be interacting with each other meaning read-and-move-csv shouldn't exist. .

Dave Suico 2021-04-13T17:11:32.016600Z

read-csv and move-csv works when called alone I guess I'm just creating my own problem by putting them together as read-and-move-csv.😅

dpsutton 2021-04-13T17:12:57.017100Z

these tests show that there's a close! function that needs to be called. You'll need to ensure that you get all the data from the csv and then close it before trying to delete it. I suspect that's your problem there

❤️ 1
dpsutton 2021-04-13T17:13:13.017300Z

this seems like a strange api to me

Dave Suico 2021-04-13T17:16:31.017600Z

ahh now it's clear to me, that csv reader is not actually closing the file. Gotta add this closing call to my reader as well. I guess we'll end here thank you very much man I appreciate your efforts!

dpsutton 2021-04-13T17:23:28.017800Z

for sure

dpsutton 2021-04-13T17:23:50.018Z

i suspect you're going to have to figure out how to get all of the results out of the csv. it's possible it's lazy and gives you results as you need? not sure

Dave Suico 2021-04-13T17:27:52.018200Z

yes it gives me the results I need but I have no idea yet how will it behave when dealing with large files or when the next call is move-csv

Dave Suico 2021-04-13T17:31:25.018400Z

can you recommend other library for reading csvs?

dpsutton 2021-04-13T17:37:22.019100Z

Clojure data csv is the go to

Dave Suico 2021-04-13T17:42:14.019300Z

okay man I'm gonna try that

Dave Suico 2021-04-13T17:42:17.019500Z

thanks!

Andy Nortrup 2021-04-13T19:47:20.021900Z

Testing question - I’m trying to test that a method outputs the proper date string.

(t/deftest test-print-period-date
           (t/is (= "2021-W53" (c/print-period-date c/period-week -1 (ti/date-time 2021 01 8))))
           (t/is (= "2020-12" (c/print-period-date c/period-month -1 (ti/date-time 2021 01 8)))))
The test is failing with this output:
; expected:
2021-W53
; actual:
(2020-W53)
The content is formatted properly, but I don’t appear to be doing the comparison / conversion correctly?

dpsutton 2021-04-13T19:48:29.022200Z

what does (c/print-period-date c/period-month -1 (ti/date-time 2021 01 8)) output in your repl?

dpsutton 2021-04-13T19:49:09.022700Z

also, i'm seeing an expectation of 2020 as the year but (ti/date-time 2021 ...) if that's your issue?

Andy Nortrup 2021-04-13T19:52:02.023300Z

I get a quoted string back when I run it in REPL

dpsutton 2021-04-13T19:52:37.023500Z

can you paste the output here?

Andy Nortrup 2021-04-13T19:53:18.023900Z

(print-period-date period-week -1 (t/date-time 2021 01 8))
"2020-W53"

Andy Nortrup 2021-04-13T19:53:41.024300Z

(package changes between my test and core NS)

dpsutton 2021-04-13T19:55:36.025300Z

well that's certainly not equal to "2021-W53" which you were expecting

dpsutton 2021-04-13T19:55:54.025600Z

it seems like your repl has some formatting of test results going on

dpsutton 2021-04-13T19:56:25.026100Z

this is what it looks like for me for (is (= "bob" "alice"))

FAIL in (foo) (NO_SOURCE_FILE:1)
expected: (= "bob" "alice")
  actual: (not (= "bob" "alice"))
nil

yiorgos 2021-04-13T21:06:55.028400Z

In Clojure, when I want to check the type of the data I normally do (class foo) but in Clojurescript that is not working, is there something similar in Clojurescript for examine the data, for example if it is a vector, map …

Lukas 2021-04-13T21:20:36.032900Z

Hi there, can anyone tell me why this

(defmacro no-matching-ctor [q]
  (when (symbol? q)
    [(constantly true)]))

(no-matching-ctor ?e)
will give me an IllegalArgumentException
1. Caused by java.lang.IllegalArgumentException
   No matching ctor found for class clojure.core$constantly$fn__5690 
macroexpand returns what I expect, but it seems I expected some not working thing 😬
(macroexpand '(no-matching-ctor ?e)) 
=> [#function[clojure.core/constantly/fn--5690]]

2021-04-13T21:42:54.033800Z

because you are returning a function object from the macro instead of code that evaluates to the function object

❤️ 1
2021-04-13T21:44:05.034200Z

basically https://clojure.atlassian.net/browse/CLJ-1206 but with a slightly different error message

omendozar 2021-04-13T22:25:17.035600Z

Hi, how can I solve this using next.jdbc.sql/insert-multi! with postgres?

Can't infer the SQL type to use for an instance of java.util.Date. Use
   setObject() with an explicit Types value to specify the type to use.
This is my table:
create table in_sms  (
  in_sms_id serial not null primary key,
  codigo int not null,
  remitente text not null,
  mensaje text not null,
  fechaingreso timestamp without time zone not null,
  unique(codigo)
);
This is the input:
(def input [{:codigo 493
               :remitente "50588997766"
               :mensaje "Loren Ipsum"
               :fechaingreso #inst "2021-04-13T18:32:00"}
              {:codigo 494
               :remitente "50589890909"
               :mensaje "Loren Ipsum"
               :fechaingreso #inst "2021-04-13T18:33:00"}])
and this is my insert:
(defn insert-incoming-sms!
  "Insert multiple SMS."
  [db sms-coll]
  (let [values (->> sms-coll
                   (mapv vals)
                   (map vec)
                   vec)]
    (sql/insert-multi! db :in_sms
                       [:codigo :remitente :mensaje
                        :fechaingreso]
                       values)))

seancorfield 2021-04-13T23:02:18.036600Z

@orlandomr27 The next.jdbc documentation talks about this… just a sec, let me pull up the link…

seancorfield 2021-04-13T23:03:12.037100Z

https://cljdoc.org/d/com.github.seancorfield/next.jdbc/1.1.646/doc/getting-started#working-with-additional-data-types — “In particular, PostgreSQL does not seem to perform a conversion from java.util.Date to a SQL data type automatically. You can require the next.jdbc.date-time namespace to enable that conversion.”

1
1
seancorfield 2021-04-13T23:05:15.039100Z

There’s a lot of documentation for next.jdbc so it can seem a bit overwhelming, but I would recommend reading through the entire thing at least once — and since you are using PostgreSQL, there’s a whole section in the Tips & Tricks page that will help you with various custom PG types.

seancorfield 2021-04-13T23:06:17.040400Z

There’s a #sql channel where it can be easier to get help on JDBC/SQL stuff (since it’s much lower traffic than #beginners — and I have #beginners muted so I don’t always see next.jdbc questions here, but I don’t have #sql muted 🙂 ).

omendozar 2021-04-13T23:08:16.042700Z

I’m reading and consulting the docs while composing my functions, but somehow I missed this part. Thank you @seancorfield I’m gonna post further questions on #sql channel. By the way! Awesome work with next.jdbc 🙂

seancorfield 2021-04-13T23:08:28.043Z

Also, be very careful about (mapv vals) over a sequence of hash maps — hash maps are unordered so you will not necessarily get the columns in the order you expect (and you aren’t really guarantee each hash map will return keys in the same order).

seancorfield 2021-04-13T23:09:46.044Z

The safest thing to do there is (mapv (juxt :codigo :remitente :mensaje :fechaingreso) sms-coll) so you can control the order of the columns.

omendozar 2021-04-13T23:10:42.044900Z

😲 I wasn’t aware of that. Thanks!

seancorfield 2021-04-13T23:10:51.045300Z

To avoid repetition, you could do:

(let [cols [:codigo :remitente :mensaje :fechaingreso]]
  (sql/insert-multi! db :in_sms cols (mapv (apply juxt cols) sms-coll)))

1
omendozar 2021-04-13T23:34:05.045600Z

worked like a charm!

1