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
Post a Comment