Fork me on GitHub
#clojure
<
2016-04-18
>
jeff-ster00:04:25

An inauspicious start to my emacs trail 😞 - I had to edit the .emacs file and add variables of package archive sites.

jeff-ster00:04:40

trial not trail simple_smile

bvulpes00:04:58

@jeff-ster: that's not inauspicious, that's the first step

jeff-ster00:04:15

now I get " CIDER's version (0.12.0) does not match cider-nrepl's version (nil). Things will break!"

jeff-ster00:04:27

Is that 'inauspicious'?

jeff-ster00:04:51

THIS is what emacs is known for. if you get my drift

jeff-ster00:04:21

Its the first step without telling you how to accomplish it. simple_smile

jeff-ster00:04:37

Anyways I am on my way

bwstearns00:04:37

@jeff-ster: I'm running into the same issue on OS-X lol.

jeff-ster00:04:38

you have to insert this in your project.clj :plugins [[cider/cider-nrepl "x0.12.0"]]

jeff-ster00:04:54

oops... no 'x'

jeff-ster00:04:08

That gets rid of the warning

bwstearns00:04:34

hm. I'll give that a go.

bwstearns00:04:43

I already had it added in ~/.lein/.profiles.clj, figured that should have done it.

bvulpes01:04:44

@jeff-ster: that you think emacs is going to work is the inauspicious thing

bvulpes01:04:10

gotta calibrate your expectations such that when it does work, you're pleasantly surprised

jethroksy01:04:23

@jeff-ster: afaik latest cider injects dependencies for you if you're doing a cider-jack-in

jethroksy01:04:38

anyway the #C099W16KZ channel would suit you

cupello15:04:33

