Clojurians
#clojure
<
2016-03-19
>

This page is not created by, affiliated with, or supported by Slack Technologies, Inc.

nnbosko01:03:12

I solved that looking through the ring-swagger logs

selfsame01:03:56

Does anybody remember an article about extreme macro optimization? Think it had yellow text on a black background

munro02:03:50

https://gist.github.com/munro/df5191d998befdb8acdc <-- anyone know of a nicer way to dynamically generate N levels of (fn [a] (fn [b] (fn [c] [a b c])))? I didn't use a macro because I wasn't sure if it would work with clojurescript. my solution is hard to understand, and it was hard to write!

tomjack03:03:57

dunno why I wrote (apply f (cons x xs)) instead of (apply f x xs) simple_smile

munro03:03:57

@tomjack: 😮 awesome! ty! should I use assert instead of deftest? doesn't seem to integrate with cursive though

tomjack03:03:12

eh, I just did that for my own convenience

mmeix06:03:13

In https://www.4clojure.com/problem/63 my solution fails the second test - why? See here:

lucj0607:03:11

@ptrwldn: just tried that but I got an error as the « ALERT » exchange is not found (the exchange I used is « data »)

swizzard13:03:36

has anyone run into an error like this using clj-http?

swizzard13:03:41

clojure.lang.Compiler$CompilerException: sun.security.provider.certpath.SunCertPathBuilderException unable to find valid certification path to requested target, compiling:(form-init2418347235443421362.clj:1:8

niwinz13:03:03

@swizzard: it is not clj-http issue, it is a commonly known jvm exception that is raised when no CA certificates found

swizzard13:03:29

yeah, i tried using http-kit and got a similar thing

niwinz13:03:32

The solution depends on the operating system and the jdk

swizzard13:03:54

i’m using mavericks

swizzard13:03:04

i’m not 100% sure which jdk i’m using but i’ll check

swizzard13:03:18

Java HotSpot(TM) 64-Bit Server VM 1.7.0_09-b05

niwinz13:03:26

I know nothink about osx

niwinz13:03:28

I know that the oracle jdk builds comes with certificates builtin

niwinz13:03:30

This is a jdk problem and you will receive that exception on every java app/lib that will try to use https or anything related to ssl/tls

lucj0613:03:37

Hi anyone has already used langohr for a RabbitMQ Client ?

lucj0613:03:26

Cannot have the Clojure client receiving messages http://pastebin.com/mA8UbAxq

lucj0613:03:02

I really cannot figure out what I’m missing simple_smile

fommil14:03:20

hi, I'm learning clojure (I'm a scala developer and write the equivalent of CIDER). I've hit this problem when setting up Emacs, can somebody please help? https://t.co/mvvM3zHyMu

fommil14:03:22

I'd like to get red squigglies

codonnell14:03:12

@fommil: you might try #C0617A8PQ

fommil14:03:25

@codonnell: I already have cider

codonnell14:03:39

I mean, ask in the #C0617A8PQ channel

fommil14:03:51

it's not a cider problem

fommil14:03:01

it's fixed anyway, the solution is to ignore the documentation

cky14:03:32

Most tweetable OH of the day. 😉

fommil15:03:48

what is the idiomatic way of loading runtime configuration into a clojure application? Do people use HOCON?

fommil15:03:06

I have an OAuth token/secret that I want to be specified in config files, not code

fommil15:03:31

I've seen people just load-file .clj files, I'm not entirely convinced about that

niwinz15:03:44

@fommil: I'm using edn files for that, I have one file with default files and other (not tracked by the repo where the user can overwrite the default settings called local.edn

niwinz15:03:55

this is a code snippet that does that

niwinz15:03:25

(defn deep-merge
  [& maps]
  (if (every? map? maps)
    (apply merge-with deep-merge maps)
    (last maps)))

(def ^:const +default-config+
  "config/default.edn")

(defn read-config
  []
  (let [defaults (edn/read-string (slurp (io/resource +default-config+)))
        local (io/resource (:local-config env "config/local.edn"))]
    (if local
      (deep-merge defaults (edn/read-string (slurp local)))
      defaults)))

