Clojurians
#clojure
<
2016-05-11
>

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

ag00:05:58

I’m new to Clojure, and asked a few experienced Clojurians if I should use Stuart Sierra’s Component in our projects and received more nays rather than yays. I’m curious why some people don’t like Component?

ag00:05:17

I couldn’t find any detailed explanation of someone’s opinion why Component rather complicate things

donaldball00:05:55

mount and yoyo are alternatives some people seem to prefer; you could review their docs and see how their arguments strike you. Myself, I’m an unabashed fan of the component philosophy.

donaldball00:05:45

Though to be fair, it’s a bundle of machinery that could confuse a beginner.

vinnyataide00:05:04

I'm new to clojure too and I'm fascinated by the philosofy of pure functions that I ask why so many other concepts like protocol, record, multimethod

vinnyataide00:05:28

:disappointed_relieved:

vinnyataide00:05:00

I'm reading through them and dont realize yet the importance, I need some meditation

roberto00:05:33

+1 for component, but if you are starting with clojure, focus on the basics first

roberto00:05:52

the Readme for component has improved a lot since when I first started using it

roberto00:05:27

I also used mount and didn’t like it. In the end, use what you feel comfortable with. To start you don’t need any of those.

leov00:05:24

[ring middleware question] hello all! did anyone experienced problems with enabled wrap-hsts? with it my handler always returns absolutely empty http 200 with HSTS header and no body on any url

leov00:05:45

(side question - can I somehow enable middleware tracing?)

donaldball00:05:32

@vinnyataide: I found clojure intimidating enough at first that I purposefully ignored macros, multimethods, records, and protocols until I was more comfortable

roberto00:05:55

I only needed to write a macro once.

roberto00:05:44

Records and protocols are often misunderstood and sadly reduced to Java interfaces and objects. But they are so much more.

roberto00:05:23

To get an idea, look at how symbols are implemented in clojurescript

vinnyataide00:05:02

thanks @donaldball @roberto for your insights. I will focus on the basics first

seancorfield01:05:32

We’ve just gone through the process of converting over to Component at work (World Singles), and there are many benefits in terms of development workflow but it — and the other, similar, libraries do add a certain amount of complexity.

seancorfield01:05:33

(and I just updated boot-expectations to make it easier to use with Component … I’ll have to blog about this!)

hiredman01:05:32

to pile on, I have not formed a favorable impression of anything besides component in this space

seancorfield01:05:25

We’d held off moving to Component because it seemed an all-or-nothing approach but after chatting to a few folks who are already using it, a piecemeal approach became apparent and we’re happy with that…

hiredman01:05:02

yeah, the amount of flexibility there is not immediately apparent

hiredman01:05:16

for example, at my last job we used component entirely using multimethods and :type tags in maps, no records, deftypes, or protocols

seancorfield01:05:28

….so our subsystem start functions set up our legacy global state now (instead of them just being delays and other weird stuff) and we’re slowly migrating our namespaces to accept a Component instead of (or as well as) just relying on that global state.

seancorfield01:05:17

If we were starting from scratch now? Definitely would use Component from Day One.

lwhorton01:05:07

can you not use reduce inside of recur to do exhaustive searching? something like…

(defn- recursive [start id]
  (loop [node start]
    (if (nil? node) 
      false
      (if (condition node)
        true
        (reduce (fn [found nxt]
                  (and found (recur (get-next node))))
                false (get-next node))))))

lwhorton01:05:26

I keep getting recur argument mismatch errors, not quite sure why.

hiredman01:05:02

if you recur in a function that takes two arguments, you must recur with two arguments

lwhorton01:05:25

woah what? the recur is not tied to the loop?

lwhorton01:05:43

it’s being recur’d inside the reduce in that example?

hiredman01:05:44

recur is tied to the closest recur frame

hiredman01:05:59

which are created via loops and functions

hiredman01:05:18

you definitely cannot recur from one function to another

lwhorton01:05:37

hmm..interesting

hiredman01:05:05

recur is best seen a restricted recursive function call, restricted to calling the current function from tail positions (the way loop works you can pretend it is a macro that expands in to a function that is immediately invoked with the initial bindings)

lwhorton01:05:38

