This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-12-21
Channels
- # adventofcode (82)
- # bangalore-clj (1)
- # beginners (44)
- # boot (7)
- # boot-dev (25)
- # cider (1)
- # cljs-dev (3)
- # cljsrn (14)
- # clojars (11)
- # clojure (210)
- # clojure-dusseldorf (4)
- # clojure-gamedev (2)
- # clojure-greece (11)
- # clojure-italy (6)
- # clojure-norway (6)
- # clojure-russia (6)
- # clojure-serbia (2)
- # clojure-spec (43)
- # clojure-sweden (1)
- # clojure-uk (77)
- # clojurescript (43)
- # cursive (1)
- # data-science (3)
- # datomic (32)
- # duct (3)
- # figwheel (2)
- # fulcro (71)
- # graphql (3)
- # hoplon (14)
- # jobs-discuss (3)
- # lambdaisland (1)
- # leiningen (2)
- # luminus (2)
- # lumo (14)
- # off-topic (16)
- # om-next (1)
- # perun (5)
- # random (1)
- # re-frame (19)
- # reagent (37)
- # ring-swagger (3)
- # shadow-cljs (157)
- # specter (6)
- # sql (29)
- # unrepl (14)
i also have a small question using the thread-last macro, can I make an exception for one of the elements and insert the result as first argument?
I tried to wrap it in a #(myfunc % params) but it doesn’t seem to work; neither does a fn 😞
hm, I guess I misunderstood thread macros; they take the functions as partials and appends an extra argument before actually calling the function? using other macros as functions might break the thread macros…
it doesn’t create partials
it rewrites the code
so you can use the anonymous functions, but it often requires extra parens
(-> [1 2 3 4]
(->> (map #(+ 10 %))
(map str)
(clojure.string/join ","))
(clojure.string/replace #"," "."))
pardon the terrible example
you can “embed” thread last in a thread first
but not the other way around
you can also use the anonymous functions with extra parens
(->> [1 2 3 4]
(map #(+ 10 %))
(map str)
(clojure.string/join ",")
(#(clojure.string/replace % #"," ".")))
you can also use the as->
macro
i’ve also seen folks write
(-> [1 2 3 4]
(->> (map #(+ 10 %)))
(->> (map str))
(->> (clojure.string/join ","))
(clojure.string/replace #"," "."))
(->> (apply concat (vals js))
(reduce reducer {})
(#(json/encode %1 {:pretty true}))
(spit "extract.json")))
i’m still not sure which form I prefer
:thumbsup:
another variant
(-> [1 2 3 4]
(->> (map #(+ 10 %))
(map str)
(clojure.string/join ","))
(clojure.string/replace #"," "."))
showing that it’s not partial application
=> (-> [a 1 b 41] (let (+ a b)))
42
it’d be neat if there was an as->
and as->>
that defaulted to thread-first or thread-last if no $
was found
I'm really tripped up on this java interop issue:
I want it to call remove(int index)
-- what would I have to do to typehint this correctly?
This is the class: https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/impl/client/RedirectLocations.html
I tried to create a function
(defn do-it [^org.apache.http.impl.client.RedirectLocations redirect-locations ^Integer index]
(.remove redirect-locations index))
for some methods you might need to call int
to cast the arg, recall that in clojure 1
is not an Integer, it’s a Long
what error are you getting?
@noisesmith just tried to understand your example from above… it wouldn’t work with (->> X (-> Y) Z)
right?
@synthomat correct - all the other arrow macros nest inside ->, but -> can’t nest inside ->>
it has to do with the mechanics of the code rewrite (the silly example with the let is to show that it isn’t smart at all - it’s just moving tokens around in lists)
@noisesmith I'm not getting an error, but it's returning a boolean false which is coming from the other method signature. boolean remove(URI uri)
@rymndhng ahh - what if you hint ^int instead of ^Integer?
(I bet I have a project with this dep, I’ll see if I can replicate in a repl)
kingfisher.core=> (defn rm [^RedirectLocations r ^long idx] (.remove r idx))
#'kingfisher.core/rm
kingfisher.core=> (rm red 0)
#object[java.net.URI 0x2a3988c0 ""]
(set! *warn-on-reflection* true)
will tell you if the compiler is emitting reflection
int primitives are not supported by the clojure compiler
so I made it a long, and it worked
@hiredman it was still calling the wrong method when I called int
kingfisher.core=> (defn rm2 [r idx] (.remove r (int idx)))
#'kingfisher.core/rm2
kingfisher.core=> (.add red 0 (java.net.URI. ""))
nil
kingfisher.core=> (rm2 red 0)
false
boolean is what the Object overload returns if it gets hit
@hiredman ahh, OK
turning on reflection warnings will make it clear when you have eliminated the reflection or not
the long hint also causes the function to implement the primitive invoke stuff(if I recall), which is orthogonal to compiling an invoke of the right method
something that’s helpful sometimes is a leiningen plugin called no.disassemble - it can expose what your function compiles down to as readable mnemonics for the byte code https://github.com/gtrak/no.disassemble
Upgrading to clj 1.9. Anyone else getting these error messages?
WARNING: boolean? already refers to: #'clojure.core/boolean? in namespace: clojure.tools.analyzer.utils, being replaced by: #'clojure.tools.analyzer.utils/boolean?
WARNING: boolean? already refers to: #'clojure.core/boolean? in namespace: clojure.tools.analyzer, being replaced by: #'clojure.tools.analyzer.utils/boolean?
WARNING: bounded-count already refers to: #'clojure.core/bounded-count in namespace: clojure.core.async, being replaced by: #'clojure.core.async/bounded-count
?my guess would be you have an older version of core.async that doesn't exclude bounded-count from clojure.core
@hiredman I have upgraded core.async, currently running on [org.clojure/core.async "0.3.465"]
This is the ns def in the file in question:
(:require [clojure.test :refer :all]
[amazonica.core :refer [defcredential]]
;; our stuff
[com.stuartsierra.component :as component]
[clojure.core.async :as async :refer [go go-loop >! <! timeout alts! alts!!]])
@bronsa: yeah, I can definitely do a bit more clojure source reading. How do you find the source? checking out clojure + grep, or the github interface, or repl/source, or ... ?
@tbaldridge: re parsing / ometa : I figured out what I was looking for -- parsec
Hello all, I'm developing a reporting generator but in Java/Clojure I do not have the right library for the charting session. The charting library is in javascript, so, is there possible to generate the charts from javascript/html and use it in Clojure as svg or image without having server/browser generating it?
how cheap/expensive is (fn [] ...)
is it as cheap as a function call, or is creating anonyous functions at runtime realy expensive ?
naively it seems for a (fn [] ...)
there is some compilation / byte code generation to be done, which might make it expensive
does clojure somehow do all this pre-emptively and cache it (despite not having the environment until runtime)
this is a drastic oversimplification, so you're saying:
1. at compile time, each (fn [...] ...)
has a class generated for it
2. at runtime, when to exec the code, the corresponding code is passsed the env as an argument, creating a "clojure function object"
3. this "function object" can then be used just like any other clojure functions, and passed arguments to make it work ?
@dominicm if by versioned we mean versioning the install script itself, seems that it already is at https://clojure.org/guides/getting_started, but maybe I'm missing your point
@dominicm it seems (at least from this cursory check) to live in the https://github.com/clojure/brew-install repo under src/main/resources/linux-install.sh
and be versioned using the script under
, which on the last line says:
aws s3 cp --only-show-errors "target/classes/linux-install.sh" "$S3_BUCKET/install/linux-install-$version.sh"
where on the 1.9.0
branch in that git repo, the maven pom.xml says <version>1.9.0.275</version>
and looking at git history we can see that the version was changed to 275 from 273 on dec 8 and 273 is what we see on the site
not 100% sure what it’s supposed to do, but ((apply comp lst) stack)
?
or ((apply comp (reverse lst)) stack)
I suppose
@qqq what is that function supposed to do? if the incoming stack is in fact a list that we are just treating like a stack and all you are doing is adding all the elements from one list to another (the stack) then you could as well just return lst
or potentially (reverse lst)
. But I get the feeling we are missing your point
so there is an object, there is a list of functions, we want to apply it one by one, so (magic obj f1 f2 f3 f4 f5) --> (f5 (f4 (f3 (f2 (f1 obj)))))
wrt your question earlier https://clojurians.slack.com/archives/C03S1KBA2/p1513859891000026 it’s highly inefficient since it involves copying
if possible, try to reframe the problem so that you can use first/last for vectors or first for lists
often, a hash-map is also a better choice
@qqq Oh now you’re making me jealous, I’ve always wanted to write my own Forth interpreter.
I should never have sold my C64.
@manutter51 I'm sure there's cycle accurate C64 emulator out there now 😄
I’m trying to pretend I don’t know that. 😉
does anyone here have any experience using clj-http with cookies on an HTTP/POST? I’m trying to convert a request over from using [http.async.client “1.2.0”] to clj-http
@mdrago1026 are you experiencing issues? what version of clj-http are you using (hopefully latest version: 3.7.0)?
@rymndhng I just got it to work. I am on 3.7.0. I was trying to pass the cookies map the previous authentication request returned into the :cookies
value of the POST map. For whatever reason it wasn’t worker. Passing the raw cookie string to the :headers map worked though
I was under the impression you could pass the :cookies map around
was just doing an auth, getting that cookies map and sending it in the subsequent POST
@mdrago1026 you should be able to pass the :cookies
map directly, I have some code around that does that
Hi all 🙂
i need a bit of advice , i'm pretty sure someone has solved my issue already but i seem have trouble finding it. I need a persistent map that is stored on disk and doesn't require me to read it all into memory to read it.
sure i could do all sorts of h2 or hsqldb sort of trickery but i really would rather not 😞
the reason why i don't want to read all into memory at once is that it just won't fit, amount of data is way bigger than the ram that i have available
datomic seems pretty complex for my needs 🙂
isn’t what you need just a database?
yes but the definition of a database is a rather wide one
maybe just sqlite or something? Sounds like that might be adequate, depending on just how big we’re talking here
OK just saying what you describe so far is something any database worthy of the name does
i manage apps that run on postgresql clusters of hundreds of gigabytes every day at work , and yeah sure that's all fine and i know how they work ... but my needs here are way different
Well…. that depends on the keys @kulminaator is using: could be objects, vectors, etc.
OK no database (or nearly none) supports all the types clojure allows in hash map keys
You'll have to write it starting from those examples: http://vanillajava.blogspot.com/2011/12/using-memory-mapped-file-for-huge.html https://github.com/ashkrit/blog/tree/master/src/main/java/bigarraylist
if you have a decade to spare you could make a new database sure
i usually despise orms and simplifications but this time it is exactly what i'm looking for, just a memory optimized storage for hash maps , which in turn have just lists of strings as values and strings as keys
something in the berkeleydb or mapdb territory
Why database? Most likely only one map type is needed.
mapdb seems to be the way to go
@kulminaator Maybe you van use the H2 MVStore? http://www.h2database.com/html/mvstore.html
@ghsgd2 because most people want insertion to be reliable and persistent and failures to be handled in a sane manner and multiple clients to be able to access it without breaking everything etc. and before you know it either you have something that doesn’t work at all, or a database
I’m not talking about query models or relations or anything here - you don’t need those to be a db
MVStore is easy to use, but I moved to Redis, since I needed access from multiple jvm's. Also easy, but needs a separate process.
but wasn't the case with redis that whatever you store there, even if backed on disk, needs to fit in ram ?
h2 is a strong candidate on my checklist so far though
thanks for the suggestions, i will break my thumbs a little bit on testing approaches out
@manutter51 @qqq this is my favorite lisp/forth story: http://www.flownet.com/gat/jpl-lisp.html (starting with “Also in 1993 I used MCL to help generate a code patch for the Gallileo magnetometer…“)
Nice 😉
more detail at https://news.ycombinator.com/item?id=12037548
(try
(throw
(ex-info "foo" {:bar "barrr"}))
(catch Exception e
(ex-data e)))
vs
(try
(throw
(ex-info "foo" {:bar "barrr"} {:baz "baaz"}))
(catch Exception e
(ex-data e)))
Second example return nil.
First example is clojure.lang.ExceptionInfo
while second is java.lang.ClassCastException
.
How do you read Expection in consistent way to get always ([msg map cause]
from ex-info
?
On the end i need it to create fingerprint
for sentry, which is unique data to identify group of errors.
(when (or error-message (force msg_))
(->> [?ns-str error-message (force msg_)]
(remove #(= "" %))
(remove nil?)))
So i want add here additional cause
to make smaller group of errors to easier debug issues.
So on the end i want call:
(throw
(ex-info "service X API" {:error-info "bla bla" {:cause {:timeout :foo}}))
^ or maybe last param could be a vector [:timeout :foo]
or just in some cases
(throw
(ex-info "service X API" {:error-info "bla bla"))
In logs i want make from that right fingerprint
for sentry to group this errors.
How to get ex-data
and cause
from ex-info
. When third parameter cause
is present in ex-info
it returns different instance and it doesn’t work so simple.(ins)user=> (ex-info "" {} {})
ClassCastException clojure.lang.PersistentArrayMap cannot be cast to java.lang.Throwable clojure.core/ex-info (core.clj:4739)
the ClassCastException is because you used ex-info wrong, and you get the thrown ClassCastException instead of the other one you were catchingthe third arg if present needs to be a throwable
it’s not that ex-info is returning a different type, it’s throwing instead of returning
the design is that cause
if present would be another exception (the one you caught originally in theory)
It would be grate to don’t have timeout issue from third part service etc. in the same group like others important errors
For now only one solution what i see is change "service X API"
in ex-info
but i don’t like it to much
(throw
(ex-info "service X API" error-info))
(when sentry-dsn
(l/debug "sentry-dsn: " sentry-dsn)
(sentry/init! sentry-dsn)
(timbre/merge-config!
{:appenders
{:sentry
{:enabled? true
:async? true
:min-level :debug
:rate-limit nil
:output-fn :inherit
:fn (fn [{:keys [level ?err msg_ ?ns-str context]}]
(let [error-message (some-> ?err (.getLocalizedMessage))]
(sentry/send-event (merge sentry-base
{:level (get timbre->sentry-levels level)
:fingerprint (when (or error-message (force msg_))
(->> [?ns-str error-message (force msg_)]
(remove #(= "" %))
(remove nil?)))
:logger ?ns-str
:extra context
:message (not-empty (force msg_))
:throwable ?err}))))}}}))
^ here is the point how I use timbre eventshmm alternatively I can use :causes
from ex-info
map
always as some kind of agreement.
@qqq by redefining clojure.core/> or shadowing it
oh sorry I misread - no, no plan for that
@qqq (clojure.core/compare \b \a) returns 1. That might be useful to you.
@qqq the clojure numeric operators will not be made generic / extensible beyond working on Number
Here's a Joy DSL I'm working on. Feedback/criticism welcome:
(defn fnj-raw [args body] `(fn [ss#] (let [[ss# ~args] (vsr ss# ~(count args))]
(vrc ss# (do ~@body)))))
(defmacro fnj [args & body] (fnjp-raw args body))
(def joy (fn [stack & lst] (reduce #(%2 %1) stack lst)))
(def joy1 #(first (apply joy [%1] %2)))
(def jw (fn [& lst] #(apply joy % lst)))
(def jdup (fnj [x] [x x]))
(def j+ (fnj [x y] [(+ x y)]))
(def j- (fnj [x y] [(- x y)]))
(def j* (fnj [x y] [(* x y)]))
(def jp (fn [x] (fnj [] [x])))
(def jcct (ffnj [x y] [(concat x y)]))
(def js2 (jw jdup j*))
(def jfilter (fnj [lst ws] [(filter #(joy1 % ws) lst)]))
(def jmap (fnj [lst ws] [(map #(joy1 % ws) lst)]))
(def jc> (fnj [x y] [(c> x y)]))
(joy ["John Smith"] (jp [(jp \Z) jc>]) jfilter)
#_ (def ji (fn [lst] #(apply joy % lst)))
#_ (joy [1 2] (jp (ji [j+ (jp 20) j* (jp 10) (jp 4) j-])) ji)
(joy [2] js2)
(joy [] (jp 2) (jp 3) j+ jdup j*)
(joy [] (jp [1 2 3 4]) (jp [jdup j*]) jmap)
@kulminaator a random idea that popped into my head: maybe http://rocksdb.org/ + https://github.com/ptaoussanis/nippy?
you don’t even need nippy for string/string right?
@qqq If you don't need it to be eager, concat
is already going to be O(1), right? 🙂
So a list would be O(1) pop, peek, and (lazy) concat but you trade off O(n) on other operations...
If what you're concat
ing is always small, a vector is going to be reasonable: O(1) for pop, peek (off the end) and (into vec1 vec2)
will be O(n) for the size of vec2
... and you still have O(1) access to other elements...
(I think -- happy for someone to confirm / deny my thinking there!)
@qqq RRB vectors gives amortized O(1) pop/peek, and O(log n) concat: https://github.com/clojure/core.rrb-vector
or maybe it is O((log n)^2) concat -- been a while since I looked at the details. Anyway, significantly less than O(n)
@seancorfield @andy.fingerhut: theXY problem is that I am implementing an 'instruction stack' most of the time, it's just pop and peek, but occasionally, I need to push a buch of ops to the front of it
sounds like you want clojure.lang.PersistentQueue/EMPTY
conj to the front peek/pop from back
@qqq you know that conj takes multiple args and that you can use into as well right?
is there a way to make jdbc dump the sql statements it’s making? I have a sql query that is working through psql but it doesnt return anything through jdbc, and I don’t get any errors either…
yeah, you can’t do the sharing clojure would normally do with lists
what about those zipper things that I refused to learn about when i was trying to learn haskell
> to make a doubly-linked list, you need to construct it all at once, and if you ever want to change any part of it, you either need to use a Zipper or just make a complete copy of it every time https://stackoverflow.com/questions/10386616/how-to-implement-doubly-linked-lists
@qqq did anyone mention finger trees yet?
@jgh Ask in #sql if you want to avoid the noise of this channel...
@noisesmith fingertrees look interesting
I just had an epiphany while implementing Joy in Clojure. Stack based langauges = basicaly programming iwth de bruijn indices instead of variable names.
If you are worried about constant factors in run time, you might want to do some profiling of finger trees vs. other data structures like plain old Clojure vectors and/or RRB vectors. I haven't done it myself, but recall that finger trees have constant factors of run time significantly higher than the others. Not O() bad things, but something that might affect what you want to use anyway.