Fork me on GitHub
#clojure
<
2016-11-30
>
angusiguess00:11:47

IIRC, the dumps are XML, you should be able to parse them with clojure.xml

olslash00:11:26

anyone using core.match in serious business? wondering why its still in alpha/2 years without commits

ghadi00:11:50

cause it's stable

ghadi00:11:37

i'm sure @dnolen would appreciate help with maintainership, but clojure doesn't really bitrot very much

olslash00:11:30

yeah i'd assume its stable if it wasn't still called an alpha

dnolen00:11:35

@olslash what’s there works OK, I have lots of ideas for enhancements but no time to work on them.

dnolen00:11:21

I could slap beta, or remove the qualification, it wouldn’t mean much

ghadi00:11:32

sorry @olslash I didn't mean to sound cranky

olslash00:11:55

sure sure, and thanks for the reply @dnolen

dnolen00:11:18

people use it in production if that’s what you’re asking about

dnolen00:11:37

there are some known gotchas, JIRA is informative here

olslash00:11:16

yeah thats mostly what i was getting at, thx

hueyp00:11:48

for the component library — is there a way to start a single component + its dependencies? I have a system map but have a few diff entry points I’d like to start just the minimal system to accomplish the action (captured by a component).

hiredman00:11:57

a system is just a map, so make another one with just the parts you want

hueyp00:11:02

yah, just wanted to check if that was like a built in thing vs walking deps myself to do this

seancorfield01:11:48

@hueyp For any given component, you need to be aware of its dependencies, but you can certainly start any constructed “subcomponent” for a given task.

seancorfield01:11:16

For example, we have a low-level system component that is a dependency for most of our other components, but we can start an instance of that and work with code that only needs that system component. Or we can start an instance of our “environment” component, as long as we create an instance of the system component and provide that as a dependency.

bfabry01:11:56

@hueyp looking at the source, start-system actually takes a list of component keys to start. I'm not sure whether it will still start the deps if they're not in the list though

bfabry01:11:12

if it doesn't do what you want, I'm pretty sure a combination of that plus dependency-graph would get you what you want

hueyp02:11:31

@bfabry yah, that was what I thought initially — just pass the key — but at the end it only starts things in that set of keys (it orders them via topo tho). punted for now and just start the whole system but want to revisit this 🙂

roelofw06:11:26

I have two functions with the same input. Is there a way I can use them in parallel ?

iku00088806:11:14

same name + same arity?

roelofw06:11:41

not the same name , both have the same arity

iku00088806:11:04

Use them in parallel means run them in parallel?

roelofw06:11:23

yep, that was my idea

roelofw06:11:45

or there must be a better way to deal with it

rmuslimov06:11:46

(let [val1 (future (func1 args)) val2 (future (func2 args))] [@val1 @val2])

iku00088806:11:28

Was going to say that 🙂

rmuslimov06:11:29

that’s very naive, you can actually make it supporting few functions and use results as you want

roelofw06:11:57

thanks, I will try that solution

spacepluk09:11:37

hi, is the nrepl protocol documented somewhere?

biscuitpants10:11:18

could someone possibly explain why clojure.walk/postwalk would give me an AbstractMethodError on a datomic entity map?

biscuitpants10:11:38

even just doing plain (walk/postwalk identity my-map-with-an-entity-map) gives me the error

biscuitpants10:11:48

but, as soon as i dissoc the entity map from the original map, it works fine

roelofw11:11:58

Someone who can help me figure out why I do not see any output here :

(defn read-image-url
  "Reads the image-url"
  [id-list]
  (map (fn [id]
          (let [art-objects (-> (str "" id "/tiles?key=14OGzuak&format=json" )
                                (client/get {:as :json} )
                              )
               ]
            {:id  id  :tiles art-objects}  ))  id-list))

(read-image-url ["SK-C-5"])

roelofw11:11:00

