Fork me on GitHub
#clojure
<
2016-05-29
>
fasiha00:05:08

Thanks @nathanmarz, very cool!

fasiha00:05:50

A question: I don't know how much I need to know before I understand why this doesn't work: (let [x 1] (eval (clojure.edn/read-string "(+ 1 x)"))). I have a string containing some clojure expression, "(+ 1 x)" here, and I want to evaluate it with specific bindings (that let). But I get RuntimeException: Unable to resolve symbol: x in this context

fasiha00:05:17

Tho, I see that this works:

(eval `(let ~'[x 1] ~(clojure.edn/read-string "(+ 1 x)")))
; also equivalent to:
(let [bindings '[x 1]] (eval `(let ~bindings ~(clojure.edn/read-string "(+ 1 x)"))))

bwstearns05:05:48

(clojure.edn/read-string "(+ 1 x)") gets you a classnotfountexception

lambeta05:05:27

Hi hivemind, I’m writing clojure tests in emacs with cider. When I remove some useless tests, saved and recompiled the test source code with C-C, C-K, I found the removed tests are still executed. Cloud you all tell me how to remove those tests completely?

seancorfield05:05:40

@lambeta: You'll have to use ns-unmap in the REPL to remove the old tests.

seancorfield05:05:20

You might want to take a look at Stuart's Sierra's "Clojure Reloaded" workflow and his Component library.

seancorfield05:05:09

@bwstearns: Don't forget to (require 'clojure.edn) first...

fasiha06:05:36

I really like that (read-string "(+ 1 2) (- 3 2)") returns (+ 1 2). But is there any way to see how many characters of the input string read-string consumed? My goal is to start out with a string like "(+ 1 2) GaRbAgE", read off the first proper Clojure expression, and then have the remaining garbage left in the string.

fasiha06:05:14

I don't really want to try and put the output of read-string back thru pr-str and try to guess how many characters in the input string were consumed…

pbaille06:05:13

Hi, How can I overide ‘seq implementation for a custom type?

seancorfield06:05:27

@fasiha: Sounds like you want read on a PushbackReader and make one of those from a StringReader?

seancorfield06:05:21

(i.e., turn the string into a StringReader then a PushbackReader and then use read which will leave the rest of the string in the reader for you to do whatever you need with)

robert-stuttaford12:05:50

how would i use core.spec to specify that either non or all of an additional, optional set of keys are present in a keyseq?

robert-stuttaford12:05:01

base-spec + all or none of other-spec

robert-stuttaford12:05:14

(s/and base other) works if other only uses :opt-un

lambeta13:05:02

Hi all, I read the doc of leiningen profiles, what does it mean when it says >If you mark a profile with ^{:pom-scope :test} metadata, then the profile's :dependencies will be added with a test scope in the generated pom and jar when active. like this? `

lambeta13:05:21

:repl {:plugins [[lein-midje "3.1.3"]
                  [lein-try "0.4.3"]
                  [lein-midje-doc "0.0.22"]]
        :dependencies [
                       ^{:pom-scope :test} [refactor-nrepl "2.2.0"] 
                       ]}}

lambeta13:05:17

where to mark this metadata?

lambeta14:05:27

hmm… after reading it's source code. I found I should add metadata like this :repl ^{:pom-scope :test} and then the private method apply-profile-meta [default-meta profile] will merge default metadata and what I added. After that, it will change every dependency like (-> dep (conj :scope) (conj (name scope))).

Alex Miller (Clojure team)17:05:06

@robert-stuttaford: :req takes and / or conditionals too for key sets - it's not in the guide but the docstring covers it

Alex Miller (Clojure team)17:05:46

For cases where there is a "tag" key, multi-spec is probably better

robert-stuttaford18:05:35

@alexmiller -gasp- that's fantastic! so something like (s/keys :req (s/or [::a ::b] [::c ::d])) ?

robert-stuttaford18:05:11

reading the docstr now

Alex Miller (Clojure team)18:05:19

Remember - maps have set semantics

robert-stuttaford18:05:27

ah, the docstr has it differently: (s/keys :req [::x ::y (or ::secret (and ::user ::pwd))] :opt [::z]) i'll try both out, thanks!

Alex Miller (Clojure team)18:05:50

Yeah sorry didn't read yours closely

hagmonk20:05:17

is anyone here familiar enough with tesser to answer a question? 🙂

jorgedfbranco21:05:42

(for [x '(1 2 3 4)] println)

jorgedfbranco21:05:54

is there some way of achieving something like this, without having to use the "x" variable?

jorgedfbranco21:05:36

I mean, what I'm looking after is to have something equivalent to (for [x '(1 2 3 4)] (println x)) but without having to refer explicitly to the x variable in the body of the for

hagmonk22:05:29

do you actually want a lazy sequence, is that why you're using for?

hagmonk22:05:30

if you want to apply a function over a collection, you'd be after (map println '(1 2 3 4))

fasiha22:05:45

@seancorfield: ooooo, this is Clojure magick I had no idea existed—is this a protocol thing? I will try to figure out how those work!

risto22:05:55

why is are there so many nuanced versions of things in clojure?

