This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-11-17
Channels
- # aws (3)
- # beginners (81)
- # boot (155)
- # capetown (2)
- # cider (32)
- # clara (14)
- # cljs-dev (40)
- # cljsrn (12)
- # clojure (158)
- # clojure-austin (5)
- # clojure-korea (6)
- # clojure-poland (1)
- # clojure-russia (63)
- # clojure-spec (45)
- # clojure-uk (75)
- # clojurescript (109)
- # code-reviews (1)
- # core-logic (12)
- # core-matrix (1)
- # cursive (36)
- # datomic (16)
- # defnpodcast (1)
- # devcards (2)
- # editors (3)
- # euroclojure (1)
- # events (3)
- # flambo (1)
- # hoplon (19)
- # javascript (4)
- # jobs (1)
- # lein-figwheel (4)
- # leiningen (1)
- # off-topic (1)
- # om (177)
- # onyx (121)
- # pedestal (14)
- # planck (19)
- # proton (3)
- # re-frame (36)
- # reagent (21)
- # remote-jobs (1)
- # ring (4)
- # ring-swagger (6)
- # spacemacs (1)
- # specter (2)
- # test-check (4)
- # untangled (9)
- # utah-clojurians (1)
- # yada (2)
Sean, I am fine with the filtered obscenities in the bad word list, there's none in french 😜 I have a huge repertoire handy 😂
I'm quite interested in moving all my tests from separate test files into the metadata of functions, from:
;; my-ns.clj
(defn my-fn
[x]
(identity x))
;; my-ns-test.clj
(deftest test-my-ns
(is= (my-fn "abc") "abc"))
... to:
;; my-ns.clj
(defn my-fn
{:test #(do
(is= (my-fn "abc") "abc"))}
[x]
(identity x))
I can see many benefits from this and only one real drawback - making the code more cluttered.
Has anybody had any experience in structuring tests like this and what worked well/not so well?@looveh Take a look at clojure.spec. I wouldn't put tests with example data trying to cover all cases right there in the function. http://clojure.org/guides/spec#_spec_ing_functions
I’m using spec and generative test for edge cases and conformity to complement my unit tests that verify actual business logic. My proposal here was to move the separate unit tests into function metadata
@looveh Aren't you happy with tests being on a separate file? How many tests per function do you have?
@yonatanel It works, but I’m always looking for ways to improve! About 1-10 tests per fn I’d say
I’m not sure how many of you are using datomic. But I recently “finished” my first itereration of a library to help with the querying of datomic entities. Any feedback would be greatly appreciated: https://github.com/petergarbers/molecule
There is #datomic too btw
that doesn't work, I tried (def err-sym #?(:clj Throwable :cljs Error))
and then using err-sym in the macro but it didn't work either
what're some useful ways to explore large datastructures? like importing a massive xml file with loads of nodes
@spacepluk macros are clojure macros (unless you are using self hosted cljs), so reader conditionals within the macro will always take the :clj
path
however, you can check (boolean (:ns &env))
at compile time - if it is true
, you are in cljs env
a lot of times the variation can be pushed down into a function
@seancorfield Has this been an issue?
@spacepluk well, this is the workaround 🙂
@petr are you referring to my reminder about the CoC?
We've had a lot of new folks join recently and one of them was using profanity that isn't appropriate in a professional environment so I thought it was worth a reminder about the CoC. Mostly this community is pretty well-behaved (unlike a few others that I admin, also with a CoC in place).
Further discussion related to conduct or the CoC should probably go to #community-development so we can keep this channel technical and professional
can I write a function of the form (fn [z y]) where x resolves to a symbol ::foo and (s/asserts ::foo y) holds ?
should work as is
user=> (defn foo [s v] (s/assert s v))
#'user/foo
user=> (s/check-asserts true)
true
user=> (s/def ::foo int?)
:user/foo
user=> (foo ::foo "a")
ExceptionInfo Spec assertion failed
val: "a" fails predicate: int?
it seems completely counter intuitive when viewed as the perspective of types -- but when viewed as specs, it makes perfect sense
clojure.test is built in for example testing and is the most common. expectations takes a different approach to unit testing and does great error reporting. test.check is the best choice for generative testing.
Clojure Applied (I am a co-author) has a chapter that covers all of the above
@alexmiller thanks again
@alexmiller Looks a very interresed book where I can learn from every chapter.
@roelofw If you like the look of Expectations after reading that chapter, there’s an #expectations channel here and I’m now one of the lead maintainers (planning to add support for clojure.test tooling for Expectations).
@hwk Perhaps consider an atom and then you can use swap!
— what are you using global dynamic state for in Clojure?
@seancorfield: I'm writing a forth interpreter; there is a state consisting of :data-stack, :env, :code-stack
@seancorfield : I would prefer to not pass the arg around all the time, and thus a dynamic var
@seancorfield I think I will read all chapters
@hwk Sounds like you should still use an atom for your (global) state rather than just modifying a Var...
(defonce state (atom {}))
Then you can use (:data-stack @state)
etc to read parts of it and (swap! state update-in [:data-stack] conj new-item)
etc to update it safely.
@seancorfield : true, but with dyanmic vars, I can have multiple threads, each running an interpreter, (as they use different dynamic bindings); with a global, I'm forced to only having one interpreter
Hi. Could you please explain how this lazy evaluation works. (first (map println (range 10)))
prints the whole sequence(when I expected it to print only 0
and then return nil). I don't understand mechanics behind this behavior. Thanks
@hwk, ah yes, I completely forgot 'bout chunked evaluation. Yes it gives up to 31 elements.
Don't mix side effects and lazy seqs
@alexmiller: can the 'mapped function' get exec-ed more than once, or is the result 'cached' aftertwards? i.e. in (first (map println (range 999))) is there a way to force (println 3) to exec more than once ?
I heard that atom functions can be exec-ed more than once, but is it also true of mapped functions?
Seqs cache their values
So the function will be executed once per each element in the input seq
Most of the "do" functions are designed for side effects. Also look at run!
@alexmiller it is mostly about understanding how stuff works. I use "do" family of functions for things that require side effects.
@mik: ask more questions -- I didn't realize map did chunked evaluation until I tried to figure out wtf was going on with your example
@hireman: (first (map (println (list 1 2 3 4 5)))) -- damn ... how do you pick up knowledge like this (besides reading the clojure source) ?
Chunked seqs are a big reason why lazy seqs are fast
IMO if you ever care about how much of a lazy seq is realized and when, you should prob not be using lazy seqs
@hwk I use this macro from time-to-time:
(defmacro update! [v f & args]
`(set! v (f v @args)))
it needs a better name, since it’s confusing with update/update-in, but it is basically swap! for a dynamic variable
another common approach is just to do (def ^:dynamic foo (atom 0)) and then you can just use swap! directly
i’ll say that interpreters and porting traditionally imperative algorithms are the one time i actually feel a need for this
@bbloom: yeah, I was initially trying to do it in a pure manner, but then I realized I had a bunch of code of the form (let [ [state0 a] ... [state1 b] ... [state2 c] ... ] ... then it was "oh, this is clearly a Either + State Monad, for storing the state + catching any errors" then it was "well, clojure algo monads doesn't work all that nice without types, .... so maybe I can do it with try/catch instead of Either, and with some set! instead of state monad" ... and now this is where we're at :-)
@hwk what are the a, b, c? can they be stashed in the state itself? composition loves singular data objects
a forth interpreter is a naturally imperative thing, so you can set “flags” in the state
@bbloom suppose we were implemetngint eh + function, in haskell, it would be like a <- pop_data b <- pop_data push_data (a+b)
@bbloom: btw, it's very nice talking to you ; clearly you suffered through these problems yourself
I don't know how you can do that with state, state has the form {:data_stack ..., :code_stack ..., :env ...}
can you make it more like (-> [state] step-1 step-2)
and have steps return the vector of state, pushing and popping?
I see, so it's like ::machine-state = [::data-stack ::code-stack ::env], ::state =[::machine-state ::aux-state]
(defn bind [state k v] (assoc-in state [:bindings k] v)
(defn scope [{old :bindings, :as state} f] (-> state f (assoc :bindings old)))
@dpsutton: I've written a metacircular scheme interpreter before. I don't know what "scope holes" are.
admittedly, this is a shortcoming of writing interpreters in clojure: there’s no static way to interleave interpreter state and machine state
@bblom: This is really cool. Your method has this additional benefit that when I dump the state, there's a "more informative" debug output.
so if you had a stack of maps with bindings, you just start at the top of the stack and search for your first binding of a
btw, writing traditional interpreters in clojure kinda sucks due to lack of tail calls - but if you fully reify the machine state, then clojure is awesome for interpreters, if a bit slow
so if you read some of chuck moore’s writings, he laments the popularity of lexical variable schemes in various forth implementations
this video gave me some very deep insights: (defn scope [{old :bindings, :as state} f] (-> state f (assoc :bindings old)))
https://www.youtube.com/watch?v=mvrE2ZGe-rs&list=PLXUHm2Eg2p-F_grko9WAypY6ea4CZeNCO&index=1
which is one of the reasons i have that update! macro 😉 i find it much easier to reason about imperative algorithms written in a forth-ish style, albiet without the clutter of stack shuffles etc
oh man, this is brilliant, I'm going to use (pop-as :a :b) (push-apply [f :a :b]) // for implementing +-*/
can extend-protocol
dispatch based on the second position, as in (map f <dispatch-on-my-type>)
@josh.freckleton no, use another function to shuffle the arguments
@bbloom ah, perfect, thank you!
either that or (s/coll-of keyword?)
they aren’t much different if you are using those independent of any other spec
but it will matter if you include that into another regex spec or not
generally, I always use a regex op (s/* here) for arg specs
Hmm. I hadn't thought of stack-based langs that way, but I guess you could consider it point-free...
@bbloom i did something like this with first-class envs and dynamic binding in JS: https://gist.github.com/anonymous/d6476b301685c6cb0ce7b523496bf9c1
as you can see you can do Self-like prototype inherited objects cuz the scopes are reified in this way
@tom, @fellshard : oh right, comp + reverse, thanks!