Fork me on GitHub
#clojure
<
2019-05-21
>
tanners03:05:44

I'm trying to get the duration of some mp3 files, anyone around that can point me in the right direction for doing that with clojure?

tanners03:05:31

Yeah thats what I came across as well. Looks like thats what I'll be going with, thanks

souenzzo15:05:25

There is some static clojure parser, that support reader macros, reader-eval and maybe read some "unreadble" things like #object[...]

Alex Miller (Clojure team)15:05:35

in what way do LispReader.java or tools.reader not satisfy the bill?

souenzzo15:05:30

(LispReader/read (new PushbackReader (io/reader (.getBytes "[#=(prn :ok)]"))) {})
;; -- expected
;; => [#reader-eval (prn :ok)]
;; -- actual
;; :ok ;; printed
;; => [nil]

Alex Miller (Clojure team)15:05:11

so you want read-eval to not eval?

😬 4
Alex Miller (Clojure team)15:05:42

well then, no that doesn't exist afaik :)

vlaaad15:05:17

maybe rewrite-clj can read that?

vlaaad15:05:27

it even preserves comments and whitespace

souenzzo15:05:46

I will look too. But tools.reader seems to be OK for now

bronsa15:05:11

depending on how desperate you are

user=> (require '[clojure.tools.reader :as r])
nil
user=> (defrecord reader-eval [v])
user.reader-eval
user=> (with-redefs-fn {#'r/read-eval (fn [rdr _ opts pending-forms] (reader-eval. (#'r/read* rdr true nil opts pending-forms)))} #(r/read-string "[#=(prn 1)]"))
[#user.reader-eval{:v (prn 1)}]

👍 4
souenzzo15:05:56

(binding [clojure.tools.reader/*default-data-reader-fn* (fn [tag value]
                                                          {:tag tag :value value})]
  (with-redefs [clojure.tools.reader/read-eval (fn [rdr _ opts pending-forms]
                                                 (#'clojure.tools.reader/read* rdr true nil opts pending-forms))]
    (clojure.tools.reader/read-string
      {:read-cond :preserve}
      "[#=(prn :ok) #?@(:clj [1] :cljs [2]) #object[] ::foo]")))
I think that I will use tools.reader

souenzzo15:05:43

Just need to figure out how to "patch" ::foo/bar to return something like #namespaced-keyword [foo :bar]

Alex Miller (Clojure team)15:05:51

the resolver is pluggable, so you can do that

Alex Miller (Clojure team)15:05:14

well, maybe not that pluggable

bronsa16:05:12

not quite sure what a good pluggable mechanism for this would be that avoids exposing the entirety of read-keyword

bronsa16:05:34

but I'm open to suggestions

Alex Miller (Clojure team)16:05:50

may I suggest that you don't do that? :)

😂 4
😕 4
souenzzo18:05:44

I think that I found a bug

(clojure.tools.reader/read-string 
  {:read-cond :allow}
  "[#?(:cljs #=(prn :ok) :default 1)]")

Alex Miller (Clojure team)19:05:06

don't you want :read-cond :preserve ?

Alex Miller (Clojure team)19:05:44

well, maybe I'm ahead of you - what do you get and what do you want?

souenzzo19:05:28

ATM I'm just playing and understanding how clojure.tools.reader works Then I see that reader-eval occur in all reader-cond branches

souenzzo02:05:56

I'm trying antlr now

ccann16:05:20

I’m looking for design advice on a feature. I’m writing some code which hits a REST API. The interface to that API exposes some abstractions like “tags”, which are strings. I want to my code to hide those strings behind a mapping, so that the caller of my namespace can pass in data (which I could spec) which will be replaced with the correct string before calling the HTTP endpoint. For abstracting over the tags, should I be using … vars? I could write a namespace that just defs each string and have the caller pass those as arguments. Or maybe just normal keywords, instead? Maintaining a mapping of keyword to string for the tags. Do namespaced keywords make sense here?

hiredman16:05:51

if tags is an open set of strings then I would just leave them as strings

hiredman16:05:12

strings are a very flexible first class data type

ccann16:05:01

the thing is they’re kind of all over the place — they’re tags on some products. So the punctuation and casing and whitespace is inconsistent. I was hoping to design so the caller doesn’t have to know if the “christmas” tag is “Christmas” or “XMAS” or whatever, they can just say tags/christmas or :christmas

ccann16:05:07

plus then if the tag itself changes, which is fairly likely to happen (maybe there is an effort to make them more consistent), I can change the value in one spot instead of searching for all occurrences

ccann16:05:48

I think then that means it’s a closed set from my code’s perspective?

quadron17:05:01

I have timeseries data that is a collection of events. the data is sparse, that is for certain timeframes there are no events. how am I supposed to build on this? do I let the collection with a lot of nil propagate through the system and put nilchecks everywhere? or should I treat the whole timeseries data as a function of time?

noisesmith17:05:59

maybe a sorted set, sorted by timestamp? that makes grabbing all items between times X and Y cheap

noisesmith17:05:11

while avoiding any need for keys with nil values

noisesmith17:05:50

(cmd)user=> (sorted-set-by #(compare (:t %1) (:t %2)) {:t 0 :a 12} {:t 1 :a 3} {:t 4 :a 0} {:t 8 :a 1})
#{{:t 0, :a 12} {:t 1, :a 3} {:t 4, :a 0} {:t 8, :a 1}}
(cmd)user=> (def s *1)
#'user/s
(cmd)user=> (subseq s > {:t 0} < {:t 5})
({:t 1, :a 3} {:t 4, :a 0})

4
✔️ 12
noisesmith17:05:38

the first arg to sorted-set-by needs to be a comparator of two events

noisesmith17:05:17

subseq takes the sorted set, and two comparison functions / compared item pairs (it can also take a single pair)

noisesmith17:05:00

instead of saying "what's the data at time t" you'd say "what are the known data points between t and t'"

quadron17:05:57

hmmm let me see how this works out.

noisesmith18:05:18

you can do the same with a sorted-map with timestamps as keys

hiredman18:05:28

whatever the representation, you shouldn't have nils laying around

4
hiredman18:05:26

like, in general, if I had a time series of data it would just be a collection of events, and any time period where there were no events, well there just wouldn't be events from that time period in the collection

hiredman18:05:41

if you need to reify your notion of time periods, then you have a set of time periods, and each event refers to a timeperiod, so a time period with no events would be added to the set of time periods, but have not events referencing it

johnj23:05:10

To expand about nils, this is just for data, functions returning nil is perfectly fine correct? (As long as it doesn't leak into data)

hiredman18:05:50

ini either case no weird nils

✔️ 4