Fork me on GitHub

Hi guys, I have a doubt here. I started to study next.jdbc awesome library (thanks @seancorfield). Unfortunately, I was not able to disable auto-commit, according to the manual, it is something like this.

(require '[next.jdbc :as jdbc])

(def mdb {:dbtype "mysql" :dbname "silly" :user "root" :password "root" :auto-commit false})

(def mds (jdbc/get-connection mdb))

(jdbc/with-transaction [tx mds]
                       (jdbc/execute-one! tx ["insert into address (name, email) values('Caoimhe','')"]))  
But the result is still there without any explicit commit (.commit tx) Thanks everyone …


@mbrum FYI, there's a dedicated #sql channel for all SQL/JDBC stuff for the future. I'm not entirely sure what you're asking: a transaction is, by definition, auto-commit unless you explicitly say it should be :rollback-only true per the docs


You generally do not want to run with-transaction on a connection: you would normally run it on a datasource (and let it manage the connection for you) and use a connection-pooled datasource.


Inside with-transaction, if you throw an exception, the TX will rollback, otherwise it will commit (per the docs). If you start with a connection that is set to :auto-commit false, it will be reset to :auto-commit false after the TX completes, but the whole point of with-transaction is to set up a committable TX on a connection (either the one you provided, or one it creates for you from a datasource).


Hello Sean, thank you so much for your reply, it is much clear now, I just started to study it and bumped into something that is not completely clear, as I told you, by the docs (as I have understood it) it should not have committed this transaction…. Thanks..


Hello, at the start of a file, at (ns ... is there a particular reason why one might use :use instead of :require ? Would there be a reason to (:use midje.sweet rather than :require it?


it is bad style to use because it undermines some benefits of strong names. It can be helpful when exploring at the repl but frankly I like to just say (:require [midje.sweet :as ms]) and type ms/...


By undermine benefits, you mean cause it does the equivalent of refer? So the namespace is not reflected?


Also, consider what happens if there is a function called foo that is in two namespaces that are both required using :use ?


Is use equivalent to refer all btw?


Am asking this question on use because I am working on a codebase with :use and was trying to make sure it makes sense to convert it to :require


Not sure what you mean by "equivalent". Both :use and :require will require/load the namespace. In addition, :use will also bind the public vars of the loaded namespace into the namespace being loaded into. In general, you can "convert" (ns my.lib (:use sub.lib)) to (ns my.lib (:require [sub.lib :as sub])) and then replace all implicitly bound vars from sub.lib (say foo) by sub/foo.

👍 1

Hey! In clojure spec, when I define a spec with an (spec/or ::spec-a ::spec-b), is the generator supposed to always generate the second type in the list? I would like it to be random


That's not how s/or works. You need to define pairs of "path name" and spec. So e.g. when you conform some data, spec will tell you which path was followed Check out the docstring


So you'd have to write something like (s/or :path1 ::spec-a :path2 ::spec-b) to get what you want


I have a function that uses filter and returns a lazy sequence. I don't want a lazy sequence, so I've used filtervto return a vector instead. Now I've stumbled upon 'doall'. It solves the same problem, but i was wondering if one way is better than the other?


I am mostly wondering if doall provides better performance, since it wont have to copy over all the elements, but just basically walk through the sequence retaining/returning the heads


the best way is actually to use (into [] (filter f) coll)


but as to your actual question, filterv will be better from a memory use pov and probably better for perf as vectors are more efficient than lazy seqs.


Thank you! I thought that (into [] (filter f) coll) was basically how filterv behaved?


similar result, totally different impl


@U064X3EF3 do you mind expanding on why the transducer version is "the best way"?


transducers are a general way to separate the input source from the transformation from the output collection. so they serve the same goal, but are much more general - you can compose multiple transducer transformations in the into and it will still be a single pass over the input to realize the result

👀 1

if transducers had been invented first, filterv would never have been added


Thanks, so I read this as it's not necessarily better in terms of performance but better for composition and reusability


yep. performance wise for this particular thing, they are both essentially a reduce from vector to transient vector so perf should be essentially the same.

Ben List15:12:41

Is there a fn like iterate that works for any arbitrary (f x). I know I can use reductions over and infinate range and just toss the collection but wasnt sure if there was a builtin for that eg: (defn iterate* [f x] (reductions (fn [dx _] (f dx)) x (range)))


(defn iterate [f x] (lazy-seq (let [res (f x)] (cons res (iterate f res)))))

👍 1
Ben List16:12:00

I think that only works with functions without arguments

Ben List16:12:12

I want to apply the result of each call to the next lazily and infinately

Cora (she/her)16:12:41

I don't know then 😞


What is a good way to update the value of a vector at a specific index? I know update function can be used to make update to a specific index position of a vector as well. But update is defined for maps and using it for vector doesn't seem idiomatic. Wdyt?


seems idiomatic to me


you can assoc at the index


Yes. I was just curious if it is somehow discouraged to use map specific functions on vectors. For my case update works well because I need to use the existing value to derive the new value.


I guess as long as it works, it's not a big deal then. Thanks.


Is there a way I can check what methods are available on a Java object instance in my REPL?


Beauty. Thanks!

👍 1
Sean Sanker18:12:33

Hi Everyone! Does anyone know why I can't get the source for this function? I don't believe the token is invalid? repl usage:

user=> (repl/source-fn 'example.namespace/example-function)
Execution error at user/eval105226 (form-init17088966657071738526.clj:1).
Invalid token: ::feature/example-feature
function definition:
(defn example-function
  [{:keys [user]}]
  (-> (user/if-feature-available
Maybe relevant? Thank you!


correct, you're running into that issue the token is valid, it's just being read in a context that doesn't have access to the alias map to resolve feature

Sean Sanker18:12:06

Ah so would the workaround be to make feature available in the namespace that I'm calling source-fn from? Is there a way to get the function source raw without trying to parse it out (thus avoiding trying to read the token)?


the source reading stuff is dumb and just reads forms without code evaluation


you need to read and understand the ns of the file containing the source to be able to accurately resolve aliased keywords

❤️ 1
Sean Sanker18:12:26

Thank you so much! I'll look into it.


keep in mind an autoresolved keyword ::a/bcd has no programmatic representation (at least not in Clojure's reader)

❤️ 1

they are fully resolved by the time they leave the reader

❤️ 1

so if something has a code form with fully resolved keywords, what should the source fn print?

❤️ 1

Doing Advent of Code, I find a lot of my functions use loop/recur , and they feel like more work and more mental effort than they ought to. Is loop generally considered a "last resort"? Does idiomatic Clojure do a lot of looping? How about recursive functions? I get the feeling things like map and filter are more powerful than I currently realise, and I keep hearing mutterings about transducers. It's easy to look up the grammar and API of a language, but harder and IMO more important, to get a handle on idiomatic usage. Any pointers, or am I asking too broad a question?