This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-06-21
Channels
- # bangalore-clj (1)
- # beginners (60)
- # boot (30)
- # cider (7)
- # cljs-dev (10)
- # cljsrn (2)
- # clojure (163)
- # clojure-conj (10)
- # clojure-france (1)
- # clojure-greece (2)
- # clojure-italy (7)
- # clojure-russia (41)
- # clojure-serbia (22)
- # clojure-spec (41)
- # clojure-uk (41)
- # clojurescript (178)
- # cursive (36)
- # datascript (1)
- # datomic (23)
- # dirac (38)
- # graphql (12)
- # hoplon (20)
- # immutant (32)
- # instaparse (3)
- # keechma (1)
- # lein-figwheel (18)
- # leiningen (8)
- # liberator (1)
- # luminus (30)
- # lumo (29)
- # off-topic (18)
- # om (17)
- # pedestal (7)
- # planck (37)
- # precept (1)
- # re-frame (67)
- # ring-swagger (2)
- # timbre (1)
- # untangled (8)
- # vim (2)
a null in a map shouldn't cause an NPE
so I'd say that's a bug in potemkin, but would need to see more to know for sure
(hashCode [this]
(reduce
(fn [acc [k v]]
(unchecked-add acc (bit-xor (.hashCode k) (.hashCode v))))
0
(seq this)))
compared to https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/APersistentMap.java#L104
it does seem like it is a bug in potemkin, I wrote up https://github.com/ztellman/potemkin/issues/52
my use case would have been better served using identityHashCode, too, so I just wrapped the object in another holder object
I'm really struggling how best to test with Clojure, specifically when I start having to mock interactions with a database etc. Looks like mock frameworks aren't super popular in clojure and I'm assuming there's a good reason that I'm missing
I, for one, prefer testing against a “real” database if possible; we test our app against a in-memory datomic DB, and against a H2 database (we use datomic and a SQL database)
@benny beware http://blog.cognitect.com/blog/2016/9/15/works-on-my-machine-understanding-var-bindings-and-roots
(def ocall #?(:cljs oops.core/ocall
:clj (not-implemented "ocall")))
(def oget #?(:cljs oops.core/oget
:clj (not-implemented "oget")))
(def oset! #?(:cljs oops.core/oset!
:clj (not-implemented "oset!")))
(def gcall #?(:cljs oops.core/gcall
:clj (not-implemented "gcall")))
doesn't work since ocall oset oget are macros
I'm trying to push the #_ (:cljs :clj) into lower level libraries. Is this possible?is there a way to list the functions that are currently ‘under instrumentation’ (clojure.spec)?
in a macro you can detect if you are in cljs or clj via &env: https://github.com/binaryage/env-config/blob/1d9a2409dad78324ed7ab2984d2b40b081173936/src/lib/env_config/impl/macros.clj#L3-L4
@qqq macros are expanded at compile time, functions are called at runtime, once you are in runtime, you cannot “go back” and do compile-time stuff (except for using eval, which is a different story)
cljs-oops (e.g. oget) is writing code for you you would otherwise write by hand, that is why is implemented as macros
if it was a function, it would at runtime dynamically perform some code, but not rewrite your existing code
again, why you cannot wrap oops macros with your own macros? where do you see a problem in that approach?
and btw. we are off-topic here, we should be discussing this in #clojurescript instead, have to go anyways
just in case a developer of clojars is around. The GSoC link in the github README is broken 😞 https://github.com/clojars/clojure-gsoc-2017
how do people feel about the idea of EDN files that have an (aliases)
header at the top to enable shorter keywords in the rest of the document:
(aliases [[monitor.reporter :as r]])
{:r/foo 1
:r/bar 2}
not proposing for this to be part of Clojure, just asking what you think of it as a practice
@tcrawley I just created another pr for some other small markdown problems that I found. Hope it helps
I am constructing a nested datastructure, similar to a binary tree, recursively using
(defn make-tree [{in :in out :out left :left right :right :as tree} indices]
(cond
(empty? indices) tree
:else (assoc
tree
:left (make-tree {:in (conj in (first indices)) :out out} (rest indices))
:right (make-tree {:in in :out (conj out (first indices))} (rest indices)))))
michaellindon: There’s https://github.com/Malabarba/lazy-map-clojure
I have come up with this, i think it is inelegant
(defn make-lazy-tree [{in :in out :out left :left right :right :as tree} indices]
(cond
(empty? indices) tree
:else (assoc
tree
:left (fn [] (make-lazy-tree {:in (conj in (first indices)) :out out} (rest indices)))
:right (fn [] (make-lazy-tree {:in in :out (conj out (first indices))} (rest indices))))))
so instead of returning the next subtree it returns a function to the next subtree, which can be called like this
(defn my-left [t] ((:left t)))
(defn my-right [t] ((:right t)))
(-> foo
my-right
my-right
my-left)
giving:
=> {:in #{2},
:out #{0 1},
:left #function[bab.core/make-lazy-tree/fn--20560],
:right #function[bab.core/make-lazy-tree/fn--20562]}
I guess delay is kind of doing the same thing?
just tried it, delay works nicely too
however the recursion will run quite deep and cause stack overflow. Is there a lazy way I can define this tree? I will not actually visit all of the tree
In short it sets up a deeply nested map, but I want to do this in a lazy way so that the values mapped to by keys are not evaluated until accessed
You can do tail recursion for the stack overflow but that won’t help with the lazy part.
you can’t tail call that code though
not without a radical design shift to move stack data into the heap
agreed. As per @schmee s suggestion i wrapped the calls with delay
(defn make-delay-tree [{in :in out :out left :left right :right :as tree} indices]
(cond
(empty? indices) tree
:else (assoc
tree
:left (delay (make-delay-tree {:in (conj in (first indices)) :out out} (rest indices)))
:right (delay (make-delay-tree {:in in :out (conj out (first indices))} (rest indices))))))
writing
(defn my-left [t] @(:left t))
(defn my-right [t] @(:right t))
I can traverse the tree to the leaf nodes that I want, without creating the others
I like this, but I'm wondering if anyone else can see any pitfalls
delay is under-utilized imho
a fun fact - force is an alternative for deref on delays, and is identity on non-delay values
only if you eagerly call it recursively
but it is easy to make a non-stack-consuming recursion that goes into deeper delays as far as you like
right, a delay is a zero arg continuation, effectively
thunk? maybe that’s the word
anyway, that overloaded behavior of force makes it convenient to write code that may or may not hit a delayed value
you've lost me now 🙂
thunks / continuations are how lazy seqs are implemented
and delays do the same thing
it’s a function that stands in for a value we might access later
@joshjones that article mentions a continuation being a one arg function, which is why I was particular about argument count - these being zero arg
https://en.wikipedia.org/wiki/Thunk whereas thunks are zero arg
so actually my first attempt was to change
:left (make-lazy-tree {:in (conj in (first indices)) :out out} (rest indices))
to
:left (fn [] (make-lazy-tree {:in (conj in (first indices)) :out out} (rest indices)))
and then I could traverse the tree by calling the function returned by :left. Is this what is meant by continuation?that’s what’s meant by thunk
ah ok, cool, im happy to be learning this
thanks for your help
@noisesmith what would be the pros/cons of delay
vs a fn
in this case?
a delay is a way of making a function that gets called only once when forced, whereas a function could get called more than once and would not cache the prior result (unless you memoized…)
delays are a more specific feature for this purpose so they eliminate some gotchas and boilerplate that come up in usage
@joshjones it has a function inside https://github.com/noisesmith/clojure/blob/master/src/jvm/clojure/lang/Delay.java
apologies for linking to my fork but that file is unmodified
another usage of delay I’m fond of is replacing nested lets inside conditionals with a let containing delays with conditionals that force certain delays as apropriate in a cond block
it’s something I only need for very imperative tasks
where I’m maybe getting a resource, maybe retrying, maybe cleaning up and bailing, etc. and it doesn’t fit a with-open or try/catch/finally well
eg. trying to use zookeeper in clojure where every operation potentially requires me to re-try or fail
(not coincidentally I am moving away from using zookeeper so I can avoid having to write code like this)
additionally, the delays can force another let bound delay inside their body, which simplifies tricky side effect tracking
Hey guys, building the first production clj/cljs app for my company. I'm looking for a best practice tip for using Stuart Sierra's component with a (postgres) database connection.
(ns my-app.components.db
(:require [com.stuartsierra.component :as c]
[clojure.java.jdbc :as jdbc]))
(defrecord Db [spec connection]
c/Lifecycle
(start [this]
(let [conn (or connection (jdbc/get-connection spec))]
(assoc this :connection conn)))
(stop [this]
(if connection (.close connection))
(assoc this :connection nil)))
It happened once in development that after a postgres io error, the connection would close and would render the app db-less. How do you guys handle this / what's a typical db component past the simple examples found online?was thinking about that. Thanks!
should clean up any defunct connections for you, with more and less aggressive options
Hello all, how can I use something like this:
'([:command "upper"] [:command "reverse"] [:command "remove-vogal"]) ;; this is the commands that I have to apply to collection
I thougth doing defmulti like:
(defmulti command (fn [[_ command] _] command))
(defmethod command "upper" [command string] (upper string)) ...
["string nubmer 1" "string nubmer 2" "string nubmer 3"] ;; is the collection
and I want to have the results in the end. I coudn´t figure out how to do this with threading macro, Is there possible?The defmulti and defmethod look ok. And threading is possible in general. Maybe you can past an example invokation?
well, that´s the problem how to apply the rules to collection and get the result : ["1 RBMN GNRTS" ... ]
(reduce #(conj %1 (command %2 collection) [] '([:command "upper"] [:command "reverse"] [:command "remove-vogal"]))
?
@fabrao It sounds like you want a reduce
over the seq of commands. seq of strings is the initial value; each pass maps command over the seq of strings
how can I use dynamic transform for each element? something like (-> element (commands ?))
That is what a reduce
would do, if I understand you correctly
(reduce
#(map
(command %1)
%2)
[seq-of-commands]
[seq-of-string])
Only I think I got the order of the args passed to the reducer wrong
Also I am not sure the dispatch syntax is correct, but that's the basic idea
Whoa that's actually what you wrote above and I guess I wasn't paying close enough attention.
@fabrao What didn't work about the snippet you sent earlier?
@captainlexington I think you trick is correct, I´ll give a try, thank you
hey guys, I'm looking forward to design an extensible library. but I'm not sure which is the best approach to it, do you know any reading matterial about this ?
What's the library's purpose?
@lxsameer if you haven’t already, you should give lispcast’s recent article series on clojure webframeworks a read: http://www.lispcast.com/why-web-frameworks , http://www.lispcast.com/arguments-against-frameworks , & http://www.lispcast.com/clojure-web-framework
@lxsameer best library possible is a bunch of little functions that compose correctly (e.g. a domain-specific algebra)
@tanzoniteblack thanks, I'll watch them
maybe one practical example is something like XPath vs. Lenses for traversing data structures
if you design w/ XPath in mind, the API will look one way, w/ Lenses probably another
and will compose differently
(or not at all)
@tanzoniteblack are you the author ?
I am not
If one thing is clear, it's that we have both too many and not enough frameworks
@alexmiller yeah that's true, At the end of the day frameworks are just tools, there are lots of good and bad tools around
I don't think that not using a framework makes you an expert. It might makes you a fool because your trying to go to a war with a water pistol
my experience with frameworks is that you trade potentially getting boxed in by constraints later for a quicker start on a project
define "framework". to me, something that works, until it doesn't. massive pain ensues.
big one is the framework code implements your -main and controls initialization and lifecycle stuff
maybe baked in libraries for handling each task (data mapping, routing, caching, rendering, etc) that’re hard to change out would be another