This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-06-09
Channels
- # babashka (63)
- # beginners (97)
- # biff (11)
- # chlorine-clover (5)
- # cider (46)
- # clara (2)
- # clj-kondo (34)
- # clojure (65)
- # clojure-austin (1)
- # clojure-europe (9)
- # clojure-france (10)
- # clojure-italy (11)
- # clojure-nl (3)
- # clojure-spec (29)
- # clojure-uk (5)
- # clojuredesign-podcast (1)
- # clojurescript (56)
- # clr (6)
- # component (17)
- # conjure (5)
- # core-typed (5)
- # cursive (23)
- # data-science (5)
- # datahike (3)
- # dirac (3)
- # emacs (20)
- # fulcro (17)
- # graalvm (10)
- # graphql (8)
- # helix (99)
- # honeysql (7)
- # jobs-discuss (9)
- # juxt (9)
- # leiningen (14)
- # malli (3)
- # meander (6)
- # off-topic (77)
- # pathom (7)
- # re-frame (12)
- # reagent (8)
- # reitit (10)
- # restql (1)
- # shadow-cljs (22)
- # spacemacs (10)
I’m incorporating Integrant into a side project, and I’m wondering if it’s common to put all of the init-key
and halt-key!
multimethods in the same file, or if folks more often break up those declarations into multiple files and rely on side-effectful imports to ensure the system is composed properly?
Hi. Has anyone got suggestions for introductory hands-on Clojurescript material. Recent enough that it's not going to collapse in a muddle of broken dependencies and with enough context that you don't have to be thoroughly conversant with the modern JS ecosystem to know what's going on?
• https://day8.github.io/re-frame/ • https://www.learnreagent.com/ • https://www.learnreframe.com/
What is the correct way to write tests for function which are defined using memoize
.? Before testing a function, my test case would often like to erase
the cache.
There's no way to clear the memoize
cache, you may only define a new memoized version
One way of implementing it is to define your pure un-memoized function (defn f* [] ...)
and then create a memoized version (def f (memoize f*))
Yes, this will use a load of memory.
It's recommended to use a different type of cache if memoize doesn't fit your performance requirements
Some libs I know of are https://github.com/clojure/core.cache and https://github.com/clojure/core.memoize
You can just create a memoized version in a let form for the duration of your test:
(let [f (memoize f*)]
; test f here
)
if I memoize a function which is already memoized, does that work? when the let finishes, is the old cache restored. Sorry, I don't really know how atoms work.
It is not just a question of directly testing memoized functions. one of my low level functions is memoized, but I need to test the api functions. They effectively rely on the memoized data. I'd like to test those api functions independently of the current state of the cache.
can I do something like
(binding [f (memoize f)] ...)
so that low level calls to f
not explicitly mentioned in my tests, will use the dynamically bound f
Like most things in Clojure, memoize
doesn’t change the function its given, it returns a new function, so yes, the original unmemoized function continues to exist in its original state.
hmm. so for memoize
functions to be testable, they need to be dynamic.
Since memoize makes the pure function stateful, you could pass the memoized function as a parameter. What aspect are you testing?
I explained before, but again: one of my lowest level functions (the work horse) is implemented with memoize. I want to test the API functions which don't call this low level function explicitly. But since the value is memoized, the tests only test according to the current state of VM. I'd like the test cases each to assume there's no cache. That seems to me like a much safer test.
right?
IMO only if I was testing caching performance and needed control over that, in which case maybe memoize is not the right tool to use. You're either unit testing the underlying function, or testing the stateful caching aspect. The reason I say that is because memoize expects a referentially transparent function, so I think it's fair to say there's a decent guarantee that what you get out is what you put in. I don't think there's a reason not to add ^:dynamic to the fn for tests, but I don't see a huge reason to do it either
I'm working off of information in Clojure: The Essential Reference from Manning and (source memoize)
suppose the function you are memoizing calls some other function. and in the mean time (in the live session) you edit that other function. Now when you run your tests, is the information cached from v1 or v2 of that other function? Even if it is referentially transparent, functions can be edited while you are editing. This means it is likely that you'll get different results from testing in your live session vs testing in stand-alone.
Basically memoizing is side-effectful computation, which makes it difficult to test.
hi everyone, is there an open source project that uses datomic in extense where I could study its code?
Did you take a look at this repository: https://github.com/Datomic/mbrainz-sample
Hi guys.I want to iterate over a nested vector and delete some elements (for example deletes "5" whenever finds it) and I want to use reduce / transducer instead of nested loop (unlike imperative systems). I do understand that the answer isnt nested loop recur. so i went for reduce/transdures but my code fails each time. Can u give me an example of doing so?
@U014CTZJK2S (clojure.walk/postwalk #(if-not (and (coll? %) (seq %)) (* 10 %) %) [[1 10] [2 10]]) This is using Clojure.walk and not reduce, also can you post here what you are trying so that we can check if we can fix it.
Caused by:
not sure what you're doing
what do you mean by "make rebl"
the error is saying that you're trying to run rebl, but rebl is not on the classpath. but I'm not sure what you're doing so I don't know how to help
https://github.com/cognitect-labs/REBL-distro#usage is info on using clj to do this
there are some wiki pages with more info on other envs https://github.com/cognitect-labs/REBL-distro/wiki
Hi, I have been working with clojure fixtures. I am running a test and take a screenshot at the end, everything working fine. My question is, is there a way to get the name of the function in the fixture? I want to use it as the file name of the screenshot. Code:
(defn fixture-selenium
[f]
(try
;; setup here
(f)
(finally
(println f) ;; Prints cider.nrepl.middleware.test$test_vars$fn__38755$fn__38760
(save-screenshot)))
Currently whenever I add new query in queries.sql
, I have to close and reopen REPL everytime to test it. I have also tried to reload in the REPL using (use '[demo.db.core :as db] :reload-all)
but it didn't work. Currently I'm using Calva plugin in VS Code. So is there any way to test it without closing and reopening REPL everytime ?
The only thing I do is to reload the namespace where hugsql/def-db-fns
importing the file is used.
I tried to reload the db.core
namespace but it didn't reflect the new changes.
There is a nice discussion here about reloading namespaces: https://stackoverflow.com/questions/7658981/how-to-reload-a-clojure-file-in-repl
I followed the same question of stack overflow and used use
as well as require
but nothing worked, even I tried to reload using Calva plugin shortcut but nothing worked.
(conman/bind-connection *db* "sql/queries.sql")
, using this way I'm getting queries.sql
file.
This is the file, it is default code of luminus framework.
I seem to recall a trick, discussed a while ago that involved some sort of compliation of the code during startup/repl? I can't recall. @alexmiller I think you mentioned it?
I'm still trying to figure out the purpose of dynamic variables when let
exists
What is the use case here
dynamic vars let you pass context down the call stack but not as parameters
Oh so it's just dynamic scope then?
generally, you should avoid dynamic variables imo - usually it's better to make that stuff explicit in the call
That's an ... interesting feature
dynamic variables are very powerful, but with power comes responsibility.
what is the right away to share global variables in clojure. e.g i have 3 different namespaces with ring routes and I want to pass db information
A common way to pass extra stuff to ring handlers is middleware that assocs that stuff into the request map
without calling what each time?
yep see Yogthos example here https://yogthos.net/posts/2015-10-01-Compojure-API.html he repeats (:db config) in each route
it looks like the responses are written in-line in this example. for that particular use case, repeating (:db config)
seems reasonable. if your views are defined elsewhere, then you can have middleware provide the db for each route
you could create a dynamic var and bind it in a ring middleware when a request arrives
I pass "configuration" as a map (usually I leave it the in last position, if a reasonable n-arity is required)
I also use juxt clip to manage some state, like a shared database connection, or a redis connection. That state is held in the map and passed around.
you guys tried aero
? I just noticed that I am not using leiningen profiles to decide which aero #profile
to choose.
I have (read-config "config.edn" (System/getenv "PROFILE"))
... someone knows if you can use the profiles passed as lein with-profile PROFILE
and catch that value to be used in aero?
I think the with profile will either be passed as an argument to the application on startup
like one of the jvm switches -Dprofile test
this might be of help
Great, so why is this more useful? The big benefit I've discovered is the .lein-env file in the root of my project. This file holds a map of environment values that can be useful during development. There are 2 ways to create this file.
The RIGHT way as set out by the creator of the project, and,
The WRONG way as in how I use it
environ also has a plugin available lein-environ which sucks profile specific settings from ~/.lein/profiles.clj and/or a project specific profiles.clj (which should not be checked into source) and creates the .lein-env file when Leiningen does its thing (effectively making .lein-env a transient file). A .lein-env file looks a little something like this.
excerpt from the above article
ouch =/ this app is a bit old now, I was happy with leiningen and decided to leave this way rsrs
Hi all! I am trying to understand how to use the component library from Stuart Sierra, but I am struggling to understand the record part. In the example, he creates a record using (defrecord Database)
, and then a constructor using map->Database
.
My doubt is: What exactly this map->
is doing? Is it mutating the Database record? How it was created?
Thank you in advance!
@joao.micena When you use (defrecord Foo)
, Clojure automatically generates two constructor functions for you: map->Foo
that accepts a regular hash map and returns a Foo
record populated from the hash map and ->Foo
that accepts positional parameters matching the fields you declared in defrecord
(and returns a populated record).
Records -- like other Clojure data structures -- are immutable.
user=> (defrecord Foo [a b])
user.Foo
user=> (->Foo 1 "Two")
#user.Foo{:a 1, :b "Two"}
user=> (map->Foo {:a "One" :b 2})
#user.Foo{:a "One", :b 2}
user=>