niwinz15:03:30

If you are using mount, later the config can be declared in this way:

fommil15:03:34

is the + on each side of the :const idiomatic or yours?

niwinz15:03:36

(defstate config
  :start (read-config))

fommil15:03:58

cool, thanks

niwinz15:03:28

I found that in other projects and I found that useful

apviitanen15:03:57

@swizzard: have you tried clj-http-lite (or perhaps clj-http 3.0.0-SNAPSHOT)

apviitanen15:03:20

I've ran into a similar problem with clj-http and that time it could be tracked down to how apache http client (that clj-http uses) worked with some particular certificates. That issue is fixed in the 4.x versions of the apache client, however clj-http 2.x still uses an older version. Back when I had the problem, I was forced to use clj-http-lite. It uses a plain HttpURLConnection which worked.

thiagofm15:03:23

@fommil: there's a package to do it called cprop

thiagofm15:03:52

I find using packages better than copy and pasting because then we can develop the ecosystem

thiagofm15:03:06

You can also use cursors to access part of the config

swizzard15:03:10

@apviitanen: i tried clj-http 3.0.0-SNAPSHOT & got the same error

swizzard15:03:14

i’ll try clj-http-lite

fommil15:03:07

has anybody here used clj-oauth? I don't understand what the verifier is supposed to be https://github.com/mattrepl/clj-oauth

swizzard15:03:21

@apviitanen clj-http-lite gave me javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

masnun16:03:00

I am trying to start two go blocks - one would produce values to a channel and one would consume. Here’s the code:

(ns cljnoob.utils.async
  (:require [clojure.core.async :refer [go chan alts! >! >!! <! <!!]]))

(defn produce [ch]
    (println "Produce")
    (>!! ch "hello")
    (Thread/sleep 1000))

(defn consume [ch]
    (println "Consume")
    (println (<!! ch))
    (Thread/sleep 1000))


(defn start-producing [ch]
    (go (while true (produce ch))))

(defn start-consuming [ch]
    (go (while true (consume ch))))

(defn make-chan
  []
  (chan))
And my main function:
(ns cljnoob.core
    (:require [cljnoob.utils.async :refer :all]))

(defn foo
  "I don't do a whole lot."
  [x]
  (println x "Hello, World!"))

(defn -main
  []
  (let [ch (make-chan)]
      (do
          (start-producing ch)
          (start-consuming ch))))
When I am executing lein run - nothing happens.
~/Projects/cljnoob ⮀ lein run
 ~/Projects/cljnoob ⮀ lein run
Interestingly, if I manually put a message to the channel instead of the start-producing function, I do see a message printed. I am pretty sure somewhere there’s a very simple noob mistake. I just started learning clojure.

masnun16:03:54

Any help would be appreciated.

masnun16:03:04

I just tried through REPL, if I start them on the REPL, it works fine

masnun16:03:00

I think I understand why - my work is being done in go blocks so the main thread is no longer running. That might be the reason why I don’t get any output.

masnun16:03:29

I added a Thread/sleep to the main thread and now it’s working fine. simple_smile

fommil17:03:06

can somebody please let me know why this code (which is my first clojure code) is returning an authentication error?

fommil17:03:38

I've put all four bits of twitter tokens into the config.clj file,

fommil17:03:11

I can confirm that the tokens all work when I use Twitter's OAuth tool, which produces a curl command for me to run.

fommil17:03:21

is this clj-oauth library known to work?

fommil17:03:52

I'm starting to think this library is just broken. I've been told https://github.com/cemerick/friend is the standard, but I can't find any docs on how to use it to do something this simple

thiagofm17:03:58

@fommil No idea, perhaps change the http/get to hit your local machine and check what are the params being sent

niwinz17:03:18

httpbin is a good service for test http requests

fommil17:03:00

this is the end of my exploration of clojure unfortunately, as I can't really build any of the demos I had in mind if authentication and GET/POST doesn't work

