This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-01-13
Channels
- # beginners (99)
- # boot (2)
- # boot-dev (4)
- # chestnut (2)
- # cider (75)
- # clara (43)
- # cljs-dev (1)
- # cljsjs (6)
- # cljsrn (4)
- # clojars (2)
- # clojure (76)
- # clojure-brasil (1)
- # clojure-france (1)
- # clojure-italy (2)
- # clojure-spec (30)
- # clojure-uk (4)
- # clojurescript (39)
- # core-async (1)
- # core-logic (2)
- # cursive (1)
- # data-science (7)
- # datomic (14)
- # docker (12)
- # emacs (6)
- # fulcro (69)
- # garden (4)
- # hoplon (7)
- # jobs-discuss (46)
- # leiningen (3)
- # lumo (3)
- # off-topic (12)
- # om (2)
- # parinfer (12)
- # perun (9)
- # re-frame (44)
- # reagent (6)
- # rum (1)
- # shadow-cljs (73)
- # specter (5)
- # unrepl (10)
- # vim (2)
@bj: try-let
is my project š I'm not aware of a better ready-made solution to the problem. I wrote it to scratch my own itch a couple of years ago, but it should work fine
How can I get with-redefs to work on a private function in another namespace?
(with-redefs [my.other.ns/fn-name (fn ...)] ...) is working for you? I was able to get that working in a REPL session test
@andy.fingerhut I didnāt for me. Ill have another go and try to see what Iām doing wrong
Calling the fn directly works for me. My function Iām wanting to redefine is in a partial though
(def my-partial (partial fn-name :foo))
fn-name is private in that namespace and redefining doesnāt seem to work
My REPL test went like this, in case it helps you (starting from user namespace): (ns foo) (defn- bar [x] (inc x)) (ns user) (#'foo/bar 10) ; returned 11
(with-redefs [foo/bar (fn [x] (* x x))] (#'foo/bar 10)) ; returned 100
Yea that works for me too.
I think the with-redefs wont work for me here though
You area trying to with-redefs my-partial ?
yea, Iām not atually invoking the function Im redefining. Im invoking the return value from partial
And the partial is invoking what I pass into it.
Again, not sure if it helps, but continuing my sample REPL session from above: (def mybar (partial #'foo/bar 10)) (mybar) ; returned 11
(with-redefs [foo/bar (fn [x] (* x x))] (mybar)) ; returned 100
Is your def of my-partial in the other namespace, and marked private?
the partial is in the same ns as the private fn im wanting to redefine
Im thinking the functions visibility is irrelevant here
And because it uses (partial private-fn ...)
instead of (partial #'private-fn ...)
you're getting the original value compiled into the partial
expression -- so there's nothing to redefine.
Per @andy.fingerhutās example, the partial
call needs to use the Var not the symbol to give you the extra level of indirection.
But if fn-name is in another namespace and is private, how do you even refer to it in the partial call, without prefixing it with #' ?
ahh thats it
yea I need to use the symbol
> the partial is in the same ns as the private fn im wanting to redefine ^ This
ah, sorry, missed that.
(def my-partial (partial fn-name :foo))
doesnāt work and (def my-partial (partial #'my.other.ns/fn-name :foo))
does
The former has the (partial fn-name :foo)
compiled at namespace load time and bound to the Var my-partial
. And fn-name
is evaluated to the value it has -- its underlying fn
value.
@andy.fingerhut @seancorfield Thanks for the help guys! I understand too now which is awesome!
The latter is still compiled but uses a Var instead -- for the reference to fn-name
-- and maintains the indirection.
so a symbol like fn-name
will evaluate to its current value and later when it is called it will invoke whatever it initially evaluated as. By using the #'some.ns/fn-name
, when invoked later will invoke whatever is currently defined for that symbol?
I think you've got the right idea. I believe that the (partial fn-name :foo) expression without the #' captures and uses the current value that the var fn-name at the time that partial expression is evaluated, and changing the value of the Var fn-name later does not change the value of the partial expression.
(partial #'fn-name :foo) captures and stores the value of #'fn-name, a pointer/reference to the Var fn-name, not to its value.
As a convenience, Clojure Vars implement an interface in the internal Java implementation that causes their current value to be looked up and called.
Right, it only matters when you use a function name in an expression, rather than in another function. In an expression, everything is evaluated, inside a function it's just compiled. (well, slight simplification there but...)
(consider that top-level def
forms are evaluated when the namespace is loaded so your :require
causes the evaluation)
Right so invoking the function (wrap in an anonymous function) will look up the value of the symbol and would work with redef and no #ā. But passing the symbol for the function straight in with #ā doesnāt? Am I on the right track?
I'd have to see the exact code before I answered that.
I think you mean this: https://www.dropbox.com/s/zrs9mvbr66o5j85/Screenshot%202018-01-12%2019.05.54.png?dl=0
yep thatās what I meant.
In case the details might be of interest, the file Var.java in the Clojure implementation defines class Var to impement interface IFn, and IFn is the interface that Clojure functions implement.
I'd have to see the exact code before I answered that.
is there a way to define a wrapper around clojure.test/is where it runs in cloljure modce, but is a no-op in clojurescript mode (this is . clojuretest/is in a *.cljc file)
Something like #?(:clj (is ... ))
?
sometimes they start with an f (`fnil`) or end in -fn (`some-fn`)
@noisesmith ok, thanks, Iāll run with that. Now that I look at that I think I might prefer the leading f. Less of an afterthought, more in your face
Hello. Last week I registered on http://www.4clojure.com and up to date i'm solving the bigger part of it tasks. But. I f I solved the task, I even can not to see any solutions of other members (that is possible on Codewars, for example) - I must follow each of choosen members personally. Why I write this here? Can you suggest me some (3-5) members, that I can follow to learn good Clojure-way style of problem solving and code organize? Thank you.
I havenāt visited 4clojure in a while, but as I recall, when you solve a problem there is a link in the ācongratulationsā text that you can click to see other peopleās answers.
If I wanted to read in a bunch of parquet files and fiddle with the data in them, what's the lightest-weight way to do that?
@manutter51 unfortunately only this >You can only see solutions of users whom you follow. Click on any name from the users listing page to see their profile, and click follow from there.
chased last one for 20 minutes -_-
(merge-with (fnil - 0 0) {:a 0} {:a 2})
=> {:a -2}
(merge-with (fnil - 0 0) {:a nil} {:a 2})
=> {:a -2}
(merge-with (fnil - 0 0) {} {:a 2})
=> {:a 2}
right, if there's no matching key the merging function is never called
it is so obvious it this example, but was not that obvious in
(merge-with
(fnil - 0 0)
{:gold 478 :wood 20}
{:gold 450 :wood 20 :stone 20})
=> {:gold 28, :wood 0, :stone 20}
especially being pre-blinded with clever fnil
useactually, most of the time debugging was spent on getting to the merge-with call, because this call is from days ago, and was considered correct
if you had used merge-with +
and negative numbers, you wouldn't have this issue - but I still think that merge-with is a poor match for this algorithm
and it was faster to use merge-with -
than to update 600 lines of edn with -
in prices : )
does #?(:cljs ... #clj ... ) mess up line numbers? the line numbers seem to not match up with my eidtor line numbers
is there something that provides "core.async channels" over websockets? I don't need the full power of core.async, what I want is a channel taht: 1. provides FIFO 2. at most once delivery 3. back pressure 4. wocks cljs <-> clj over websockets
Most of that is impossible with websockets
Code a protocol to the web socket api and youāll be much happier
Also consider a pull based model, as those are much easier to scale and maintain than a push based model
See Kafka vs RabbitMq for an example
@U07TDTQNL: what's the logic of "most of that is impossible with websockets"
intuitively, client side: keep a queue of items to be delivered send first item over websocket server side: wait for item on receive, send ack if item already recieved (check counter), ignore counter increments, so server side needs only store "value of last counter"
I'm trying to abstract out the mess of disconnections / having it auto reconnect websockets
Eh, I mis-read "at most once" as "exactly once". But aside from that, what you're talking about here is TCP over Websockets (over TCP).
And in the end it's just not something that works well. Websockets don't implement back pressure, so you have to implement that as well in the user layer, which slows things down even more.
When a client disconnects it could re-connect through a different server in a load-balanced cluster
All this goes away in a pull-based model.
1) Client connects 2) Server replies "there are 2000 available messages" 3) Client says "well I have 3 so far, so get me the next 100" 4) Server replies "here's 4-104, btw, you have 10000 available messages" 5) Client says "I'm behind, let me skip forward to message 9950 and get me 50 messages" 6) goto 4
This also scales well over slower bandwidth systems, and reduces the amount of tracking the server has to do. Infact the entire protocol is stateless and can be implemented over HTTP. Which has the nice side-effect of working in places where websockets don't (corporate networks)
I'm working on an "editor" where: * frontend = DOM / SVG on localhost:8000 * backend = clojure + jvm + ring + websockets * all "logic" is done in backend * "frotnend" is just (display this SVG/DOM, and routes all keystrokes / mouse events to backend) * this will be fully scriptable in clojure so now, I need a way for clients to "push" these keyboard / mouse events to the localhost webserver