Fork me on GitHub

Could someone please point me to where Clojure's memory model is implemented? The part where differences are branched off


Do you mean where path copying is implemented for collections that you are updating, so that they return a new collection instead of modifying the one they are given?


If you mean something else, it is not clear from your question


Clojure's memory model is Java's memory model since it runs on the jvm


I mean the path copying as you say


based on Bagwell's HAMT (with some mods for performance)


> Any errors are my own i love this comment


I am trying to deploy a package in clojars . I am getting following error

java.lang.IllegalArgumentException: Must provide valid :files to deploy-artifacts
Can anyone help me with this?


@suren try asking in the #clojars channel. Someone may be able to help there. 🙂


Is there currently a “best” Clojure SFTP client library? “Best” is kind of squishy but something that is relatively well maintained and provides good examples. I was thinking but its tests are currently failing and it is somewhat lacking in examples (was looking specifically for a put example from an in-memory file).


We’re suddenly having production issues with org.httpkit.client throwing java.lang.IllegalStateException: Client/Server mode has not yet been set whenever we try to connect to one of our other servers over https. The only thing that’s changed since last Friday when everything was fine is that Daylight Savings Time ended over the weekend. Java version is 1.8 (and not Java 11, which seems to have had a lot of issues with this). It’s a long shot, but has anyone else ever seen a problem like this?


Thanks! The documentation implies that it is FTP only. Does it work with SFTP connection?


yes, it does


awesome, thanks!


I even made a little PR related to that, to that lib


take-while as a transducer "takes while" the input satisfies some predicate. easy enough to write but is there a transducer that "takes while" the accumulated value satisfies some predicate?


(defn foo [rf finish?]
    ([] (rf))
    ([result] (rf result))
    ([result input] (let [result' (rf result input)]
                      (if (finish? result')
                        (reduced result')


built-in or possibly in cgrande's lib?


it isn't really safe for transducers to make assumptions about result


do you know of a concrete example that can help clarify for me?


@dpsutton, why not just use the built in take-while ?

(defn take-while
  "Returns a lazy sequence of successive items from coll while
  (pred item) returns logical true. pred must be free of side-effects.
  Returns a transducer when no collection is provided."
  {:added "1.0"
   :static true}
     (fn [rf]
         ([] (rf))
         ([result] (rf result))
         ([result input]
            (if (pred input)
              (rf result input)
              (reduced result))))))
  ([pred coll]
    (when-let [s (seq coll)]
      (when (pred (first s))
        (cons (first s) (take-while pred (rest s))))))))

Jan K19:11:03

I agree with hiredman, this is something out of scope for an individual transducer (imagine if it's attached to a channel, what's the accumulator value?). But I guess you could use clojure.core/reductions and wrap the reducing function manually with some transducers if needed, and then take-while the resulting sequence.


transduce calls (f) before applying the xform to f, so you cannot assume result is the value returned by your step fn's init arity


@smith.adriane because no inputs are bad. its when i've taken "enough" inputs that i can stop


something like (reduce (reduce-until + #(> % 100)) (range 300))


the accumulator could be anything. it seems like you may want to write your own transducible process if you want to make assumptions about the accumulator value


i don't follow. using a reducing function assumes i know something about the accumulator shape.


(fn [acc input] ...) if acc is completely opaque then i could never reduce anything


the transducer (map f) can work when the accumulator is a core/async channel, a clojure sequence, a socket connection, standard out, outputstream, and many other accumulator types. not sure how your take-while would work with all those examples


(defn part [n]
  (fn [retf]
      ([] {:value (retf)
           :part []})
      ([{:keys [value part]}]
       (if (seq part)
         (retf (retf value part))
         (retf value)))
      ([{:keys [value part]} item]
       (let [new-part (conj part item)]
         (if (= (count new-part) n)
           {:value (retf value new-part) :part []}
           {:value value :part new-part}))))))
user=> (let [f ((part 2) conj)] (f (reduce f (f) (range 10))))
[[0 1] [2 3] [4 5] [6 7] [8 9]]
user=> (transduce (part 2) conj (range 10))
([8 9] [6 7] [4 5] [2 3] (1 0))
user=> (into [] (part 2) (range 10))
Execution error (NullPointerException) at user/part$fn$fn (REPL:13).
Cannot invoke "clojure.lang.ITransientCollection.conj(Object)" because "coll" is null


part there is a kind of naive purely functional transducer that wraps the input result to keep a buffer, and unwraps it at the end


and if you sort of manually do the things when you use it with reduce, it works, but in a "real" usage with a function that takes a transducer it doesn't


it almost sort of works in that example with transduce, but will completely fall apart with different types and reducing functions


result is opaque, the only operation you can safely do on it is call rf


thanks everyone


if you need to keep a count then you need to keep it in an atom closed over by your reducing function, similar to how the stateful transducers work