apviitanen17:03:40

@swizzard: ok, then it’s most likely a case of missing CA certificates

thiagofm17:03:11

@fommil: perhaps try different alternatives

swizzard17:03:30

@apviitanen: yeah, i figured

swizzard17:03:38

but i’m not sure where my system certs would be

swizzard17:03:00

it doesn’t seem like /Library/Java/JavaVirtualMachines/jdk1.8.0_74.jdk/Contents/Home/jre/lib/security/cacerts is correct

fommil17:03:48

@thiagofm: I can't find anything else. The only other OAuth than I could find is Friend, which has no documentation or examples for OAuth 1.0A and has been dormant for years

thiagofm17:03:50

You could try using oauth by hand, find a model that works and write your own lib

fommil17:03:28

@thiagofm: this is my first attempt to write some clojure, I think what you're suggesting is beyond what I'm capable of at this point.

thiagofm17:03:02

Isn't oauth just a http request? You discover how the protocol works, implement something that builds up some params and send a http request

thiagofm17:03:49

I'm pretty sure you can learn much from it and this seems easier as a first project than relying on other people libs(I still have much difficult in that, clojure doc for most libs suck)

fommil17:03:57

I'm not interested in implementing OAuth in clojure

thiagofm17:03:10

You could learn a bit about clojure interop with java and perhaps use a stable java lib to do it for you instead

thiagofm17:03:19

I'm just trying to help

fommil17:03:03

I've already specced out the demo app I want to write, I'm am not interested in going into rabbit holes like implementing OAuth

thiagofm17:03:23

I have had the same experience as you for like 5 years with clojure, but I always go back and saddened by the fact I wasn't improving much my clojure-fu

fommil17:03:36

I only have one day to do this, and I've basically wasted it. I don't know when I'll get another chance to investigate clojure again.

niwinz17:03:31

Do not worry, the life don't ends here!

niwinz17:03:00

I think you will found an other day for solve that issues!

fommil17:03:03

nope, I have too many obligations in scala open source. I gave myself one day to explore clojure, and it's gone.

lucj0617:03:05

Hi, any idea why my langohr clients does not receive message from my RabbitMQ ? http://pastebin.com/mA8UbAxq ?

thiagofm17:03:49

@fommil: I can usually be 1283928x more productive in a ruby/java/?? because of the tooling, the docs and stuff in general, but if you can go step by step with a problem, take your time and try to do it in clojure, you'll learn a lot

niwinz17:03:03

@fommil: I'm not clearly understand that you pretend constantly saying that you have wasted your time...

niwinz17:03:33

we can try help you with real problems but we can't solve your problems for you

niwinz17:03:22

Please read that @thiagofm says. With a little time and dedication

niwinz17:03:45

you can solve your problems, but if you don't want do that, we can't do anything here

thiagofm17:03:03

@fommil: I don't think you can get a real impression about anything in life in just one day. Instead of writing clojure, I would spend sometime watching some talks of what people are building with clojure and see if it makes sense for what you want to do. If they are working in the same kind of problems you want, you join the community, learn the language and prepare yourself to "lose" a lot of hours debugging.

thiagofm17:03:07

I see things that way

thiagofm17:03:12

I hope it helps you

fommil17:03:13

@thiagofm @niwinz I don't know what either of you are saying here.

fommil18:03:08

basically I read several books on learning clojure, I've got 10+ years of lisp experience, I'm a JVM professional, and I gave myself a day of hacking around with clojure to see what it feels like.

tomjack18:03:13

@fommil: you're passing empty strings as +twitter_access_token+ and +twitter_access_token_secret+ ?

thiagofm18:03:20

@fommil: I'm not asking about your credentials. It's also okay to get frustrated by losing a day with something, but I'm pretty sure that in "10+ years of lisp experience" you've probably had at least one full year of this experience.

thiagofm18:03:23

@fommil: I won't discuss anymore, I hope you feel fine, cheers

fommil18:03:48

@thiagofm: I'm actually completely confused

