How to write idiomatic clojure (+ functional) code? -


i started hacking around clojure, , although adore language, can't understand how things idiomatically.

writing web-app using compojure, here's 1 of controller actions:

(defn create [session params]   (let [user (user/find-by-email (params :email))]     (if user         (if (user/authenticate user (params :password))             (do (sign-in session user)                 (resp/redirect "/home?signed-in=true"))             (resp/redirect "/?error=incorrect-password"))         (let [new-user (user/create params)]           (sign-in session new-user)           (resp/redirect "/home?new-user=true"))))) 

i'm writing in imperative way. using many lets/ifs/dos, can't think i'm doing wrong. how write functionally?

here's psuedocode i'm trying do

look if user exists   if user exists, try sign user in using password provided     if password wrong, redirect "/?error=incorrect-password"     if password correct, sign user in , redirect "/home?signed-in=true"   else create user, sign user in, , redirect "/home?new-user=true" 

thanks much!

there isn't non-functional if - it's good, purely functional construct evaluates expression conditionally. many ifs in 1 place might warning sign though, should using different construct (e.g. cond? polymorphism protocols? multimethods? composition of higher order functions?)

do more tricky: if have implies doing side effect, non-functional. in case sign-in , user/create appear side-effectful culprits here.

what should side-effects? necessary, challenge how structure code ensure side effects controlled , manageable (ideally refactored out special state-handling danger zone rest of code can stay clean , purely functional).

in case might consider:

  • passing "user/authenticate" function part of input (e.g. in form of context map). allow pass in test authentication functions, example, when don't want use real database.
  • return "successfully authenticated" flag part of output. caught higher level handler function responsible performing side effects related signing in.
  • alternatively return "new user" flag part of output, handler function likewise recognise , perform required user setup.

Comments