So Iβm looking for a GUI framework to use on desktop, something with minimal boilerplate. I think I can store my state in flat edn files.
Nevermind. Got tabs working just fine.
I usually end up with a DB anyway even if I start with flat files. You can try datalevin if you want to use datalog. Else an embedded db like sqlite or hsqldb might also work well.
How exactly does something like Datalevin work? Does it create a file? If so, what file? What format? Is there a default location?
I think you should compare it to sqlite: do you care in which format sqlite stores its db?
I more so want to be able to find it. Like I care if itβs a dotfile or stored in /tmp/ or something like that.
I just took a look at the datalevin binary.
$ dtlv --help
Datalevin (version: 0.4.9)
Usage: dtlv [options] [command] [arguments]
Commands:
exec Execute database transactions or queries
copy Copy a database, regardless of whether it is now in use
drop Drop or clear a database
dump Dump the content of a database to standard output
load Load data from standard input into a database
stat Display statistics of database
Options:
-a, --all Include all of the sub-databases
-c, --compact Compact while copying.
-d, --dir PATH Path to the database directory
-D, --delete Delete the sub-database, not just empty it
-f, --file PATH Path to the specified file
-g, --datalog Dump/load as a Datalog database
-h, --help Show usage
-l, --list List the names of sub-databases instead of the content
-V, --version Show Datalevin version and exit
Omit the command to enter the interactive shell.
See 'dtlv help <command>' to read about a specific command.
In the code you will refer to the db file as (def conn (d/get-conn "/var/datalevin/mydb" schema))
so it's pretty clear where it stores the data
Ah I see. Thank you for your help. Imma try understanding and implementing it now.
@c.westrom - This one looks promising
I think a reagent based tookit will be good as Iβm quite comfortable with hiccup.
Was also checking out electron.
I'm confused - if you're looking for desktop gui, why not use Swing
Some of the options on desktop are: β’ https://github.com/JetBrains/skija/ (no event handling afaik) β’ https://github.com/cljfx/cljfx clojure library on top of JavaFX β’ https://github.com/clj-commons/seesaw clojure library on top of swing β’ any cljs lib + electron β’ https://github.com/phronmophobic/membrane Obviously, I'm biased towards the last one (membrane)
Ok, maybe I donβt care about boilerplate too much. I could go with electron because itβs what I know and I have access to node for more flexibility.
I've used electron before and it works well
Anyone try using proton native with cljs?
Been there! π
Also, 1
is not a prime. π
@qmstuart Your solution seems to be the fastest by far out of all the ones posted so far though!
just for fun, a (relatively) faster version with transients
(defn sieve-mask [n]
(let [upper (inc n)
mask (transient (vec (repeat upper true)))]
(loop [p 2
mask mask]
(if (< n (* p p))
(persistent! mask)
(if (get mask p)
(recur (inc p) (reduce #(assoc! %1 %2 false) mask (range (* 2 p) upper p)))
(recur (inc p) mask))))))
(defn sieve [n]
(let [mask (map vector (range (inc n)) (sieve-mask n))]
(->> (filter second mask)
(mapv first)
(drop 2))))
(time (sieve 1000000))
;; => "Elapsed time: 485.8439 msecs"
Probably poorly optimized, would be interested to see how fast we could push thisI donβt know how fast it can be pushed, but know it can be pushed quite a bit beyond that nice piece, @eagonmeng
You can probably win some millisecs by starting with 3 and adding the 2 at the end.
how would you merge list of maps into a map? :thinking_face:
(apply merge [{:a 1} {:b 2}]) => {:a 1 :b 2}
@audrius are you looking for something like this
You could replay in a thread. That would remove a need to tag specific person and prevent from common mistake - tagging wrong person π
Sorry audrius, keep that in mind π‘
Hi everyone. I'm working on an SVG library and am wondering about idiomatic use of spec. I found myself creating a few predicate functions from my specs using s/valid? but wonder if this is actually a good way of using spec?
(defn pt2d? [a] (s/valid? ::pt2d a))
(defn pts? [s] (s/valid? ::pts s))
(defn element?
"Checks if `elem` is an SVG element."
[elem]
(s/valid? ::svg-element elem))
I use these functions (and specs) for :pre validation, but also inside conditionals from time to time.
(defn translate
{:pre [(s/valid?
(s/or :one (s/coll-of :svg-clj.specs/svg-element)
:many (s/cat :elems (s/coll-of :svg-clj.specs/svg-element))) elems)
(s/valid? :svg-clj.specs/pt2d [x y])]}
(let [elem (first elems)
elems (rest elems)]
(when elem
(cond
(and (specs/element? elem) (= 0 (count elems)))
(translate-element [x y] elem)
(and (specs/element? elem) (< 0 (count elems)))
(concat
[(translate-element [x y] elem)]
[(translate [x y] elems)])
:else
(recur [x y] (concat elem elems))))))
I have a hard dependency on spec in my library, and I don't know if that's a good idea, or if it's advisable to re-work things and make it unnecessary.
I have an open issue on the project related to this question. https://github.com/adam-james-v/svg-clj/issues/2
Any advice is greatly appreciated :)I don't see a problem with your usage of spec right now. Except that you maybe might want to add some explain output if things are not valid
Ya, I noticed while I was using it that I still asked "but why did that fail?" s/explain should help with that at least.
@adam.james It might also be interesting to look at malli, which is a more data driven approach to data validation. I am considering adding that to babashka if people are in favor of this. It's not an either/or between spec, but spec is still in development, whereas malli is already out of the alpha stage.
Hmmm... I'll give that a look/experiment a bit. The original thinking for spec was to 'use the official tools'. It's also why I stick primarily with deps.edn vs lein. But it's not a strongly held opinion of mine, so I'm willing to change. Thanks for the tip!
The official things aren't always better than community things, but it is a benefit that something is built-in.
What is the correct way to control the clojure random number generator. I see the functions https://clojuredocs.org/clojure.core/rand-int and https://clojuredocs.org/clojure.core/rand ? But I don't see the discussion of how to get and set the random seed, how to reset the generator to a previous state (e.g., for reproducing errors in functions which use random numbers), and how to assure (or whether it is assured) that new processes get their seed set the same way.
@jimka.issy It's probably better to use a library like clojure.data.generators or clojure.test.check for this
or raw Java interop
In particular, class java.util.Random provides an explicit method to set the seed, and a variety of methods to get different distributions/types of randomly generated values from such a generator.
https://docs.oracle.com/javase/8/docs/api/java/util/Random.html
There is also SecureRandom
Sorry, to help me understand. are you suggesting I should avoid rand, rand-int and rand-nth, and in stead use the java Random interface? Or are you suggesting that rand, rand-int, and rand-nth promise to use the java Random interface, so I can mix and match them freely?
the first, if you need seed
I believe that the JVM methods used by the Clojure function rand
has no way of setting a seed explicitly.
That is the reason for suggesting the former, if you want to explicitly assign seed values.
sometimes i run a lein run
command and after completion, the process doesn't exit, so I have to CTRL-C
to exit
anyone know why this happens or how I can prevent it?
@nbtheduke that depends entirely on the code that's being run, but a couple things you might check for are https://www.baeldung.com/jvm-shutdown-hooks and https://stackoverflow.com/questions/8695808/clojure-program-not-exiting-when-finishing-last-statement
if the code ever uses pmap
for example, there are going to be non-daemon threads running (which prevents the JVM from shutting down)
Thanks! I'm not using pmap
anywhere, but I do call require
instead of using :require
in the ns
macro. i'll poke around to see what i'm missing
turns out I had a call in another file that was doing somthing like that. thanks for the heads-up to both of you!
q: does anyone have a recommendation for clojure friendly jvm instrumentation ? Something like newrelic or dynatrace
Instrumentation for what purpose? Profiling? Perhaps this can be useful:Β https://github.com/jgpc42/jmh-clojureΒ (edited)
hmm. I'm looking to get metrics on our app's performance and to capture errors
There are obviously a number of choices; Elastic APM has worked fine for me. Quite easy to write your own simple wrapper around the Java agent API. Or I guess you can also take a wrapper such as https://github.com/Yleisradio/clojure-elastic-apm, provided to you by the Finnish national public broadcasting company.
@ivar We'll been using New Relic in production for years with Clojure and we've been very happy with it. A couple of caveats: if you're using a "non-standard web server", such as http-kit, New Relic doesn't support that very well (we switched back to Jetty to address this); adding Trace
metadata is a bit of a pain -- I blogged about that some years ago on https://corfield.org/blog/2013/05/01/instrumenting-clojure-for-new-relic-monitoring/ (and see also https://corfield.org/blog/2016/07/29/clojure-new-relic-slow-startup/ which may have been addressed in a later New Relic release but I think we still have that config in place).
ok, I'm familiar with newrelic from my days as a rails dev, so I think I'll start exploring that now that I know it's viable.. Thank you everyone for your feedback - very much appreciated!
Thoughts on this idea? I'm trying to turn a Trie data structure that is represented in Clojure as a HashMap (`{"D" {"O" {"G" {:val "DOG"} "T" {:val "DOT"}} :val "DO"}}`) into a "https://www.aclweb.org/anthology/W09-1505.pdf" which is just a raw array of bytes in a particular order. To work with that trie-as-a-byte-array data structure, I need some help navigating around the byte array. I was thinking some type of "cursor". It has a reference to the byte array, but all the iteration protocols are implemented by adjusting the location of the cursor. Something like this...
(defprotocol IByteArrayCursor
(loc [_])
(jump [_ loc] "Moves location of cursor to specified index.")
(forward [_] [_ n])
(backward [_] [_ n])
(slice [_ end])
(ba= [_ other-ba]))
(deftype ByteArrayCursor [ba loc]
clojure.lang.Indexed
(nth [_ i]
(if (and (>= i 0)
(< i (count ba)))
(ByteArrayCursor. ba i)
(throw (ex-info "Index out of bounds."))))
(nth [self i not-found]
(if (and (>= i 0)
(< i (count ba)))
(ByteArrayCursor. ba i)
not-found))
IByteArrayCursor
(loc [_] loc)
(jump [_ loc] (ByteArrayCursor. ba loc))
(forward [_ n] (ByteArrayCursor. ba (+ loc n)))
(backward [_ n] (ByteArrayCursor. ba (- loc n)))
(slice [_ n]
(loop [i 0 r []]
(if (or (= i n)
(>= (+ loc i) (count ba)))
(ByteArrayCursor. (byte-array r) 0)
(recur (inc i) (conj r (aget ba (+ i loc)))))))
Is this reasonable? Am I overlooking a simpler alternative? Am I not seeing any particular "gotchas"? Thanks for any thoughts anyone has.i think you're making a zipper. i'd check out that
Feel free to DM me with Qs if you run into issues with New Relic and Clojure @ivar
It seems odd that a 'cursor' implements a slice operation like that. If the cursor is really just an index into a byte array ...
thanks - the project I'm instrumenting uses aleph, so I have a feeling it fits in the 'non-standard' category
http://recurial.com/pldi19main.pdf may be up your alley
That's a good point. I might not need it. I'm basically doing a lot of packing and unpacking bytes. So I'll read one byte that says "The next 20 bytes make up that value you want to decode.". Then I'll take a 20 byte slice and send it to the decode function. That decode function also makes use of the cursor functionality. But it eventually reads all the way to the end of whatever its given. I guess another type of interface that would give me the functionality of being able to read from the start to the end of some bytes in the middle of a byte array would be a "view" rather than a "slice".
Definitely. I was able to get some way with http-kit by explicitly telling New Relic to instrument certain classes/methods via configuration. Not sure if I still have that on hand but I can search our repo history for it if needed.
are you aware of java.nio.ByteBuffer?
(it is super mutable, which is meh)
but it basically does all those things
My thought when seeing spec wrapped up in :pre/:post is that you may want to look at using s/fdef
in concert with either clojure.spec.test.alpha/instrument
(which will verify that that function arguments match your spec) or the orchestra
library which does similar but also checks that function outputs are what you specify
You may want to drop into #clojure-spec if you want to discuss in more detail
I just tried out the clojure-metrics
library the other day for the first time, it may have some useful tools for you. https://github.com/metrics-clojure/metrics-clojure/
Oh interesting. That looks like a great idea. I think a wrapper around ByteBuffer will be nice.
We just recently migrated from New Relic's old plugin architecture (and their ancient metrics Java lib) to the new Telemetry SDK stuff which provides access to their Metrics API as well as Logging API and a couple of other APIs. Apart from the resolutely Java-focused API design, it was pretty easy to get it all integrated and working. We publish a lot of custom application metrics. (I ranted about this SDK on Twitter recently because of the custom types it uses to try to encapsulate what could just be a regular hash map!)
Hi there, folks. Iβm trying to sort a map with an initial decreasing numeric sort and a tie-breaker alphabetical sort.
[{:name "Andy", :score 22} {:name "Charlie", :score 25} {:name "Bruce", :score 25} {:name "Xerxes, :score 7}]
This should sort to be:
[{:name "Bruce", :score 25} {:name "Charlie", :score 25} {:name "Andy", :score 22} {:name "Xerxes, :score 7}]
The tie of β:score 25β is resolved alphabetically by the :name field.
Iβve looked at sort-by
and it shows examples of tie-breaker sorts. I see examples of https://clojuredocs.org/clojure.core/sort-by#example-542692cbc026201cdc326c2c with juxt
, and examples of overriding with https://clojuredocs.org/clojure.core/sort-by#example-57ae5e86e4b0bafd3e2a04f1 with >
. However, Iβm having problems finding examples that combine the two. Can someone help? Thanks in advance!@scotto (juxt (comp - :score) :name)
is probably good enough for your needs here?
Although your data seems to have a string for the :score
for "Andy"
-- is that true? (that scores can be strings or numbers)
If you have to deal with potential strings sorting as the number they represent, you'll need a helper function in there, something like (fn [s] (if (string? s) (Long/parseLong s) s))
-- which can go in the comp
between -
and :score
Oops, I did not mean a string for Andyβs score. π Thanks for the catch
looks like I have the go-ahead to change our webserver from aleph to jetty, so that's step one. I'm hoping it's as straightforward as it seems π€
speaking of Andy https://clojure.org/guides/comparators is a guide for writing and using comparators in clojure, which is another way to do this
Iβll check it out.
Wow @hiredman - That page is excellent and thorough! Thanks!
Also, I had to scratch my head a while about the minus sign in @seancorfieldβs example above. I think the minus sign is a negative-making function, so sorting by the scores negatively sorts them descending. Thatβs a nice little trick! Thanks!
(comp - :score)
= (fn [data] (- (:score data)))
or (fn [data] (- 0 (:score data)))
There's also clojure.core/unchecked-negate
is it possible to load a clojure script file from java, and then execute a function from that clojure file?
if you mean a clj file, yes it's pretty easy https://clojure.org/reference/java_interop#_calling_clojure_from_java
one call to require the ns, another to lookup the function, then you can invoke it