fommil18:03:03

@tomjack those values are defined in the config.clj

fommil18:03:57

@tomjack: they are being picked up ok because a C-x C-e on the credentials definition or something has content in it

fommil18:03:30

actually, a C-x C-e on the variables themselves shows the content

jethroksy18:03:52

@fommil: did you follow the README on the page?

jethroksy18:03:59

it looks like you didn't get your request token

fommil18:03:12

@jethroksy: yup, and been through all the src and tests

fommil18:03:19

I don't even understand how the tests compile

fommil18:03:36

there is a line where it says ...verifier... which is clearly pseudocode

fommil18:03:16

@jethroksy: well in OAuth there is a mechanism for going from your application keys to get the user to log in and approve the app, which will give you the access token (and secret)

jethroksy18:03:58

afaik this token and secret is different from the access token

fommil18:03:00

but because I am developer and user, I can just get the access tokens directly from ... that bits fine, I don't want to faff around with that bit since I just want to get something working for myself

jethroksy18:03:22

users authenticate with your app based on the token and secret

jethroksy18:03:27

in return you get an access token

jethroksy18:03:45

you then use this access token to call the API

fommil18:03:46

@jethroksy yes, I already have the access token and secret, I'm not using the library to do that bit

fommil18:03:59

@jethroksy: yeah, so that last bit is the bit that's failing

fommil18:03:34

so the call to oauth/credentials is wrong, or that function is broken, or I'm calling http/request incorrectly

jethroksy18:03:49

it looks fine for the most part

jethroksy18:03:59

could you change your get to GET and see if it makes a difference?

jethroksy18:03:06

:get and :GET are different in clojure

fommil18:03:13

used to have :GET actually, but I can change it back

fommil18:03:03

actually in the README he uses http whereas I'm using https

fommil18:03:18

but if I use http, twitter says I have to use SSL so I changed that

jethroksy18:03:51

I would help you debug your issue, but the token and secret are sensitive info

jethroksy18:03:02

sorry you're having a bad time with Clojure

fommil18:03:13

heh, that's life

fommil18:03:32

there are two twitter clients, I've been reading those as well

fommil18:03:35

to get some ideas

fommil18:03:06

I don't want to use them directly because that would defeat the point of writing a OAuth / REST demo

jethroksy18:03:26

my only other suggestion is that you try the step you omitted

jethroksy18:03:29

where you generate the token

jethroksy18:03:45

assuming the library is working this must have been where it went awry

jethroksy18:03:55

could be a consumer/access-token mismatch

fommil18:03:08

I couldn't work out what needed to happen in there. The README basically waves its hands at that point

fommil18:03:48

the thing is that when I use these exact tokens to generate a query for curl using https://dev.twitter.com/oauth/tools/signature-generator/9530038?nid=731 it all works

jethroksy18:03:56

(oauth/access-token) is multi-variadic

jethroksy18:03:05

you can run it in the repl

fommil18:03:33

it may be multi-variadic, but if that verifier is not passed in then you get a 401

jethroksy18:03:48

twitter supports oauth2

jethroksy18:03:54

so if you don't mind you can try buddy

fommil18:03:03

the docs say its all OAuth1.0A

fommil18:03:22

are you sure it works with OAuth2?

jethroksy18:03:58

i'm not versed in this area

fommil18:03:46

interesting

fommil18:03:02

I googled for clojure buddy and it came up with a repo on github with no code in it

fommil18:03:33

what is a "ring" and is that what I'd want?

tomjack18:03:38

@fommil: so the curl query you're doing is using an 'Authorization:' header, right?

jethroksy18:03:41

that's the old one

jethroksy18:03:48

now it's split into individual packages

rauh18:03:05

@fommil: It might be quicker to just try this lib: https://github.com/r0man/oauth-clj

tomjack18:03:20

but in your http/get, you're passing it all as query parameters

jethroksy18:03:57

that one sets up the oauth backend

fommil18:03:32

@rauh: is this a rewrite of clj-oauth ?

