This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-12-13
Channels
- # adventofcode (84)
- # aleph (1)
- # announcements (2)
- # aws (27)
- # beginners (52)
- # braveandtrue (2)
- # calva (440)
- # cider (7)
- # clara (2)
- # cljdoc (26)
- # cljs-dev (70)
- # clojure (131)
- # clojure-berlin (4)
- # clojure-brasil (1)
- # clojure-europe (2)
- # clojure-greece (4)
- # clojure-hamburg (1)
- # clojure-italy (4)
- # clojure-losangeles (6)
- # clojure-nl (14)
- # clojure-spec (7)
- # clojure-uk (25)
- # clojurescript (26)
- # component (2)
- # cursive (13)
- # datomic (60)
- # dirac (59)
- # docker (1)
- # figwheel (1)
- # figwheel-main (2)
- # fulcro (12)
- # graphql (5)
- # juxt (33)
- # leiningen (19)
- # nrepl (1)
- # off-topic (37)
- # protorepl (2)
- # re-frame (18)
- # reagent (46)
- # remote-jobs (1)
- # ring-swagger (1)
- # shadow-cljs (88)
- # sql (10)
- # tools-deps (64)
- # vim (24)
I'm looking at packaging Clojure for Guix - can anyone tell me where the source for the bin/clojure
shell script lives? I can't see it in the main clojure git repo.
https://github.com/clojure/brew-install/tree/1.9.0/src/main/resources
Now that clojure is on java 1.8 might IFn start to extend from builtin java function interfaces beyond Callable and Runnable?
We’ve been looking at it - follow https://dev.clojure.org/jira/browse/CLJ-2365
Thanks @alexmiller. Do you know if there's a script that merges the built clojure/clojure with clojure/brew-install to make something like what's found at https://download.clojure.org/install/clojure-tools-1.9.0.X.tar.gz?
That repo is where the build happens
The build basically runs script/package.sh
Great, thanks @alexmiller
Is anyone working on a TUI REPL thing like REBL that uses Datifiable/Navigable? Something like datawalk?
I have a question about datafy. I expected to be able to implement the protocol via metadata, but I can’t seem to get it cooperate:
user=> (def x ^{:clojure.datafy/datafy (constantly [3 4 5])} [1 2 3])
#'user/x
user=> (meta x)
#:clojure.datafy{:datafy #object[clojure.core$constantly$fn__5657 0x49c6c24f "clojure.core$constantly$fn__5657@49c6c24f"]}
user=> (d/datafy x)
[1 2 3]
user=> (def x ^{:clojure.datafy/datafy #(str "foo")} [1 2 3])
#'user/x
user=> (d/datafy x)
[1 2 3]
same behavior 😕
user=> (def x ^{`d/datafy #(str "foo")} [1 2 3])
#'user/x
user=> (d/datafy x)
[1 2 3]
user=> (def x (with-meta [1 2 3] {`clojure.core.protocols/datafy (fn [_] 1)}))
#'user/x
user=> (d/datafy x)
1
in CLJS:
(def y (with-meta [1 2 3] {:clojure.datafy/datafy (fn [_] 1)}))
(d/datafy y)
;; => 1
@lilactown no, the protocol function in cljs is cljs.core/-datafy
but that keyword thing is how it was implemented in clojure too, before metadata protocol extension got introduced
(also, why does cljs not have a clojure.core.protocols
namespace? that seems like an odd diversion from clojure)
there’s an issue it looks like: https://dev.clojure.org/jira/browse/CLJS-2999
Yeah, the datafy port was done a while back, so Clojure could have moved a bit from it since.
hello, can i use a transient hash-map as an atom,and many threads change it ? with persistent hash-map it works,with transient it doesn't . its my code bug or its transients?
atoms will transparently retry on collisions from thread, and if you store mutable data in them, you will get a bad state
@takis_ what problem are you trying to solve by putting transient data in an atom?
takis_: While this is true, going mutable is tricky. I would not recommend doing so until you have evidence you need to.
I would strongly recommend building it and measuring, your intuition is almost certainly wrong
The Clojure core devs have put a lot of effort into making the persistent data as fast as possible.
do you know if its possible to define in Clojure a synchronized method?like in Java a method that max 1 thread can use
Yeah, there’s locking
(doc locking)
-------------------------
clojure.core/locking
([x & body])
Macro
Executes exprs in an implicit do, while holding the monitor of x.
Will release the monitor of x in all circumstances.
Atoms are designed to use STM and be, usually, faster than locking. locking is mostly for interop with Java, and it is used infrequently.
takis_: it sounds like you want something like Clojure's reducers, maybe? https://clojure.org/reference/reducers
How can I refer to components of my project.clj from within my program? In particular, I need to get the :version from project.clj
Take a look at this https://groups.google.com/forum/#!topic/leiningen/7G24ifiYvOA
The version is available in different places based off how you run the app - i.e. lein repl vs. as an uberjar. I think the solution provided in that doc will work in most cases - but remember to test it out in whatever sort of environment the app is being run in.
Interesting. It looks like there is no real way to just read the edn of project.clj, then?
You can read in the project file like you would read in any other EDN file, then parse out the version - but the issue is you don't always have the project file available to you, depending on how the app is being run/compiled
Compiling my apps via uberwar, so I don't know that project.clj persists
I suspect that this solution will work for you: https://groups.google.com/d/msg/leiningen/7G24ifiYvOA/h6xmjeWaO3gJ
Ok. Hard to test, though, since it's repl-incompatible
We build our war files and deploy them to have an open REPL port which you can connect to and run the function to grab the version
i.e. with immutant you can specify which port to connect to in your project.clj.
https://github.com/immutant/lein-immutant/blob/master/docs/deployment.md
then you can connect to the REPL with
lein repl :connect host:port
wow. That's cool
Is it possible for project.clj to look at a config file for certain values, like version?
You can use something like lein-v for that: https://github.com/roomkey/lein-v
...it externalizes your version to a git tag and then it has middleware that replaces the value in project.clj
What would be the clojure equivalent to this python snippet?
import os
path = "~/Downloads"
{
z[0].replace(path, '')[1:]: z[1]
for z in os.walk(".") if z[0].replace(path, '') and not z[2]
}
What does os.walk do?
What does the output look like?
It’s building a dictionary of folders mapped to a list of empty children. os.walk returns a tree of files
you could construct the equivalent tree by splitting the paths of items from file-seq and using those paths with assoc-in or update-in
user=> (pprint (file-seq (java.io.File. ".")))
(#object[java.io.File 0xdbd8e44 "."]
#object[java.io.File 0x7ac0e420 "./foo"]
#object[java.io.File 0x78383390 "./foo/bar"]
#object[java.io.File 0xdb57326 "./foo/bar/baz"]
#object[java.io.File 0x34a875b3 "./Investor Type no PII.csv"]
#object[java.io.File 0x4748a0f9 "./Untitled spreadsheet - Sheet1.csv"])
if you map str
on the files, you just get the path strings
user=> (pprint (reduce (fn [t p] (assoc-in t p {})) {} (map #(clojure.string/split (str %) #"/") (file-seq (java.io.File. ".")))))
{"."
{"foo" {"bar" {"baz" {}}},
"Investor Type no PII.csv" {},
"Untitled spreadsheet - Sheet1.csv" {}}}
nil
Pretty close, I can work with that. Here’s the test file structure and the actual output:
## File Tree
# (root)
# |- a (dir)
# | |- b (dir)
# | | |- (empty)
# |- c (dir)
# | |- d (dir)
# | | |- (empty)
# |- e (dir)
# | |- f.txt
#
## Output
# {'/a': ['b'],
# '/a/b': [],
# '/c': ['d'],
# '/c/d': []}
oh also my snippet above doesn't differentiate files from directories
(require '[clojure.pprint]
'[clojure.string :as string])
(defn directory?
[file]
(.isDirectory file))
(defn directory-with-no-files?
[file]
(and (directory? file)
(empty? (->> file
(.listFiles)
(filter #(.isFile %))))))
(defn relative-name
[path dir]
(let [dir-path (str dir)]
(string/replace dir-path (re-pattern path) "")))
(defn pair-files
[path dir]
[(relative-name path dir)
(->> dir
(.listFiles)
(filter directory?)
(map #(.getName %)))])
(defn find-empty-dirs
[path]
(->> path
()
(file-seq)
(drop 1)
(filter directory-with-no-files?)
(sort)
(map #(pair-files path %))
(into {})
(clojure.pprint/pprint)))
(find-empty-dirs "/Users/jay/Projects/map-comp/test/")
so really what you want isn't a tree, but sort of a weird adjacency-list
where every item also includes all parents
(in its key)
(let [root ( "/Users/jay/Downloads/test/resources/")]
(transduce
(comp (remove #{root})
(keep
(fn [^java.io.File file]
(when (.isDirectory file)
(let [path (.getPath file)
;; Split path into two parts at the last /
[parent _] (string/split path #"(?=/[^/]+$)" 2)]
[parent path])))))
(fn
([m] m)
([m [parent child]]
(-> m
;; Update the parent entry to add the child.
(update parent (fnil conj []) child)
;; Create an entry for the child if it doesn't exist.
(update child (fnil identity [])))))
{}
(file-seq root)))
@jayzawrotny ☝️ here’s an equivalent to your previous post without extra calls to .listFiles
and .isDirectory
.
I think you just beat me, I was pretty close too
{"/a" ("b"), "/a/b" (), "/c" ("d"), "/c/d" (), "/e" ()}
You could use reduce
and do all the logic in one reduction function if you want. But, with respect to your desired output, these are the parts.
You could use this script to test against the expected output
mkdir -p a/b
mkdir -p c/d
mkdir e
touch e/f.txt
Though there may be a potential issue, I find myself having to replace the (rest)
call with (drop 3)
Right, that’s what I figured it was intended for but I’m finding the root directory is still included
But I’m mostly doing this for learning purposes so you don’t need to waste more time on it unless it’s holding your attention 🙂