This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-10-22
Channels
- # announcements (21)
- # aws (7)
- # beginners (105)
- # berlin (1)
- # calva (14)
- # cider (20)
- # clj-kondo (62)
- # cljdoc (7)
- # cljsrn (1)
- # clojure (206)
- # clojure-dev (2)
- # clojure-europe (11)
- # clojure-france (2)
- # clojure-italy (2)
- # clojure-nl (1)
- # clojure-uk (34)
- # clojured (1)
- # clojurescript (52)
- # copenhagen-clojurians (2)
- # core-async (1)
- # cryogen (3)
- # cursive (36)
- # data-science (27)
- # datomic (48)
- # emacs (1)
- # events (1)
- # fulcro (27)
- # hoplon (51)
- # jobs-discuss (1)
- # leiningen (1)
- # nrepl (2)
- # off-topic (52)
- # pathom (43)
- # quil (10)
- # re-frame (11)
- # reitit (28)
- # remote-jobs (2)
- # shadow-cljs (36)
- # sql (12)
- # tools-deps (7)
- # vim (32)
- # xtdb (17)
so after friend, and then buddy, is there a new/actively maintained webb security library?
I do not know, not having used such libraries, but do friend and/or buddy still work? Some libraries in Clojure are stable and working, even if they haven't been changed in a while.
I think one can also make use of Apache Shiro directly: https://shiro.apache.org/index.html
I am learning Clojure and would like to know if I am the right track from experienced developers who preceded me in their learning path. So far what I accomplished is: 1. Studying all the basics of Clojure Language from different sources like Clj for brave true.. & Quick Clojure (awesome book btw). 2. Learn all the basics of Clojurescript from a web dev ebook. 3. Tried to delve into Fulcro and studied until 3.8 but could not continue for several reasons not relative to mention here. 4. Studied Luminus framework, liking it from Web Dev 2nd edition book. But I realized that I am still not so good with Clojure basics so went back to revise before I continue. What I meant to say that my learning style is coming back and forth a lot and is very dynamic. I wonder if this is how most of you learned and if there is a more efficient way to learn through practice for example to know the best practices. Highly appreciated.
I learned enough of the basics to get going, did some 4Clojure, then landed a job writing Clojure. I personally don't think there's much point in reading up too much unless you actually intend to use the language - either for a hobby project, or in production. So my suggestion would be to do just that - if you like the language, find a way to use it "in anger", the rest of the learning will follow. Books will only take you so far.
Agree with @sgerguri - Iโm writing a cljs frontend for my company and just seeing how it works out.
Learning from books is fine but I only really learn when trying to build something, preferably on a deadline..
Going through http://www.4clojure.com/ exercised can help with getting acquainted learning the basic functions, doing things like loops, conditions, manipulating data-structures etc.
Books can help with overall application design hints. But like other said, practice makes perfect
Thank you a lot for all the advice. Really helps. I'll definitely try 4clojure and yes I have project in mind. Is there a way to work for any company over seas for free through assignments?
That's one other thing I wouldn't do either. Build a project of your own, or extend something that you're using already. Better yet, find a place where you can sneak Clojure in at your current place - there's bound to be some scope for an internal miniproject where nobody will honestly care what technology you're using as it's not going to be critical for project delivery. Build support and excitement for the language, run learning groups, etc. It's a lot easier (and better in the long term) to try and build support for something you care about where you are than trying to jump through hoops to land something remote overseas.
quick questions about clojure.datafy/nav
. the first argument coll
is the result of the previous clojure.datafy/datafy
right? not original object passed to datafy
?
wondering if I should implement nav
on the original object or via metadata on the datafy result
Given a system that is already happily configured for logging using a combination of logback and slf4j, have folks found any compelling reasons to migrate to using timbre?
the words "happily" "logging" "logback" "slf4j" are so rare in one phrase that i would keep stuff like they are ๐
After running multiple (15+) Clojure apps in production I found that what happens with logs after they're being produced is way more important, how you log is a secondary concern ๐ We use tools.logging + logback with a custom formatter and MDC in few places and it doesn't feel like we need to change anything. What would be your reason for migrating to timbre if current setup is working?
We thought Timbre looked like a great idea and used it for several years @kelveden but we recently migrated our entire code base (back) to tools.logging
, log4j2, and its various bridges/adapters. There's a lot to be said in favor of industry standard logging...
We have pretty much the exact same setup as @U0JEFEZH6.
timbre is really horrible if you want more customized log message and really easy for things like changing log level dynamically at runtime (which is much harder with tools.logging & log4j2)
Thanks for the thoughts guys, really interesting. It confirms my gut instinct: if it ain't broke don't fix it, particularly when it is a tried and tested stack used across the industry.
Doesn't the as-> macro make clojure's immutability strength pointless?
you didn't mutate anything there @UNQ70RULA - you just rebound foo
here's the macroexpansion of your expression:
(let* [foo 1 foo (inc foo)] (println foo))
You mean we over written foo's value so in that case it's not considered mutation because it was on purpose?
it's not mutation - you are effectively creating a new foo
which shadows the old one, but you aren't mutating any values. if the value of the original foo
was stored anywhere, it is not changed by the inc
Is the above screenshot from some sort of tutorial? That looks very misleading for beginners
Quick Clojure book
I'm still confused a bit but telling myself perhaps when I practice it will be more clear.
hmm, I'm not sure how good a reference that book is.. from the chapter previews it looks like it's written from quite an imperative standpoint
does this make it any clearer @UNQ70RULA
(let [bar-a (atom nil)]
(as-> 1 foo
(reset! bar-a foo)
(inc foo)
(println foo))
(println @bar-a))
;; 2
;; 1
;; nil
I like it to be honest because it attempts to be concise whereas most books try to be comprehensive which is not a good start for beginners.
The chaper on "Sequences" starts off by introducing doseq
and saying looping over collections to carry out side effects is a common task in Clojure ๐ฆ
Thanks Craig. Yes it does. But in the first example we printed foo's shadow =2... is that considered still safe to use in any app without risk of a value changing without our consent? In other words is it safe to use as-> or it makes an app less safe?
@UCPS050BV I'm surprised since this book is probably the most recent of all my collection being in 2017... most other books are probably 2015-16
Or maybe to rephrase @U0524B4UW... isn't it safer to create a new variable to assign it the increment or that's pointless?
@UNQ70RULA it's still safe - as->
isn't doing anything special, it's just saving you the work of writing some let
bindings and hopefully making the intent of your code easier to divine... (although, that said, i rarely use as->
)
you certainly can create a new variable to assign the increment, but that has its own difficulties (it's very easy to accidentally refer to the un-incremented variable in later code, especially after some refactoring)
Nice thoughts ๐
I remember when i learned some rust they used a similar concept of shadowing rather than creating a new variable.
i generally prefer the thread macros which don't bind a variable... ->
and ->>
- there are no such issues with them
that may just be my personal preference though
I make thumbs up it disappears for some reason... ๐
Another issue I'd have with that example is that as->
is designed to be used inside ->
hence the "odd" argument order.
I hadn't heard of Quick Clojure but based on this thread I think I would recommend avoiding it.
Maybe "avoiding immutability" was just misplaced and it can improve in next book version. To be honest the rest of the book was enjoyable so far..
I'd never heard of that author. Searching for his name and Clojure only yields that book so it's hard to tell his credentials. There are certainly bad Clojure books out there. Enjoyable != good, necessarily ๐
I have posted the complete section where he mentioned the as-> macro for fairness
The reason I also included this is to be clear that the author used as-> to avoid the alternative complicated version he mentions.
That's pretty horrible stuff. Now I'll definitely recommend people avoid that book!
Glad to have your opinion about this to be aware.
I thought Apress are selective.
He's coming at this from completely the wrong angle -- and the comment about doseq
in the sequences chapter confirms that.
Apress is better than Packt but...
So if you recommend 3 books for beginners... what they'd be?
A lot of these publishers churn out books just so they have something in a given section.
Living Clojure and Getting Clojure are probably the first two that come to mind. When I'm at my desk I can be more sure if that.
Thanks!
I skimmed through some examples on amazon and I agree with Sean. This is a badly written book (as is common with many Packt books)
I concur with Sean's recs, or Clojure for the Brave and True, or Programming Clojure
Thanks Alex
(I am a co-author of the last so I am biased here :)
My only concern that books published in 2015.. 4 years passed. Probably back then clojure was 1.7? Some things changed right?
1.10 now.
Clojure changes slowly enough that it really doesn't matter much
Clojure changes fairly slowly, by design. A few things that have been added are important, but a lot of Clojure 1.3/1.4 era advice is still good.
Transducers (1.7), Spec (1.9), the new CLI/`deps.edn` (1.10). Those are important additions, but the core is very similar.
I would avoid anything that was based on 1.2 tho' since the Contrib libraries went through a massive change between 1.2 and 1.3.
clj/deps was actually 1.9
https://github.com/clojure/clojure/blob/master/changes.md gives a good sense of what has changed in each version. It's almost always pure additive and very stable (it's why we've run alpha/beta builds in production since Clojure 1.3).
Programming Clojure is based on Clojure 1.9 and includes spec, clj, etc
Perfect.
Ah, it isn't listed in the changes log (which makes sense) so I was just trying to put "large" features into release buckets ๐
Getting Clojure is either 1.8/1.9 era, can't remember
Living Clojure is 1.6 era
Clojure for the Brave and True is probably similar, can't remember
Or maybe there is something not clear for me?
I mean if we're going to work around it anyway we might as well use javascript or java... no?
@thheller i think @seancorfield and/or @lilactown should be able to answer your question about datafy/nav if you haven't gotten an answer already
shortly after I asked I realized that next.jdbc
had support for this so I just looked there. so yeah it is the result of datafy not the original value
@thheller I wrote a blog post about the principles behind datafy
/`nav` that might help... https://corfield.org
Guys, is there any book for clojure app design patterns?
Thanks alot
We thought Timbre looked like a great idea and used it for several years @kelveden but we recently migrated our entire code base (back) to tools.logging
, log4j2, and its various bridges/adapters. There's a lot to be said in favor of industry standard logging...
Another issue I'd have with that example is that as->
is designed to be used inside ->
hence the "odd" argument order.
ah. reading it its not avoiding the immutability as much as avoiding bindings. Ie, you don't have to name things if you thread it through
Quick Clojure
It's definitely poor wording (and that can be seen in previews for other chapters too).
are the bindings in a let
clause guaranteed to be evaluated in lexical order?
If I write something like
(let [start-time (java-time/local-time)
result (do-really-long-computation)
finish-time (java-time/local-time)]
{:start-time start-time
:result result
:finish-time finish-time
:elapsed-secs (java-time/as (java-time/duration start-time finish-time) :seconds)})
might I sometimes get a nasty surprise with the measurements?thanks
longer explanation: clojure isnโt lazily evaluated and you can refer to the letโs defined above the one youโre currently defining so it couldnโt work another way
You could get a nasty surprise if do-really-long-computation
returned a lazy sequence very quickly, and that wasn't what you expected to be measuring.
(prn (quote (quote foo))) or (prn (read-string โโfooโ)) I actually want to print a quoted foo not a foo
Hi Clojurians, what is your favorite library for authentication? A friend wants to use Pedestal with something fairly out-of-the-box friendly
I am aware of Buddy, but I don't know much about the current sample size, so I figured I'd ask. Danke.
buddy++
how many deps does buddy drag along ? ๐
uhh, just checked, bouncy castle, cheshire, jackson ... this stuff is heavy ๐
I think the auth/z stuff in it is well-done, but would consider using something very simple and hard to mess up for encryption
@vincent493 i think it depends on the problem i'd have to solve ๐
if you dont care about client cpu time - jwt is perfectly fine
with a public-private key algo like rsa
jjwt has gone nicely modular recently , so you can ship your own lightweight json engine instead of jackson ... and use the crypto stuff from within jdk itself. works pretty ok in my experience with rsa and even some ec keys
ec is quite a wild zoo though ๐
But the original question posed stated: > A friend wants to use Pedestal with something fairly out-of-the-box friendly
buddy certainly sounds like it gets you going quickly ๐
well ... i think some stuff is on the other end of the spectre
a person needs a wheel to turn some wheels and we tend to give them the whole carfactory
buddy people already have made some stuff modular, i hope they continue their path and make some light-weight setup possible too
i don't think people have to do everything by hand, but nicely modular things are better ๐ (and i wouldn't touch clojure with a stick if it'd tell me to install scala runtime, half of apache spark and spring boot just to make it bring up a repl)
in a weird way i hope clojure core parts will remain as they are. the weight feels just about right.
Iโm just becoming skeptical of whether I could ever take clojure seriously for something I care about. Modular is nice, but back to cars โ I still prefer to just buy a car rather than build one myself from spare parts. I have other things to do
yes of course, you should be able get a car that just works
but if you pull in jackson - that thing alone is bigger than clojure
and bouncycastle is even bigger and you will likely use 5% of it or less
which is especially weird if your jdk supports the needed crypto parts out of the box
well if buddy guys could make you choose between jackson and data.json for start
this would be nice, no ?
i only do data processing with clojure, no webapps. (those in my architecture are plain boring old java, sorry)
I donโt think being sarcastic about people making a best effort to give helpful advice is good behaviour
many of these topics are the ones where even disagree with ourselves ๐
Iโm not being sarcastic at all. I thought we were having a nice conversation. Sorry if I offended you @kulminaator. Iโve been very interested in what you have had to say
you didn't offend me ๐
i think this is a healthy discussion
people want lightweight tooling . lightweight for usage patterns (when you just start out) and lightweight to own (which you get to once you have piled up all possible deps for years)
So do you have any thoughts about why a lightweight library doesnโt yet exist in clojure for such a common need?
i'm not sure. i don't even think adding another library will improve things much. it would be better if people motivated would get involved in slicing up buddy more ๐
if you look at rubygems and npm world ... having 5 libraries too many for a problem hasn't really solved issues
my guess: crypto is scary, the java libs are very mature and well maintained if clunky, so people just use the clunky java libs
i have a ruby project around here that depends on about 100 open source libraries "collected" 10-5 years ago
you can only shiver thinking about how many of those are still properly maintained
crypto is somewhat scary yes. messing up is very easy to do.
The README for buddy says that it has 4 independently-usable parts. I haven't used it, but perhaps that split already helps avoid unnecessary dependencies, if you figure out which one part you want to use?
but then again, if you pull in jackson which has had a handful of remote code execution issues over the last 2 years ... uh oh ๐
andy the ones i mentioned were in buddy-core
i didn't even look into the other ones
thumbs up to cheshire people at least that they bumped up their jackson dependency with the security updates released to jackson :thumbsup:
Well, again thanks for your thoughts on this @kulminaator. Itโs very helpful to hear about this from the perspective of somebody with much more experience
We ended up using the Apache OLTU stuff (including jose.jws) for our OAuth-based auth/security stuff. It seemed simpler than either Buddy or Friend, TBH, but the docs are pretty poor.
Speaking of which, I'm implementing an OpenID/Oauth2.0 compliant identity server (ring/datomic w00t!) Does anyone have any good identity server projects to point to (any language really, but preferably Clojure)
@goomba Let me know if you find any -- that was the hardest part for us. There seem to be lots of libraries for OAuth2 clients but almost nothing for servers (which is why we eventually settled on Apache OLTU).
I'm not really seeing anything, but if I get it figured out I'll do a writeup.
More security on the web is better!
@goomba I came from Ping Identity where we had a OIDC/Oauth2 server product. There is quite a bit of work involved here but you probably donโt need all the features we incorporated. I am happy to look at a writeup of requirements if you like.
I'll message you ๐
The source code for OLTU and the RFC spec for OAuth2 processes were our guide ๐
(so we ended up with separate Auth, Login, and API services based on that)
10-4... I'll take a look!
he's also the one behind flatland/useful which is a good example of clojure code style and a good utility lib
Perfect
oh it moved but google knows where it moved https://github.com/clj-commons/useful
So in what way are these functions useful?
Like in large projects?
I believe in general they are things that the author found generally useful across multiple projects they worked on, similar to how many functions in clojure.core are generally useful.
In much the same way we found several "almost-core" functions to be useful enough to put them in a library: https://github.com/worldsingles/commons/blob/master/src/ws/clojure/extensions.clj
Perfect, Bookmarked!
The beauty of such extensions seems to reduce / compress lots of boilerplate code.
1 line replace 20...
@seancorfield it looks like apache OLTU is also marked as retired (is this some sort of trend), did the implementation get picked up somewhere else?
@clypto Good question! I haven't checked to see if it was superseded by something else or just moved elsewhere. Finding the basis of an OAuth2 server setup was hard so I hope there is still a version of it or an alternative somewhere that is well-maintained ๐
We use Keycloak (Red Hat, Java) as an identity server, then our application sends users through it as an OpenID 'redirect flow' and talks to it as an OpenID API client
interesting, it looks like Keycloak is robust - at least with identity brokering, and account federation
Right, that's why we wanted it - it means we don't have to build 'either user/password, or SSO via this SAML server' or other stuff like 'configure password restrictions' in the main application
In the application side we're using a Java library "Nimbus Oauth 2.0" to parse requests/make response URIs - just implements the spec/JWT/JSON, track your own state