jethroksy18:03:32

@tomjack: that's what the docs suggest

fommil18:03:36

@tomjack: I'm passing the full credentials object, yes, as per the README of clj-oauth. Do you spot something wrong there?

tomjack18:03:48

yeah, it doesn't match the working curl query you're doing simple_smile

fommil18:03:57

well isn't that a problem with the clj-oauth library?

tomjack18:03:20

it may be a problem with the README, yeah

fommil18:03:59

the curl command sets a bunch of hashes to headers.

fommil18:03:36

@rauh I'll try this lib you found, it's more recent, it has a better chance of working

fommil18:03:24

I want to stay away from buddy / friend. They are completely incomprehensible to me.

borkdude18:03:08

@fommil: I've used that library once from the twitter-api library. Maybe it's helpful: https://github.com/adamwynne/twitter-api/blob/master/src/twitter/oauth.clj

borkdude18:03:02

@fommil: also it helps to experiment from the REPL. It's the first thing you should learn when doing Clojure, if you haven't realized it already simple_smile

tomjack18:03:00

@fommil: oh. really your problem is that you're not passing screen_name in the actual request

fommil18:03:02

@tomjack yeah I thought about that and added it to the payload (with a :merge), but then I get a different auth error. Is this just twitter having crappy error messages?

fommil18:03:19

@borkdude yeah, I've been using the repl extensively

fommil18:03:25

I'm used to lisp in Emacs

tomjack18:03:48

merge, not :merge, right?

fommil18:03:27

in https://github.com/r0man/oauth-clj the author doesn't seem to be showing the import statements, is there anything obvious missing from that demo?

fommil18:03:32

@tomjack: I think so

tomjack18:03:10

well, works for me

tomjack18:03:17

no, your code doesn't pass screen_name in the actual request. but with that modification, yes

fommil18:03:50

@tomjack ok maybe I had a typo, I'll revert my WIP and try that again

fommil18:03:59

wow, that was it! Thanks @tomjack

fommil18:03:26

I'll push my code before I forget what I did. Now I can write a little macro around this

tomjack18:03:34

don't write a macro

fommil18:03:45

why not? It's perfect for it

tomjack18:03:54

a function will do just fine, no?

fommil18:03:58

an http POST/GET with oauth

fommil18:03:44

so basically the README for the OAuth library is just completely broken

borkdude18:03:11

@fommil: First rule of macro club is don't write a macro when a function (or data structure containing functions, etc) suffices (which is 99% of the time), but for educational purposes it's perfectly fine

tomjack18:03:47

perhaps the "or with clojure-twitter" is what the author tested

borkdude18:03:08

@fommil: One of the reasons is that macros don't compose (i.e., you can't pass the value of a macro)

fommil18:03:33

it would be nice if there was an easier way of going from the app tokens to the user's access tokens, that is a nice feature of https://github.com/r0man/oauth-clj

fommil18:03:56

@borkdude yeah, I know simple_smile I've done elisp for a long time. I'm just keen to try out the language features.

borkdude18:03:58

@fommil: Cool. I see you are also active in the Scala community. I've just started with that, so maybe we can help each other 😛

fommil18:03:10

@borkdude use ENSIME and let me know how it goes simple_smile

fommil18:03:27

we should add a "Learning Scala" page soon, because more people are coming to us first

borkdude18:03:37

@fommil: shall we continue in #C03RZGPG3 about this

fommil18:03:15

I don't know the slack etiquette. But I would have thought for a channel that's been dead most of the day, pretty much anything goes simple_smile

borkdude18:03:09

@fommil: well, some people catch up with the history so too many off topic remarks aren't appreciated I think

borkdude19:03:00

@fommil: I say this only because I've written way too many off topic remarks here in the past 😉

colliderwriter20:03:39

here's something on topic: i have been trying to DRY up some damp parts of my stack, which for these purposes consts of boot, system, component and schema. I'm trying, in short, to add schema sanity checks to my components in a standard way

colliderwriter20:03:32

