This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-02-21
Channels
- # announcements (39)
- # architecture (7)
- # aws (9)
- # babashka (111)
- # beginners (139)
- # bristol-clojurians (1)
- # calva (47)
- # chlorine-clover (5)
- # cider (17)
- # clj-kondo (26)
- # clojars (25)
- # clojure (251)
- # clojure-berlin (1)
- # clojure-dev (5)
- # clojure-europe (22)
- # clojure-france (1)
- # clojure-hungary (6)
- # clojure-losangeles (8)
- # clojure-nl (18)
- # clojure-spec (3)
- # clojure-uk (68)
- # clojured (32)
- # clojurescript (32)
- # core-async (10)
- # core-typed (120)
- # cursive (8)
- # datascript (10)
- # datomic (11)
- # docker (2)
- # emacs (6)
- # figwheel-main (4)
- # fulcro (10)
- # graalvm (92)
- # hoplon (2)
- # instaparse (9)
- # jobs (3)
- # jobs-discuss (31)
- # joker (2)
- # kaocha (1)
- # lambdaisland (5)
- # leiningen (10)
- # luminus (1)
- # lumo (14)
- # meander (30)
- # mid-cities-meetup (1)
- # midje (1)
- # off-topic (46)
- # pathom (22)
- # perun (2)
- # re-frame (10)
- # reitit (1)
- # remote-jobs (8)
- # shadow-cljs (71)
- # spacemacs (7)
- # sql (40)
- # tools-deps (31)
- # tree-sitter (11)
- # vim (14)
- # vscode (2)
- # xtdb (5)
what's an idiomatic way to thread a nilable value through multiple functions?
should i use multi-arities thoughout or?...
(def f1
([] (f1 nil))
([x] (if (nil? x) (f2) (f2 x))))
(def f2
([] (f2 nil))
([x] (...)))
weird idea: (apply f2 (remove nil? [x]))
probably not what you want haha
it's clever
but i'm worried about being legible rn
alternatively, i guess i could pass it through and only interrogate it at the terminal
like this
(def f1 [x] (f2 x))
(def f2 [x]
(if (nil? x) ... ...))
But if you're concerned about threading, and not really about designing a fn that returns nil on nil. You could look into using some->
and some->>
instead
i've never heard of those, thank you for the heads up
Im working on an application that has degraded to a mess. It uses Apache POI as one of its main dependencies. (Basically acts as a wrapper for it) The users uploads an excel workbook and then use the web app to input values, the application evaluates the spreadsheet and returns the outputs. I am using VisualVM to try and pinpoint where exactly the bottleneck is and to my surprise none of the functions that I suspected are showing up. This could be because I dont know how to use VisualVM. Here is a screenshot of the result
the two clojure.lang.reflector methods nearest the top should be combined - because the same fix eliminates both, and when combined they are near the top (under what is essentially polling that shows up looking like work)
waiting on a promise-deref / poll / select are all basiically polling, so shouldn't be optimized
*warn-on-reflection*
will usually help you eliminate the reflection overhead
user=> (doc *warn-on-reflection*)
-------------------------
clojure.core/*warn-on-reflection*
When set to true, the compiler will emit warnings when reflection is
needed to resolve Java method calls or field accesses.
Defaults to false.
nil
I got a wall of orange text! Let me fix those reflection warnings. Good catch, perhaps this is the golden ticket
I've gotten into the habit of putting (set! *warn-on-reflection* true)
immediately after my ns
form in almost every new file these days 🙂
Maybe I should put them in the clj-new
templates? 🙂
I learned the other day that there's a clj
/ deps.edn
version of lein check
, I wonder if that turns on reflection warnings
oh yeah, it does https://github.com/athos/clj-check
@mario.cordova.862 after coming back and looking again, it looks like a significant amount of time is spent on file system ops - I don't know your domain, but maybe active objects don't need to be files on disk? A common mistake is thinking that since the thing you work on is commonly refered to as a "file", that it needs to exist on a file system while your app works on it
but then again it could be that POI is inflexible and can't use in-memory data (?)
eg. once I worked on a webservice that resized files for dynamic frontends, and we eliminated most of our turnover latency by doing all the image ops in memory and not using the disk except for caching
That could be the case but I am not familiar enough with the codebase to know enough about what exactly is going on. As far as I am aware the WorkBook object should be in memory.
@tjb Do you mean beyond the resources
/`src`/`test` top-level part?
Not really. Different people -- and different companies -- prefer different things.
I tend to separate things by "domain" concepts more than "function", although within a pure sort of MVC web app, the core is often broken into handlers
, model
, views
or some such.
controller = handler
I've never been a fan of a generic "service" layer. I think that is a bit artificial.
I think you'll see some sort of "store" section in a lot of Clojure apps but I think, overall, things are a lot more organic.
I tend to start with one function per "request" (or "route") and group "related" functions together in a single handler... so maybe ws.admin.handlers.photos
would be all the photo-handling functions.
And each of those would start off doing all of whatever is needed and then I organically refactor into smaller functions as needed and shuffle those off into different parts of the domain and/or "store" or whatever.
At work, we tend to evolve our structures quite a bit over time.
We have a monorepo now, with about thirty subprojects. Some of those are sort of "core" function for different parts of our overall system, some of them are actual "web apps".
Some of our apps don't have the handlers/model/views separation, some do. Kind of depends on what the app looks like -- whether it has a small number of generic views or a larger number of specific, more complex views. Same with the handlers and "model" aspects.
Here's a concrete example of one app that doesn't have that breakdown:
ws
└── seo
├── geo
│ ├── affiliate.clj
│ ├── core.clj
│ ├── data.clj
│ ├── listing.clj
│ ├── locale.clj
│ ├── page.clj
│ ├── photo.clj
│ ├── profile.clj
│ └── search.clj
├── geo.clj
└── sitemap.clj
And then here's another app that is much more traditional MVC-structured:
$ ls ws/admin*
ws/admin.clj
ws/admin:
handlers model screening.clj views web
Main entry points are ws.seo.geo
above and then ws.admin
below.
The admin app has 30 handler namespaces and 16 model namespaces.
The SEO Geo app is the total code shown.
"domain model"?
It has namespaces corresponding to separate aspects of the domain model, yeah, but not "objects"/"classes".
the handlers correspond instead to the sections of the web app itself, not the domain.
thank you for another clojure lesson @seancorfield!
Feel free to hit me up in DMs any time you have Qs.
(I can share more of how we do stuff in private)
Non-code stuff -- CSS JS images
EDN files
Hello
i've gotten very used to luminus and how it operates BUT i have no idea how to setup 'batteries' and create my template.
I started with lein new app X
and i'd like to grow it to have 'batteries' similar to luminus (clj, cljs, db, api, reloaded workflow....)
are there any resources/tutorials or something i could have a look at this that would get me started
or give me hints how to start ?
for instance i have trouble with reloaded workflow
I have added ring, jetty i cider-jack-in
and the app works - great
but when i make changes i have to cider-quit
then jack-in
again in order to have changes
how do i make it nice so that jetty uses handler that is changed once it's changed
hopefully my questions make sense
yes but that doesn't do it and i don't wanna do that manually all the time. I'd like to save file and it's reloaded (just like in luminus)
luminus includes a reloading middle ware. You could set up a similar thing. I just c-c c-k. Its the same number of keypresses as c-x c-s 😉
note that server side luminus last time I used it didnt reload immediately, but on next HTTP request
which meant if you were working in an async system with websockets, saving the file didnt hotload the code
@U1QQJJK89 do you have any resources to recommend that i could use to figure out reloaded workflow or atleast what's out there? i saw some people are using namespace.tools
If you get into the habit of eval'ing every change you make (e.g., change a bit of code, eval surrounding/top-level form), then you don't even need to worry about saving files to get the REPL caught up to the latest state.
That's the work folks like Eric Normand and Stu Halloway recommend for REPL-Driven Development -- and I've found it to be a really good practice.
I've never liked any of the auto-reload/refresh workflows and with that RDD workflow, I just don't need them.
I tend to prefer what Sean already said.
One situation when I've been using tools namespace refresh is when switching git branches (I did that lot in the past few days).
Also, it seems that @U45SLGVHV may need to pass in the actual var ( #'
) instead of just plain symbol
Why weird?
That is just a keyword nothing special
Hey everyone! Does exist a function for compare list values?? I tried to use compare
, but it does not work with a list
😅 i should had done this before
=
is enough for any comparisons in clojure. 🙂
Not the one that i would. But i can try convert my list to sets and then make it work.
According to the documentation, two lists with same elements but not in same order are not equal when using =
. The same does not apply to a set. So probably my approach will turn this list into a set to =
compare them.
Well if you wanna check the equality you should be checking the order also. But yeah on the other hand I don’t know your use case. So if you wanna check if all the elements are there or not then yeah. converting into set works.
or if you don’t wanna convert your list to set you might wanna do something like this
(every? #(.contains [1 2 3] %) [2 1 3])
My case is: i'm doing a etl, so now i'm checking if the ids on the old database are available in the new
If you want equality of the set of elements, ignoring order, then elements of a set and =
are things Clojure provides to do that for you. There are other ways, too, of course, but if you prefer to use something built in, a set is a good way to go.
At least, if all of that fits in memory at one time 🙂 If not, then you either need to find a bigger memory machine, or do it in some other way.
So i do a select in both bases, do a map for get the id of each element and then turn into a set
Doing the every? thing will help you certainly
Thanks @US20QKF36!!!
This solution will be better than transform to another data structure just for compare values
I just would like to understand something with it: using every?
, what i saying is: for every element in one list, apply this anonymous function that check if this element exist in the other list. Am i right?
Yeah it takes a predicate and checks if the predicate is true for every element in the list
If you want equality of the elements of two collections, viewed as sets, you would have to do the every? in both directions: is every element of A in B, and is every element of B in A? If you only do it in one direction, e.g. is every element of A in B, then you have shown that A is a subset of B, but that doesn't necessarily mean they are equal sets.
The thing is he doesn’t wanna do it on set he wanna do it on lists. And he wanted to check it in one direction only. That’s why I suggested changing the data structure just to compare is an overhead
@tjb Following up on our discussion last night: https://clojurians.slack.com/archives/C0904S2QJ/p1582289250041300?thread_ts=1582275550.036400&cid=C0904S2QJ
is it typical to use a mocking library in clojure or do folks stick with with-redefs
and write their own "fakes"?
(i feel like i have to question every convention i'm familiar with from java land)
there's a strong preference to stubs over mocks, but there's libs that do both
thank you @noisesmith i'll go in that direction.
also, the usage of immutable data and "mostly pure" functions means doing a lot less of either
if done properly
by "mostly pure" I mean segregating things that must do mutation (eg. IO) so that they touch as few other parts of the system as possible
that's definitely my intention. fewer tests and segregating pure/impure functions
I don't know about fewer tests, but definitely less need for mocking/stubbing when you use immutable data and non-side-effecting logic
most tests should look like (is (= {some data literal here} (f some input literal)))
i'm having some trouble using with-redefs
across multiple namespaces. in the source code, i import a library (`clj-http :as http`) and then invoke http/get
. can with-redefs
target that get
function, or should i wrap it in the source code like (def get http/get)
?
it looks like there is a clj-fake-http
lib for this, but i'm interested in working it out myself if possible
maybe another option is to import the lib using refer like [clj-http :refer [get])
but then i'm shadowing get
with-redefs
can use qualified symbol names.
does qualified mean namespace qualified? naively, i've tried (with-redefs [sut/http-client/get stub-http-get
but that throws unable to resolve var
(with-redefs [http/get stub-http-get] ,,,)
Just like you'd use http/get
in your own code.
aha, ok. that is working. thank you!
(for a minute it looked like the real call was still going through, but it was an un-stubbed underlying call)