This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-12-30
Channels
- # adventofcode (7)
- # announcements (9)
- # babashka (20)
- # beginners (182)
- # calva (9)
- # cider (20)
- # circleci (3)
- # clj-kondo (1)
- # clojure (269)
- # clojure-europe (2)
- # clojure-india (1)
- # clojure-italy (6)
- # clojure-nl (5)
- # clojure-uk (50)
- # clojurescript (56)
- # code-reviews (3)
- # core-async (174)
- # datomic (4)
- # duct (1)
- # emacs (3)
- # events (1)
- # fulcro (31)
- # graalvm (10)
- # graphql (8)
- # jobs (1)
- # joker (11)
- # juxt (7)
- # luminus (2)
- # malli (4)
- # off-topic (2)
- # overtone (1)
- # pathom (2)
- # re-frame (24)
- # shadow-cljs (42)
- # sql (1)
- # tools-deps (10)
any thoughts on the right datastructure to represent a guitar fingerboard? I am building something where any of the 2048 subsets of the chromatic scale are represented as some combination of 1 b2 2 b3 3 4 b5 5 b6 6 b7 7 (always containing 1 (example: [1 b3 5 b6 7]) I want to render these on an ascii fretboard using their proper note name according to the key they’re being played in. Example: [1 b3 5 b6 7] in the key of G major is G Bb D Eb F# (because Gmaj has 1 sharp, F#)
It depends, seem like order matters, and you'd be able to use indices to access certain ones. So vector of vectors sounds pretty good to me
@ludvikgalois good question. i’m kind of figuring this out as I go. I’m building a practice tool based on Wayne Krantz’ Improviser’s OS 2nd edition.
http://azzang.github.io/audible-math/ is an example of something that let’s you browse the combinations by clicking and hearing the tones of any “formula” (1 b3 5, for example is a formula). I’d like to go a little further and generate exercises and diagrams for various “formulas”
this may mean being able to do analysis for any representable chords within a “zone” (4 fret section of the fretboard), search for related formulas, etc.
it’s kind of an exploratory thing right now. i built something simple which does the basic thing: 1. It generates all combinations of the chromatic scale 2. You can select any combination and play it 3. You can take a combination and find any nameable (common or exotic) scale that matches it
However, it does not take into consideration key signatures, so while the resolved note may be enharmoic, it does not represent the context of the key. For example, D# may be printed, but in context it’s actually named as Eb, because it’s in Ab major
https://gist.github.com/devn/5ffa260ef0384580a498d4b44d2b6669 is what I have so far if anyone is interested.
It’s a bit of a mess. Representations shift between midi note numbers, total number of semitones from the root, scale pattern, and the actual nameable notes (like C#4). It feels dirty to have all of these representations.
but, I was trying to take advantage of what Overtone already had. Maybe there’s some good rationale for the definition of REVERSE-NOTES https://github.com/overtone/overtone/blob/master/src/overtone/music/pitch.clj#L90 here, but it seems to ruin any notion of resolving correct note names by key for a midi note number
@devn I'm not sure how far down the rabbit hole you want to go, but I believe you might be interested in "Pitch Class Sets", which is a very interesting approach to modeling music theory. This (http://www.jaytomlin.com/music/settheory/help.html) seems like a decent introduction (without going all the way to a Music Theory textbook). You would have to project the pitch classes back onto a fretboard, but once you wrap your head around music theory as sets, the projection will likely be the easy part. (A fun aside, writing programs for this in University is what made me decide to switch to a Computer Science major)
scrolling through, i had in my head that there was some connection to a matrix, but was unsure how to proceed
The matrices are just scratching the surface. This is means to leverage the rigor of discrete math + graph theory in the context of music. This will also unlock the gateway to transition between different musical keys in ways that classical tonal theory say shouldn't exist.
yes, that’s really what im interested in. part of this book is about finding those things on your own
im less interested in the composition side, and more interested in the improvisation, but they can’t exist without one another. If I pick a random key and formula, I would love to be able to find good candidates to explore instead of sitting there working through 2048 combinations of the chromatic scale
“Computer, tell me all of the most likely tonal planets which orbit 1 b2 b5 7 that could sustain life in Gmaj”
The program I mentioned writing up above was a graph traversal tool. "Given that I'm at chord X in key foo, and I want to get to chord Q in key L, find me all the paths from X to Q with the most parsimonious motion. Play it. Ok, Try some different inversions, expand the path, enhance, ok, perfect. Project that back into sheet music (fret board)"
This is a frequent thing I sit there and work out on my own, though without any serious degree of rigor beyond my own ear
I’ll play some phrase that’s “out” and try to make it “in”, and then try to find paths from or to it
as a tool for improvisation it would be really cool to generate interesting ways to get home, and then mark paths as interesting as i play
have footswitches to expand or contract the paths, the features that the pathfinding uses, etc.
The biggest takeaway I hope to give is to not represent sharps/flats as b2
or a keyword, but to use the pitch sets. Then you can more easily reason about which notes are in multiple keys at the same time, without worrying about representation.
I hope you have fun, I lost months of my life to exploring this topic. And you may have just inspired me to dive back in haha
so i play some phrase on my guitar, midi pitches hit the computer, it thinks im playing in 7/4 and loosely in F. it comes up with an idea and tries it out. I respond, repeat.
@joe.lane that’s a really valuable suggestion. this book i’m reading gets to the end and starts talking about formulas and their application: … 3. as containers of subsets 4. as superimpositions into tonalities that contain them as subsets 5. as superimpositions into tonalities that don’t contain them as subsets
@joe.lane FWIW, if you’re interested in working on something, DM me. Sounds like you know good deal more on this topic and I’d love to collaborate
@joe.lane one question I suppose I have is: as far as improvisation is concerned, would you still be advocating for thinking in pitch sets?
is there any valuable reason to prefer a dumber representation when not in front of a computer that can crunch the numbers?
You're technically off by 1, but yes, that looks right (thats how I would represent it on a computer anyways 0-11 not 1-12.)
if it’s not too much trouble i’d love links to those dissertations or at the very least some titles to peruse
I think it's extremely valuable to understand pitch sets because it will force you to understand the relationship of subsets of notes within your chords as they relate to their positions in other possible chords you could transition to. That being said, I wouldn't "think" in pitch sets, because they are far too low level, but they will inform whatever higher level model you're going to use. Be it the normal "tonal" model, or something like a more "modal" approach which doesn't adhere to the concept of a key with a tonic. In either case (you may come up with a third!) pitch sets are the underlying model.
RE: Dissertations, I can send you a photo of their titles or type them out. whichever you prefer. I got them off of JSTOR so you may need to go to a Library for access.
finally, on one level i can’t believe my luck in receiving such an interesting set of replies, but on another i was slightly unsurprised to find multiple clojure projects that were focused on this book Improviser’s OS.
No problem, I can't tell you how much joy it brought me to revisit this part of my life.
1. Enharmonic systems: A theory of key signatures, enharmonic equivalence and diatonicism 2. Cross-Type Transformations and the Path Consistency Condition
finally, interesting enough, i think i basically wound up at pitch class sets before we started chatting about this:
(map INTERVAL-LOOKUP '(:1 :b3 :b5 :5 :6 :7)) ;;=> (0 3 6 7 9 11)
Well, you guys are discussing two parallel things. One is the correct musical model, and the other is the correct data-structures for that model 😛
Can't help with #1. But, when it comes to data-structure, its mostly about optimizing queries.
And I feel in your case, you'd probably eventually end up with multiple representations. Like instead of having a single data-structure that you navigate for everything, you might want to have a few different one, even if they duplicate the content, it seems like the structure of the content matters a lot, and you might want multiple structures exposed
The thing is that queues are most useful between threads or cases where identity can be maintained over the stateful data structure. We have a better solution for that - core.async channels (or even Java queues). The only place I use the persistent queue is in a single-threaded algorithm over a graph or a tree. This is way less common than the other persistent structures.
My personal opinion is that I do not think queues deserve a literal. I do think it would be worth making the queue
constructor and predicate queue?
@U064X3EF3 “between threads or cases where identity can be maintained over the stateful data structure.” Can you elaborate on this? How is it related with a fifo data structure?
Because it is a persistent queue, changes result in a new queue instance. If you have two threads, you need an identity that both threads can hold on to, like an atom that wraps the queue.
A shared queue is inherently stateful (identity + value) and the persistent queue is just the value part. Core.async channels are both and much better suited to this than pqueue+atom
@i https://clojure.atlassian.net/browse/CLJ-976 It's been discussed (several times).
Its just not a data structure people use enough I think to motivate the work to bring it in as first class
Though now that CLJS has it, it might be a better argument to just copy what they did, dunno
Yeah, I asked about it nearly eight years ago (in the Google Groups thread linked in that ticket). But the reality of those eight years since is that I've hardly ever used the persistent queue data structure and certainly not enough to be bothered by the lack of a literal syntax for it so...
I don’t use it much in practice, but when tinkering with ideas it’s nice to have it printed readably
Ya, its also, since the proposed syntax anyways is just a default reader literal, anyone who really cares can add it themselves to their own code base
I don’t think the general line has changed: PersistentQueue’s lack of polish suggests you should stop and think whether you want what it’s offering. I might be overstating but I think it’s the case that no part of the clojure core codebase uses it, unlike every other data structure defined by the language.
Well, its that everything needs to be vetted by Rich Hickey, and that's a good thing in my opinion. But it also means that priorities go to high impact issues.
And my impression is there's a philosophy of good enough that plays into priorities as well. Persistent Queue feels good enough that when you need a queue, you'll manage with it
Also, I feel, when do you reach for a queue? I can only think of distributed or concurency use cases, and for that, you'd either use SQS/RabbitMQ directly, or you'll want a BlockingQueue or a core.async channel
@devn for a tool for improvising, a solver for the 5 species of counterpoint could be useful
@ghadi you owe me a DM along with will. ;) Interested in talking about the practical applications.
if you take the complete opposite approach that AWS took with Deep Composer you'll be golden 🙂
a lot of the stuff of counterpoint I’ve heard and worked through was sickeningly sweet and doesn’t even come close to anything approximating improvisation, though it may not claim to
I'm working on a macro to wrap functions that accept success and error callbacks and return a Manifold deferred value (like a promise), but having some trouble. When evaluating a defn
using this macro, I get:
Unable to resolve symbol: de__31544__auto__ in this context
I tried removing pieces and testing, so I think it's the references to de#
inside the callback fns. Is it something about nesting a syntax quote section inside an unquote section?From https://clojure.org/reference/reader#syntax-quote: "All references to that symbol within a syntax-quoted expression resolve to the same generated symbol."
Nested syntax-quoted forms are still different forms.
You can just run macroexpand-1
on your macro and see for yourself.
If callback-accepting-fn
is a regular function call, you can use something like
(defmacro defer [callback-accepting-fn]
`(let [de# (m/deferred)]
(~@callback-accepting-fn
(fn [~'response] (m/success! de# ~'response))
(fn [~'error] (m/error! de# ~'error)))
de#))
(although, it should work for any iterable, not just a list that represents a function call).
And your variant with concat
could be written as
(defmacro defer [callback-accepting-fn]
(let [resp-fn `resp-fn#
err-fn `err-fn#]
`(let [de# (m/deferred)
~resp-fn (fn [~'response] (m/success! de# ~'response))
~err-fn (fn [~'error] (m/error! de# ~'error))]
~(concat callback-accepting-fn
[resp-fn err-fn])
de#)))
And you don't need to use auto gensym for response
and error
since they cannot affect any scope. Using auto gensym here is actually a bit detrimental as it makes the functions' signatures worse.
Also, I'd say that using ~@
is much more idiomatic than using concat
. But if you really need concat
, please tell me why - maybe I don't know something.
How do you run workers in async? I have mysterious issue:
(defonce queue (chan 100))
(defonce queue-warehouse (chan 100))
(defonce worker
(go-loop []
(let [job (<! queue)]
(l/debug "run job" job)
(when-not (nil? job)
(<! (thread
(try
(job)
(catch Throwable ex
(l/error ex)))))
(recur)))))
(defonce worker-warehouse
(dotimes [x 3]
(go-loop []
(let [job (<! queue-warehouse)]
(l/debug "run warehouse job" job)
(when-not (nil? job)
(<! (thread
(try
(job)
(catch Throwable ex
(l/error ex)))))
(recur))))))
One per 2-4 weeks both workers stop doing jobs at the same time. I have no idea why.
Can channels close themself for any reasons?Do you have something that consumes data from worker channel?
(defonce worker (go-loop …
returns a channel so it is possible to overflow default capacity if nothing is consuming data from it
you can also run https://visualvm.github.io to check if something is blocking or overusing queues
we are using JMX on production
> what is the best solution to run workers and not have this issue? run separate and independent worker for each incoming message
right now your code consuming data to process and start processing in the same thread. it is better to keep those stages separated
do you mean
(>!! ch f)
and run
(thread
(try
(<! queue)
(catch Throwable ex
(l/error ex))))
I am confused… What is the point of async if I can’t have workers? I could run thread instead of channels then
I’m not sure that core.async is the best way to handle queue/workers pattern)
it is always better to handle messages synchronously to track all problems and deadlocks.
But i’m not pro there, probably worth to ask in #core-async
Uch I was learning async so long time ago. I don’t remember it deep right now. I have to refresh my memory.
What JMX exactly do? As I can see it lets connect by port to JMX and run some queries like `
:HeapMemoryUsage
Why not remote REPL then?You can not get all information (or at least I don’t know how) from running repl. state of threadpools as an example
Internal threadpools dedicated for core.async
I'm also not super knowledgeable in core.async. But, I'm curious, what's the point of using core.async here? Just so you can run warehouse jobs and worker jobs concurrently?
It also seems a bit weird, you recur all the time, but as soon as job is nil, it means the channel has closed
(go-loop []
(if-let [job (<! queue)]
(do
(l/debug "run job" job)
(thread ...)
(recur))
(l/debug "Closing!")))
This code looks pretty good to me btw. I think the key is to first add enough code that you can diagnose why things stop when they do. Is the problem with adding jobs (channel is full), taking jobs (channel is empty), or go blocks not running (usually b/c they are doing io and blocked).
The last one is pretty easy to spot from a thread dump
And by the way (when-not (nil? job) ...)
is same as (when-some job ...)
I added more logs and we will see after a few weeks. At least I will close a few hypothesis.
I used to always go with apply
but recently ran into a case where reduce was many times faster, I think because it avoided having to allocate the entire sequence
There are cases where I use apply over reduce, its when I want to tack on some extra numbers to add
Another somewhat stylistic question - are there semantic differences between the following forms?
(assoc data
:foo (something)
:bar (something-else))
(into data
{:foo (something)
:bar (something-else)})
(merge data
{:foo (something)
:bar (something-else)})
I almost always use assoc
and assume it's faster (haven't done benchmarks), but noticed others using into
quite frequently
into
should be the fastest because it utilizes transient collections when they're available. But arguably, it has a more vague semantics because with assoc
and merge
you're pretty sure that you're working with associative collections.
I don't think you should care about the fastest option unless it's a bottleneck in your application.
I almost always use assoc
when the set of keys and values is known since it has the clearest display of intent IMO.
What is there out there for sandboxing Clojure using whitelists? Clojail hasn't seen an update in 9 years
https://github.com/huahaiy/clojail this seems to be a somewhat updated fork
@U2APCNHCN sci can do that: https://github.com/borkdude/sci/
if that's not sufficient, I have an up to date fork of clojail as well: https://github.com/borkdude/clojail (
this is used in tests for speculative: https://github.com/borkdude/speculative
The author passed away. It might have been forked and picked up by clj-commons or someone else though.
I'm trying to get clj-kondo set up, but it doesn't seem to like Orchestra's defn-spec
. Anyone know what function lints quite like that, or how to go about writing one if none exists?
Fwiw, you can use this alternative: https://github.com/danielcompton/defn-spec
which can be linted as schema.core/defn
what you can also do is put a (declare my-fn)
before the call to defn-spec
and ignore the call to defn-spec
via the config. this way clj-kondo will know that there is a var with the name my-fn
Yeah, that would be a lot of clutter/maintenance. I might actually look into the other one
If only I didn't already have a ds
as a standard prefix in my code.
(ns foo {:clj-kondo/config '{:linters {:unresolved-symbol {:exclude [(orchestra.core/defn-spec)]}}}})
(require '[orchestra.core :refer [defn-spec]]
'[clojure.spec.alpha :as s])
(declare get-meow)
(defn-spec get-meow any?
[meow-map (s/map-of keyword? any?)]
(:meow meow-map))
(get-meow)
`Thanks for the help. I think I'm going to explore this other one.
The complete picture with the other one:
(ns my.ns
{:clj-kondo/config '{:lint-as {net.danielcompton.defn-spec-alpha/defn schema.core/defn} }}
(:require [net.danielcompton.defn-spec-alpha :as ds]
[clojure.spec.alpha :as s])
(:import [java.time ZonedDateTime]))
;; Predicate definitions elided for brevity
(s/def ::instant any?)
(s/def ::zone-id any?)
(s/def ::zoned-date-time any?)
(ds/defn to-zoned-dt :- ::zoned-date-time
[instant :- ::instant
zone-id :- ::zone-id]
(ZonedDateTime/ofInstant instant zone-id))
Unfortunately, it looks like that one doesn't work with clojurescript
Hmm, too bad. Maybe post an issue about this at clj-kondo and I'll give it some thought
Using logback for logging in clojure is there a clear way to write to the Mapped Diagnostic Context?
I need some help with launching a custom server and figwheel together via lein.
I’m following the instructions outlined on the figwheel main docs site. While it illustrates how to run a custom server with the Clojure CLI, I’ve been unsuccessful at getting it to work with lein.
I’ve a scripts/server.clj
and I am running it as lein do exec -p scripts/server.clj, fig
where fig is an alias that starts figwheel.
What happens is that the scripts/server.clj
launches, but somehow, figwheel doesn’t. join?
in run-jetty is set to false
does it work if you do them as two separate commands?
Yes it does
And so cool too, but no idea why the lein do exec doesn’t
One thing though, the fig task is a trampoline
This is really confusing. The standalone server starts just fine, and independently figwheel.main when launched via leiningen also launches fine
But put them in a lein do, and it doesn’t
Which makes sense since the script is a server and putting it in a do will not yield at all, but how does clojure -i achieve the same?
@duck I don’t think this can be done via lein alone. You will have to do it programmatically. Think about it, lein will launch a server and that process won’t stop till the server exits, so lein can’t do a thing to launch figwheel
Another way to do it is to have lein launch a target other than figwheel main which calls figwheel main and requires the server somehow
Is it possible to launch figwheel as a mounted component? (in certain environments)
That's something I might want to look into myself so that figwheel starts even before I connect.
Yes. figwheel has api exposed and can be programmatically started
Hi - is this odd?
> (.format (ZonedDateTime/now (ZoneId/of "UTC"))
(DateTimeFormatter/ofPattern "YYYY"))
"2020"
My software is breaking, anyone else experiencing this?It is not 2020 yet in UTC afaik:
> (ZonedDateTime/now (ZoneId/of "UTC"))
#<java.time.ZonedDateTime@5723da7f 2019-12-30T17:11:17.712Z[UTC]>
Y is used for week based years
which causes this kind of thing
@markmarkmark - thanks, friend.
no problem
@hhausman what environment are you using that prints using the style:
#<java.time.ZonedDateTime@5723da7f 2019-12-30T17:11:17.712Z[UTC]>
@ghadi - that was copy/pasted from my CIDER repl. Not sure if that's the default output style - I use puget for pretty printing.
(java.time.ZonedDateTime/now)
#object[java.time.ZonedDateTime 0x832285c "2019-12-30T12:53:28.767326-05:00[America/New_York]"]
howdy! I am reading a csv file that a header contains comas (i.e. :this,is,a,key
) I tried to do a rename-keys but I get a unable to use symbol
when the keyword contains a comma. I though about making the keyword in to a string replacing the comma with "'
to remove it. How can I correct the keywords by removing the comas and keeping the values as they are?
I thought about using [(keys col) (val coll)]
but I am positive I can get the keywords and the values in a complete different order
keys
and vals
are guaranteed to return the items in the same order
(val is incorrect, I assume a simple typo)
Hello, I get the following exception java.lang.IllegalArgumentException "Don't know how to create ISeq from: java.lang.Character" when I try to call this function
(defmacro info
"Log at the info level"
[& args] (apply info-impl args))
Which library is it @huthayfa.ainqawi?
You'd better ask them how you're supposed to use it then...
without knowing the definition of info-impl
it's hard to say what's wrong...
Having a macro that doesn't use a syntax quote for the form it expands to looks a bit suspicious.
Can you show us the info-impl
function (or, more likely, macro)?
(defn ^:no-doc info-impl
([msg] (info-impl {} msg))
([ctx & args] `(cambium/info (into default-context ~ctx) (str ~@args)) ) )
`(into {} "msg") IllegalArgumentException, don't know how to create ISeq from clojure.lang.Character`
Where I'm guessing you can optionally add key/values to that map and it'll show in the logs
A small pedantic correction - into
does accept strings (`(into [] "abc")`). The issue is that a character cannot be turned into a MapEntry
.
"msg" perhaps is not a good ctx 🙂
@UECLGBLES Don't import it. Just use the fully-qualified name where you need it.
you would confuse the hell out of people who would not expect Float to be java lang Float 😄
(info "msg") works fine ? 🙂
@kulminaator yeah I tried that
i suppose (info {} "msg" "msg") also would ...
Tell that team to start writing docstrings so folks know how to use the library! 🙂
nobody needs docs .... until you need them 😛
It looks like (info "msg")
and (info {} "msg" "msg")
both ought to work tho', per @kulminaator @huthayfa.ainqawi
And, preferably to not have multiple arities with different meanings for a particular argument on the same spot ^^
@kulminaator @seancorfield Thank you!
I agree with @lennart.buit -- that's not good design so maybe open an internal issue about that too @huthayfa.ainqawi (in addition to asking for docstrings to be added!)
how can I set an environment variable? tried using System/setProperty
but when I try accessing it via System/getenv
it's nil
properties and env vars are separate things
there's no portable way to set an env var in the vm - there's code that's unix-only that does this via jni
(via third party libs)