where 'options' is a function that decomposes the component's schema and returns the keyword names

colliderwriter20:03:43

does this seem reasonable as a standard practice? it's DRY and it works but aesthetically i'm not sold

masnun21:03:28

What would be a good tool to format my clojure code? (Something like go fmt for golang)

borkdude21:03:09

@masnun: I never used it, but saw it on twitter recently. Normally I just use this function in emacs: (defun iwb () "Indent whole buffer." (interactive) (delete-trailing-whitespace) (indent-region (point-min) (point-max) nil) (untabify (point-min) (point-max))) (global-set-key (kbd "s-<f2>") 'iwb)

masnun21:03:52

I am using Atom

borkdude21:03:06

There is probably something similar for atom

borkdude21:03:31

It just indents the whole buffer

borkdude21:03:07

@masnun almost the same function, but then in coffeescript instead of elisp: https://github.com/griiin/atom-auto-indent/blob/master/lib/auto-indent.coffee

masnun21:03:08

nice, thanks, will try them out

borkdude21:03:21

atom is just an emacs rip off 😛

masnun21:03:32

never tried emacs

masnun21:03:34

so no idea

borkdude21:03:22

Atwood's Law: If it can be written in JavaScript (CoffeeScript included), it will be written in JavaScript.

weavejester21:03:07

Incidentally, cljfmt has a clojurescript version, so it can be run under node. Could probably be integrated into Atom without too much difficulty.

masnun21:03:17

Yes, I am familiar with Atwood’s law. ClojureScript included 😄

borkdude21:03:50

@weavejester: cool simple_smile

borkdude21:03:24

whoa... using clojurescript for Atom... it's becoming interesting simple_smile

masnun21:03:45

I read through “Clojure for the Brave and True” last night and I’m loving Clojure so far. I wish the error messages were a bit more easy to understand sometimes.

borkdude21:03:19

someone should make a clojure-clippy plugin (like this https://softwaremill.com/scala-clippy-helping-understand-compiler-errors/ but for clojure)

weavejester21:03:38

masnun: The error messages are sometimes quite cryptic, unfortunately.

masnun21:03:13

I’m hopeful, things will gradually become better

borkdude21:03:50

@masnun: experiment with the REPL in tiny steps

weavejester21:03:07

They’re probably better than they were. I know that last year’s Clojure survey rated them as the top problem in Clojure, so there’s certainly attention there.

weavejester21:03:08

Part of the problem is that in a dynamically typed language, better error messages tend to cost performance.

weavejester21:03:02

I guess it would be nice if more assertions were used, or something else that could be turned off and on.

masnun21:03:16

@borkdude: yes, that’s what I am doing right now, first doing things in the repl and then putting them in the code

borkdude21:03:44

One other problem is that Clojure is a hosted language. That + dynamic means errors will sometimes come from a distant source and in terms of the hosting environment

borkdude21:03:01

for example: ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn

weavejester21:03:48

Yes, and once the error is thrown, it doesn’t retain an exact position in the source code. Just the line number, if I’m not mistaken.

jmayaalv21:03:57

Aviso.Pretty does a great job to help you visualise the stacktrace https://github.com/AvisoNovate/pretty

niwinz22:03:47

Also improves repl exprience and improved stacktraces thanks to the already mentioned AvisoNovate/pretty

masnun22:03:35

interestingly I have ultra in my plugins

masnun22:03:45

how to activate it?

masnun22:03:54

lein repl doesn’t bring in ultra

lmergen22:03:02

one question about core.async, i understand that go blocks are lightweight threads, which is great. i am trying to figure out how to best wrap around, for example, a synchronous database library. would these green threads be the best way to wrap around these calls, or is there a move clever solution hidden in core.async ?

lmergen22:03:19

ideally, i would want my db client api to be asynchronous, but that's not available

lmergen22:03:26

so i'm wondering what the best way to deal with this is

jonahbenton22:03:45

hey @lmergen if your db client library uses blocking IO to communicate with the db server, you're going to need to allocate a thread for each active connection