({:number 15, :name "Flowers"},{:number 16, :name "Books"}) Hi, guys! Which is the best way (Clojure way) to add 1000 to each number in this collection? I think that the solution that I have is a bit verbose... (map #(hash-map :number (+ 1000 (:number %)) :name (:name %)))

conormcd15:04:23

(map #(update % :number inc) ...)

bostonaholic15:04:57

@lucelios: (map #(update % :number (partial + 1000)) foo)

bostonaholic16:04:08

note: update was added in 1.7

bostonaholic16:04:22

use update-in if you’re using < 1.7

bostonaholic16:04:41

if you do a lot of nested operations like this, take a look at https://github.com/nathanmarz/specter

lwhorton16:04:47

i’m curious if anyone is familiar with ring/compojure and middlewares — i’m wondering if it’s possible to write a proxy middleware?

lwhorton16:04:12

well, I was digging around in there and the problem I’m having is perhaps conceptual

lwhorton16:04:41

when passing the merged http-opts to clj-http.client/request is that a blocking operation?

john.carnell16:04:45

Hey guys. Just curious everytime I try to hit an https endpoint in my ring clojure application, I see the :ssl-client-cert field as nil even thought I have the ring service setup to handle https. (I can hit the https endpoint, but the client cert is always nil)

lwhorton16:04:03

because it seems to me that there’s some issue with the sync/async nature — if I do a GET, it is successfully proxied, but the response is always 404.. even though logging after the request happens shows the correct proxy result.

lwhorton16:04:23

almost like ring says “oh no immediate response i’m going to use a 404 middleware"

lwhorton16:04:19

disregard that whole thing… I had a misplaced paren that was causing a bad if-let block to return too soon.

john.carnell17:04:06

Does anyone have example of to do an https call using clj-http. I want to pass an actual client certificate and not just the :insecure option

john.carnell17:04:33

Thanks for the pointer

ghadi17:04:04

there's a test that exercises what you want, hope it serves as a good example

bojan.matic18:04:26

what's the consensus on parinfer?

nkraft18:04:05

Personally, I much prefer parinfer.

nkraft18:04:03

I find paredit more than a little overbearing.

dpsutton18:04:13

i'm a big fan of paredit. but i haven't looked too far into parinfer. I also really liked lispy, but haven't used it much recently as sometimes it gets into an invalid state with a mismatched paren

hiredman18:04:47

parinfer is just really new, and anyone who has spent time using paredit has had their brain so thoroughly warped by it that they usually aren't looking for anything else

hiredman18:04:53

there is actually some other emacs mode that is sort of like paredit, which I tried for about a day before my paredit addled mind rejected all the slight differences from paredit as wrong

bojan.matic18:04:18

i’m actually using atom text editor right now, not emacs

nkraft18:04:08

Actually, I had my brain so warped by paredit with Emacs that I was institutionalized in a Vim rehab facility. Gave up on using Emacs for Clojure (and lisp) until parinfer came along.

hiredman18:04:10

non-emacs text editors are where there is a lot of new people picking up clojure, and many of them are javascript based, so parinfer drops in well, and if you are new to clojure you likely are not so accustomed to paredit that you don't want to use anything else

hiredman18:04:50

doesn't cursive default to using parinfer now instead of the port of paredit?

nkraft18:04:54

I started with Emacs and Common Lisp many, many years ago, long before Clojure came along. I got along fine with just parenthesis matching. Then people told me that I just had to start using this new paredit thing, and it was all downhill from there. On the other hand, parentheses were never my biggest issue in writing lisp-y code. I know some people just love it.

amonks18:04:45

I use parinfer in vim and it’s fantastic

bojan.matic18:04:53

funny thing is, i used emacs up until around 2 years ago

bojan.matic18:04:08

but now i’m starting clojure, maybe i should look at emacs again

bojan.matic18:04:42

is emacs still the best when it comes to having a repl built-in?

amonks18:04:40

vim does too, can’t speak to whether emacs’ support is better

hiredman18:04:24

I was using vim up until I got my first clojure job about six years ago, that job wanted everyone with a similar setup for the sake of pairing, and I cannot imagine switching back to vim

bojan.matic18:04:23

there are jobs where you HAVE TO use emacs? 😄

dpsutton18:04:33

i can't imagine using an emacs mode on a lisp that didn't have some notion of structured editing, like slurp

hiredman18:04:24

My point with parinfer is basically, it is a new and interesting looking thing, but you'll find many (but not all) people who have been writing clojure for a long period of time (many using emacs) who are not all that interested, not because of anything problematic with parinfer, but because they have already made their peace with some other bit of tooling

hiredman19:04:58

when I used vim, I would use vim for writing code, but now I use emacs, I use it for so much stuff, I want to say everything even though it isn't really. at one time I had some patches that embedded a webkit view in an emacs buffer (and it sort of kind of worked). org-mode is amazing

amonks19:04:36

a webkit view, that’s incredible

amonks19:04:45

that sounds pretty cool

bojan.matic19:04:00

i think the biggest drawback of emacs is that it’s still centered solely around text

bojan.matic19:04:09

UIs have changed so much

amonks19:04:42

what should it center on?

bojan.matic19:04:46

atom, by being a browser under the hood, and exposing js and css, can house some really powerful plugins that you could never implement in emacs

amonks19:04:14

like what?

bojan.matic19:04:16

its crazy that you need a patch to bundle a half-working webkit view in a buffer

amonks19:04:30

(asking as an occasional atom user looking for Cool Tips)

bojan.matic19:04:56

@amonks: look up activate-power-mode 😄 😂

amonks19:04:28

ok yeah that’s totally nuts

amonks19:04:08

do you have a favorite case where that kind of ui control is used for something more useful?

amonks19:04:30

I can imagine some possibilities

amonks19:04:31

activate-power-mode would be fun for livecoding

bojan.matic19:04:39

rendering your application in a buffer sounds good already, graphical tools for building UIs ala Netbeans for java etc.

bojan.matic19:04:00

custom buttons etc.

bojan.matic19:04:09

there’s a toolbar plugin for atom that i’m using too, it makes using proto-repl easier

Yehonathan Sharvit19:04:01

I need help with writing a macros

Yehonathan Sharvit19:04:40

I have a macro like this:

Yehonathan Sharvit19:04:09

that displays an expression and its evaluation

Yehonathan Sharvit19:04:57

(disp (map inc [1 2 3])) returns (map inc [1 2 3]) => (2 3 4)

hiredman19:04:27

no, the code you pasted isn't valid, it will throw an error when the reader tries to read it

Yehonathan Sharvit19:04:01

I’ve fixed the code of the macro

Yehonathan Sharvit19:04:40

now I want to be able to pass several expressions to my macro and to get the expressions and their evaluations one by one

hiredman19:04:27

the easiest way to do it, is to not use a macro

bojan.matic19:04:28

for me, (disp (map inc [1 2 3])) returns "(map inc [1 2 3]) => [email protected]

hiredman19:04:03

treat the expressions as data by making them quoted forms, and call eval on them when you want to see what they eval too

Yehonathan Sharvit19:04:52

I don’t want to use eval

hiredman19:04:10

eval is exactly what you want

hiredman19:04:49

if you have a collection of forms, you can map eval over them

Yehonathan Sharvit19:04:09

I know but I feel that macro is more elegant in this case

hiredman19:04:16

your feeling is wrong

hiredman19:04:34

because eval exactly meets your requirements, and macros do not

hiredman19:04:36

if you use that macro, and don't treat forms as data, you can't even have a collection of forms

hiredman19:04:15

and even if you could, you couldn't use that macro to do what you want

Yehonathan Sharvit19:04:16

what do u mean by treating form as data?

hiredman19:04:52

when you quote a form, you get the datastructure of the form, instead of the evaluated result

hiredman19:04:18

user=> (for [form ['(map inc (range 10)) '(map dec (range 10))]] [(pr-str form) (pr-str (eval form))])
(["(map inc (range 10))" "(1 2 3 4 5 6 7 8 9 10)"] ["(map dec (range 10))" "(-1 0 1 2 3 4 5 6 7 8)"])
user=> 

bojan.matic19:04:21

you could call it like this (disp ['(map inc [1 2 3]) '(map inc [3 2 1])])

Yehonathan Sharvit19:04:23

I have modified my macro to use print instead of str like this

Yehonathan Sharvit19:04:18

and now it returns the evaluated result instead of the datastructure of the form

Yehonathan Sharvit19:04:38

why print and str don’t behave in a similar way?

hiredman19:04:07

it doesn't do that

hiredman19:04:34

you may think you are seeing it do that, but that is an artifact of something else

hiredman19:04:04

e.g. maybe you have some function in which the macro is called and didn't realod the function after changing the macro

hiredman19:04:39

but that macro definitely doesn't return the evaluated result of anything

Yehonathan Sharvit19:04:06

I’m testing in the REPL

hiredman19:04:59

then the macro you created isn't what you pasted

hiredman19:04:16

(macroexpand '(disp x)) will show you

hiredman19:04:21

yeah, so you said it returns the evaluated result, to me that means it returns the result of evaluating the form (talking about return values of macros is problematic for reasons), what did that mean to you?

hiredman19:04:54

in that repl I see it evaluating to a string of the form and the result of evaluating the form

Yehonathan Sharvit19:04:03

to me, the form is (map inc [1 2 3]) and the evaluation is (2 3 4)

Yehonathan Sharvit19:04:11

which is exactly what I wanted

hiredman19:04:17

yeah, and those are both in that string

Yehonathan Sharvit19:04:33

which is exactly what I wanted

Yehonathan Sharvit19:04:03

but with str I got

hiredman19:04:43

because the .toString on things isn't readable

hiredman19:04:07

if you want readable forms use the pr family of functions

hiredman19:04:21

(pr, prn, pr-str, etc)

Yehonathan Sharvit19:04:58

so again, why my macro -with pr-str - is wrong?

hiredman19:04:57

are you asking because it is doing something you don't want it to do? or are you asking for a general critique of the endeavor?

hiredman19:04:07

try mapping it over a collection of forms

hiredman19:04:24

(you won't be able to map a macro directly)

Yehonathan Sharvit19:04:36

This is what I’m trying to do

Yehonathan Sharvit19:04:45

But with no sucess

hiredman19:04:48

yeah, so don't use a macro

Yehonathan Sharvit19:04:00

The problem with eval

Yehonathan Sharvit19:04:14

is that I want my code to be portable and to run on clojurescript

Yehonathan Sharvit19:04:40

and I don’t want to use self-host cljs for this case

bojan.matic19:04:44

clojurescript is self-hosted now, so it should have no problem eval'ing

hiredman19:04:48

yeah, you want it to run in a text area where people can type forms in to the browser and see the results, right?

hiredman19:04:09

you cannot do that with a macro

hiredman19:04:32

macros only have data available during compilation to work with

hiredman19:04:49

you are talking about taking data from when the program is running

Yehonathan Sharvit19:04:24

not really. I want to handle this kind of cases: (disp (map inc [1 2 3]) (map dec [4 5 6]))

hiredman19:04:58

but you want (map inc 1 2 3) to be something someone can type in to a text area in a webpage, right?

hiredman19:04:26

so where does (map inc [1 2 3]) come from?

Yehonathan Sharvit19:04:00

The whole (disp (map inc [1 2 3]) (map dec [4 5 6])) is going to be typed by the user

hiredman19:04:21

you cannot do that without eval

hiredman19:04:37

that is straight up code to run, eval is what does that

hiredman20:04:18

the definition of eval is basically: given a clojure expression, what is its value

hiredman20:04:00

yeah, klipse uses self hosted cljs to do that

hiredman20:04:54

if you have requirements, where any part is "given a clojure expression, get its value" that is eval

Yehonathan Sharvit20:04:08

I know, I’m one of the authors of klipse

Yehonathan Sharvit20:04:29

But I don’t want to use self-host inside the self-host code of klipse

Yehonathan Sharvit20:04:15

I still cannot understand why I couldn’t be able to evaluate (disp (map inc [1 2 3]) (map dec [4 5 6]))

hiredman20:04:48

as long as the expressions are always compile time constants you can

hiredman20:04:06

but that is basically never the case

hiredman20:04:14

if you want to have a text box a user can type a form in to, and evaluate it, that form isn't known at compile time, so a macro won't know what to do with it

Yehonathan Sharvit20:04:44

I think that in my use case, it works

Yehonathan Sharvit20:04:57

the proof is that with one expression everything works fine

Yehonathan Sharvit20:04:09

I just can’t find the proper way to make it work for several expressions

hiredman20:04:01

;; hiredman ಠ_ಠ
(defmacro disp [& forms] (cons `list (for [form forms] ...))) 

Yehonathan Sharvit20:04:19

I am able to get the form but not its evaluation

Yehonathan Sharvit20:04:04

(disp (map inc [1 2 3]) (map dec [4 5 6])

Yehonathan Sharvit20:04:19

=> ("form => (map inc [1 2 3])" "form => (map dec [4 5 6])”)

darwin20:04:51

yes, that’s how it should work

hiredman20:04:01

you need (list 'quote form) not 'form

hiredman20:04:28

and, again, use the pr family, not str

hiredman20:04:12

looking at the macro expansion should be illuminating

Yehonathan Sharvit20:04:43

Now I get ("(quote (map inc [1 2])) \" => \" (map inc [1 2])”)

Yehonathan Sharvit20:04:56

macroexoand didn’t help

Yehonathan Sharvit20:04:12

I cannot find the way to evaluate an expression inside a macro

hiredman20:04:29

;; hiredman ಠ_ಠ
(defmacro disp [& forms]
   (cons `list (for [form forms]  (str (pr-str (list 'quote form)) " => " (pr-str form)))))

hiredman20:04:07

oh, duh, right

hiredman20:04:16

I should have just used syntax quote like darwin did

telent20:04:36

suppose I am writing a library to implement a protocol which is built on http. Are there good ways to allow my user to choose their own http client library? e.g. they may want to use clj-http or aleph or ...

hiredman20:04:48

(defmacro disp [& forms] (cons `list (for [form forms]  `(str (pr-str '~form) " => " (pr-str ~form)))))

telent20:04:35

;; something like this with the thing-that-does-http passed in on each request
(my-library/query #(http/post ""
               {:content-type %1
                :accept %2
                :body %3})
            "SELECT  ?p ?o WHERE { </foo/2> ?p ?o }")

darwin20:04:43

@telent I would abstract calls into a http library with set of well-defined functions, and provide one default implementation for clj-http or what is your favourite one, this way you allow user to swap them for their own implementation

hiredman20:04:50

I pretty much don't use anything besides clj-http, what are libraries are you trying to support, and how closely do their models of http match?

telent20:04:29

aleph is an awful lot like clj-http (it says) but returns deferred objects that need dereffing

telent20:04:35

so not plug-compatible

darwin20:04:57

actual swapping mechanism is not that important IMO, Clojure protocols would work, multimethods is also an option, or plain map would work as well

hiredman20:04:15

re: disp, generating literal calls to list can result in some oddess http://dev.clojure.org/jira/browse/CLJS-1617

darwin20:04:34

a very dirty solution would be to declare the methods as ^:dynamic and let user swap them in the namespace

telent20:04:44

http-kit says "modelled after clj-http" but again i don't know how closely

hiredman20:04:47

so maybe just provide an async and a sync option built in to the library instead of arbitrary http client plugability

telent20:04:27

of course option (c) is Just Use clj-http because the chance in any production stack of it not being a dependency of something else the client already uses is tending to zero quite rapidy

telent20:04:44

protocols sound like they ought to be the "elegant" answer though

darwin20:04:24

in one of my libraries, I simply keep pluggable methods in a config map, and provide one default imlementation:

joshg21:04:35

If a library extends a protocol to Throwable, and I extend the same protocol to clojure.lang.ExceptionInfo, which implementation will win?

joshg21:04:25

nm, I see that ties are broken by the class hierarchy

tetriscodes21:04:29

Anyone know a solid mqtt broker library?

tetriscodes21:04:41

Most that I find look to be abandoned