This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-04-26
Channels
- # beginners (20)
- # cider (59)
- # cljsrn (6)
- # clojars (7)
- # clojure (91)
- # clojure-boston (1)
- # clojure-dusseldorf (3)
- # clojure-finland (1)
- # clojure-italy (8)
- # clojure-losangeles (1)
- # clojure-nl (16)
- # clojure-spec (25)
- # clojure-uk (113)
- # clojurescript (126)
- # core-async (27)
- # cursive (5)
- # data-science (3)
- # datomic (22)
- # emacs (24)
- # fulcro (30)
- # garden (7)
- # graphql (7)
- # leiningen (3)
- # nginx (1)
- # off-topic (63)
- # onyx (13)
- # portkey (1)
- # re-frame (1)
- # reagent (28)
- # shadow-cljs (92)
- # tools-deps (1)
- # uncomplicate (1)
- # vim (24)
- # yada (8)
Is printing a list like (1 2 3)
instead of '(1 2 3)
a mistake in design in clojure? often I want to paste some printed value to test something in the REPL, but I have to change these to make it work
the REPL tries to evaluate the first element of a list so when you give it (1 2 3)
it will look up 1
and attempt to evaluate it with args 2 and 3... that is why you give it (quote (1 2 3))
or shorthand '(1 2 3)
as in 'treat this as a list and don't evaluate the first element of teh form'.
when it prints there is no need for that.
difficult to articulate sorry ... or i may be absolutely wrong 😓
x is unbound (unbound != nil)
how do I make a type support the seq function such that it can be used in map/reduce etc? I think the idea is to use extend-type
but I'm tripped up by needing to provide an interface
definitely - the interface here is clojure.lang.ISeq
the core Clojure collection/seq interfaces are all Java interfaces internally
I have a lot more about this in Ch 2 of Clojure Applied
so lets say I'm interop working with a 3DPoint
that supports .x
.y
and .z
and I want to be able to map over those three values.
(extend-type 3DPoint clojure.lang.ISeq (seq [point] [(.x point) (.y point) (.z point)]))
well, you’re returning a vector, which is not an ISeq
so wrap (seq …) around that
ISeq doesn’t have a seq method
what might be more useful for you here is to implement clojure.lang.Seqable instead
(extend-type 3DPoint clojure.lang.Seqable (seq [point] (seq [(.x point) (.y point) (.z point)])))
that is, make 3DPoint something capable of returning a seq
all of the core sequence functions will coerce their arg to a seq when invoked and know how to do so for Seqables
😅
(extend-type UnityEngine.Vector2 clojure.lang.Seqable (seq [point] (seq [(.x point) (.y point)])))
System.ArgumentException: clojure.lang.Seqable is not a protocol
at clojure/core$extend__9637.invokeStatic (System.Object , ISeq ) [0x00000] in <filename unknown>:0
at clojure/core$extend__9637.doInvoke (System.Object , System.Object ) [0x00000] in <filename unknown>:0
at clojure.lang.RestFn.invoke (System.Object arg1, System.Object arg2, System.Object arg3) [0x00000] in <filename unknown>:0
at game/core$eval__38124__38136.invokeStatic () [0x00000] in <filename unknown>:0 => at game/core$eval__38124__38136.invoke () [0x00000] in <filename unknown>:0
This might be an artifact of the fact that I'm working with ClojureCLR@alexmiller Yeah I know. I was testing if a var had some value, but I should have used https://clojuredocs.org/clojure.core/bound_q (which I discovered only now!)
Also, this is one area which differs in ClojureScript: https://clojurescript.org/about/differences#_vars_and_the_global_environment
@idiomancy ah right, because this is an interface it really needs to be embedded in the type you can’t extend independently. sorry wasn’t thinking clearly. Depending on your end goals, there are other possibilities via CollReduce protocol
@nicola you can do what you are asking with comp
if I understand your question
(comp (filter even?) (map inc))
is a transducer composition
but to move to a transducer you need a transducing context, and that's going to depend on what's going on in ->> and maybe on what's consuming it
(->> foo
(filter even?)
(map inc)
(partition 2))
(into [] (comp
(filter even?)
(map inc)
(partition 2)
foo))
the translation tends to be very easy, but it's not something a regex can do
you’ll notice some similarities there
and you could just dogmatically replace one with the other, but I think you’d be doing a disservice to the options transducers open up
and transducers are not always better than sequences
there are tradeoffs about when to use one vs the other
so I guess back to the original question, I think you should not want the thing you’re asking for :)
@alexmiller any idea where I could read up more on strategies like that? RE: collreduce
nothing official
if your goal is to apply a transformation (anything transducer like) to a collection, then supporting reduce is sufficient to do anything transducers can do
The base interface for reduction is IReduceInit (and it’s slightly expanded child IReduce). If you control a type, I would recommend implementing one of these. But there is a protocol path into this interface as well called CollReduce and that’s good for types you don’t control as protocols can be extended to any type.
http://clojure.github.io/clojure/clojure.core-api.html#clojure.core.protocols/CollReduce
so you could extend like:
(extend-type 3DPoint CollReduce (coll-reduce [point f val] (reduce f val [(.x point) (.y point) (.z point)])))
hmm, seems like were almost there. throwing some kind of complaint about wrong number of args passed to core/eval but this is really good intell, I'll be playing around with this!
I only implemented one of the coll-reduce fns there ^^ should probably do the other arity too
(extend-type 3DPoint
CollReduce
(coll-reduce [point f] (reduce f [(.x point) (.y point) (.z point)]))
(coll-reduce [point f val] (reduce f val [(.x point) (.y point) (.z point)])))
but no guarantee on when (you are at the whims of the GC)
it is certainly possible to create a large number of them that stick around until there is memory pressure
and in extreme cases, blow your heap (if you are created them faster than the GC can notice and remove them)
it’s different in that keywords are cached/interned
via WeakReferences
which can be GC’ed but are not the first thing GC’ed
and then there is a reference queue that is used to notice this cleaning, which can lag
there’s an additional level now too in that keywords are made of strings and Java 8 (with a flag) and 9+ (by default) de-duplicate strings in the GC automatically
so for example, if you are creating namespaced keywords, you might have many keywords that share the same namespace string and all of those strings will actually only be stored once in memory by the GC. I did some tests when this first came out, and it definitely has a (positive) effect around keywords.
@alexmiller I don't think string de-dup is on by default in 9+
you’re right
[~]$ java -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version | grep StringDedup
uintx StringDeduplicationAgeThreshold = 3 {product} {default}
bool StringDeduplicationRehashALot = false {diagnostic} {default}
bool StringDeduplicationResizeALot = false {diagnostic} {default}
bool UseStringDeduplication = false {product} {default}
java version "9.0.1"
so you’d need to set UseStringDeduplication
try it out, might be useful
Is there a reason why the clojure cli tools should not run on windows? the clojure-tools is a jar file that should run anywhere I guess and the clj and clojure files are linux executables presumably?
I’ve done a lot of work on this, just haven’t had time to finish it off
if you have knowledge on git+ssh and git+https configuration in windows (Specifically how ssh-agent and git-credential-cache) I'm sure #tools-deps would appreciate you hanging around
@ghadi My knowledge in these things is close to non existent except using it a bit. But I'd be willing to test drive everything windows related.
Since I'm on Windows 10, I do all of that sort of dev work in Ubuntu via WSL. clj
etc works great there 🙂
@U04V70XH6 You also use cursive / intellij idea if I remember correctly. Does that mean you access the files on ubuntu via /mnt/c/Users/...
and with intellij via the windows folder structure like c:\Users\...
.
Does that work seemlessly?
I use Atom/ProtoREPL, so my source is all on C: and therefore in Ubuntu it's /mnt/c/...
So editing and using the REPL is on Windows. Any command-line stuff is purely Ubuntu tho'.
Is there a way to write high performance code in C, Java, Kotlin, Rust, ... where: 1. we can call it from Clojure 2. the same code also compiles to webassembly, and we can call it from CLJS