if in the above node had something like {:upstream [foo bar baz …]}, how would you search node, then if not found in node, search across :upstream node? mentally it maps perfectly to a recur

lwhorton01:05:02

but I dont know how else you could do it except some sort of map or reduce across all :upstream

lwhorton01:05:23

or (incorrectly) only searching 1 of the possible upstreams

hiredman01:05:15

hard to say, I don't entirely follow what you are saying about the shape of your data, you may just want a function call, not recur

lwhorton01:05:39

if the dataset is enormous I run the risk of a stack overflow with anything but recur, though, right?

hiredman01:05:56

it doesn't map to recur, at least in the algorithm as written

hiredman01:05:15

you can only call recur from the tail position of a loop or function

hiredman01:05:43

so on at least two counts recur doesn't work the way you think it does and the way you are trying to use it

hiredman01:05:15

if your algorithm is not iterative, and is in fact recursive, recur is not magic

lwhorton01:05:56

hmm.. point taken ill think about this some more

hiredman01:05:22

if you rewrite your algorithm to be iterative, then you can implement it using recur

thug.nasty01:05:49

could anyone with experience with Bouncer please tell me why I continue to get the default generic error message even though I provide a custom one? http://pastebin.com/E71kPuXY

ag04:05:42

can someone help me. sorry for noob question. I need to define a route such that it would redirect and serve a resource from resources/public folder. e.g. when /fonts/modern/foo.woff2 is requested it should be served from /better-fonts/modern/foo.woff2/

ag04:05:50

#compojure

ag04:05:22

so basically for anything that starts with /fonts it need to replace it with /better-fonts

janiczek08:05:22

Does anybody else have problem with lein uberjar? All of a sudden it doesn't want to compile my code:

clojure.lang.Compiler$CompilerException: java.io.FileNotFoundException: resources/see-also.edn (No such file or directory), compiling:(info.clj:143:38)
My project.clj dependencies:
:dependencies [[org.clojure/clojure "1.7.0"]
                 [clj-slack-client "0.1.6-SNAPSHOT"]
                 [org.julienxx/clj-slack "0.5.3"]
                 [enlive "1.1.6"]
                 [schejulure "1.0.1"]
                 [com.novemberain/monger "3.0.2"]
                 [yesql "0.5.2"]
                 [org.postgresql/postgresql "9.4-1201-jdbc41"]
                 [clj-time "0.11.0"]
                 [org.clojure/tools.nrepl "0.2.12"]
                 [cider/cider-nrepl "0.12.0"]]
No mention of see-also.edn in my code. Is some of the dependencies broken?

wagjo08:05:42

@janiczek: it's being discussed in #C0617A8PQ

slipset09:05:51

you see this example:

slipset09:05:59

(def data-file (io/file
                 (io/resource 
                   "hello.txt" )))

slipset09:05:21

given that I package my project as a uberjar, I get an exception:

slipset09:05:33

Exception in thread "main" java.lang.IllegalArgumentException: Not a file: jar:file:/home/erik/stress-0.1.0-SNAPSHOT-standalone.jar!/underscore-1.3.3.min.js

slipset09:05:54

this is due to

slipset09:05:09

which states that the thingy passed has to start with a file: whereas when you read the resources from an uberjar, the thingy starts with jar:file

slipset09:05:15

bug or feature?

plexus09:05:56

feature. A resource is not necessarily a file on the filesystem. The call to io/resource will give you java.net.URL, which you should be able to use directly wherever you need it

plexus09:05:14

e.g. (slurp (io/resource "hello.txt"))

plexus10:05:37

how come EDN doesn't have an IANA media type yet? is it just a matter of no-one caring enough to go through the process, or is there a reason they don't want to go there?

danielcompton10:05:14

@plexus: Rich said he doesn’t know a lot about it, and isn’t sure how it would limit future changes

plexus10:05:27

I see, I suppose having it registered would imply a stable spec, so I guess there's a concern that it would hinder EDN from evolving...

chunsj10:05:36

Anyone help me on how to specify java source code path in boot? That is, in build.boot file.

martinklepsch11:05:45

@chunsj: #C053K90BR is probably the best place to ask

chunsj11:05:33

@martinklepsch: thank you :simple_smile:

triss13:05:10

Hey all, has anyone else had problems jacking in to CIDER today?

