This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-12-14
Channels
- # adventofcode (62)
- # beginners (78)
- # boot (26)
- # boot-dev (9)
- # cider (73)
- # cljs-dev (33)
- # cljsrn (36)
- # clojure (159)
- # clojure-android (1)
- # clojure-austin (1)
- # clojure-greece (79)
- # clojure-italy (10)
- # clojure-nl (3)
- # clojure-russia (11)
- # clojure-spec (33)
- # clojure-uk (26)
- # clojurescript (107)
- # core-async (22)
- # core-logic (12)
- # cursive (16)
- # datomic (13)
- # devcards (5)
- # duct (36)
- # emacs (4)
- # figwheel (3)
- # fulcro (107)
- # graphql (171)
- # hoplon (27)
- # instaparse (24)
- # jobs-discuss (34)
- # juxt (3)
- # lein-figwheel (1)
- # leiningen (8)
- # lumo (11)
- # off-topic (9)
- # onyx (79)
- # parinfer (1)
- # pedestal (75)
- # re-frame (27)
- # rum (1)
- # shadow-cljs (11)
- # spacemacs (20)
- # specter (17)
- # unrepl (96)
OK, probably a deep dark corner of Clojure functionality I haven't seen before, but can anyone explain what ('subset? ...) is doing in this line of code within the Clojure tests? https://github.com/clojure/clojure/blob/master/test/clojure/test_clojure/rt.clj#L97
I just figured that out from REPL experimentation, which I probably should have done before asking. I knew that worked with a keyword as the first value in the form, but don't think I've ever used it with a symbol as the first value in the form.
@andy.fingerhut clojure.lang.Symbol
implements clojure.lang.IFn
just like clojure.lang.Keyword
, and seems to implement it in basically the same way, invoking RT.get
on the argument passing itself as the lookup key
I will most likely forget this, and not miss the knowledge because I wouldn't want to see this in my code 🙂
I've only ever written Clojure as a hobby, but a lot of hours have gone by without me seeing this in people's code.
would be interesting to mine crossclj for the most rarely used features. I don't think I've ever seen :strs or :syms destructuring in the wild, for instance
now I'm kind of sad that there's no clojure.lang.String that also implements IFn. Then we'd have three types you can both destructure and use to look themselves up.
@hagmonk We have :strs
destructuring in our production code... 🙂
but it's not "in the wild" so I think I escape on a technicality. ag
reveals I actually have used it twice in just this one project I checked 😳
Spec question: If I have a function that takes a destructured map, what's the best way to spec that function, so that the values of the keys in my map are also specced? The best I've got right now is (s/keys :req-un [::a ::b ::c])
given (defn foo [{:keys [a b c]})
But, I'd kind of want the names of the keys for my function to not match the spec name of their value. And I'd rather define the spec for them inline. Any easy way to do that?
Would be nice to have something like (s/map :req [:a int? :b string? :c ::other-spec])
for this scenario
Is there a way to make this point free #(assoc %2 :id %1)
I get that. This was a just a challenge based on a discussion we are having internally at my company.
That's not point-free...
What is point-free? I thought it merely meant "don't use variable names, and chain together functions"
But args
and %
are variables.
we need to removeargs from (->> args (interpose :id) reverse (apply assoc))
and then we're good
Here's a point-free version: (comp (partial apply assoc) reverse (partial interpose :id) vector)
boot.user=> ( (comp (partial apply assoc) reverse (partial interpose :id) vector) 123 {} )
{:id 123}
@stuartrexking ^ does that answer the challenge?
@seancorfield Sure does! Thanks!
The page on transients says that:
> In Clojure 1.6 and earlier, transients would detect any (read or write) use from a thread other than the one that created them and throw an exception. That check was removed in 1.7 to allow for more flexible use in frameworks like core.async go blocks that enforce the single-threaded constraint via other means.
Emphasis mine. But under summary it still says:
> Thread isolation - enforced
I tried the following in
1.8:
(dotimes [_ 5]
(def tv (let [tv (transient [])]
(future (Thread/sleep (rand-int 3))
(conj! tv 1))
(future (Thread/sleep (rand-int 3))
(conj! tv 2))
tv))
(Thread/sleep 3)
(println (persistent! tv)))
;; =>
;; [2 1]
;; [2 1]
;; [2 1]
;; [2 1]
;; [1 2]
So it clearly is possible to modify a transient from different threads. What, then, does "thread-isolation--enforced" mean?
https://clojure.org/reference/transients[just guessing] perhaps it means that with respect to a transient, conj! pop! push! are all atomic -- i.e. if you run them from different threads, its as if they're beintg run from the same thread in some order - they won't 'trample' on each other due to race conditions
also, the above example confuses me, as I thought you were supposed to look at the return value of conj! ... instead of printing the 'original transient'
quoting: https://clojuredocs.org/clojure.core/assoc!
;; The key concept to understand here is that transients are
;; not meant to be `bashed in place`; always use the value
;; returned by either assoc! or other functions that operate
;; on transients.
not sure if "other functions" includes conj!There are several cases where conj! May not change the input, and instead may return a new collection
So yes, treat transients like persistent collections.
I'm looking for a clojure DSL that lets me output C code. Is https://github.com/aaronc/c-in-clj (5 years since last commit?) the best we've got ? Pre-emptive: why not just use C?: C's macro system is lacking. I want to use the full power of Clojure amcros for my macro system.
Not that I know of, it’s not really a easy thing to pull off since C lacks almost everything Clojure would need
But writing a AST to C layer wouldn’t be that hard. I know of several projects that do that
@tbaldridge: I'm not trying to do Clojure -> C . I'm trying to do "Clojure data representing a program -> C".
I have some code which deals with nothing but tensors of floats -- no other data structure, no gc-ing, nothing else and I want to represent this code as 'clojure data', and then generate C from it (which will let me hit both WebAssembly and Cuda afterwards)
Interesting Idea, but probably needs some time to become doable. For example if? in the future Kotlin can compile to web-assembly it will become easier.
Actually not that far away, https://blog.jetbrains.com/kotlin/2017/11/kotlinnative-v0-4-released-objective-c-interop-webassembly-and-more/
@U26FJ5FDM: I think we are discussing different problems. What problem do you think I am trying to solve?
I'm not asking for "Clojure -> Cuda" or "Clojure -> WebAssembly" I want "very restricted DSL -> Cuda" and "very restricted DSL -> WebAssembly" this "very restricted DSL", expressed as Clojure Data, is NOT FULL CLOJURE -- in particular, I do NOT want to emscriptsen the entire JVM I want a very restricted DSL for describing manipulations on tensors of floats -- and compiling this DSL to WebAssembly / CUDA the main relation to CLojure is that I want to implement this very-restricted-dsl via clojure data
if I'm dealing with a java class that extends a HashMap, is there an easy way to cast a map into it?
public class RowData extends HashMap<String, Object> {
}
would love to do (cast RowData (java.util.HashMap. {:a 1}))
but that raises a ClassCastException
thanks, that results in
ClassCastException hex.genmodel.easy.RowData cannot be cast to clojure.lang.IPersistentCollection clojure.core/conj--5112 (core.clj:82)
ended up with this, suboptimal but works:
(defn ->row-data [m]
(let [row (RowData.)]
(doseq [[k v] m]
(. row put k v))
row))
I'm playing with function specs and I wondered if one could use it to emulate type checking, during compile time, something like this:
(s/fdef divide
:args (s/cat :x integer? :y integer?)
:ret number?)
(defn divide [x y] (/ x y))
;; should throw when compiled?
(defmacro divide-by-foo []
(eval `(divide 6 :foo)))
yet this namespace doesn't throw, why?This is exactly what spectrum does: https://github.com/arohner/spectrum
hi guys
why this work in second case and not work in the first
@fbielejec you need to have instrumentation enabled to have it throw
@fbielejec something like https://github.com/jeaye/orchestra
@fbielejec by default, clojure spec doesn't circumvent evaluation to perform spec analysis, you need to tell it to check your specs
think it's after you define your specs, but before you evaluate your function that you want spec analysis for
note that instrumentation was turned on after the specs have been introduced and evaluated
this is my problem - I don't understand why at compile-time the macro doesn't become (eval (/ 6 :foo))
, which should still throw. The divide-by-foo will fail for sure (with an exception or spec validation error depending on whether instrumentation is turned on), like you say.
I think eval runs in its own environment, which means within eval, you have not instrumented the divide function. That's my guess at least.
Try:
(defmacro divide-by-foo []
(divide 6 :foo))
Instead, after having instrumented divide. This will make a call to divide at macro-expansion time which should fail validation of the spec by instrument.Does either "lein repl" or "boot repl" have a web interface? I want something like "boot web-repl" or "lein web-repl" to 1. open up a webserver on port 8081 2. I can go to <localhost://8081> and interact with the repl 3. have certain forms of output render nicely into HTML tables / SVG diagrams / ...
You can do a plug-in with it https://github.com/yudai/gotty
Do it with a socket repl and it'd be pretty easy
.. why did I not just try running cljfmt on it earlier. I keep running it on my .clj files
Hi, I am transducing over a lazy sequence that reads from a file (hurray). However I am having some trouble figuring efficient ways to debug or any plausible way to debug at all. Maybe you can comment? Here's code:
(ns cleanser.dictionary-test
(:require
[clojure.pprint :refer [pprint]]
[puget.printer :refer [cprint]]
[clojure.inspector :as inspect :refer [inspect-tree]]
[cleanser.dictionary-search :refer :all]
[ :as io]
[clojure.set :refer :all]
[clojure.math.combinatorics :refer [cartesian-product]]
[clojure.test :refer :all]
[ :as io]
[clojure.string :refer [split]]))
(defn text-file-reader [filepath reader]
" return a lazy sequence for streaming through the file contents "
(with-open
[file-reader (reader filepath)]
(line-seq file-reader)))
(deftest names-dictionary
(let
[text (slurp "resources/names/hebrew-wikipedia-content.txt")
names-dump-filter (remove #(re-matches #"# < > \[ \] \{ \} / @ \*" %))
names-dump-breaker (mapcat #(split % #"\|"))
names
(sequence
(comp names-dump-breaker names-dump-filter)
(text-file-reader "resources/names/user-names-unique.txt" ))
dictionary (build-dictionary names)]
(println (search text dictionary))
(println (type names) ; a lazy stream
(println names)))) ; java.io.IOException: Stream closed
printing names
seems futile, the stream has been expended by then. Any suggestion for a better design for stream-processing file contents with transducers?
Any best practice for debugging within the transduction itself is very welcome as well
Many thanks!@matan you could use trace to monitor the input/output of your transducer functions https://github.com/clojure/tools.trace
actually, I am not very sure how I'd trace
very elegantly in transducing code like above
@matan I though it would be easy with trace, but it doesn't work as expected in my case
(defn xflog []
(fn [rf]
(fn
([] (rf))
([res] (rf result))
([res input] (println input) (rf res input)))))
it works as expected, but you could extend it to include a tag (e.g. "before filter odd?")
@matan Or use the debug atom trick. Something like
(defonce a (atom []))
(def dbg-xf (map (fn [x] (swap! a conj x) x)))
(comment
;; The atom now contains every value that passed through dbg-xf
@a
)
@matan you can also just use a plain old debugger like the one available in Cursive. You can also use scope-capture as a more powerful version of the debug atom trick, which also supports a form of breakpoint (disclaimer: I'm the author!): https://github.com/vvvvalvalval/scope-capture
I have a system.edn file that needs a database url that I don't want to check in to source control. How can I introduce a variable into an edn data structure?
@captaingrover there are a bunch of config libs for Clojure, here’s some examples:
cprop is nice!
@schmee I've always used environment variables. That way I can have an .env.example file people can copy and modify to their likings and not check it in
the environment-variable approach is also great when paired with direnv https://direnv.net/
I’m using jvisualvm to successfully profile my app, locally, on macOS 10.12. It works correctly through several jvm reboots, and jvisualvm suddenly fails to connect with “Failed to create JMX connection to target application.” I wasn’t explicitly creating JMX connections beforehand. Rebooting my mac fixes it, but is there any way to solve it without rebooting?
once it’s hosed, restarting both my clojure jvm and the visualvm process doesn’t fix it
something about port acquisition logic?
$ java -version
java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)
I feel like this code can be much shorter: I'm trying to tokenize a string via . a list of regexps:
(defn- token-len [t]
(count (:str t)))
(defn lex [pats s]
"lex :: obj.pats -> string -> [obj.token]"
(let [regexps (mapv pat->regexp pats)]
(loop [tokens []
s s]
(if (empty? s)
tokens
(let [token (first (keep #(regexp-match % s) regexps))]
(assert token (str "failed to tokenize substring: " s))
(assert (> (token-len token) 0)
(str "empty token: " token " s: " s))
(recur (conj tokens token)
(subs s (token-len token))))))))
https://clojuredocs.org/clojure.core/subs <-- does clojure not offer an O(1) time substring ?
No. Clojure doesn’t have a string type and just uses Java’s strings. If Java’s strings don’t have it Clojure doesn’t have it.
you’d think with immutable String you could make an immutable CharSequence that used an indexed range of a string - except of course unicode we can’t have it because unicode
since you can’t guarantee that the index of a string by character starts at any given byte
UTF-16 requires either 16 or 32 bits to encode a character
you have to walk the string up to the point of your index to find its byte offset
Indexes into Java strings are indexes of 16-bit values, whether they are in the middle of a 32-bit code point or not.
so indexing is O(1), but isn't guaranteed to be the index of a full Unicode character.
oh - so subs
can return garbage?
TIL
=> (subs "💩" 1)
"?"
There have been bugs related to this in Windows applications, I've heard.
I’m not surprised in the least - I would have expected subs to index by character not by pair of bytes
There are libraries that can turn Java strings into sequences of Unicode code points, but then there are also complexities in Unicode like modifying graphemes (I think they are called) that can require understanding sequences of multiple Unicode code points, if you want to know how many "graphical things to display"
I have heard that Perl for about a decade has strings that are something like UTF-8 in memory, but if you index them by integer, they actually take the variable-number-of-byte encoding into account and give you the index of the i-th Unicode character.
I suspect that they might even implement some kind of caching of 'character index' -> 'byte offset' under the hood if you index the same string many times, but haven't looked.
(without an O(n) scan that is)
ztellman has a new immutable strings implementation in his bifrucan library that gives you log(n) substringing I think
the problem with java's strings is the lack of a tree structure, so you can can't just hold a reference to the parts you need, your substring ends up holding a reference to the whole string
which was causing enough of a memory issue that they switched from what you propose (substring returning a special string that refers to the other string with offsets) to substring returning a copy
but you could make a CharSequence that is cheap to construct from a String and uses a simple tree of some sort - and if code breaks when you use CharSequence instead of String the code is bad
https://dev.clojure.org/jira/browse/CLJ-112 I opened this issue in assembla before clojure was on jira (after asking rich about it on irc)