Fork me on GitHub
#clojure
<
2019-09-30
>
andy.fingerhut00:09:58

If you mean the ones in the clojure.core namespace, included as part of Clojure, most functions are pure functions, but not all. Any particular transducer you are curious about?

andy.fingerhut00:09:39

Here are functions that return transducers whose implementations I believe are stateless: map, cat, mapcat, filter, remove, take-while, replace, keep, halt-when, random-sample Stateful: take, drop, drop-while, take-nth, distinct, interpose, partition-by, partition-all, map-indexed, keep-indexed, dedupe. I did not notice any in my stateless list that contain any functions that are themselves stateful, unless you want to consider random number generation stateful, which in a sense it is because it is implemented by reading and modifying the state of a pseudo-random number generation algorithm. I put it in the stateless list because except for that, which one ideally hopes looks "independent" from one call to the next, it is stateless.

creese04:09:38

That’s pretty close to my list.

creese04:09:16

take-while feels stateful because it has to know to stop sending output. For a finite stream it can be made stateless. It isn’t clear how this could be stateless for an infinite stream.

jaihindhreddy08:09:15

Transducers are process transformations where a process is a reducing fn to be used by something that implements IReduceInit, which supports reduced as the early termination mechanism. take-while uses that to stop the process in the middle. Here's the source of the transducer-returning arity of 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}
  ([pred]
     (fn [rf]
       (fn
         ([] (rf))
         ([result] (rf result))
         ([result input]
            (if (pred input)
              (rf result input)
              (reduced result)))))))

jaihindhreddy08:09:29

As you can see here, the init and the completion arities of the returned process are as usual, but in the input-consumption step, take-while bails out using reduced. Please watch Rich Hickey's Transducers talk at Strange Loop if you're confused about what I mean by a "process"

jaihindhreddy08:09:28

All take while needs is whether the current input satisfies the predicate, and not any information about previous inputs, so no state is necessary. take on the other hand needs to know how many more things it needs to take, which means it needs to keep track of how many things it already took. And that requires state.

creese11:10:27

I think I’m using these a little differently. I’m using transducers in a stream processing application where each call to into [] only sees the current input.

creese11:10:40

It’s a collection of size one.

creese11:10:14

I don’t think take-while can work as intended when the collection is of size 1, but maybe there is better way to convey these from the underlying Kafka topic.

creese04:09:29

I didn’t know about halt-when

andy.fingerhut06:09:50

All transducers have the ability to stop producing new elements. I don't know the implementation details, but I believe that is how both halt-when and take-while stop producing new elements.

andy.fingerhut06:09:47

Well, when I say "all transducers", I do not mean that all of the ones in clojure.core have this ability -- I just mean that whenever one writes a transducer, the capability is available to write it so that it stops propagating elements from its source.

borkdude10:09:14

Alex's talk at ClojuTRE about lessons learned and spec2: https://www.youtube.com/watch?v=KeZNRypKVa4&amp;feature=youtu.be

vlaaad11:09:52

Woah, they already published videos

vlaaad11:09:58

personally, my favorite talk was Dave's about essential complexity that's impossible to disentangle and how to deal with it (if i understand it right, I think I need a re-watch it) https://www.youtube.com/watch?v=xYqWREPb3Lc

borkdude11:09:20

I missed that one, I need to watch it. Was talking to some folks in the hallway tracks.

jumar14:09:19

At first glance it sounded like "Don't bother trying to achieve simplicity". But perhaps a better takeaway would be that some systems are inherently complex and we can't hope to simplify them because we would only obscure things. However, I think we should strive to avoid creating complex systems in the first place.

Las07:10:31

Dave’s point (also incorporated in his Cynefin framework) is that there are different domains in which different methods are appropriate. He emphasized that there are domains, in which methods that try to establish linear causality that rely on repeatability of simple cause & effect chain don’t work, you need a different perspective. His talk is less about how we should write software, more about how to classify problems (simple, complicated, complex) and what are the appropriate methods to tackle them.

denik16:10:37

Applied Complexity Science is an amazing field. I'd recommend the writings & math papers of Nassim Taleb as an entry point. Very closely aligned to Dave's conclusions.

Karol Wójcik11:09:36

Is there a transducible equivalent of clojure.core/some fn?

borkdude11:09:58

@karol.wojcik Maybe you can roll your own like this?

(transduce (map inc) (completing (fn [acc x] (when (pos? x) (reduced x)))) 0 (range -10 10))
1

borkdude11:09:22

@karol.wojcik You can also look at https://github.com/cgrand/xforms, which has a some reducing fn

💯 4
vlaaad11:09:06

@karol.wojcik (comp (keep pred) (take 1))?

borkdude11:09:31

right, like: (first (sequence (comp (filter pos?) (take 1)) (range -100 100)))

vlaaad11:09:09

first could be a transducer...

Karol Wójcik12:09:45

Thank you guys!!

sgerguri16:09:48

Is there a way to force spec to recursively conform an s/or over a bunch of multi-specs?

Alex Miller (Clojure team)16:09:56

don't understand the question, can you give an example?

Alex Miller (Clojure team)16:09:08

also maybe in #clojure-spec instead

sgerguri16:09:22

Will head over there and post more.

hmaurer18:09:56

Hi! Is there an alternative to Plumatic Schema that isn’t clojure.spec? (a popular alternative)

Alex Miller (Clojure team)18:09:29

maybe if you shared why those weren't a good match for you, it would help trigger alternatives

hmaurer18:09:03

@alexmiller oh it’s not about them being a bad match, I just want to know if I am missing another popular lib

hmaurer18:09:28

I am doing a survey of them

sooheon18:09:38

spec-tools is popular, not an alternative but a lib that builds on top of spec. https://github.com/metosin/spec-tools/blob/master/docs/02_data_specs.md

Alex Miller (Clojure team)18:09:00

possibly core.typed as well, depending on your goals

borkdude18:09:29

seqexp is something which I almost wanted to implement (by extracting parts from spec), thanks for sharing

borkdude18:09:30

if I'm not mistaking, seqexp is older than spec. was using regexes for spec inspired by this maybe?

Alex Miller (Clojure team)18:09:46

not the inspiration, but we did look at it as one example while implementing (can't remember if it was before or after the current impl)

Alex Miller (Clojure team)18:09:09

as always, cgrand does great work

Alex Miller (Clojure team)18:09:46

iirc there were a couple choices in seqexp that were not aligned with what we wanted to do, but it's a good lib

Alex Miller (Clojure team)18:09:46

I really like parts of truss and herbert too

denik16:10:37

Applied Complexity Science is an amazing field. I'd recommend the writings & math papers of Nassim Taleb as an entry point. Very closely aligned to Dave's conclusions.