Fork me on GitHub
#clojure
<
2020-06-19
>
ivana00:06:50

I used it at least once in universal gui datastructures viewer (as part of my debugger), very useful for infinite or long lazy lists. Thow it can be implemented in user code, via take or loop or reduce or any else way

ivana00:06:36

I just tried to gui-inspect one funny structure (defn f [] (lazy-seq (repeat (f)))) 🙂

alexmiller01:06:54

core.async has a private bounded-count (pre-dates the core one) but the args are the reverse of the one in core. messes me up every time.

murtaza5205:06:58

I am trying to parse a string date for inserting into datomic using java-time lib - (jt/java-date "dd/MM/yyyy" "26/06/2020") - Can someone help on this one.

ivana08:06:57

@murtaza52 we use this code

[java.text SimpleDateFormat]

(defn parse-date ^Date [^String format ^String date-string]
  (.parse (SimpleDateFormat. format) date-string))

(defn format-date ^String [^String format ^Date date]
  (.format (SimpleDateFormat. format) date))

murtaza5213:06:52

hi @U0A6H3MFT thanks. let me try it out.

jumar09:06:26

I'm trying to serialize operations executed inside a directory (e.g. executing only one git operation at a time) and the best thing I could make is this:

(defn update-repo-using
  [repo-path update-fn]
  ;; intern the repo-path string to make sure the same paths are actually the same object
  (locking (.intern repo-path)
    (update-fn)))
Is that a good approach? it's slightly hacky with the .intern method call but otherwise the same Strings can be different objects and it wouldn't work. In general, I'd like to be able to serialize access on objects that are equal (or even use an arbitrary predicate) but not neccessarily the same instance.

borkdude09:06:52

@jumar that probably works if you have just one writer process

jumar09:06:26

What do you mean by that?

borkdude09:06:17

if you have multiple processes (JVMs) writing to that file, this won't work

borkdude09:06:25

but often that's a reasonable assumption

jumar09:06:41

Ah of course - that’s not an issue in this case

borkdude09:06:56

for clj-kondo I'm using RandomAccessfile which supports inter-process locks

jumar09:06:55

That could work but I don’t really like file locks sonce they tend to be quite brittle and it’s more complicated in this case. But thanks for sharing that.

borkdude10:06:11

often the better answer is: use a database 😉

jumar10:06:04

These are git repositories on the disk so that’s not really possible

jumar10:06:24

Thanks for the link. Actually my colleague ended up using agent based approach which I found much more complicated and more error prone. The example in the SO answer isn’t really complete I think

ryan10:06:39

Yeah. I think locking on interned strings could work, but you would need to be very careful that you didn't lock on these strings elsewhere, as you could end up with deadlocks, etc

ryan10:06:45

May be a good approach

jumar11:06:25

Good point about possible deadlock. I’ll chech Guava too.

Daniel Stephens12:06:44

for the general equals case, perhaps you could have a memoized function that looks up your locking object (def m (memoize (fn [s] (Object.)))) and lock on the value of that function, should work for values other than strings

👍 3
jumar12:06:07

Is the memoized version guaranteed to be thread safe, that is to return always the same lock object when multiple threads call it at once? Looking at the implementation I’d say it could return two or more different locks...

Daniel Stephens12:06:26

that's a good point, I think the current implementation is as you say, you could reimplement the same functionality that would be thread-safe to that extent

borkdude13:06:00

@jumar memoize is not thread-safe

Daniel Stephens13:06:18

would

(defn safe-memoize [f]
  (let [mem (atom {})]
    (fn [& args]
      (swap! mem (fn [m] (if (contains? m args)
                           m
                           (assoc m args (apply f args)))))
      (get @mem args))))
be a threadsafe version?

borkdude13:06:52

you can get away with using the result value of swap!

👍 3