risto22:05:04

for example, why is there definterface and defprotocol? and why is there deftype, defrecord, and reify? couldn't they have just chosen one of each and let the community write their own flavor since it's homoiconic?

risto22:05:38

I feel like the slight differences aren't enough to justify the extra work newcomers have to take to learn the language completely

risto22:05:34

which reduces adoption

maxov22:05:51

@risto generally speaking newcomers won’t have to use definterface

maxov22:05:57

I think that the nuanced versions, at least in that particular case, have to do with some of the inherent ugliness of java interop

risto22:05:48

@maxov All of these have propped up in libraries I've been looking at using, so I have to know them. Can you elaborate on how they have to do with java interop?

risto22:05:46

I'm concerned that a lot of this stuff is just the general feature creep garbage that happens in every language/library/business that eventually sinks it

maxov22:05:21

I don’t think they are feature creep, they all have stayed in the language for a while. I can’t say when they were added, but they were added before I started

maxov22:05:22

definterface generates Java interfaces for interop, while defprotocol is more like multimethods that delegate based on type

hagmonk22:05:39

None of this is feature creep, the rationale given on that page is pretty detailed

maxov23:05:09

yeah, that’s a great page for explaining it

hagmonk23:05:38

As for the effect this has on newcomers, personally I would refer to Rich's Simple vs Easy talk … it's not that Clojure aims to be hostile to newcomers, but it definitely doesn't aim to be "easy" in the way a newcomer would appreciate

risto23:05:18

I've read that page before and I wasn't entirely convinced

risto23:05:41

My general thinking when I read it went like this:

risto23:05:39

"It ends up that classes in most OO programs fall into two distinct categories: those classes that are artifacts of the implementation/programming domain, e.g. String or collection classes, or Clojure’s reference types; and classes that represent application domain information, e.g. Employee, PurchaseOrder etc. " -- Ok, so why not just have one datatype, and keep application domain information in a simple map

risto23:05:15

"This is why Clojure has always encouraged putting such information in maps, and that advice doesn’t change with datatypes." -- Ok... so why did you introduce a datatype? was not defprotocol and multimethods enough? I'm not getting this

risto23:05:13

"While deftype and defrecord define named types, reify defines both an anonymous type and creates an instance of that type" -- What problem does this solve? was it worth inventing new syntax to solve this problem? in other words, is the problem so common in programming that we should include reify as part of the core language rather than a popular library?

risto23:05:27

"The use case is where you need a one-off implementation of one or more protocols or interfaces and would like to take advantage of the local context. In this respect it is use case similar to proxy, or anonymous inner classes in Java." -- So why not just have one of them rather than both reify and proxy? whichever is the most flexible should win

risto23:05:18

And definterface vs defprotocol... from my understanding you can still write java interfaces with defprotocol, is that right? so what have definterface. And even if you couldn't, it seems like it's not a stretch to make it work with Java

risto23:05:29

it sure has the same naming structure

risto23:05:37

Also to comment on Simple vs Easy. I watched that talk a month or two ago. I'm all for making programming substantially simpler by learning powerful constructs, having learned Haskell and other functional languages. But none of them really tack on all this stuff like clojure does

maxov23:05:54

I prefer using simple maps where I can, and use protocols + records where I need some level of abstraction or polymorphism

maxov23:05:41

defprotocol generates java interfaces, but they ostensibly look very “weird” in java-land, as their methods take the thing they’re acting on as the first argument

maxov23:05:09

I also find that when I’m dealing with datatypes that are often composed with each other a lot, say I’m implementing my own Number class as a contrived example, that reify is handy to define implementation

risto23:05:31

so? from my understanding the point of clojure interop with java is to leverage the large body of libraries available in Java, not to write Java code with clojure

maxov23:05:57

well the point is to go both ways

risto23:05:17

it's adding an unnecessary learning curve to make a very uncommon use case less "weird"

maxov23:05:39

I agree it’s uncommon, which is why it is almost never used. You came across a library that did need to use it

risto23:05:01

Right, so the point is why is definterface even part of the core language?

risto23:05:27

For a newcomer, that's an extra amount of effort to learn something they'll never use, and would have to instead figure out the nuances between that and defprotocol

maxov23:05:15

I can’t think of any clear way to implement definterface without it being part of the core language

risto23:05:47

It's not "hard" in any sense, it's just headache-inducing minutia. "Hard" is something like learning hindley-milner type inference or category theory, which can produce structurally nice code once you've learned it, although it's not really hard once you realize what it actually is, just foreign to most programmers.

risto23:05:04

You wouldn't include it, that's all

risto23:05:21

Maybe I'm wrong, but I don't see deftype and defprotocol as necessary either, because I feel like you can solve the same set of problems with just simple maps, defprotocol and multimethods.

risto23:05:26

If you have to preface your language construct as "x is just like y but (here's a list of a few nuanced differences:)", then that raises a red flag for me

risto23:05:55

It also seems like some of this stuff boils down to performance issues. But really I feel like the cleaner way to deal with that kind of thing is to just introduce pragmatic directives that you can include as a declaration in your code, not unlike how every other language deals with those kind of optimizations...