This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-01-20
Channels
- # aatree (42)
- # admin-announcements (25)
- # alda (28)
- # aws (56)
- # beginners (67)
- # boot (248)
- # braid-chat (9)
- # cider (52)
- # cljsrn (11)
- # clojars (4)
- # clojure (341)
- # clojure-czech (5)
- # clojure-japan (3)
- # clojure-nl (2)
- # clojure-russia (57)
- # clojured (10)
- # clojurescript (35)
- # community-development (18)
- # cursive (17)
- # datascript (5)
- # datomic (39)
- # dirac (25)
- # editors (2)
- # events (3)
- # hoplon (60)
- # jobs (5)
- # ldnclj (9)
- # leiningen (5)
- # mount (20)
- # off-topic (3)
- # om (263)
- # onyx (69)
- # perun (5)
- # proton (55)
- # re-frame (7)
- # reagent (24)
- # spacemacs (6)
- # yada (16)
@jsa-aerial: docs at http://clojure.org/reference/compilation#directlinking
if you scroll up slightly from there, there are docs on how to enable compiler options including direct linking
I'm going through the Living Clojure book, and I'm a bit lost on a topic. Say I were to build a tradition CRUD/todo list backend. What would I use the following for: Atoms, Refs and Agents?
@bcoop713: You might not use them anywhere… Once you really get into using Clojure, you’ll be surprised at how rarely you need mutable state inside the program.
For example, we have about 30,000 lines of production Clojure and only 30 atoms — and those are nearly all just caches. We have just 3 agents, and no refs at all.
I can’t find a non-pithy way to say it: atoms/refs are mostly used when you need mutable state 😛
Mutable state is a last resort 😸
Your crud/todo list backend could have its database state stored in an atom, fer instance
(as long as nothing else is likely to modify the DB under you)
Or you might implement a database connection pool using an atom. It’s hard to give a general principle for their use except, as sean says: lightly?
interesting. And under the covers, is it actually mutating state, or does it use some sort of state monad?
When you swap!
or reset!
an atom, it updates the value inside the atom, atomically, so it’s "real state".
You just really don’t need it much.
For example if it's a state you need to keep across function invocations like cache or in-memory database - then an atom/ref might make sense.
If it's a - say - iteration state then you can do recursion or use the loop
macro (which is sugared-up recursion).
Also an indication you might need an atom or ref if you need to coordinate something, possibly across threads. Access to atoms is guaranteed to be serialised, and access to refs can be wrapped in ACI transactions.
is that if i wasn't using core.async or would there be a use case to use atoms along with channels?
Depends on your use case, I suppose. If you need to accumulate what you get over the channel somehow, atoms and refs sound more sensible than using a loop
parameter or something. If you just need to react as-you-go and don't need to keep things around, you can do away with atoms.
The difference between channels and reference types is a bit akin to the difference between a queue and a database, just in-memory.
Like all analogies, it's certainly approximate and can lead to a bit confusing intuitions - monads are not burritos - after all, but I think it's a good first-degree approximation of their respective niches.
If I am running emacs and evaluate something like (in-ns ‘my-namespace)
in a buffer, if I evaluate (clojure.core/ns-name clojure.core/*ns*)
in my CIDER REPL, the namespace remains user
. But, obviously, if I evaluate (in-ns ‘my-namespace)
directly in the REPL, the namespace changes. Why does this work this way?
Did some research, seems like the only clj graph library + graph query language that works is neo4j. ogre/titanium are woefully out of date and/or depend on writing Java. Loom is amazing but doesn't really have a query language.
@alexmiller: how do you enable direct linking in Leiningen/Boot?
@bradford: does this help? http://stackoverflow.com/questions/4166092/neo4j-license-limitations/15217988#15217988
@danielcompton: in lein you'll need :jvm-opts ["-Dclojure.compiler.direct-linking=true"]
(I think, doing that all from memory)
in boot, don't know off the top of my head
@alexmiller: Aha - yes, I see it now. Thanks!
@danielcompton: BOOT_JVM_OPTIONS
for boot
how would you remove all leiningen dependencies, in order to check if a clean checkout and the a lein run
would work as expected?
delete your ~/.m2 directory
maven stores all deps locally there
I'm trying to use a protocol I wrote in clojure in my java project. I built the uberjar and copied it in my java projects classpath. But when I try to compile the java project using plain and simple "javac -cp mycloj.jar Main.java" I get a "cannot find symbol".
nberger: tx i was able to resolve the issue (i placed the slamhound dep, in :plugins instead of :dependencies)
jan.zy: nberger its supposed to fix missing require ns , but i only see it remove unneeded ones so far
I'm implementing the resulting interface. But it cannot resolve the import, whereas it has no problem resolving i.e. clojure.lang.IFn
@shaym it fixes missing requires... perhaps you are hitting an edge case? what's not fixing?
@nberger: I had a file which was using some fns from another file in the same dir , but slamhound didnt add the needed require , maybe it adds the ns when the require already exists
@dm3 its just a usual java project setup with src and lib. The protocol interface is in the uberjar.
@shaym: that should work. except for example if the fns are also found in the default :refer's from clojure.core for example... or if there's a compilation issue in the other namespaces...
IIRC it does kind of a brute force search for the symbols on every reachable ns, and your other ns should be included in that search if it compiles correctly
When I don't include my uberjar in the classpath it also complains about clojure.lang.IFn not being found
@dm3 maybe have a quick look at my clojure code? Its hosted at github: https://github.com/drosowski/slack
Its not the latest version, but I only changed the methodnames on the protocol (removed the dashes)
@dm3 I never had the case that a class is not found during compile time, but is available at runtime. Only the other way round
Can you dispatch a multimethod on multiple arguments while preserving their isa?
hierarchy?
Should I compute the lowest common ancestor of the arguments in the dispatch function and dispatch on that?
For people using system/components, how do you deal with redefining Records? It seems like quite a common thing, especially as you are building out your app with dependencies for components, etc. Right now I'm forced to re-start my REPL to get the new record into memory. Am I missing something?
Sometimes you can get away with fully reloading all namespaces.
And tossing all references to the old record. That usually means starting all components from scratch again to be safe.
jcromartie: If I run (stop) then (start) again anything defined in defrecord is still stale.
hm, same here roberto. So if you add a (println "foo")
in some record's start fn, run (stop)
and (start)
, does "foo" show up then?
@oskarth: @yogthos just published some thoughts on this in http://yogthos.net/posts/2016-01-19-ContrastingComponentAndMount.html.
thanks @jindrichm, will read through it
so it seems to mostly advocate mount, which might be a good idea, but doesn't really help dealing with components in a more sane way
I tried mount
, and it is easier to get started, but I’ll be sticking to component. With mount
I found it easier to make a mess.
one thing I learned is that defining the interface functions generically means you can usually avoid making too many changes
@roberto: you don’t need to restart the repl with reloaded, but you can’t keep any state there either
@yogthos: hm, so it seems like you are saying it is possible to change the record of a component and restart the system without restarting the repl?
using https://github.com/weavejester/reloaded.repl or the equivalent
right, but that's a different case. I still don't understand how to change a record and not restart the repl.
(for those types of things I'd just use cider-eval-buffer
or eval region in a (comment ...)
section)
and yeah I don’t think reloaded obviates the need to restart the repl, you just do it less often
so @roberto is right in saying I don’t think you can, because they are
instantiated`.? I'm confused. I don't know enough about how records are implemented and evaluated to have a good mental model of this.
it seems particularly weird to me because so much of using system and components consists of actually designing the components interface, which leads to a lot of repl restarts, hence the feeling that I'm missing something
components are the outer interfaces or ports
of your app. Also, not everything should be a component. I normally start developing inside -> out.
The inside
or inner
layer, I can just start working on it in the repl without needing component. So I have never had the need to rebind
a component.
I think that's mostly what I'm doing, but I'm converting things from a non-component workflow to a component workflow, and mapping out dependencies and such
the protocol can define a resource, and then the instance lifecycle can be managed by defstate
it's possible my components aren't generic enough and thus requires a bit too much fiddling compared to what components/systems is optimzied for
yeah, if you started without component, and your codebase got large, it can be tricky to shoehorn component in there.
I normally add component as soon as I have more than two systems
that need to interact
then it should not be that difficult. Also, you can do everything in the repl, just assign the component to a var
(.start MyComponent) returns a component, and you can inspect it and pass it around if you assigned it to a var
@roberto: > I found it easier to make a mess can you share a bit more of you experience which lead to this reasoning? you can do it in a #C0H7M5HFE channel if it is more appropriate
it was easier to just say: I can just have a giant atom here and mount it, and have it accessible everywhere.
interestingly, https://github.com/weavejester/reloaded.repl/blob/master/src/reloaded/repl.clj#L55-L57 seems to solve the use case of adding stuff in the record, as far as I can tell
I am more interested in "lead me to think I'll make a mess with it" line of reasoning, if you can share of course
yeah, you can use reset
and it will do that: reset your system with the new definitions
@oskarth did you have suspendable components? because all the reset-all
does besides suspending is just a namespace refresh
so the answer to my question then is: use reset, and this mean that records can be changed.
My original question was: "For people using system/components, how do you deal with redefining Records? It seems like quite a common thing, especially as you are building out your app with dependencies for components, etc. Right now I'm forced to re-start my REPL to get the new record into memory. Am I missing something?"
@tolitius: yeah I know, but I falsely assumed component took take it (why wouldn't it)
I thought you wanted to maintain the state of your app, and be able to redefine a single record, and swap it from underneath all the other components that depended on it
for example, refresh doesn't help you with external libraries, so I thought records by a certain name weren't affected by whatever start/stop did.
https://github.com/weavejester/reloaded.repl/blob/master/src/reloaded/repl.clj#L55-L57
the problem with (reset)
in REPL is with records that were previously defined in REPL. you generally should not see problems with (reset)
, unless something does not compile, then you have to do (refresh)/(refresh-all) which also does not work sometimes, usually when components have incorrect destructors..
@tolitius: I don't understand, how is calling refresh/refresh-all different from reset? reset(-all) calls those.
yeah, if you have a ring
component, and you don’t stop the server in the stop
Lifecycle of the component, then reset
will not work
honestly, for me it just works, I don’t spend time trying to figure out why. As @tolitius mentioned, when reset
fails, I do reset-all
, but it rarely happens to me.
yeah, I assume start/stop are properly implemented. I'm just talking about the record.
I guess the confusion is the weavejester/reloaded.repl
and how to just use clojure/tools.namespace
directly
argh, lots of misunderstandings. The answer was simply reset/reset-all rather than just stop/start.
@oskarth: could you provide an example of what does not work? would it easier to help/discuss
e.g. that's how I typically use tools.namespace
: https://github.com/tolitius/mount/blob/master/dev/clj/dev.clj#L36
when I asked what I was doing wrong no one said reset
, and I later found by experimentation and looking at reloaded.repl source code that my use case works
I’d recommend reading the clojure/tools.namespace
README if you want to get a better understanding. It was very helpful when I was starting off with the reload workflow
.
@oskarth: yes, sure. it is always best to go to the root (i.e tools.namespace
), rather than try to understand how it's wrapped
more misunderstandings! I must not be expressing myself very clearly. The problem was not with not understanding how refresh
works, but in thinking that component/reloaded already did that in start/stop.
it doesn't matter though, everything is fine, the answer is to use reset
when changing records
If I had read http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded more carefully I would've found this out earlier (ctrl-f heart)
@tesseract: I think the SoundCloud and Netflix guys published a lot of stuff about precisely this
@tesseract: like this one http://blog.josephwilk.net/clojure/building-clojure-services-at-scale.html
@val_waeselynck: thank you!
I liked the swan book too. I’ve heard good things about “Living Clojure”. I’ve read “Clojure for the Brave and True”, which was really good. Was hard to gauge because I’d already read an intro at that point.
is this still the current solution if you need a gen-class to reference its own name in either a return value or a type hint? https://groups.google.com/forum/#!searchin/clojure/gen-class/clojure/A9Si6Ow581U/sstYR15uBgAJ
if anyone didn't take the Stackoverflow developer survey - it ends in a few hours https://www.surveymonkey.com/r/so-2016 say nice things about Clojure! :)
@vanrysss: A lot of the Clojure books are available on Safari Books Online, if you're limited on budget and just want to get a feel they have a trial and are pretty reasonably priced otherwise.
@shaun-mahood: hey, is Clojure Applied on there? I heard a rumor that was the case.
Heya. I'm looking for something like cond
, but if test is true, I want to use the result of test in the expr. Does that make sense? I think as-> kinda gets me there...
you want "or"
oh, never mind
I understand what you're asking for
@jaen: just one branch. I basically want the output of the test to be usable in the expr I execute
Yeah, I kind of didn't notice the as
before ->
and wanted to suggest some->
, but that's not it.
So you basically want to have something like when-let
but with multiple branches, like in cond
. Not sure if there's something like that.
Yeah, it'd look something like
(condb->
(:pipelines a-graph) (prn "pipeline name:" %)
(:graphs a-graph) (prn "graph name:" %)
(:sources a-graph) node) (prn "source name:" %)
)
https://github.com/amalloy/useful/blob/ecbdaf10ffe341d7af3ed47b2706d1c668a37da4/src/flatland/useful/experimental.clj#L31 https://github.com/puppetlabs/clj-kitchensink/blob/master/src/puppetlabs/kitchensink/core.clj#L964
There's more here - https://crossclj.info/clojure/cond-let.html
I like how if I can think of the name of something, someone probably wrote it and it does what I expect. It's like, casting a magic spell or something.
@alexmiller: Clojure Applied is on Safari - https://www.safaribooksonline.com/library/view/clojure-applied/9781680501476/ From what I can tell, they have all the Clojure books from Pragmatic Bookshelf , O'Reilly books, Manning, and PacktPub books on there. They don't go on same day as they're published and you can't get access to the betas' but otherwise it's got a pretty complete Clojure library.
Yeah, Clojure Applied is a very good book. I think its ~perfect as a second Clojure book
I actually just got Clojure Applied! It's moving a bit fast for me but I like it so far.
slester, first chapter or so hits a bit harder than I’d maybe like but hang in there. I think it becomes worth it
@tmtwd: not super new, no. I did Advent of Code in Clojure and whatnot, but I'm progressing beyond toying with it and trying to write applications
@csmith: it's just that I haven't seen some of this syntax before, like {:keys} 😞 I guess I might be too green for it.
understood. Might be helpful to read a different book first or spend some time programming… I find {:keys } destructuring incredibly useful but it was very weird at first
I usually have to spend some time solving problems and hitting certain walls before reading the right thing and having something really stick
Sure, but on the other hand I might not come across certain things just "programming" (not sure what that means even, tbh!)
yeah, that phrase wasn’t well formed. I meant building things to practice the language
I did have a question I haven't seen answered very well anywhere about structuring a project. I'm currently doing a game and I'm in circular dependency hell.
still having trouble with circular dependencies though, flipping through I didn't really see anything that dealt with it
haha. It is usually making namespaces smaller but the exact remedy isn’t always obvious
err, often adding one namespace can fix it. if A and B depend on each other, like: A <-> B, then adding C and pulling some things out, making them both require C. that sort of thing
I may just have to do a rewrite to avoid going insane trying to figure out how to cut it cleanly. Thanks for the input @csmith!
Anyone know the correct way to take a function’s var (e.g. #’my-namespace/sample-job
), convert it to text (`str` appears to do the trick), then back to a var again?
Essentially, I want to be able to store the function’s name, then recall it for evaluation later.
I don't know how to get a clean symbol from a var. But you'll ultimately want to use symbols with ns-lookup to resolve the var again.
I mean ns-resolve
for example: (ns-resolve 'clojure.core 'map)
returns the var #'clojure.core/map
You’re right – the var is one step away from being able to evaluate the function.
well the var is good enough
you can call a var
(#'clojure.core/+ 1 2)
(do we have a clojure bot here?)
I remember in IRC I could do:
,(+ 1 2)
So the missing piece, then is taking a string and converting it to a symbol?
I feel like parsing (str #'whatever) is a little bit iffy... should be a cleaner way
metadata to the rescue
I've got a simulation question for ya'll. I've built a distributed stream processing system, basically a DAG of queues and workers (powered by .jars). I'd like to simulate it on a single box. So I'm thinking of using that same DAG, but core.async = queues and Agents = workers. Is that the right way to think of this?
@kendall.buchanan: the map returned by (meta some-var) has a :name key with a symbol, and a :ns key with the containing ns object itself
K, playing with it now...
and you can call ns-name to get the ns symbol
so, like: (-> #'map meta :ns ns-name)
returns 'clojure.core
Are you suggesting this? (str (-> #'map meta :ns ns-name) “/" (-> #'map meta :name))
for the fully qualified string?
where are you storing this?
It’ll be stored in Redis. My goal is to recall a function as a “job”.
ah ha
That can be called elsewhere.
And I’d rather not use matching keys (if I don’t have to).
(Thanks for indulging this, by the way.)
well, if it's making a round trip as a string, you might as well just use str or pr-str I guess
I'd be concerned about the security implications of getting a var from a string and calling it
Okay, so I think I got it now: var -> str, then str -> symbol -> var.
you can also round-trip a var with (-> a-var pr-str read-string eval)
but, again, security...
Right.
that's why I usually stick with namespaced keywords for job/command dispatch
with a multimethod
(defmethod do-job ::whatever [x] ...)
That’s actually a fine idea. Thanks.
Cool, thanks for all insights.
I basically want a Var that's shared between threads, but scoped locally to a function
why would you use a var for that?
java has a threadLocal concept
but it usually goes against all clojure concepts
Well, I'm trying to test something, and I need to purposely create a synchronization bug
I don't my declaring a global var, just thought it would be better I could avoid polluting the namespace with it
@alexmiller: By the way, when are 2015 State of Clojure Community survey results coming?
Hi. Is there a way to pretty-print into a string w/o hacks like capturing output?
@andrewboltachev: pprint takes an optional writer argument, so a StringWriter in there would work. imo capturing output is simpler
@bfabry: thanks!
(with-out-str (clojure.pprint/pprint foo)) vs (let [sw (StringWriter.)] (clojure.pprint/pprint foo sw) (.toString sw))
yeah, didin't know about with-out-str
hey everyone, I am using aleph and manifold. when I make a post request ->
(-> (aleph.http/post url opts)
(manifold.deferred/on-realized cb cb))
the request ends up getting sent twice.
but, if I instead write
(-> (aleph.http/post url opts)
(manifold.deffered/chain cb)
(mainfold.deffered/catch cb))
It works fine. : |
My question is, what could be the different between (d/chain) and (d/on-realized), that could cause the request itself to send twice?@juhoteperi: Last I heard Alex say he had written up the survey results and someone is editing that report - should be soon.
I don't know why I didn't think of it, but a local atom used with reset is basically a mutable variable shared across thread. So it's essentially similar to a global root var.
@didibus: well, you'd still have to ensure the same atom is used across threads. a true local, e.g. created in a function-local let, would be created anew on each function invocation. an atom captured in a closure, though, would be a shared mutable.
@jonahbenton: ya, that's true, in my case, that's exactly what I wanted, for the state to be reset when I call the function again
not that i'm actually planning on using this in any meaningful way, but is there a way to go from a "compiled" anonymous function object back to the s-expressions used to create it?
or is it compiled to jvm bytecode and then the actual list discarded?
quick question - I have a clojure project that provides an http server, but as part of that project I've also written some scripts that do db schema migrations and such (on postgres). right now I'm just triggering those scripts by executing them in lein repl
, but it would be great if I could make some kind of standalone command (either as part of lein or even outside of it) that would run those. how might I go about doing that?