Clojurians
#clojure
<
2016-01-06
>

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

datamadic00:01:44

Sorry for butting in. Quick question about the reader and the forward slash in macros (regarding the namespace usage, http://clojure.org/reader, apologies if this has been asked…) Is it the case that because the reader cannot (?) be decorated you cannot pass /whatever to a macro? For example `(defmacro silly-macro [& forms] (str forms))` If anyone has a link, I’d love to read about it more…

datamadic00:01:02

sorry bad snippet…

polymeris00:01:32

Can anyone recommend a CSV parsing library? It needs to be relatively permissive, since many of the files deviate from the standard (and worse, they deviate in different ways).

alexmiller00:01:43

I use data.csv frequently

polymeris00:01:18

Yeah, I found that and clojure-csv (which hasn't been updated in a while, but is not like csv changes much). I'll just try both and hope either one can read the malformed files

alexmiller00:01:53

You could also look for Java csv parsers

polymeris00:01:34

Higher level than the other options and wraps them

meow00:01:43

@datamadic: for pasting in multiline code you can use triple single quotes `

meow00:01:11

Not sure I understand your question or what you are trying to do.

meow00:01:47

forward slash is usually used as an accessor to some namespace: (def foo (some-ns/bar ...))

meow00:01:18

I've never seen it used for anything other than that in clojure code in the wild.

meow00:01:43

@datamadic: and by all means, feel free to butt in with whatever questions you've got - that's what slack is for :simple_smile:

meow01:01:07

I guess I don't understand what you intend /what to represent in your example. It seems to me that it doesn't matter that you are passing it to a macro or just a regular function. Clojure has to figure out how to resolve /what and I'm not sure that's a valid reference, but I could be wrong.

meow01:01:43

And I'm sort of exhausted so maybe I'm just not thinking straight.

datamadic01:01:22

I was just playing around (spit ) ing html to a file

datamadic01:01:59

and dealing with strings makes means i cant auto-format multi-line entries

datamadic01:01:27

i sure this is dumb… but then i happened to notice that /> caused a problem

datamadic01:01:41

at it got me thinking… hey this is a macro, why is clojure trying to eval it

datamadic01:01:52

that lead mo to reading about the reader

datamadic01:01:50

i found it interesting that even to a macro (supposedly un-evaled forms) still get processed a bit. I mean it makes sense, you have to go from text to data struct somehow

datamadic01:01:25

then i was wondering if you can override that behavior at the reader level. All of this is motivated by me wanting to copy and paste a bit of html into clojure (not as a string) and spit it out as a template (I know there are better ways to do this, this is more of a learning exercise for me)

datamadic01:01:44

thanks @meow for the welcome / response

meow01:01:41

no problem - I'm a fan of doing crazy things to test the limits as a way of learning :simple_smile:

meow01:01:26

today's phrase, btw, is moar meta

meow01:01:46

@alexmiller: What's up with the Clojure/West CFP topics?

meow01:01:03

And I quote: Fun - art, games, or other less serious uses

meow01:01:31

Seriously, I take my artsy fartsy use of Clojure very seriously.

meow01:01:40

Actually, I was glad to see that on the list as I was thinking about submitting a proposal for something related to the artsy stuff I've been doing.

meow01:01:06

"How to Get More Fun Out of Functional Programming"

alexmiller01:01:15

That would be welcome :)

meow01:01:08

Even if I'm serious about my programming?

meow01:01:04

I mean, I just added core.matrix to my project dependencies - that's pretty serious stuff there.

meow01:01:36

@alexmiller: I'm going to do it. I think it's time. Been too long since I've been to a tech conference. I'll probably ask for a mentor as well. Why not.

meow01:01:08

email sent

meow01:01:27

fingers crossed

nxqd06:01:05

hi guys, I have an idea that I will walk through datomic schema, then get value type, then generate ui based on that information. But I haven't used walker before, is there any good tutorial about it ?

martinskou09:01:00

Trying to code a CRUD webapp and need to represent the database schema. I have come up with something like this https://gist.github.com/martinskou/a765f29b9e4089a823f2 and could use some feedback or alternatives.

notjonas09:01:15

is there any way to get the port of a running repl?

frank10:01:44

How can I unquote forms in project.clj? I'm trying to use ~(System/getenv "DATABASE_URL") inside of the defproject form in project.clj, but I'm getting this:

Exception in thread "main" java.lang.IllegalStateException: Attempting to call unbound fn: #'clojure.core/unquote, compiling:(/private/var/folders/g2/b9wxt05j1wlg7cs_0hr26ktc0000gn/T/form-init8842813568841950115.clj:1:125)

shanekilkelly10:01:47

That should work. At least it seems to in an old project of mine: https://github.com/ShaneKilkelly/jetcan-server/blob/master/project.clj#L65

shanekilkelly10:01:01

Are you using it in the same way?

frank11:01:40

@shanekilkelly: yeah this is actually also for migratus, but it's not working for me for some reason :disappointed:

shanekilkelly11:01:44

drat, can you show us your project.clj?

frank11:01:23

oh wait, figured it out

frank11:01:17

I was doing something silly like this: (str "//" ~(System/getenv "DATABASE_URL"))

shanekilkelly11:01:32

Ah, so the quoted form needs to be at the top level

tnama13:01:56

@martinskou: how meaning to first char of keyword is uppercase ? https://gist.github.com/martinskou/a765f29b9e4089a823f2

sveri13:01:50

@nxqd hi. I am building some kind of a crud generator here: https://github.com/sveri/closp-crud it is still considered alpha, but if you got some time to look at it, i would love to hear opinions.

spacepluk13:01:31

is there any big picture guide to clojure's source?

spacepluk13:01:08

I mean the compiler and core libraries

bronsa13:01:26

no but if you have any specific questions feel free to ask me

spacepluk13:01:23

thanks, any recommendation to where to start reading the code?

bronsa13:01:46

RT.java is a relatively accessible starting point

bronsa13:01:32

it's where the bootstrapping starts and what causes core.clj to load

bronsa13:01:01

to understand how the special forms work you'll have to read Compiler.java, which unfortunately is not so easy to read/understand

bronsa13:01:37

LispReader.java is the reader. if you'd rather read the clj version of that, try reading tools.reader's source code

spacepluk13:01:06

is the clj version part of the clojure-in-clojure effort?

bronsa14:01:16

there's no official clojure-in-clojure effort, tools.reader is part of a set of contrib libraries that reimplement/rearchitect the infrastructure around the clojure compiler in clojure

bronsa14:01:46

but it's independent from that, it's used by cljs as its reader for example

spacepluk14:01:18

I read this and thought it was somehow in the works http://dev.clojure.org/display/design/Compiler+in+Clojure

spacepluk14:01:56

thanks again, I think that's enough to keep me busy for a while :simple_smile:

jaen15:01:08

I know there are parsers (combinator or otherwise) for strings. Are there parsers for sexps? I remember Cursive's creator talk about implementing something that for Cursive, but a cursory Google can't seem to get me a library that could do it (or I'm blind).

jaen15:01:41

Looks interesting, thanks.

jcomplex15:01:38

Anyone has a link to a good tutorial on EDN?

sdegutis15:01:36

@jcomplex: EDN is just like JSON but using Clojure's syntax and primitive-data-type semantics.

sdegutis15:01:41

The end :simple_smile:

donaldball15:01:07

I’d say rather that edn is just the data structures part of clojure

donaldball15:01:26

Is there something specifically you’re looking for help with, @jcomplex?

sdegutis15:01:08

@donaldball: but its main domain is the same as JSON's: data transportation

jcomplex15:01:19

No I am just getting into that part and wanted to read up on it.

peterbak15:01:36

@jcomplex one of the Datomic training videos has an overview of EDN, if you'd rather listen than read: http://www.datomic.com/part-ii-the-datomic-information-model.html

jstew15:01:49

I'm reading about mount, and it looks pretty awesome. I'm not sure if the author is in here, but the docs are very well done. Congrats.

donmullen16:01:55

@jstew: I believe @tolitius is here.

nha16:01:13

Yes he is, there even is a #C0H7M5HFE channel

jstew16:01:18

Good to know! I'm definitely giving it a try on my next project. My current one has component's tentacles in it.

jaen16:01:08

Component is all nice and good and then until the code starts looking more like Java than Clojure : V

ghadi16:01:11

jaen: another amazing little library is cgrand/seqexp

jaen16:01:21

Bounce seems like an interesting library as well.

tolitius16:01:52

@jstew: thanks :simple_smile: feel free to change/crud it if you find anything

ghadi16:01:07

what is mount?

jaen16:01:36

Less OO-oriented component alternative basically.

jaen16:01:59

@ghadi: couldn't figure out how to do groups with seqex, this one has that described in the readme.

ghadi16:01:07

also look at ericnormand/squarepeg

nha16:01:58

@jaen what is bounce ?

jaen16:01:49

> Less OO-oriented component alternative basically.

jaen16:01:18

Seems like a less monad-y remake of yoyo.

jarohen16:01:33

^ yep, tis

ddellacosta17:01:01

so, I feel stupid asking this, but that generally means it’s a question I should ask: what is so OO about component?

ddellacosta17:01:20

or maybe to slightly reframe it: what is it about component that bothers people such that they qualify it as more "OO-like” than other solutions?

ghadi17:01:22

yeah don't feel stupid

ghadi17:01:45

it seems like a strawman attack to me

ghadi17:01:58

component is too OO not clojurey...

ghadi17:01:10

not really a convincing argument to me

donaldball17:01:21

I don’t find that a good critique either. I tend to find that clojure embraces objects when they’re useful, e.g. when encapsulating state; it just doesn’t hold that every domain entity merit a bespoke class.

donaldball17:01:00

On another front: has anyone run across a good clojure library for rendering graphs of data structures as e.g. a uml diagram?

mnespor18:01:19

Loom might have what you're looking for: https://github.com/aysylu/loom

donaldball18:01:59

Very nice, thanks

andy.fingerhut18:01:03

@donaldball: If by 'rendering' you mean to create images of them, Rhizome may be what you are looking for: https://github.com/ztellman/rhizome

sdroadie18:01:20

Hey all, I have a leiningen question, I guess. If I load a file in the repl, then delete a function from it and reload, the repl still has the function available and returns whatever the latest implementation was. Is this normal?

jarohen18:01:20

@ddellacosta, @ghadi, @donaldball: subjectively speaking, I prefer using values and functions over objects - Component seems to shoehorn people into wrapping everything up into a defrecord

jarohen18:01:35

(granted, that might be the way it's used over the way it was intended)

jarohen18:01:56

@sdroadie: yes - although you can (remove-ns 'your.namespace) before you reload the file to clear it out

jarohen18:01:27

there are tools to do that transitively too (i.e. reloading all of the namespace that depend on the namespace you've just changed) - clojure.tools.namespace, in particular

sdroadie18:01:02

@jarohen Thanks!

jarohen18:01:06

(there are tonnes of blogs etc talking about it)

jarohen18:01:48

@ddellacosta, @ghadi, @donaldball: it then seems a reasonably common (anti-?) pattern that every time a function needs to use a dependency, those functions then get wrapped up in a Component (maybe to take advantage of the DI?), which then propagates up the call stack

jarohen18:01:37

(should say, of course, that this is just based on what I've seen when talking to other people at work/conferences/dojos/down the pub, but to me it seems reasonably common)

jarohen18:01:24

having said that, I do seem to recall someone mentioning in a blog post/conf talk that you should only make a Component to encapsulate either state and/or lifecycle, and hence avoid these 'transitive' components

jaen18:01:39

@ddellacosta, @ghadi, @donaldball - it is a simplification, that's for sure, but I wouldn't call it a strawman. When writing code with component you're basically left with two choices - you either write code inside a defrecord as to close over components you depend on so you can refer to them easily in the function bodies or write functions externally to the defrecord and have to pass a component and destructure it to get at it's contents in each function that depends on it. Both options result in Clojure that can feel awkward - first option makes it look and feel like a parenthesised Java (hence "too OO"), the other is repetitive and verbose.

ddellacosta18:01:44

@jarohen @jaen thanks for the explanations. jaen, I think that’s the clearest explanation I’ve seen yet, thank you

meow19:01:50

@donaldball: We've got a #C0F0V8DT5 channel as well where we talk about, you know, data visualization stuff :simple_smile:

donaldball20:01:28

I guess the approach I’ve tended to take to that problem, @jaen, is to lean heavily on protocols to describe the service(s) provided by the stateful components, coding against those protocols in the business fns, and rely on component to wire up a system of the form I want at the time e.g. for production or repl use, or maybe just reify simple impls for unit tests of those business fns. That has tended to work out pretty well for me, though I reckon it probably does break down for components with really broad responsibilities?

snowell20:01:12

Anybody know how to make lein deps :tree work when a dependency is missing? The whole reason I want to use it is to see what’s bringing in that missing dependency!

jaen20:01:33

Well, broad responsibilities would be a SRP violation anyway, so there's that. And I suppose (defn something [db id] (proto/retrieve db :user id)) can somewhat alleviate the need to destructure. It's just probably me being uneasy with using a lot of polymorphism then.

jr20:01:53

@snowell: lein deps cannot know a dependency unless it is specified in pom.xml. the compilation stacktrace should point to the offending file though right?

snowell20:01:36

@jr It’s not a compilation exception: Just a Could not find artifact error

snowell20:01:59

And if I try to do my lein deps :tree > some_file it only outputs that error instead of a tree AND that error

snowell20:01:18

Well for now I can stick the offender in :exclusions until I determine I actually need it. Dependency hell is always fun /s

djanus21:01:25

Hi all, does anyone else think frequencies would benefit from having a variant with arity 2? The additional argument would be the initial map of frequencies, defaulting to {}

ghadi21:01:17

not that necessarily, but taking a transducer arg, yes.

ghadi21:01:00

(You can always merge-with + an initial map of frequencies)

timvisher21:01:11

are there any mature and feature-rich migrations frameworks on the JVM that would compete with rails migrations?

meow21:01:10

@djanus: I've recently felt that frequencies was very specific and wonder if it couldn't be generalized.

meow21:01:14

I wrote a function that got me thinking on this. Let me grab it.

meow21:01:01

(defn hashmap-set
  [keyvals]
  (persistent!
    (reduce
      (fn [ret [k v]]
        (assoc! ret k (conj (get ret k #{}) v)))
      (transient {}) keyvals)))

meow21:01:42

Not crazy about the name and maybe someone has better code for this but I just need a map with sets as the values.

meow21:01:12

Also wrote this:

(defn zipmapf [f coll]
  (zipmap coll (map f coll)))

meow21:01:11

Both solve very general problems in a way that didn't exist in clojure core, yet clojure core has frequencies which is such a specific use case. Not trying to start a "why isn't this in core" argument, just wondering if there are some patterns that could be explored and exploited.

meow21:01:53

@ghadi: I see your suggestion of a transducer option playing into this as well.

meow21:01:03

I've come to rely on into as my go-to swiss-army-knife of data transformations, in part because of the transducer variation when needed.

meow21:01:54

I'm sure others have written very similar functions as the ones I posted here. I just think it would be nice to have something concise but open-ended enough to feel as comfortable and handy as into, my poster child example.

ghadi21:01:51

i have to agree, into is emblematic of power+simplicity in the language

meow21:01:28

Once I got used to into it has come in so handy my code is full of example uses of it. And I recently converted a bunch of code someone else had written and I replaced every single loop/recur with either into or into with some for comprehensions. And at least for me the code is so much smaller and easier to understand.

meow21:01:15

I really hesitate to write these little helper functions, like hashmap-set and zipmapf because I know that for anyone else reading the code they won't have anywhere near the initial understanding of what these functions do compared to a function from clojure core.

danstone22:01:12

@meow: I wonder if instead of hashmap-set if you could write a transducable group-by fn like

(defn group-by-into 
    ([to f from])
    ([to f xform from]))
So in your example you would implement hashmap-set like (group-by-into #{} key (map val) keyvals) Not sure if better!

danstone22:01:23

Probably a bad idea :simple_smile:

jaen22:01:19

> Both solve very general problems in a way that didn't exist in clojure core I must say I never understood why there's no zip and you have to do (map vector ...).

akiva22:01:10

What about mapv?

jaen22:01:44

Well, all it would do is to change the result from seq to a vector, wouldn't it?

jaen22:01:02

I kinda understand it - there's less incentive to write zip if you have vararg sequence functions

jaen22:01:42

But sometimes I wanted to use zip with for for example (where specifying two sequences would result in Cartesian product and not side-by-side iteration).

ghadi22:01:40

jaen: there's no zip exactly because you can do (map vector ...)

meow22:01:23

@danstone: sorry, off in other conversations at the moment - um, maybe

meow22:01:00

I guess I'd have to see an actual example of your alternative compared to mine

ghadi22:01:24

look at cgrands bonus transducers

ghadi22:01:46

pkobrien ^

meow22:01:09

you know, I looked at those a while back but haven't done so recently - will do - definitely good stuff there

meow22:01:29

@ghadi: thanks for the reminder :simple_smile:

danstone22:01:31

I am 99.9% sure its a bad idea and should be forgotten about (its not something I've used, I just looked at your fn and your comments about into). However, the key take away is perhaps it'd be nice to have better tools for pouring collections into associative structures if you want to be able to say, group into sets.

danstone22:01:33

^ looks like cgrands xforms has already done all of this

meow22:01:40

Yeah, I'm definitely going to take a real close look at cgrands stuff because he is hella smart and because I think I see a variety of transducers that relate to stuff I might need in my current project.

jaen22:01:48

@ghadi: yes, I know, but that's just verbose.

ghadi22:01:15

if you say so ¯\(ツ)

ghadi22:01:29

there aren't a lot of helpers in clojure that really encourage making positional things easy -- rather to favor associative, yada yada

jaen22:01:48

And maybe more importantly - it's cryptic at first. I used to have to google each time I wanted to zip for quite a while.

ghadi22:01:58

^^^^^^^ that

jaen22:01:59

But I guess I can agree that Clojure favours associative structures. Maybe I just want tuples more often than it's healthy in Clojure, I suppose.