Fork me on GitHub
#clojure
<
2017-03-05
>
tbaldridge02:03:54

@paulocuneo only use one of those (not both), and you have to use a protocol with the deftype as all the mutable fields are private

tbaldridge02:03:24

and as the docs say, only use :unsynchronized-mutable if you really, really, know what you're doing.

paulocuneo02:03:27

@tbaldridge Thanks! I see now, the reflection error was because of private access field. The field is intended to become read only after i set it so guess is a fair use of mutable.

qqq04:03:50

is there a builtin for #(clojure.string/join "\n" %) ?

joshjones05:03:49

@qqq so instead of (join "\n" coll) you want something like (make-lines coll)?

qqq06:03:22

does core java provide anything for doing "ttf font" -> "list of bezier curves" ?

kauko08:03:29

I'm trying to redefine the logging function a 3rd party library uses during initialisation (for fun mostly). My understanding is that something like

(with-redefs [(var-get (ns-resolve 'third.party.library.core 'log/info)) (fn [& args] (println "foo"))] (library/start))
should work, but I'm getting clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol

kauko08:03:56

(defn add-five [a] (+ 5 a))

(with-redefs [add-five (fn [a] (+ 10))] (add-five 5)) ;; 15

(with-redefs [(var-get (ns-resolve *ns* 'add-five)) (fn [a] (+ 10))] (add-five 5)) ;; Error

add-five ;; #object[....]
(var-get (ns-resolve *ns* 'add-five)) ;; #object[..]
`

lmergen10:03:10

I suspect this might have something to do with the argument list being a vector

rauh10:03:54

@kauko with-redefs already wraps the binding in a var, so use with-redefs-fn instead

kauko10:03:41

(with-redefs-fn {(ns-resolve *ns* 'add-five) (fn [a] (+ 10)} #(add-five 5)) ;; 15

kauko10:03:53

Thanks @rauh 🙂 I need to read a bit more about symbols and vars

rauh10:03:57

@kauko The problem is you can't go from value -> var.

rauh10:03:19

But instead of getting the value from a symbol, you can get the var (with var).

kauko10:03:13

Yeah I think I get it

kauko11:03:20

(with-redefs-fn 
{(ns-resolve 'library 'log/info) 
#(println "foobar")} 

(fn [] (library/start)))

kauko11:03:01

I can run this in the REPL with no errors, but it doesn't seem like the log/info function is getting redefined

kauko11:03:19

The library requires clojure.tools.logging :as log

scknkkrer11:03:19

guys, a schemaless dbms can help the development process to decresing the time ?

rauh11:03:12

@kauko What are you actually trying to do? log/info is a macro...

kauko11:03:47

ahh right, that complicates things

kauko11:03:05

I was trying to see if I could make the library use a different method of logging

kauko11:03:14

mostly for fun, as I mentioned

rauh11:03:42

@kauko Java logging is extremely configurable. But it's a lot of stuff to just explain in chat

rauh11:03:18

So basically ct.logging will use some backends (that can be configured with some xml files, java style) and they'll receive the clj-namespaces as an argument

rauh11:03:58

You can configure which namspace can log which level (warn, info etc) and I believe even redirect just that ns to some other file

sveri11:03:00

@rauh @kauko You could as well use a properties file, if xml scares you

kauko11:03:38

Yeah, actually I already have an .xml file for configuring the logging. 🙂

kauko11:03:00

I was just trying to see if I could use with-derefs (or something similar) in this case

kauko11:03:03

for learning purposes

mpenet12:03:07

There's a lib called unilog that makes all this stuff more clojure friendly

abhiroop13:03:08

How does Clojure STM deal with Reentrancy?

tbaldridge13:03:54

@abhiroop inner transactions become part of the outer transaction

abhiroop13:03:42

So for every yield it will spawn a new transaction?

abhiroop13:03:51

And treat it as nested?

andrea.crotti13:03:34

is there anything like python setup.py develop in Clojure? To be more clear, some way to try out a lein plugin from my local checked out version?

tbaldridge13:03:44

@abhiroop not sure what you mean by yield

tbaldridge13:03:26

@andrea.crotti you can do lein install and that will put the project in your local .m2 folder

andrea.crotti13:03:37

ah cool that should it do it thanks @tbaldridge

abhiroop13:03:47

@tbaldridge I guess I was not very clear. So what I mean by reentrancy is when a thread actually yields its control flow without the scheduler preempting. And reenter the original control flow. So Thread1 --yields--> Thread2 --reenter--> Thread1. I am not sure if STM supports this kind of interaction, which is common in normal lock based concurrency. Thats why the question.

abhiroop13:03:28

I am not sure if yield is the correct word here. I might use interrupt instead

tbaldridge13:03:37

yes, that is supported.

tbaldridge13:03:40

refs are slots where the mutable state being modified is stored. When a transaction commits, it locks all the refs it will operate on and performs the updates. Other transactions can barge the locks, and not all modifications of locks cause rollbacks of other transactions, but that's the general gist.

abhiroop13:03:41

Other transactions can barge the locks -> Really? Could you elaborate a little bit on this?

tbaldridge13:03:27

yeah, if it comes time for one transaction to commit, but it can't because another transaction has the refs locked, there's a way for the two threads to communicate. The slow transaction will rollback and the faster one will commit.

tbaldridge13:03:13

So here's the thing that makes Clojure STM different from more mutable languages. The only things that are tracked during a transaction are refs (and agents, but skip that for now).

abhiroop13:03:29

Oh I see it now you have a CountDownLatch which countsdown for the other thread till 10 seconds

abhiroop13:03:34

And then barges in

abhiroop13:03:04

I was looking for a bit more than this communication. For instance, (I am not sure if this is possible) but if 2 core.async channels exchange messages with each other via a channel rather than just talk about whether the other is holding a lock for too long.

abhiroop13:03:32

I was wondering if 2 threads in the middle of a transaction can do that.

abhiroop13:03:54

Though I think that would break the ACI guarantee of STM

shakdwipeea14:03:36

Hi guys. I have just started learning clojurescript and started with a leningen template. The build was working initially , but now the figwheel repl is stuck and I see Please run lein figwheel to start the ClojureScript compiler and reload the page. message. Where should I look for errors.

shakdwipeea14:03:57

Sorry I posted in the wrong channel.

Ethan Miller15:03:50

Let’s say I have the following edn:

{:db/id #db/id[:db.part/user -1000007], :thing/name “thing1”}
And I want to try to convert it and read it with edn/read-string. I try:
(def tx {:db/id #db/id[:db.part/user -1000007], :thing/name “thing1”}  
(edn/read-string (prn-str tx))
Getting an error:
RuntimeException No reader function for tag db/id  clojure.lang.EdnReader$TaggedReader.readTagged (EdnReader.java:784)
To avoid the error, I do instead:
(edn/read-string {:readers *data-readers*} (prn-str tx))
;; {:db/id #db/id[:db.part/user -1000009], :thing/name "thing1"}
Can anyone explain, why that works?

netsu15:03:01

Hello there, folks! I'm n00b in clojure yet, just trying the water.

tbaldridge15:03:23

@ezmiller by default I don't think read-string uses the data-readers found in data-readers. However, that data reader is installed by Datomic, so it works fine if you give it the correct information

netsu15:03:30

Trying to make simple http request, use clj-http (should I try another library for that?), but got strange ssl error:

1. Unhandled javax.net.ssl.SSLException
   Certificate for <api.dribbble.com> doesn't match any of the subject
   alternative names: [, ]
Have no idea how to fix that, would be grateful for any advices, guessing, suggestions. Thanks.

jmsul15:03:12

@netsu are you following the tutorial and using clj-http 2.0.0?

netsu15:03:57

[clj-http "2.3.0"] in project's :dependencies.

netsu15:03:35

Make request like that:

(http/get (followers-url given-user)
          {:headers {:access_token api-client-access-token}})

netsu16:03:07

Pretty sure that I doing dumb mistake somewhere.

jmsul16:03:52

Try upgrading clj-http to the latest version. 3.4.1

netsu16:03:46

thanks, will try.

netsu16:03:53

Well, nope, didn't help(

jmsul16:03:05

Did you restart your repl?

Ethan Miller16:03:05

@tbaldridge not sure what the data-readers are… is there a doc you could point me to?

netsu16:03:01

@jmsul trace:

AbstractVerifier.java:  165  org.apache.http.conn.ssl.AbstractVerifier/verify
StrictHostnameVerifier.java:   67  org.apache.http.conn.ssl.StrictHostnameVerifier/verify
     AbstractVerifier.java:  141  org.apache.http.conn.ssl.AbstractVerifier/verify
     AbstractVerifier.java:  114  org.apache.http.conn.ssl.AbstractVerifier/verify
     SSLSocketFactory.java:  580  org.apache.http.conn.ssl.SSLSocketFactory/verifyHostname
     SSLSocketFactory.java:  554  org.apache.http.conn.ssl.SSLSocketFactory/connectSocket
     SSLSocketFactory.java:  412  org.apache.http.conn.ssl.SSLSocketFactory/connectSocket
DefaultClientConnectionOperator.java:  179  org.apache.http.impl.conn.DefaultClientConnectionOperator/openConnection
ManagedClientConnectionImpl.java:  328  org.apache.http.impl.conn.ManagedClientConnectionImpl/open
DefaultRequestDirector.java:  612  org.apache.http.impl.client.DefaultRequestDirector/tryConnect
DefaultRequestDirector.java:  447  org.apache.http.impl.client.DefaultRequestDirector/execute
   AbstractHttpClient.java:  884  org.apache.http.impl.client.AbstractHttpClient/doExecute
  CloseableHttpClient.java:   82  org.apache.http.impl.client.CloseableHttpClient/execute
  CloseableHttpClient.java:  107  org.apache.http.impl.client.CloseableHttpClient/execute
                  core.clj:  304  clj-http.core/request

netsu16:03:13

may it be apache problem? (Not sure why apache may required).

jmsul16:03:16

Can you make a request to https://api.dribbble.com?

netsu16:03:17

oh, nope, still same error

netsu16:03:07

request to works just fine 🙂

jmsul16:03:09

I get an OK from https://api.dribble.com using clj-http 3.3.0

netsu16:03:15

can't believe that dribbble use invalid certificate. Maybe.. Is there a way to force use that one certificate as correct?

netsu16:03:06

let me try 3.3.0..

netsu16:03:20

> SunCertPathBuilderException unable to find valid certification path to requested target sun.security.provider.certpath.SunCertPathBuilder.build (SunCertPathBuilder.java:141)

jmsul16:03:32

I had this same problem with Let's Encrypt certificates with clj-http 2.0.0; updating fixed it. I would get a Java SSL error but not for other cert authorities

netsu16:03:38

1. Unhandled sun.security.provider.certpath.SunCertPathBuilderException
   unable to find valid certification path to requested target

jmsul16:03:02

@netsu that's the same error. Your version of clj-http is not updating. How are you doing it?

netsu16:03:29

To be sure that it does not affected by Emacs configuration:

netsu@thinkpad:~/Documents/Projects/dribbble-stats$ lein repl
nREPL server started on port 46073 on host 127.0.0.1 - 
REPL-y 0.3.7, nREPL 0.2.12
Clojure 1.8.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_121-b13
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

dribbble-stats.core=> (require '[clj-http.client :as http])
nil
dribbble-stats.core=> (http/get "")

SSLException Certificate for <api.dribbble.com> doesn't match any of the subject alternative names: [, ]  org.apache.http.conn.ssl.AbstractVerifier.verify (AbstractVerifier.java:165)
dribbble-stats.core=> 
`

jmsul16:03:25

Did you do lein install?

netsu16:03:36

$ lein deps :tree | grep clj-http
[clj-http "3.3.0"]

jmsul16:03:27

Well, this is identical to my situation with 2.0.0 until I updated to 3.3.0. Maybe start a fresh lein project with the newer version from the beginning?

netsu16:03:43

Oh, got, it so stupid, yes, lein install helped

dergutemoritz16:03:11

Huh that's odd, lein install shouldn't help at all, it installs the current project into your local maven repository. The certificate of https://api.dribble.com/ is invalid, try connecting with any browser or even curl to see!

dergutemoritz16:03:46

So if it works for you now without errors, something must be wrong 🙂

netsu16:03:29

@jmsul thank you so much, upgrading to new version and lein install saved my day.

Tim17:03:35

If I have this,

weights 
=> #{{:name betsy, :weight [12 32]} {:name jake, :weight [1 2 3]} {:name shyq, :weight [342 4 6]}}
, how do I get the name or the map, based on if the weight contains a number?

Tim17:03:58

(get by-weight {:weight #(some #{12} %)})

hlolli18:03:29

@tmtwd you mean the vector of the weight contains number or the key :weight is keyed to a number?

Tim18:03:42

yes I think so

Tim18:03:16

so for example, if I input 12, I would get {:name betsy, :weight [12 32]} or something like that

hlolli18:03:57

(map :name (filter #(number? (first (:weight %)))
                   #{{:name 'betsy, :weight [12 32]} {:name 'jake, :weight [1 2 3]} {:name 'shyq, :weight [342 4 6]}}))

Tim18:03:35

(map :name (filter #(some #{6} (:weight %)) #{{:name 'betsy, :weight [12 32]} {:name 'jake, :weight [1 2 3]} {:name 'shyq, :weight [342 4 6]}}))

Tim18:03:37

this works

sudodoki18:03:02

Hi! I’m trying to make my data structure compatible with map/filter fns, etc. Was trying to extend ISeq but it seemed to still pickup default things for structure. Here’s my latest code https://gist.github.com/sudodoki/7141ce03f934a47fe13ff41df51387f2 and I get java.lang.ClassFormatError: Duplicate method name&signature in class file. Can someone point out how I make this work?

bronsa18:03:16

defrecord already extends seqable

bronsa18:03:34

if you want custom seqable behaviour you'll have to use deftype instead of defrecord

hlolli18:03:37

also looks like you end there with (concat 1 nil nil)

sudodoki18:03:00

@hlolli it would be (concat nil (list 5) nil) -> (5), so this is expected behavior

sudodoki18:03:15

@bronsa thanks. No way to have prefer-method or similar mechanics for this?

hlolli18:03:33

that's right @sudodoki very recursive stuff there.

bronsa18:03:34

@sudodoki no, there's no way to override default methods in defrecord

luisdevlopez18:03:08

Guys, do transducer achieve the same effect as Elixir's stream module? For example, if I had a range from 0 to a million and I wanted to apply maps and filters to it but without having to pass the result of one map to the next map or filter and so on until the pipeline is done.

luisdevlopez18:03:15

I think Elixir calls it lazy enum operations.

lmergen18:03:16

This is correct. Effectively, transducers will look like a (map (f (f' (f'' x ))) xs), for example

lmergen18:03:41

or whatever

lmergen18:03:43

point being, it is very efficient and doesn't create intermediate sequences, so doesn't unnecessarily copy

sudodoki18:03:31

After switching from defrecord to deftype, to avoid Don't know how to create ISeq from: TreeNode I updated code https://gist.github.com/sudodoki/7141ce03f934a47fe13ff41df51387f2 but now I’m getting IllegalArgumentException interface clojure.lang.ISeq is not a protocol clojure.core/extend (core_deftype.clj:769) anything I’m still missing? 🙇

bronsa18:03:40

ISeq is an interface, not a protocol

bronsa18:03:43

you can't extend it

bronsa18:03:54

you have to inline the def on deftype

sudodoki19:03:00

@bronsa sorry, just got to these parts, and can’t find a good example of deftype with inline method definition w/o protocol, can you give me a hint?

(deftype TreeNode [val l r]
    (first [this] (leftmost-in this))
    (next [this] (drop 1 (dfs this)))
    (more [this] (drop 1 (dfs this)))
    (cons [this v] (xconj this v)))
; => ClassCastException clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol
seems to be erroring for some other reason…

bronsa19:03:39

you're missing the interface name

bronsa19:03:46

deftype has the same signature as defrecord

sudodoki19:03:11

duh! thanks

sudodoki19:03:11

for some reason thought those were protocols as well from docs

sudodoki19:03:13

nah, nevermind, I guess I’m not yet ready for doing this yet. ¯\(ツ)

dominicm20:03:13

I'm super curious. go/parking threads, is there an equivalent when using libraries like Manifold?

richiardiandrea20:03:42

@dominicm there is the concept of deferred that should kind of being similar iirc..

richiardiandrea20:03:54

well, it is more like an abstraction over the specific concurrency primitive you are using

dominicm21:03:55

@richiardiandrea it's the parking thread mechanic I'm mostly curious about (or why it doesn't apply)

netsu21:03:41

How can I annotate in Clojure unused function? Is (def ^{:suppress-warnings "unused"} fn would be correct analogue for @SuppressWarnings("unused") fn() {?

seancorfield21:03:54

What tooling is giving you a warning about it?

seancorfield22:03:15

There’s no standard for Clojure tooling, as far as I know. For example, Eastwood will give various warnings for unused function arguments and unused locals etc — but you can’t suppress most of those.

seancorfield22:03:17

And simple Clojure metadata does not correspond to Java annotations so if you’re talking about Java tooling, it’s more complicated than that.

seancorfield22:03:25

This blog post talks about how to add Java-level annotations to functions in Clojure: http://seancorfield.github.io/blog/2013/05/01/instrumenting-clojure-for-new-relic-monitoring/ — bear in mind that Java annotations are actually types (classes) and the annotations need to happen at the Java level — hence that post uses definterface and deftype to expose Java-level methods that can be annotated with Java-level classes.

istvan22:03:51

heh, with pipelining Rapidoid can do ~3M req/s serving JSON API (sort of hello world no other IO) looks promising https://gist.github.com/l1x/2b12971e94d6160ac70f551ab8ee40ff#file-wrk_rapidoid-10g-36core-pipeline3-out

tbaldridge22:03:43

um...wrong chat window?

istvan22:03:25

well, i was looking for a Java HTTP framework that I could use in Clojure that has decent performance and easy to use

tbaldridge22:03:05

so what are you doing that needs 3M req/s ? For more realistic performance numbers there's quite a few good clojure frameworks out there

istvan22:03:47

writing 200Byte messages to an analytical store

istvan22:03:08

what do you mean by more realistic?

istvan22:03:19

is this based on jetty?

joshjones22:03:58

So, they ran the 3 tests at the end which seem to be identical, and got 3x improvement on the last vs the first. Am I reading it right? @istvan

istvan22:03:17

yeah i have increased the pipelining to 10

joshjones22:03:25

but the last 3 tests are identical?

istvan22:03:33

on the server end yes

istvan22:03:45

pipelining went 3 9 10

joshjones22:03:14

what's being pipelined specifically?

istvan22:03:21

http requests

istvan22:03:51

you open a connection and send N requests instead of 1

istvan22:03:08

this is pretty common scenario in industrial grade load-balancers

istvan22:03:31

this is how F5-s achieve several million req/s / load-balancer for example

joshjones22:03:35

yeah, so this is nothing "special" then it seems?

istvan22:03:45

no, it is absolutely standard

istvan22:03:53

just people forget about it all the time

joshjones22:03:14

ok, making sure i was not missing something 🙂

istvan22:03:44

i have spent some of my time as systems engineer with amazon so we had to understand HTTP really well

istvan22:03:25

there are a lot services with more than 1M req/s / datacenter

istvan22:03:59

there are other challenges when you reach this sort of performance

istvan22:03:12

i am really glad NIO brings that to the JVM finally

joshjones22:03:41

well nio's been around for a while 😉

istvan22:03:50

true that, i wasn't familiar with NIO 🙂

istvan22:03:40

most of the projects done in Java are happy with the 30K req/s that you can get with any framework you like, i did not need to look into JVM performance. i just started to discover what can we do to go beyond that sort of performance

tbaldridge22:03:24

So yeah, I guess when you said "decent performance" that made me think "normal performance".

istvan22:03:31

tbaldridge :))

istvan22:03:44

these are relative terms, yes

istvan22:03:56

i am curious about this tool though: https://github.com/pinterest/jbender

istvan22:03:04

havent had a chance to try it

Al Baker22:03:48

are there any reasons to use bidi over compojure, other than a preference of data structures over macros?

dominicm08:03:10

@albaker A really nice side effect of bidi being data, and we use it regularly at juxt, is that you can walk the data structure to update various leaves. Also, you can easily build things like site maps. The biggest feature though is probably the bi-directional urls. So you never need hard-code a URL again!

dominicm08:03:26

Disclaimer: I work for Juxt

Al Baker14:03:00

thanks, that makes sense

Al Baker22:03:08

e.g. any performance metrics or async stuff that compels usage?

tbaldridge23:03:37

@albaker I don't know about bidi, but there is with Pedestal's router. It has several advanced routing algorithms that are much faster than what you will find in other libraries. See the "routers" section here: http://pedestal.io/reference/routing-quick-reference

istvan23:03:28

no idea, never used it, did you run into performance issues that you definitely need to solve? if yes look into it, if not just use what you got. i guess 🙂

thedavidmeister23:03:18

@albaker bidi works in cljs too

alex-glv23:03:04

What’s a de-facto transit ring middleware library?