This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-08-05
Channels
- # bangalore-clj (1)
- # beginners (99)
- # boot (108)
- # cider (15)
- # clara (4)
- # cljs-dev (12)
- # cljsjs (37)
- # cljsrn (4)
- # clojure (110)
- # clojure-italy (2)
- # clojure-spec (12)
- # clojurescript (168)
- # cursive (1)
- # datomic (24)
- # graphql (6)
- # hoplon (5)
- # jobs-discuss (2)
- # keechma (21)
- # mount (5)
- # off-topic (140)
- # om (2)
- # parinfer (37)
- # planck (6)
- # re-frame (4)
- # reagent (9)
- # rum (2)
- # spacemacs (4)
googling for "debrujin indices clojure" brings up surprisingly few results; is there a library for this in clojure, or for some reason, does debruijn indices not match well with clojure ?
1. clojure vectors has efficient "lookup n-th element" does it have either: (a) efficient insert @ front + delete from front OR (b) efficient insert @ end + delete from end ? [I'm basically looking for something like a stack -- push/pop from the same end -- but I also want efficient indexing (otherwise, I would just use a list) ]
@qqq lists and vectors both implement IPersistentStack and peek / pop efficiently
vectors conj and pop from end, lists from head
https://clojuredocs.org/clojure.core/pop -- was not aware you could pop a vector; thanks!
there's also PersistentQueue, which has no literal but peek / pop is from the opposite end of conj
one gotcha with PersistentQueue - don't use list ops or it turns into a seq and doesn't behave right any more
(I dealt with a bug where someone used swap! rest on a queue, it became a list, and thus went from fifo to lifo)
I'm not touching queue; this is implementing eval with debruijn, which requires only stack + indexing
s/lol/I'm sorry for your pains in debugging the vec <-> list bug, I've dealt with a few of those myself.
the worst thing is that I'd literally told the author of the code "don't use rest on a queue", but neglected to tell him why it was a bad idea
so he just put it on his long list of things I have an opinion about but he's never going to change, lol
@noisesmith : you should have made him find the bug himself; then he'd realize "noisesmith is a genius; I need to buy him beer for the next month"
Is it possible to find a list of all types somewhere? (i.e. clojure.lang.\ and java.lang.\)
you could walk the class path and iterate all classes you find
but then you have to decide if eg. (class +)
counts as a "type" distinct from (class -)
- the jvm doesn't have types in a way that makes much sense to me at least
and in clojure each of those is its own class
*instance of its own class
oh, I thought your code wanted the list
if any editor did that it would be Cursive
To be honest, I’m just trying to optimize a thing that switches on types into a protocol:
(defn- recombobulate [item]
(cond
(string? item) (clojure.string/trim item)
(map? item) (recombobulate-map item)
(coll? item) (recombobulate-vector item)
:default item))
It’s mostly me going “wait, strings are Java types, right? Or are they Clojure types?” I.e., should I use java.lang or clojure.lang
the repl makes answering all this easy
"" is a java.lang.String
for coll? I'd use java.util.Collection
for many classes (supers (class foo))
is more informative than (class foo)
- and all the collections we typically care about extend java.util.Collection
for map? java.util.Map probably
right
though now that I check (source coll?)
it actually is checking if the arg is a clojure.lang.IPersistentCollection
but every clojure.lang.IPersistentCollection is also a java.util.Collection iirc
yeah - you can extend any of them for your protocol
the trick is picking the right ones of course
vectors are not ISeq
nor are sets
perhaps you want clojure.lang.Sequential (though that leaves out sets...)
heh - well supers outputs sets, so you could do it in clojure with the right graphing bindings 😄
Of course, and Proto REPL probably already comes with the graphics libraries to do it 🙂
+user=> (set/difference (set/intersection (supers (class [])) (supers (class #{}))) (supers (class {}))) ; it's shared by [] and #{} but not {}
#{java.util.Collection}
oh, wow, TIL
{} isn't java.util.Collection - so I misinformed you earlier
(defn find-common-ancestors [& things]
(apply set/intersection (map #(-> % class supers) things)))
It leaves me with two “catch all” clauses instead of one:
(extend-type nil
Recombobulate
(recombobulate
[thing]
thing))
(extend-type java.lang.Object
Recombobulate
(recombobulate
[thing]
thing))
@henrik I see small optimization here, use extend
to provide common map of functions. This way you define them once.
(def recombobulate-common {:recombobulate identity})
(extend Object Recombobulate recombobulate-common)
(extend nil Recombobulate recombobulate-common)
does the threading macro work with swap!
? Ex:
(swap! app-state (->
(assoc :idx 1)
(assoc-in [:a :b] 3))
@donyorm it works if you put the threading macro inside a function
the arg to swap after the atom needs to be a function
you need (swap! app-state #(-> % (assoc :idx 1) (assoc-in [:a :b] 3))))
since (-> ...) doesn't return the function you want to call, but describes the function you would want
can someone help me with Java interop? i'm trying to convert the following example Neo4j plugin file to Clojure, but i'm struggling with the Java annotations.
https://github.com/neo4j-examples/neo4j-procedure-template/blob/3.1/src/main/java/example/Join.java
is this off to the right start?
(ns example.core
(:import [org.neo4j.procedure.Description]
[org.neo4j.procedure.Name]
[org.neo4j.procedure.UserFunction])
(:gen-class {:name ^{org.neo4j.procedure.UserFunction []
org.neo4j.procedure.Description ["This is the description"]}
example.core}))
(defn join [value]
(str "Echo: " value))
@joshkh a small thing - you can pick between import and fully qualifying the class names - either works alone and you never need both
import doesn't make classes load, referring to them does (it's a jvm thing) - import is for renaming
if join is supposted to be a method, it should be -join
you can change the prefix, it defaults to -
got it! updated:
(ns neoxj.core
(:import [org.neo4j.procedure.Description]
[org.neo4j.procedure.Name]
[org.neo4j.procedure.UserFunction])
(:gen-class {:name ^{UserFunction []
Description ["This is the description"]}
neoxj.core}))
(defn -join [value]
(str "Echo: " value))
any idea how i would use the @Name annotation within the join
method arguments?
public String join(
@Name("strings") List<String> strings,
@Name(value = "delimiter", defaultValue = ",") String delimiter) {
hmm - the docs don't indicate being able to annotate args https://clojure.org/reference/datatypes#_java_annotation_support
but by extension, I would assume it would look like (defn -join [^{Name "strings"} strings, ^{Name "delimiter"} delimiter] ...)
if it worked at all
method annotations can be done like so using gen-class
https://github.com/clojure/clojure/blob/master/test/clojure/test_clojure/genclass/examples.clj#L39
is there any difference between using the :gen-class key in ns
vs. say calling gen-class
at the bottom?
right, OK, so you annotate the method declaration in gen-class
I can't think of any reason to not use the :gen-class key if your file has an ns form (yes there are rare uses for files without ns forms)
the problem with the key version is that you need to reference the methods by name and they haven't been defined yet
why does that matter?
you are giving their names and not passing the vars, afaik
i think in this example foo
cannot be resolved in the ns
function:
(ns example.core
(:gen-class {:methods [
[^{Deprecated {} Override {}}
foo [^{java.lang.annotation.Retention java.lang.annotation.RetentionPolicy/SOURCE
java.lang.annotation.Target [java.lang.annotation.ElementType/TYPE
java.lang.annotation.ElementType/PARAMETER]}
String] void]]}))
(defn foo [])
that needs to be -foo
I find it surprising that this doesn't work...
also this is a part of clojure where you could easily reach a point where just writing a small java class that uses clojure via interop is a lot less work
by the way, you're right - cursive complains that -echo cannot be resolved, but it compiles just fine:
(ns neoxj.core
(:import [org.neo4j.procedure.Description]
[org.neo4j.procedure.Name]
[org.neo4j.procedure.UserFunction])
(:gen-class {:name ^{UserFunction []
Description ["This is the class description"]} neoxj.core
:methods [
[^{UserFunction []
Description "This is the join description"}
-echo [String] ]]}))
(defn -echo [^{Name "strings"} value]
(str "Echo: " value))
oh, so it's a cursive bug?
and I would have expected echo in :methods (you are describing the method that is visible) and -echo in the defn (you are supplying a thing to call for that method)
🍻 Hey guys, just thinking about online meeting 1 on 1 or in small group where we can look at some code, discuss about some issues and solutions. I would like to meet more Clojure people working remotely like me, so i can meet them only remotely 🙂 What do you think about it? Somebody would like to? 🙂
@kwladyka : a while back, we had a debate about the behaviour of reagent in #off-topic; someone fired up a http://livecoding.edu session, we tested it out for about 30-mins, and everyone found it highly instuctive
By http://livecoding.edu you mean https://www.liveedu.tv ?
yeah, sorry, http://liveedu.tv
the important part is that one person live streams their dev env, and everyone else watches / comments
some senior devs could take a day to make a dojo in a "how to do this thing" way, we can use tmate as a tool for everybody has a chance to change the code...