hi, is the nrepl protocol documented somewhere?
@madeofcode has joined the channel
could someone possibly explain why clojure.walk/postwalk would give me an AbstractMethodError on a datomic entity map?
even just doing plain (walk/postwalk identity my-map-with-an-entity-map) gives me the error
but, as soon as i dissoc the entity map from the original map, it works fine
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"])
Im expecting to see something like { :id SK-C-5 :tiles "http:
@roelofw because map is lazy, no execution is performed until the result is consumed
wrap the map with a doall
like (doall (map …))
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)) and there I see output
but I will try the doall
because pmap is semy-lazy
while map is fully lazy
hmm, no difference , still I see in Cursive Process finished with exit code 0
with no further output
try to prn the output
(prn (read-image-url [”SK-C-5”]))
the output it must be there, maybe just a Cursive displaying issue
Then I see output , thanks
no problem
is it worth to return a spec from a function? I am trying to spec a reducing function as a state machine.
@donniemattingly has joined the channel
@biscuitpants AFAIK datomic maps implement just the associative bits of maps, they don't implement e.g. dissoc
@mokr Maybe something like https://github.com/shenfeng/mustache.clj , we’ve made a (simple) variant of this. Maybe we should opensource it
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?
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 userHello 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.
I guess I'll have to use atom to mutate user state, any feedback on this ?
@baptiste-from-paris can’t you have one go-loop per user?
@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
since you’re already modeling your mutations as channels
@dpsutton yes I am in the repl
@joost-diepenmaat how would I do that ?
@dpsutton forget the def states, I just use (fsm [:first :second]) in the repl, it's not clear, I give you that ^^
ah ok
so since its pulling from the channels constantly saying :prev and :next, is this a random walk through the states?
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 🙂
@baptiste-from-paris call (fsm …) when you add a user
@dpsutton yep !
cool
@joost-diepenmaat as simple as that ^^, I guess I'll have to use a timeout then, in case user stop making actions
and what was the issue again? I was making sure I was following the code first
It's working great on a 1 user putting stuff in the channels
but I want to keep states for every different user in the application
can you not change from :next vals on your channels to {:user 1 :state :next} or some equivalent?
and then the thing you are recurring on is a map of maps where each user moves through?
I don't get it
here is a typical use-case =>
you're moving one value through your fsm right now
- user 1 make a next action
- user 1 make a next action (:second state)
- user 2 make a next action (:first state)
Right now I am able to keep state without the user notion
as I am the only one to make actions
but can't figure out simply how to make this work for 10 different users at the same time
make sense ?
this is what i was thinking
i don't have async loaded in my repl so i haven't tested it but the gist should be correct
let me 2min to look out the code ^^
thx for your time
absolutely
but we're just keeping a map around that puts a user id with each state
so when you say next state, you're including a user id
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
So I have 1 go loop handling all users inputs ?
I think I have an other id but not sure, let me work 5min
no prob
and in the case where the final state is reached you could recur with (recur (dissoc userstates (:user user))
and could even get more fancy by remembering who has completed the fsm and not allow them to enter again
its also possible that this is a terrible idea but it was something i came up with at the time
@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
@prayerslayer has joined the channel
@amorokh has joined the channel
or I use pub/sub with user-id as topic
which looks weird because it means that I dynamically have to create go loops if user-id is seen for the 1st time
@gedeon has joined the channel
@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})
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
It then keeps track of each user's state.
I really don't know if it's the "right" way to do it
@markus_s has joined the channel
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 Clojureare they all transform operations?
comp the transform functions and then map
how to emulate the usage ? like an object
that is my pain point
😞
do you see what I mean @jr ?
yeah so you'll want to add a chain attribute to the record and then add will simply conj the function onto chain
(defrecord Chain [chain-fns]
IChainable
(add [this chain-fn] (Chain. (conj chain-fns chain-fn))))
and evaluate will do something like this
(map (apply comp chain-fns) args)
(add [this chain-fn] (Chain. (conj chain-fns chain-fn))))
like that ! thanks @jrthat was my problem, I was thinking on atom/refs/agents ....
but you solved very well
thanks
then you can thread it like so
(-> (Chain.)
(add (partial * 4))
(add (partial * 5))
evaluate)
OMG ! that is so cool !
thanks @jr
I’m sure I will click someday to think like that 😄
thanks !
I recommend reading "The little schemer" to get your gears spinning on recursive functions
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)
that one, right ? https://mitpress.mit.edu/books/little-schemer @jr
i like protocols in cases where the underlying implementations will vary, and it's not clear to me whether they would here
correct
thanks mate !
@meurig has joined the channel
is there a defense for this? (number? Double/NaN) ;; => true
this is why i love test.check.
well, despite its name NaN does actually behave like a number in a lot of places
boot.user=> (/ Double/NaN Double/NaN) NaN
whether there's a defence for that is probably more a question for the original people at Sun 😆
always room for a sharp edge i guess.
welp. i’ll just beef up the :post condition a bit more...
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
(defn finite? [n]
(and (number? n)
(Double/isFinite n)))ugh.
spec actually has a spec for this, double-in
yeah. this is in a :post condition though. i don’t really wanna wrap the return value with spec/assert.
i guess spec/assert could be in the :post condition but that feels dirty.
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
of course, that doesn't satisfy integers 🙂
jumps from a high place
NaN is part of the IEEE 754 standard for floating point numbers...
well there you go
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"
Is there a way I can ignore objects?
@ibarrick this would do the trick:
(edn/read-string {:readers {'object str}}
"[:a :b #object[work.core$eval10426$fn__10427 0xf94f00 \"work.core$eval10426$fn__10427@f94f00\"]]")you are free to use any function for interpreting object (instead of str).
Thank you!
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
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?
what other option do you have? 🤔
No other options, just wondering if this is a 'bug' or idiomatic Java that is working as expected?
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.
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"))))
Not like that
You might be able to put the let around the defrecord though?
@gamecubate you could use the let form around the defrecord
Hmmm
didnt think of that
will try
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)))
I don't think you want that defn
Indeed. Doesn't work.
Problem is I am trying to code to support multiple instances of the implementor (Engine).
OK. I can always move the let to the actual defrecord invoker
passing the bindings to the constructor
@gamecubate you can also define a protocol and use reify to make different implementations wherever you want.
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))))
@gamecubate not to assume too much but if you're calling defrecord at runtime you may be misunderstanding things
Seems to work
@bfabry Just trying to create as many instances of a canvas engine I am writing as there are canvases on the (DOM) document.
I do no think that it is called at runtime. See revised code.
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
I see
thnx
👍
Makes perfect sense. Defining a record type everytime seems like a big nono
Revised code works. Thanks everyone!!
The asking gave me the answer. 🙂
“ask and you shall answer” hehe
haha
absolutely
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" 🙂
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"
I had understood you. 🙂
gotta go. Thank you again.
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.@kenny you're using the interface that the protocol defines there, I would use the protocol instead
So use hyphens?
though realistically it probably makes no difference..
Just wondering what people generally use
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
@specious has joined the channel
The hyphen isn't supported in Cursive 😞
ie protocols are an object that gets stored in a var in the ns, you don't need to use the :import interface stuff
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 "boot.user$eval1466$fn__1467@1f9fc6da"]}}
foo=>
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
Oh I see, interesting. What is the :import actually doing for a protocol because it works
it's importing the java interface that is generated for the protocol
defrecord lets you implement both interfaces and protocols. by implementing the protocol's interface you satisfy the protocol, and vice versa
but in general, you want to stick with the clojure types when you can
Ah, got it. Cool thanks
the hyphen is supported in Cursive just for the record, I use it almost every day
cursive does seem fine with the hyphens when I use the protocol
Not when you use :import
right if you use import you have to use the _
@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 ?
Well, it seems you can use the hyphen even if you use :import (at least it worked in the REPL)
Yes, protocols are great for when you have an abstraction. Where abstraction is defined as a common interface over multiple implementations
@tbaldridge how would you tackle that -> https://clojurians.slack.com/archives/clojure/p1480530204018108
I'm guessing the reason it works is because protocol function names get munged from - to _ when they're compiled or something like that
oh, sorry @tbaldridge ! cross chat
can i jump in and ask when you'd implement a protocol using defrecord and when you'd use reify?
reify is like an anonymous implementation of a protocol
So anytime you don't actually want to define a record for the impl
@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.
@oliv what you have is really close to transducers
that makes sense
(def chain-instance-one
(comp (map (fn [x] (* x 4)))
(map (partial * 5)))
(into []
chain-instance-one
[1 2 3])
;; Untested
and yay, my parens are off
nice one, have to look into transducers
thanks for the new topic 🙂
@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"
Hi, I’m messing with macros and I wondered if there is a way to run a macro multiple times
This returns a function, but I’d like to pass a list that created many functions
seems like this is generally frowned upon, but I’d like to see how it could work
@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"
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 !
(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 )the usage was that
(-> (Chain. [])
(add inc)
(add inc)
(evaluate [1 2]))
and evaluate correctly
but as you and many others said. protocol fits better when we have multiple implementations
( i’m still on my clojure journey studies, so if have any other solution, I will appreciate )
Hm. Does lein uberjar happen to run with a limited DYLD_LIBRARY_PATH?
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
(same code works fine in CIDER, lein repl, &c)
IIRC, the dumps are XML, you should be able to parse them with clojure.xml
anyone using core.match in serious business? wondering why its still in alpha/2 years without commits
cause it's stable
i'm sure @dnolen would appreciate help with maintainership, but clojure doesn't really bitrot very much
yeah i'd assume its stable if it wasn't still called an alpha
@olslash what’s there works OK, I have lots of ideas for enhancements but no time to work on them.
I could slap beta, or remove the qualification, it wouldn’t mean much
sorry @olslash I didn't mean to sound cranky
sure sure, and thanks for the reply @dnolen
people use it in production if that’s what you’re asking about
there are some known gotchas, JIRA is informative here
yeah thats mostly what i was getting at, thx
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).
a system is just a map, so make another one with just the parts you want
yah, just wanted to check if that was like a built in thing vs walking deps myself to do this
@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.
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.
@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
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
@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 🙂
@find_my_way pinned a message to this channel.
@mikeb has left the channel
I have two functions with the same input. Is there a way I can use them in parallel ?
same name + same arity?
not the same name , both have the same arity
Use them in parallel means run them in parallel?
yep, that was my idea
or there must be a better way to deal with it
(let [val1 (future (func1 args)) val2 (future (func2 args))] [@val1 @val2])
Was going to say that 🙂
that’s very naive, you can actually make it supporting few functions and use results as you want
thanks, I will try that solution