This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-12-15
Channels
- # adventofcode (1)
- # beginners (79)
- # boot (23)
- # cider (15)
- # cljs-dev (14)
- # cljsrn (27)
- # clojars (4)
- # clojure (172)
- # clojure-dusseldorf (23)
- # clojure-india (2)
- # clojure-italy (1)
- # clojure-nl (23)
- # clojure-russia (43)
- # clojure-spec (29)
- # clojure-uk (70)
- # clojurescript (97)
- # clr (8)
- # cursive (10)
- # datomic (69)
- # events (3)
- # garden (12)
- # hoplon (120)
- # immutant (34)
- # lein-figwheel (9)
- # leiningen (4)
- # off-topic (4)
- # om (10)
- # onyx (51)
- # rdf (1)
- # re-frame (15)
- # reagent (23)
- # ring-swagger (8)
- # test-check (3)
- # untangled (96)
- # yada (1)
@gdeer81 I tend to start with the simplest abstraction first. If only for the reason that I can then refactor fast and it's easier to grok. So I'd start with maps until I understood the use cases better.
I have same approach around maps vs records and multimethods vs protocols
although I'm not entirely sure multimethods are 'simpler' than protocols I think they're more explicit (in my mind).
What can I do to get rid of these warnings :
WARNING: reader-conditional already refers to: #'clojure.core/reader-conditional in namespace: clojure.tools.reader.impl.utils, being replaced by: #'clojure.tools.reader.impl.utils/reader-conditional
WARNING: tagged-literal already refers to: #'clojure.core/tagged-literal in namespace: clojure.tools.reader.impl.utils, being replaced by: #'clojure.tools.reader.impl.utils/tagged-literal
Sounds like you’re pulling in an old version of tools.reader somewhere.
(probably through a transitive dependency)
If you’re using Leiningen, lein :deps tree
should show you all the libraries being pulled in and their versions. That will show you what’s pulling in tools.reader and what version it is.
@seancorfield then I see this output :
C:\Users\rwobb\Desktop\clojure\paintings2>lein :deps tree
':deps' is not a task. See 'lein help'.
Did you mean this?
deps
that gives this output : https://www.refheap.com/124267
oke, cloverage it too blame : [cloverage "1.0.9"] -> [org.clojure/tools.reader "1.0.0-beta3"]
@st @seancorfield is it safe to follow the rest of the recommendations
I saw that chesire schould be excluded and that would be a problem with clj-http and json input from a external api
What is a good plugin for validating that you use clojure well ? I know that kibit and eastwood are two choices
Kibit and Eastwood are good for different things. Eastwood for stylistic things and issues like your dependency problems above and kibit suggests alternative fns you may not have thought of.
Although Eastwood makes some fn suggestions Kibit is more comprehensive
what went wrong here :
C:\Users\rwobb\Desktop\clojure\paintings2>lein deps
Retrieving lein-kibit/lein-kibit/0.1.3/lein-kibit-0.1.3.pom from clojars
Retrieving jonase/kibit/0.1.3/kibit-0.1.3.pom from clojars
Retrieving org/clojure/core.logic/0.8.11/core.logic-0.8.11.pom from central
Retrieving org/clojure/core.logic/0.8.11/core.logic-0.8.11.jar from central
Retrieving jonase/kibit/0.1.3/kibit-0.1.3.jar from clojars
Retrieving lein-kibit/lein-kibit/0.1.3/lein-kibit-0.1.3.jar from clojars
C:\Users\rwobb\Desktop\clojure\paintings2>lein kibit
'kibit' is not a task. See 'lein help'.
Have you added it to :plugins in your project.clj or ~/.lein/profiles.clj?
Needs to be in :plugins and not : dependencies
I see now two recommendations :
At C:\Users\rwobb\Desktop\clojure\paintings2\src\clj\paintings2\api_get.clj:14:
Consider using:
(client/get
(str " " id)
{:as :json,
:query-params
{:key (env :key),
:format "json",
:type "schilderij",
:toppieces "True"}})
instead of:
(-> (str " " id)
(client/get
{:as :json,
:query-params
{:key (env :key),
:format "json",
:type "schilderij",
:toppieces "True"}}))
At C:\Users\rwobb\Desktop\clojure\paintings2\src\clj\paintings2\api_get.clj:50:
Consider using:
(client/get
(str " " id "/tiles")
{:as :json, :query-params {:format "json", :key (env :key)}})
instead of:
(-> (str " " id "/tiles")
(client/get
{:as :json, :query-params {:format "json", :key (env :key)}}))
The two options in the first one are equivalent.
(-> (foo) (bar))
expands to (bar (foo))
Basically, ->
takes the result of the first thing, and “threads” it in as the first argument to the second thing.
@agile_geek so is it better to change it of let it what it is
Anyone know a way to measure the size of a ref? or atom?
@roelofw Up to you. Kibit is just saying that for just two expressions it's just as clear to nest them in parens. For more than 2 the thread first macro is probably a better choice
@josh_tackett a ref or an atom doesn't really have a size. The data structure referenced by a ref or an atom may have. If that data structure is a collection you can use count on the dereferenced atom or ref: (count @my-atom)
@agile_geek thanks
@josh_tackett however it's rare to want the number of elements in a collection as this is usually something done in imperative languages to process all elements in a for loop. We usually use map
to process a collection (or reduce
if the result has to be an accumulation)
@agile_geek So the issue is that this ref is growing in memory and I need to find out why, and also how to garbage collect properly. Need to see the size print out to know that...
@seancorfield any ideas ^^^
Must be a massive data structure if it's consuming that much memory. The garbage collector will clean up any data structure no longer referenced so while you have a data structure in a ref or an atom it will never be GCed. For this to be a problem you are probably doing something a bit strange. It's typical to maintain all requiredstate if required in an atom, for example, in a Clojurescript application and it would not normally consume much memory. Something is fundamentally wrong if you're running out of memory. Are you eagerly fetching a large amount of data from a file or database?
Just wondering and I know this may be a very general question but just wondering if there is a typical way in clojure to represent state? i.e. do I typically want one map that contains all of my data or is it common to have more than 1 stateful collection that I operate on?
@kyle_schmidt the short answer is try and avoid keeping state at all. For example, in a CRUD web app you can just process data through a stack of function calls without storing it anywhere but in the database.
Can I do that also in for example a accounting website. I thought I need somewhere the amount of every account so I can do checks on it. Or do I every time calculate that again ?
If absolutely necessary (usually only on client side UI using Clojurescript) you would typically store a map of maps and vectors in a single atom to represent all state in one place
You don't need state in your application code. You would need to store the state in some persistent data store (a database or even a file)
@agile_geek Thanks! That makes sense!
It it common practice to have a single clojure atom with your system state, which may itself mediate access to external persistent storage
@roelofw You can also use JWT with an expiration time that the client would send to the server to verify that the REST request is valid
and you wouldn't need to store login server side
oke, and how can I then deal with checks that accounts may not be negative. Calculate every time the amount of a financial account ?
@kyle_schmidt if you want to maintain being logged in between browser sessions that's a good solution. Although I typically force a login on every session depending on app
@roelofw or store the total
Although storing the total in a multi tenanted environment may be problematic and lead to deadlocks etc
Well presumably the account data is in database anyway right?
And transactions as children of an account?
So if you always have to fetch the txns and /or you know there aren't many per account you could just total them in the process of transforming them for display.
But if you aren't always reading all txns per account you'll need to store the total
and what if there are many txns? Would you store those in an atom and write them all to the database after a period of time to reduce i/o?
many txns across many accounts**
@kyle_schmidt depends on the database. If it's relational and you can't bulk update you might as well update directly. These aren't really Clojure questions more architecture. For instance if you had to load millions of txns then I might read them, write them to an asynchronous messaging system and have another service or another process in same app read from the message queue to write in bulk. If ot was really big data maybe use a streaming framework like Onyx
gotcha. sorry, didn't mean to stray off topic
I use atoms sparingly and usually for small amounts of data in a specific use case that only needs in memory transient storage...and even then I might use an in memory database
@kyle_schmidt no problem 😄