darwin13:05:32

it there a way to enable compiler warnings when I use apis from newer clojure version than expected deployed version? say I want to use only stuff up-to Clojure 1.7

darwin13:05:51

I’m working on a clojure library

naomarik13:05:07

@triss i've been having more trouble with that lately than normal, seems a combination of restarting emacs and the nrepl server solves it

triss13:05:50

@naomarik: first time I experienced it today.

triss13:05:29

just found this in the #C0617A8PQ room, it fixed everything: https://clojurians.slack.com/archives/cider/p1462956148001569

naomarik13:05:15

ahh, somehow my own intermittent issue is connecting to nrepl and CIDER saying it's not jacked into anything when I try to eval code.

fasiha15:05:56

I want to write a markdown file and embed some Clojure (maybe ClojureScript) code in fenced code blocks as I'd run it in a REPL, so I'd have (require '[clojure.string :as string]) etc., and I want to include the evaluated output that the REPL prints out right below each code snippet. Before I hack together something to do this, any suggestions? I don't want anything as heavyweight as Hydrox or Marginalia which are more for annotating source code/tests, I want something much more expositionary.

roberto15:05:37

would devcards fit your usecase?

fasiha15:05:26

@roberto thanks for mentioning that. Not ideal because I'd like to be able to use the processed markdown file as a Github README, but also I'd like to use JVM things.

fasiha15:05:39

As much as @bhauman is my hero…

bhauman15:05:00

@faisha yeah not good for your use case

triss15:05:02

how does one write the type of a byte-array in Clojure? (type (byte-array 4)) tells me it's a [B

fasiha15:05:07

@triss Isn't the only type in a byte-array Byte?

ddellacosta15:05:42

@triss you can use (Class/forName "[B”)

triss15:05:49

@fasiha: Um yes. I want a function to behave differently depending on type of argument passed in.

fasiha15:05:27

Doh, sorry @triss I didn't see the type there :cry:

triss15:05:31

thanks @ddellacosta !

pcbalodi15:05:29

Hi guys, we are doing a meetup and want to review some open source project/library, go through its code and learn some good patterns of the language. Any suggestions for a clojure project/library that is also beginner friendly?

borkdude16:05:31

@pcbalodi: a library like environ maybe? it's fairly easy to read https://github.com/weavejester/environ/blob/master/environ/src/environ/core.clj

virmundi16:05:53

My question will involved a complex map. What is the prefered code example site here? I can't get to pastebin

arrdem16:05:20

Slack will let you post a "note", or you can use http://refheap.com

borkdude16:05:47

http://gist.github.com is fine, but https://www.refheap.com/ is built in Clojure, thus cooler :wink:

virmundi16:05:04

unfortunately I'll have to use github. Firewall stops refheap

pcbalodi16:05:10

@borkdude: that looks very good for first time, short and easy, thanks :simple_smile:

agile_geek16:05:04

@virmundi: lucky you. Firewall in my current client blocks Github too!

virmundi16:05:24

thanks for the patience. Here's the gist

virmundi16:05:50

i assume I have to use walk, but I'm not really sure how.

scriptor16:05:52

if I want to extend a record in another namespace, is :import still the idiomatic way to bring that record into the current ns?

virmundi16:05:29

What's tripping me up is the nested vectors

virmundi17:05:22

This is what happens when I ask a question at lunch.

borkdude17:05:37

@virmundi: so you want to remove column 2?

virmundi17:05:22

yea, in reality i need to remove some 100 columns, but that would take too long

virmundi17:05:27

too long to type for an example

virmundi17:05:30

Each map in the list has 115 column/keys

borkdude17:05:53

@virmundi: I tried this in the REPL: (zipmap (keys m) (for [v (vals m), m' v] (update m' :lines (fn [v] (mapv #(dissoc % :column2) v)))))

borkdude17:05:43

@virmundi: probably Specter is a nice use case to update a deeply nested structure

borkdude17:05:56

it is incorrect too, I see now, but maybe you can fix it now you have a start :wink:

virmundi17:05:45

thanks. I'll give it a shop

borkdude17:05:54

(zipmap (keys m) (map (fn [v] (mapv #(update % :lines (fn [v] (mapv (fn [m] (dissoc m :column2)) v))) v)) (vals m)))

borkdude17:05:25

horrible code to read

nathanmarz17:05:06

virmundi: Here's how to do it with Specter: (transform [ALL LAST ALL :lines ALL] #(dissoc % :column2) m)

borkdude17:05:03

@nathansmutz: why LAST?

borkdude17:05:46

ah, the value in the key-value pair?

virmundi18:05:13

@nathanmarz: how do I get to just the jar? It's not showing up in Maven Central. I'm having to work with nothing by java -cp and Notepad.

borkdude18:05:55

@virmundi: use leiningen, much better

virmundi18:05:27

I literally don't have lein, mvn or gradle. What I'm not seeing, and that could be due to me looking like old people run, is the link to the jar itself

didibus18:05:53

Question about evaluation order. I know that functions evaluate inside out, meaning the inner form is evaluated before the outer form. But what about macros? It looks to me like they are expanded from outside in, meaning the outer macro is expanded before the inner macro. Is this correct?

lewix18:05:32

@didibus: I don't think so

val_waeselynck18:05:12

@didibus: yes they are

val_waeselynck18:05:08

@didibus: cf macroexpand

val_waeselynck18:05:37

@didibus: but note that this is not really evaluation

virmundi18:05:15

@nathanmarz: I tried the transform. The columns still exist. Does specter work over a map with a lot of keys at its root?

didibus18:05:23

Ok, cool, good to know. Ya I know it's simple expansion, but it means you can't do: (doto (object) (if (not (nil? object)) (.put "wtv"))) for example. Since the (if) will expand after the (doto)

val_waeselynck18:05:08

@didibus: it's more a matter of compilation vs evaluation than expansion order. (not (nil? object)) is not an information that's available at compile time.

lewix18:05:53

macros receive argument as unevaluated , they transform data into a form clojure can evaluate. If the outer macro is expanded before the inner macro, how does the outer macro evaluate without the evaluation of the inner macro? @val_waeselynck

val_waeselynck18:05:54

you really have to consider that macros manipulate code, not values

lewix18:05:00

I don't think the outer macro is expanded before the inner macro.

borkdude18:05:23

@virmundi: works on my machine

jr18:05:32

user=> `([email protected](println "outside") (defn foo [] [email protected](println "inside")))
outside
inside

val_waeselynck18:05:38

@lewix: it's easy to prove that it is.

jr18:05:52

evaluation order seems outside to inside

val_waeselynck18:05:10

@jr quicker than me :simple_smile:

lewix18:05:23

I stand corrected :simple_smile: thanks

borkdude18:05:20

@virmundi: check out the snippet

virmundi18:05:11

I'm looking. Right now I want to make sure I'm adding the other 110 columns to remove properly into dissoc

lewix18:05:25

@jr your example is not nested

val_waeselynck18:05:48

@lewix: try this

val_waeselynck18:05:54

(defmacro say-hello [& body] (println "hello")) (comment (say-hello "coucou"))

jr18:05:56

((clojure.core/defn user/foo []))

jr18:05:13

how is that not nested?

virmundi18:05:06

@borkdude: you're right. thanks

val_waeselynck18:05:21

@lewix: if macro expansion was outside-in the second for would trigger the println

hiredman19:05:03

the compiler walks down the tree of code analyzing forms, before analysis it calls the macro expander, thus macros are expanded from the outside in

val_waeselynck19:05:21

oh yeah right sorry I meant inside out

hlolli19:05:52

Has someone written any documentation on tagged literals? I'd like to know how to create and manitpulate them. Any pointers appreachiated.

sveri20:05:18

Hey, I am using seesaw to build a gui. I created a swingx/table-x component and want to sort columns that contain doubles. However, table-x seems to sort only alphanumeric, is there a way to pass in a specific sort function? Or maybe tell seesaw that my column contains numbers

sveri20:05:21

Ok, seems like I have to override a method of the tablemodel class to achieve that. Jeez, such a simple thing, yet so hard to achieve

richiardiandrea21:05:50

@sveri it is still Swing after all :smile:

danielsz21:05:26

I published the results of my research around code reloading in Clojure and thought this might be of interest to some of you: http://danielsz.github.io/2016/05/06/Ghosts-in-the-machine