Im expecting to see something like { :id SK-C-5 :tiles "http: }

bruno.bonacci11:11:02

@roelofw because map is lazy, no execution is performed until the result is consumed

bruno.bonacci11:11:27

wrap the map with a doall

bruno.bonacci11:11:38

like (doall (map …))

roelofw11:11:38

oke, I was doing the same as here :

(defn read-data-painting
  "Reads the title, description, date , collection, colors and url of a image"
  [id-list]
  (pmap (fn [id]
          (let [art-objects (-> (str "" id "?key=14OGzuak&format=json&type=schilderij&toppieces=True")
                                (client/get {:as :json} )
                                :body
                                :artObject)
                description (:description art-objects)
                date        (get-in art-objects [:dating :year])
                collectie   (first (:objectCollection art-objects))
                colors      (:colors art-objects)
                ]
            {:id  id :description description :date date :collectie collectie :colors colors }  ))  id-list)) 

roelofw11:11:51

and there I see output

roelofw11:11:01

but I will try the doall

bruno.bonacci11:11:10

because pmap is semy-lazy

bruno.bonacci11:11:46

while map is fully lazy

roelofw11:11:57

hmm, no difference , still I see in Cursive Process finished with exit code 0

roelofw11:11:05

with no further output

bruno.bonacci11:11:08

try to prn the output

bruno.bonacci11:11:26

(prn (read-image-url [”SK-C-5”]))

bruno.bonacci11:11:56

the output it must be there, maybe just a Cursive displaying issue

roelofw11:11:23

Then I see output , thanks

pedroiago12:11:26

is it worth to return a spec from a function? I am trying to spec a reducing function as a state machine.

bronsa12:11:12

@biscuitpants AFAIK datomic maps implement just the associative bits of maps, they don't implement e.g. dissoc

jeroenvandijk12:11:23

@mokr Maybe something like https://github.com/shenfeng/mustache.clj , we’ve made a (simple) variant of this. Maybe we should opensource it

nha13:11:55

Is https://github.com/clojure/java.jmx equivalent to using JVM starting options(`-Dcom.sun.management.jmxremote`...)? Or is is only clojure-to-clojure? ie. is it possible to integrate clojure/java.jmx with traditional monitoring?

baptiste-from-paris13:11:53

Hello guys, I have a core.async question 🙂! I am currently using go loop as a state machine, the following code is working on clojure =>

(def states [:first :second :third :fourth])

(def next-state (chan 1 (map (constantly :next))))
(def prev-state (chan 1 (map (constantly :prev))))

(defn fsm [states]
  (let [next (async/pipe next-state (chan 1))
        prev (async/pipe prev-state (chan 1))
        max-idx (count states)]
    (go
      (let [actions (async/merge [next prev])]
        (loop [idx 0]
          (when-let [val (<! actions)]
            (if (= idx max-idx)
              (println "This is the end of the FSM with the state : " val)
              (do
                (println "Current state is : " (nth states idx))
                (condp = val
                  :prev (recur (dec idx))
                  :next (recur (inc idx)))))))))))
You just have to put any valu in the next-state channel and it keeps track of where you are. Now I just want to make it work with different users, typically, something like (>!! next-state :user-1) and it keeps of the state for each different user

plamen13:11:27

Hello all - I have a may be stupid question around something which I always had the feeling that works - if I have 3 namespaces and being in ns1, call from there ns1/ping, I would expect the output is "pong" which works. Now if I reevaluate the definition of ns3/pong to return "ping", invoking again ns1/ping should also give "ping", but in my case it doesn't.... (I mean - I just redefine a function in another namespace, as such, not all namespaces which use it get reloaded, but the actual function is bound to the symbol, so it should actually work...) Example source follows - all namespaces are in different source files named accordingly: (ns ns1 (:require [ns2 :as n2])) (defn ping [] (n2/ping)) (ns ns2 (:require [ns3 :as n3])) (defn ping [] (n3/ping)) (ns ns3) (defn ping [] "pong") I switched recently to clojure-1.9.0-alpha14 and use the latest Cursive/IntelliJ if that matters.

baptiste-from-paris13:11:41

I guess I'll have to use atom to mutate user state, any feedback on this ?

joost-diepenmaat13:11:07

@baptiste-from-paris can’t you have one go-loop per user?

dpsutton13:11:34

@baptiste-from-paris i see that you def a vector called states but then named your parameter states, so you shouldn't be able to reach your vector

joost-diepenmaat13:11:41

since you’re already modeling your mutations as channels

baptiste-from-paris13:11:55

@dpsutton forget the def states, I just use (fsm [:first :second]) in the repl, it's not clear, I give you that ^^

dpsutton13:11:32

so since its pulling from the channels constantly saying :prev and :next, is this a random walk through the states?

plamen13:11:37

and while I wrote my question I discovered, that I have "-Dclojure.compiler.direct-linking=true" in my project.clj.... So - please ignore my question 🙂

joost-diepenmaat13:11:48

@baptiste-from-paris call (fsm …) when you add a user

baptiste-from-paris13:11:37

@joost-diepenmaat as simple as that ^^, I guess I'll have to use a timeout then, in case user stop making actions

dpsutton13:11:44

and what was the issue again? I was making sure I was following the code first

baptiste-from-paris13:11:11

It's working great on a 1 user putting stuff in the channels

baptiste-from-paris13:11:29

but I want to keep states for every different user in the application

dpsutton13:11:06

can you not change from :next vals on your channels to {:user 1 :state :next} or some equivalent?

dpsutton13:11:22

and then the thing you are recurring on is a map of maps where each user moves through?

baptiste-from-paris13:11:05

here is a typical use-case =>

dpsutton13:11:10

you're moving one value through your fsm right now

baptiste-from-paris13:11:21

- user 1 make a next action
- user 1 make a next action (:second state)
- user 2 make a next  action (:first state)

baptiste-from-paris13:11:18

Right now I am able to keep state without the user notion

baptiste-from-paris13:11:26

as I am the only one to make actions

baptiste-from-paris13:11:38

but can't figure out simply how to make this work for 10 different users at the same time

dpsutton13:11:08

this is what i was thinking

dpsutton13:11:55

i don't have async loaded in my repl so i haven't tested it but the gist should be correct

baptiste-from-paris13:11:40

let me 2min to look out the code ^^

dpsutton13:11:27

but we're just keeping a map around that puts a user id with each state

dpsutton13:11:40

so when you say next state, you're including a user id

dpsutton13:11:12

it looks up that user id and then increments or decrements their counter like you were doing before and rather than recurring on the number, recurs on the map of all users

baptiste-from-paris13:11:08

So I have 1 go loop handling all users inputs ?

baptiste-from-paris14:11:58

I think I have an other id but not sure, let me work 5min

dpsutton14:11:47

and in the case where the final state is reached you could recur with (recur (dissoc userstates (:user user))

dpsutton14:11:02

and could even get more fancy by remembering who has completed the fsm and not allow them to enter again

dpsutton14:11:36

its also possible that this is a terrible idea but it was something i came up with at the time

baptiste-from-paris14:11:11

@dpsutton no idea is terrible, it only depends on the use case ! thx for your help, I'll making a diagram that I want to share in 5min

baptiste-from-paris14:11:58

or I use pub/sub with user-id as topic

baptiste-from-paris14:11:52

which looks weird because it means that I dynamically have to create go loops if user-id is seen for the 1st time

baptiste-from-paris15:11:58

@dpsutton I've done this =>

(def app-state (atom {}))
(def input-chan (chan 1))

(defn simple-fsm [states chan]
  (let [next (async/pipe next-state chan)
        max-idx (count states)]
    (go
      (loop [idx 0]
        (when-let [val (<! next)]
          (if (= idx max-idx)
            (println "This is the end of the FSM with the state : " val)
            (do
              (println "Current state is : " (nth states idx))
              (condp = val
                :prev (recur (dec idx))
                :next (recur (inc idx))))))))))

(go
  (loop []
    (when-let [input (<! input-chan)]
      (if-let [user ((:sender-id input) @app-state)]
        (>! (:chan user) input)
        (let [c (chan 1 (map (constantly :next)))]
          (swap! app-state assoc (:sender-id input) {:chan c})
          (simple-fsm states c)
          (>! c input)))
      (recur))))

(>!! input-chan {:sender-id :123456})
(>!! input-chan {:sender-id :123456})
(>!! input-chan {:sender-id :12345678})

baptiste-from-paris15:11:39

go-loop take all the inputs and check in an atom that user is known. If it's not the case it creates a new channel and a new simple-fsm. If it's the case it retrieve the user's channel and put the input into it

baptiste-from-paris15:11:33

It then keeps track of each user's state.

baptiste-from-paris15:11:48

I really don't know if it's the "right" way to do it

tdantas18:11:24

I’m struggling on how to port my js function to clojure

function Chain() {
  var pipeFns = [];

  return { add: add, evaluate: evaluate };

  function add(fn) {
    pipeFns.push(fn);
    return this;
  }

  function evaluate(items) {
    return items.map(function(el) {
      return pipeFns.reduce(function(acc, fn) { return fn(acc); }, el);
    });
  }
}
the usage
var chainInstsanceOne = new Chain();
var result = chainInstsanceOne
  .add(function timesFour(a) { return a * 4 })
  .add(function timesFive(a) { return a * 5 })
  .evaluate([1,2,3,4]);

console.log(result); //=> [20, 40, 60, 80] 

var chainInstsanceTwo = new Chain();
var resultTwo = chainInstsanceTwo
  .add(function plusTen(a) { return a  + 10})
  .evaluate([1,2,3,4]);

console.log(resultTwo); //=> [11, 12, 13, 14] 
I’m trying to do with defrecords and defprotocol. but I’m stucked with the state pipeFns
(defprotocol IChainable
  (add [this &fns])
  (evaluate [this args]))

(defrecord Chainable []
  IChainable
  (add [this &fns])
  (evaluate [this args]))
how do you guys would port the JS above to Clojure

jr18:11:44

are they all transform operations?

jr18:11:07

comp the transform functions and then map

tdantas18:11:27

how to emulate the usage ? like an object

tdantas18:11:38

that is my pain point

tdantas18:11:13

do you see what I mean @jr ?

jr18:11:12

yeah so you'll want to add a chain attribute to the record and then add will simply conj the function onto chain

jr18:11:32

(defrecord Chain [chain-fns]
  IChainable
  (add [this chain-fn] (Chain. (conj chain-fns chain-fn))))

jr18:11:59

and evaluate will do something like this

(map (apply comp chain-fns) args)

tdantas18:11:57

(add [this chain-fn] (Chain. (conj chain-fns chain-fn))))
like that ! thanks @jr

tdantas18:11:22

that was my problem, I was thinking on atom/refs/agents ....

tdantas18:11:27

but you solved very well

jr18:11:49

then you can thread it like so

(-> (Chain.)
(add (partial * 4))
(add (partial * 5))
evaluate)

tdantas18:11:57

OMG ! that is so cool !

tdantas18:11:13

I’m sure I will click someday to think like that 😄

jr18:11:24

I recommend reading "The little schemer" to get your gears spinning on recursive functions

trptcolin18:11:44

i'd personally lean towards using plain old sequences / core functions rather than protocols & records in this case:

user=> (def x4 #(* % 4))
#'user/x4
user=> (def x5 #(* % 5))
#'user/x5
user=> (map (apply comp [x5 x4]) [1 2 3 4])
(20 40 60 80)
user=> (def p10 #(+ % 10))
#'user/p10
user=> (map (apply comp [p10]) [1 2 3 4])
(11 12 13 14)

trptcolin18:11:13

i like protocols in cases where the underlying implementations will vary, and it's not clear to me whether they would here

jr18:11:15

correct

tdantas18:11:18

thanks mate !

noprompt19:11:31

is there a defense for this? (number? Double/NaN) ;; => true

noprompt19:11:55

this is why i love test.check.

bfabry19:11:14

well, despite its name NaN does actually behave like a number in a lot of places

bfabry19:11:22

boot.user=> (/ Double/NaN Double/NaN) NaN

bfabry19:11:58

whether there's a defence for that is probably more a question for the original people at Sun 😆

noprompt19:11:04

always room for a sharp edge i guess.

noprompt19:11:51

welp. i’ll just beef up the :post condition a bit more...

noprompt19:11:36

…and the docstring.

bfabry19:11:37

personal opinion: NaN always seemed cute as hell to me and looked like something I'd see in a toy language, not an 'industry' language like java

noprompt19:11:40

(defn finite? [n]
  (and (number? n)
       (Double/isFinite n)))

bfabry19:11:42

spec actually has a spec for this, double-in

noprompt20:11:41

yeah. this is in a :post condition though. i don’t really wanna wrap the return value with spec/assert.

noprompt20:11:05

i guess spec/assert could be in the :post condition but that feels dirty.

bfabry20:11:25

boot.user=> (s/valid? (s/double-in :infinite? false :NaN? false) Double/NaN) false boot.user=> (s/valid? (s/double-in :infinite? false :NaN? false) 1.0) true

bfabry20:11:59

of course, that doesn't satisfy integers 🙂

fiddlerwoaroof20:11:56

NaN is part of the IEEE 754 standard for floating point numbers...

bfabry20:11:55

well there you go

ibarrick20:11:19

I have a bunch of ring requests spit into a file. I need to read them in as clojure objects but edn/read-string keeps breaking on "No reader function for tag object"

ibarrick20:11:28

Is there a way I can ignore objects?

saeidscorp20:11:39

@ibarrick this would do the trick:

(edn/read-string {:readers {'object str}}
                 "[:a :b #object[work.core$eval10426$fn__10427 0xf94f00 \"[email protected]\"]]")

saeidscorp20:11:28

you are free to use any function for interpreting object (instead of str).

danielcompton21:11:02

This is probably my ignorance of Java idioms, but I'm using Transit and trying to read multiple elements from the stream. transit/read in Clojure says that it throws an EOFException, but in ReaderFactory (https://github.com/cognitect/transit-java/blob/0b115adb67f824b7acf62b5e8ed2db17da4cbb6a/src/main/java/com/cognitect/transit/impl/ReaderFactory.java#L114) it catches the EOFException and rethrows it as a RuntimeException

danielcompton21:11:58

I'd rather not have to catch all RuntimeExceptions when I'm only wanting to handle EOFExceptions. Is this idiomatic Java to check the internal exception and rethrow if it's not an EOFException?

saeidscorp21:11:28

what other option do you have? :thinking_face:

danielcompton21:11:34

No other options, just wondering if this is a 'bug' or idiomatic Java that is working as expected?

tom21:11:43

Trying to get an http SNS subsription confirmed with AWS. Using compojure-api. I find that using :body [sns s/Any] for the sns data (to get SubscribeURL). Yet it's coming through empty.

gamecubate22:11:54

Hi all. Is it possible to use the let form within defrecord? What I tried (that failed):

(defprotocol IEngine
  "A canvas engine"
  (init [this])
  (start [this])
  (stop  [this]))

(defrecord Engine [canvas]
  IEngine
  (let [a 12]
      (init [this] (log (str "initializing engine with a = " a)))
      (start [this] (log (str "starting engine with a = " a)))
      (stop [this]  (log "stopping engine"))))

danielcompton22:11:53

You might be able to put the let around the defrecord though?

bfabry22:11:53

@gamecubate you could use the let form around the defrecord

gamecubate22:11:09

didnt think of that

gamecubate22:11:14

Something like this?

(defn make-engine [canvas]
  (let [a 12]
    (defrecord Engine [canvas]
        IEngine ;
        (init! [this] (log (str "initializing engine with a = " a)))
        (start [this] (log "starting engine"))
        (stop [this]  (log "stopping engine")))
    (->Engine canvas)))

bfabry22:11:31

I don't think you want that defn

gamecubate22:11:16

Indeed. Doesn't work.

gamecubate22:11:52

Problem is I am trying to code to support multiple instances of the implementor (Engine).

gamecubate22:11:20

OK. I can always move the let to the actual defrecord invoker

gamecubate22:11:28

passing the bindings to the constructor

saeidscorp22:11:40

@gamecubate you can also define a protocol and use reify to make different implementations wherever you want.

gamecubate22:11:09

Like:

(defrecord Engine [canvas sketch]
    IEngine ;
    (init! [this] (log (str "initializing engine with sketch " sketch)))
    (start [this] (log "starting engine"))
    (stop [this]  (log "stopping engine")))

(defn launch []
  (doseq [c (sel "canvas")]
    (let [sketch-name (.getAttribute c "data-sketch")
          eng (->Engine c sketch-name)]
      (init! eng))))

bfabry22:11:12

@gamecubate not to assume too much but if you're calling defrecord at runtime you may be misunderstanding things

gamecubate22:11:14

Seems to work

gamecubate22:11:52

@bfabry Just trying to create as many instances of a canvas engine I am writing as there are canvases on the (DOM) document.

gamecubate22:11:02

I do no think that it is called at runtime. See revised code.

bfabry22:11:09

yeah cool. your second example is fine. defrecord only gets called once, at compile time, which is what you want. your example before that was dangerous because it calls defrecord multiple times, which creates orphan tricksy classes

gamecubate22:11:50

Makes perfect sense. Defining a record type everytime seems like a big nono

gamecubate22:11:16

Revised code works. Thanks everyone!!

gamecubate22:11:43

The asking gave me the answer. 🙂

gamecubate22:11:02

“ask and you shall answer” hehe

fiddlerwoaroof22:11:38

Yesterday, I spent several hours trying to figure out why some code wasn't working, it turned out I had typed "::role" instead of "::roles" 🙂

bfabry22:11:45

nb: I'm using "compile time" and "runtime" like they're different things when this is a lisp and they are not. what I actually mean is "once at file load/program startup time" vs "during regular execution"

gamecubate22:11:15

I had understood you. 🙂

gamecubate22:11:31

gotta go. Thank you again.

kenny22:11:08

When implementing a protocol defined in a different namespace that has a method defined with a hyphen, should you use an underscore or a hyphen? Example:

(ns myns.ns1)

(defprotocol Saucy
  (do-salsa [_]))

(ns myns.ns2
  (:import (myns.ns1 Saucy)))

(defrecord Thingy []
  Saucy
  (do-salsa [_] "aaa"))

;; OR

(defrecord Thingy []
  Saucy
  (do_salsa [_] "aaa"))
Both ways work.

bfabry22:11:54

@kenny you're using the interface that the protocol defines there, I would use the protocol instead

kenny22:11:18

So use hyphens?

bfabry22:11:30

though realistically it probably makes no difference..

kenny22:11:46

Just wondering what people generally use

bfabry22:11:52

yes I would use hyphens, and I would use this form rather than the import form

boot.user=> (defprotocol Saucy (do-salsa [_]))
Saucy
boot.user=> (ns foo)
nil
foo=> (defrecord Thingy [] boot.user/Saucy (do-salsa [_] "blah"))
foo.Thingy

kenny22:11:19

The hyphen isn't supported in Cursive 😞

bfabry22:11:29

ie protocols are an object that gets stored in a var in the ns, you don't need to use the :import interface stuff

bfabry22:11:48

foo=> boot.user/Saucy
{:on boot.user.Saucy, :on-interface boot.user.Saucy, :sigs {:do-salsa {:name do-salsa, :arglists ([_]), :doc nil}}, :var #'boot.user/Saucy, :method-map {:do-salsa :do-salsa}, :method-builders {#'boot.user/do-salsa #object[boot.user$eval1466$fn__1467 0x1f9fc6da "[email protected]"]}}
foo=>

bfabry22:11:07

the hyphen might be supported by cursive if you use the protocol instead of the interface. not sure. certainly java interfaces don't support hyphens

kenny22:11:18

Oh I see, interesting. What is the :import actually doing for a protocol because it works

bfabry22:11:44

it's importing the java interface that is generated for the protocol

bfabry22:11:11

defrecord lets you implement both interfaces and protocols. by implementing the protocol's interface you satisfy the protocol, and vice versa

bfabry22:11:22

but in general, you want to stick with the clojure types when you can

kenny22:11:27

Ah, got it. Cool thanks

tbaldridge22:11:54

the hyphen is supported in Cursive just for the record, I use it almost every day

bfabry22:11:05

cursive does seem fine with the hyphens when I use the protocol

kenny22:11:06

Not when you use :import

tbaldridge22:11:47

right if you use import you have to use the _

tdantas22:11:57

@trptcolin, agree > i like protocols in cases where the underlying implementations will vary, and it's not clear to me whether they would here how would you solve the problem ?

kenny22:11:29

Well, it seems you can use the hyphen even if you use :import (at least it worked in the REPL)

tbaldridge22:11:47

Yes, protocols are great for when you have an abstraction. Where abstraction is defined as a common interface over multiple implementations

bfabry22:11:12

I'm guessing the reason it works is because protocol function names get munged from - to _ when they're compiled or something like that

tdantas22:11:56

oh, sorry @tbaldridge ! cross chat

olslash22:11:11

can i jump in and ask when you'd implement a protocol using defrecord and when you'd use reify?

kenny22:11:11

reify is like an anonymous implementation of a protocol

kenny22:11:26

So anytime you don't actually want to define a record for the impl

tbaldridge22:11:39

@olslash right, use reify when you just want to implement a protocol and don't care about the name of the type and don't need assoc, keyword lookup, etc.

tbaldridge22:11:51

@oliv what you have is really close to transducers

olslash22:11:51

that makes sense

tbaldridge22:11:30

(def chain-instance-one
   (comp (map (fn [x] (* x 4)))
                  (map (partial * 5)))

(into []
    chain-instance-one
   [1 2 3])

;; Untested

tbaldridge22:11:45

and yay, my parens are off

tdantas22:11:36

nice one, have to look into transducers

tdantas22:11:43

thanks for the new topic 🙂

tbaldridge23:11:59

@oliv To break down the parts of that: * map without a collection at the end says "make me a transducer (a processing step)" that will apply this function to each thing it receives * comp combines transducers so they run one after the other * into says "pour these values into this collection running them through this transducer"

etherfuse23:11:30

Hi, I’m messing with macros and I wondered if there is a way to run a macro multiple times

etherfuse23:11:25

This returns a function, but I’d like to pass a list that created many functions

etherfuse23:11:57

seems like this is generally frowned upon, but I’d like to see how it could work

bfabry23:11:56

@etherfuse that returns a piece of code that when executed defines a thing. if you want a macro that defines multiple things you just need it to return a piece of code that does that. if I want a piece of code to do multiple things I reach for do 🙂

foo=> (do
 #_=>   (def a "foo")
 #_=>   (def b "bar")
 #_=> )
#'foo/b
foo=> a
"foo"
foo=> b
"bar"

tdantas23:11:38

yeah @tbaldridge sorry, I was reading 🙂 Yeah I see what you did. but on my problem I need two functions ( add | validate ) , that was the reason to create a protocol !

tdantas23:11:14

(defprotocol IChainable
  (add [this &fns])
  (evaluate [this args]))

(defrecord Chain [chain-fns]
  IChainable
  (add [this func] (Chain. (conj chain-fns func)))
  (evaluate [this args] (map (apply comp chain-fns) args)))
that is the final solution ( credits to @jr to help me )

tdantas23:11:37

the usage was that

(-> (Chain. [])
    (add inc)
    (add inc)
    (evaluate [1 2]))

tdantas23:11:45

and evaluate correctly

tdantas23:11:54

but as you and many others said. protocol fits better when we have multiple implementations

tdantas23:11:46

( i’m still on my clojure journey studies, so if have any other solution, I will appreciate )

lvh23:11:54

Hm. Does lein uberjar happen to run with a limited DYLD_LIBRARY_PATH?

lvh23:11:13

I’m seeing an error that’d be most easy to explain if it couldn’t dlopen a native library but only when running in uberjar mode

lvh23:11:20

(same code works fine in CIDER, lein repl, &c)