This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-01-31
Channels
- # aatree (1)
- # admin-announcements (3)
- # aws (3)
- # beginners (36)
- # boot (227)
- # cljsrn (27)
- # clojure (57)
- # clojure-czech (6)
- # clojure-miami (8)
- # clojure-poland (17)
- # clojure-russia (113)
- # clojurescript (9)
- # community-development (1)
- # core-async (11)
- # core-matrix (2)
- # core-typed (3)
- # cursive (3)
- # datomic (5)
- # editors (40)
- # emacs (6)
- # heroku (1)
- # hoplon (50)
- # incanter (1)
- # ldnclj (4)
- # luminus (3)
- # mount (1)
- # om (132)
- # onyx (5)
- # proton (3)
- # re-frame (5)
- # spacemacs (1)
- # testing (12)
- # yada (6)
any recommendations for a good place to start with building your first clojure web application?
@drewverlee: I haven't studied the source, but semantically, the "in-transaction" part of commute gets thrown away IF someone else updated the ref during or after the "in-transaction" execution of your function occurred. Think about it- in that case, your change was definitely lost. So commute will run it again. Alter provides "serialization" semantics, which is why there are rollbacks.
@drewverlee: re: the (dosync (future...))- yes- dosync and commute/alter have to be executed in the same thread
hi @fred, so, oooo is the top level function and it should receive a data structure like css1. clojure.string/join wants to receive a sequence which should be the transformation of the data structure into strings by the lower level functions, starting with ooo. using the map function to effect this transformation should work- e.g. (clojure.string/join "\n" (map ooo nestedmaps)) . similarly, ooo needs help to transform the block, which it can get from oo, again using map: (str selector " { " (map oo block) " } ")) you can repeat this process of having the higher level functions get help from the lower level functions using the map function to apply the lower level function to the appropriate portion of the data structure that the higher level function receives. now- this is definitely a tricky approach to try to compose all at once. doing this work at the repl in a "bottom up" fashion can be very helpful. e.g. start with (def p {:font-family "Times New Roman"}) and make a function to transform that data into the string you want. Then add a second or third key/value pair and use a collection operator like map to apply the transformation to all the key/value pairs. Then wrap a data structure around those and repeat the process. Being able to take this step by step through the repl is tremendously helpful because you can see the data at each step.
hope that's helpful, good luck
Many thanks @jonahbenton I guess if my approach is tricky I'm not one the best path to solve this in clojure đ I first solved it interactively like this by following the CSS logic (ruleset, selector, declaraction block, properties & values) :
(defn nmap->css [nmap]
(clojure.string/join "\n" (map (fn [[k v]] (str k " { " (clojure.string/join "\n" (map (fn [[property value]] (str (name property) " : " (if (keyword? value) (name value) (str "\"" value "\"")) ";")) v)) " }")) nmap)))
and then I thought "what would be the right way and most elegant to decompose this in clojure? probably with comp
and partial
... "
my intuition here is that join
kind of get in the way of showing me the true structure of the global function...
many thanks for your advice 
@jonahbenton: thanks again friend!
hi, iâm not very sure what happens when you add a token to :body in the response hashmap when you do a POST for say, a successful login
i tried navigating to another page after i did a login, but the :body doesnât contain the encrypted token anymore
The :body returned by a handler is what the server sends to the client, for example, a web page or a JSON response.
And the body that is passed to the handler is what the client sends to the server
The client needs to send the token with every connection, that doesn't happen automatically
There are some wrappers to automatically manage sessions though, you might want to look into those
This might help: https://github.com/ring-clojure/ring/wiki/Sessions
hey @fred- so let me suggest an alternate approach. what i meant by tricky is that this problem space- rendering a data structure into a stream, or taking a data structure and generating code- is a surprisingly deep and subtle one. here are a couple of examples of solutions: james reeve's hiccup, which renders data to html: https://github.com/weavejester/hiccup/blob/master/src/hiccup/compiler.clj and cheshire, which renders data to json: https://github.com/dakrone/cheshire/blob/master/src/cheshire/generate.clj this is not to discourage at all, just to provide some context- this is a great area in which to learn! a suggestion in terms of learning- instead of thinking about the problem from the code perspective- what's the structure of the code to work with this data- think about the problem from a data perspective- what data structure makes the code simple. for instance, try using vectors rather than maps, and try keeping all values as strings. e.g. [ :body [ [:background-color "#d0e4fe" ]] đ [[:font-family "Times New Roman"] [:font-size "20px"]]] and then look at the walk function to traverse the structure.
Hi @jonahbenton many thanks, trying to explore an html dsl is on my list definitely. If you tell me looking into hiccup is way to go that's what I'm gonna do đ anyway learning clojure is really an exiting journey đ cheers
I'll offer up a +1 for Hiccup -- we use it extensively at World Singles.
this exercise from clojure brave and true is breaking my circuit: > Create a function that uses futures to parallelize the task of downloading random quotes from http://www.braveclojure.com/random-quote using (slurp "http://www.braveclojure.com/random-quote"). The futures should update an atom that refers to a total word count for all quotes. The function will take the number of quotes to download as an argument and return the atomâs final value. Keep in mind that youâll need to ensure that all futures have finished before returning the atomâs final value. Hereâs how you would call it and an example result:
(quote-word-count 5)
; => {"ochre" 8, "smoothie" 2}
I'm not sure how to go about ensuring the threads i want to spawn to fetch fetch words + update counter have all finished. Assuming the happy path, where they always succeed how can i trigger checking the atom at the right point?I guess I might have to use a counter to keep track of how many have finished. Then watch the counter
Im guessing the next chapter on core.async is going to give me a better answer.
@drewverlee: If you are solving it in Clojure, perhaps a refinement on your âwaiting on counterâ idea is to use Javaâs CountDownLatch
.
thanks @mfikes, ill give it a look. Is there another way to do this besides a counter? I mean, at a high level I think something has to bee keep tracking threads and tracking that they finished. I haven't done any of this type of thing so i'm not sure if i'm using the wrong... err tool.
Thread has a join()
methodâthatâs a pretty low-level construct. But, it wouldnât work if the threads are returned to some pool.
at this point in the book i have [futures, promises, delays, vars, atoms, refs]. I assume i'm supposed to start a thread for each request and update atom inside that thread (as the order shouldn't matter). The problem is knowing when i'm done. > (As in, put all your futures in a collection, and then deref all of them serially.) I don't follow đ
Then if you do (deref f)
(or, equivalently @f
), you will see that it blocks until done.
Then extend that idea to collections of tasks
(def coll [(future (Thread/sleep 10000) (println "done") 100) (future (Thread/sleep 10000) (println "done") 100)])
which you can wait for all to be done via (doseq [f coll] @f)