Fork me on GitHub
#clojure
<
2016-06-11
>
andmed07:06:59

hi. it it possible to have this function: (defn my-or [x y] (or x y)) but with varargs? because of the macro i cant think of the way to do it..

andmed07:06:35

And what is the reason of not having built-in boolean operators, short-circuited? in Clojure?

hiredman07:06:29

not sure what you mean, or and and both short circuit

andmed07:06:49

as macros, yes

andmed07:06:58

thats back to question one

hiredman07:06:31

you can't have functions that short circuit in an eager language

hiredman07:06:16

in a strict language, all arguments are evaluated before invoking a function

andmed07:06:06

so, there is no way to implement a pseudo-boolean operator which takes variable args?

hiredman07:06:15

you can implement it, but the arguments you pass to it will be evaluated before the function is invoked

hiredman07:06:36

clojure is a strict language

hiredman07:06:58

there are some constructs you can use to delay evaluation, but you have to explicitly use those

hiredman07:06:22

you can wrap your computations in delay, or use lazy-seqs

andmed07:06:24

I was thinking about recursive function, may be, anyway the point is that macros cant be made work with varargs, thus I must not rely on or implementations altogether?

hiredman07:06:49

(defn or' [& args] (reduce #(or %1 %2) args))

hiredman07:06:16

which doesn't short circuit, depending on what you mean by "short circuit", if you mean "stop checking when it hits some condition", you can add that using reduced or implement it using loop

hiredman08:06:07

but if you also mean "and don't evaluate the rest of the things to be checked" as part of "short circuit" then you cannot, because the arguments in args were evaluated before the function was invoked

andmed08:06:48

@hiredman: great, thanks! yes, this ubiquitous reduce..

luxbock08:06:50

I remember coming by a REPL utility library that gives you a summary or a description of a large data-structure that you'd otherwise not want to print to inspect because of its size, but I can't recall what it was called and Google is failing me

luxbock08:06:08

would anyone know which one I'm talking about?

luxbock08:06:48

it basically saves you the trouble of doing repeative (-> x :foo :bar keys) or (-> x :foo count) calls

luxbock08:06:04

actually Cider's inspecting functionality works prety well for that

jrychter12:06:53

Hmm. I was hoping that the new clojure.spec conform will help me with data conversions, but it doesn't always. Specifically:

(s/def ::item integer?)
(s/def ::itemset (s/coll-of ::item #{}))
(s/conform ::itemset [1 2 3]) => this gives [1 2 3] instead of #{1 2 3}

jrychter12:06:50

I expected that the initial collection to s/coll-of will be used to "re-pour" the items using into.

jwm13:06:06

you guys like clojure.spec?

jwm13:06:25

seems to me to just be red tape heh

plexus14:06:55

@jrychter: AFAIK that last argument is only used as a "seed" when using specs as generators

plexus14:06:14

but you could use a custom conformer

plexus14:06:45

(untested)

plexus14:06:49

(s/def ::itemset (s/and (s/coll-of ::item #{})
                        (s/conformer (partial into #{}))))

jrychter14:06:59

@plexus: At the moment I'm here trying to check if my expectations are completely out of whack — it often turns out that I'm misunderstanding something horribly 🙂

jrychter14:06:01

@plexus: and that code snippet does what you said it would (tested).

plexus14:06:30

it is counterintuitive that (s/coll-of ::foo #{}) doesn't check the collection type IMO, but I guess that's how it is

jrychter14:06:53

Then I wonder if it's intentional. I'm conforming output from a database (RethinkDB, although this will likely apply to any db) and turning vectors into sets when conforming is intuitive and very, very useful.

jrychter14:06:35

I guess I could just define this for general use:

(defn set-of [spec]
  (s/and (s/coll-of spec #{})
         (s/conformer (partial into #{}))))

plexus14:06:04

yeah that should work

jrychter14:06:36

It's just that then I have to find a place to keep this, and include it everywhere I need it.

drewverlee18:06:36

i’m curious if anyone is up discussing the first complaint in (http://ashtonkemerling.com/blog/2016/06/11/my-increasing-frustration-with-clojure/) namely.. > And the namespace is completely riddled with bugs. union returns duplicates if some of the inputs are lists instead of sets depending on their length. Which i assume refers to this (i was also expecting an error):

try-spec.core=> (clojure.set/union [1,2] [1,2]) [1 2 1 2] 
The author argues... > for the above bugs there are two possible fixes: raise an IllegalArgumentException if anything other than sets are provided Isn't this an argument for types? Wont this type of problem be a problem in any dynamic language? What is the union of anything besides sets?

donaldball18:06:38

The whole post seems to boil down to, “I don’t like the way clojure core fns operate when called with invalid arguments”. I actually tend to agree with that, but the broader thrust of the post isn’t particularly convincing.

plexus19:06:00

I would say it's the other way around, he's using that merely as an example, and you can argue with that example, but the attitude he describes is very real

plexus19:06:50

I come from the Ruby world, where it's very much "humans first". We like Humane Interfaces (http://martinfowler.com/bliki/HumaneInterface.html), we try our best to be nice to people (MINASWAN). Being friendly is seen as very important, on bug trackers and mailing lists, when writing documentation, and when writing libraries and interfaces that people will have to consume

plexus19:06:17

In comparison I find things on the Clojure side much more curt, much more "you're on your own, do your homework", much more "won't fix don't ask"

plexus19:06:54

This is in relative terms, there are excellent counterexamples, lots of great people, friendly projects, etc, but the difference is noticeable, and it will hurt mainstream adoption

drewverlee19:06:36

I’m asking specifically about his objection to clojure.set/union. Discussing the merits of various communities is to big of a pie for me to digest 🙂

plexus19:06:48

as far as I understand all of the bundled clojure libs will get specs, so in this case, at least in development, the spec would make sure you only pass in sets. Maybe people have been reluctant in the past to add hard coded type checks because something like spec was part of a long term plan, that's speculation though

jballanc19:06:27

I was actually wondering the same thing...it can be very hard to read the Clojure core team's attitude sometimes because they aren't, as a rule, very open with their thinking and motivation.

jballanc19:06:20

And that's a double-edged sword: on one hand, rejecting outside opinions may be necessary to realize a long-term vision (Rich's in the case of Clojure)...

jballanc19:06:32

...but on the other hand, the community runs the risk of stumbling blindly down the completely wrong path, with no one capable of providing a "guiding voice" to pull us back.

bbloom20:06:56

@drewverlee: I explain that set/union makes perfect sense as is here: https://news.ycombinator.com/item?id=11884609

bbloom20:06:55

I know I don’t need to tell @richhickey, @alexmiller, et al this, as they certainly already know it, but anyway: Ignore the haters. Keep on doing awesome work! Thank you 🙂

plexus20:06:39

> Clojure is a language for people who know what they are doing by people who know what they are doing.

plexus20:06:11

^ and another person reading HN decides their time is better spent learning Go/Rust/Elm/...

ghadi20:06:43

Brian Goetz (chief architect of java) his keynote for the Conj a couple years ago is pretty much required reading before saying "Clojure should do/fix X"

plexus20:06:13

> Understand that if enough people have the same issue, it’s the codes fault and a FAQ entry is not good enough.

plexus20:06:33

could not agree more with the original post on this

bbloom20:06:59

shrug I couldn’t agree more with the stance of the clojure core team. Good thing there’s so many languages to choose from

lewix20:06:05

where can i find more info about cqrs and clojure

lewix20:06:56

How does expressing one's opinion make him a hater

jballanc20:06:34

bbloom: How is this code by people "who know what they are doing": `

jballanc20:06:37

boot.user=> (clojure.set/union '(1 2) '(2 3))

bbloom20:06:04

=> (doc clojure.set/union)
-------------------------
clojure.set/union
([] [s1] [s1 s2] [s1 s2 & sets])
  Return a set that is the union of the input sets
nil

bbloom20:06:14

i don’t think the docs could be any more clear there

jballanc20:06:26

"Return a set"

bbloom20:06:32

"input sets"

bbloom20:06:39

garbage in, garbage out

bbloom20:06:34

If you’re giving lists to clojure set, you either 1) don’t realize you’re doing that or 2) don’t understand why that is wrong

bbloom20:06:42

in cases of #1, spec may help

jballanc20:06:54

bbloom: but I wonder, would you also defend if nth didn't check bounds?

ghadi20:06:59

spec will help more than people realize. it's so early, give it a few months.

bbloom20:06:38

jballanc: nth doesn’t check bounds

bbloom20:06:47

=> (nth nil 5) nil

jballanc20:06:16

boot.user=> (nth '(1 2 3) 4)

jballanc20:06:18

java.lang.IndexOutOfBoundsException:

ghadi20:06:18

There are certainly warts in clojure. I just have an instinctual reaction when I hear the would "should" or "should just" - or please fix for "symmetry's sake"

ghadi20:06:36

As in "Clojure should just do X"

bbloom20:06:50

@jballanc: nth on some types happen to check bounds, but that’s not a promise

bbloom20:06:10

it might be

bbloom20:06:14

=> (doc nth) ------------------------- cljs.core/nth ([coll n] [coll n not-found]) Returns the value at the index. get returns nil if index out of bounds, nth throws an exception unless not-found is supplied. nth also works for strings, arrays, regex Matchers and Lists, and, in O(n) time, for sequences.

bbloom20:06:21

anyway, i wouldn’t care if nth didn’t check bounds

jballanc20:06:54

but then why are you using Clojure instead of C?

ghadi20:06:56

this community by 2016 is well aware of advice like considering the problem fully before the solutions

jballanc20:06:06

(yes yes, that's a straw man, I know...)

bbloom20:06:12

i’m not even going to respond to that

bbloom20:06:21

i will however say that I use terra instead of rust

bbloom20:06:25

and believe me, i’ve tried to use rust 😛

ghadi20:06:58

some problems don't have satisfactory solutions, and saying just "fix" clojure.set is like saying "just break people's code"

jballanc20:06:13

Honestly, I'm sympathetic to Rich and crew, but I also think that Ashton makes a really good point about them not following their own advice

bbloom20:06:24

what advice aren’t they following?

jballanc20:06:57

Yes, core.spec will cure many ills, but if things like union were implemented as protocol methods then this wouldn't even be an issue

zentrope20:06:11

Wasn’t clojure.set implemented before protocols was a language feature?

bbloom20:06:16

making that change would make everybody’s use of sets slower across the board. the core team has said over and over again that they rather not change things without a very strong justification. so you can say woulda coulda shoulda all that you want - but they value stability over error checking

bbloom20:06:46

if you don’t like that tradeoff, feel free to maintain your own clojure implementation

drewverlee20:06:59

> union were implemented as protocol methods then this wouldn't even be an issue this is interesting! what would this have changed?

bbloom20:06:31

i assume his argument is that you’d get a “blah does not implement ISet error"

bbloom20:06:40

but that wouldn’t solve the problem for the 1 arity case

bbloom20:06:59

you’d still have some garbage in/out cases

bbloom20:06:17

user=> (clojure.set/union :definitely-not-a-set) :definitely-not-a-set

jballanc20:06:43

bbloom: I'm not asking Clojure to hold my hand a la Java

bbloom20:06:52

i didn’t say you were

jballanc20:06:01

but there are solutions in the language already that would clean up some of these issues

lewix20:06:09

suck rock dichotomy

bbloom20:06:31

i’m just particularly annoyed about the reoccurring complaints about garbage in/out and the core team’s stance on this issue - the team listened and has designed a solution: spec. Complaining about it after spec has been announced and then writing spec off as a non-solution before giving it a chance is just entitled behavior

jballanc20:06:22

I've heard (repeatedly) the whole "not making a change without good justification" line and also "don't want to screw up other peoples code/performance", but I do think there is a line between being conservative and being...lazy? (for lack of a better term)

jballanc20:06:05

bbloom: spec is a specific solution to some specific problems, but there is the issue of core team's extreme reluctance to revisit any existing code

dnolen20:06:06

I think people should be considerably more respectful how much time gets put into Clojure

bbloom20:06:07

lol @ lazy - these guys are anything but lazy

drewverlee20:06:22

@bbloom sorry. Im a tad of a newbie. You refer to garbage in/out like it refers to a particular thing. When i google that with clojure attached i get.. your comments 🙂

bbloom20:06:41

the lazy thing to do would be to cave to the demands of people crying about stuff that just doesn’t matter to people who use clojure every day

jballanc20:06:46

"lazy" is the wrong word...maybe "blase" is more like it

bbloom20:06:59

how could they not be jaded?

bbloom20:06:09

they deal with it in a loop

dnolen20:06:15

none of these words reflect the process

ghadi20:06:20

changes have costs, implications broader than some one who posts a drive-by hot take. languages have to pay a lot more attention to cost than libraries.

bbloom20:06:27

it sucks that people try to contribute and their one interaction is bad - but they have thousands of interactions & only so much time to have them

lewix20:06:40

you guys rationalize the decisions that have already been made emotionally

ghadi20:06:53

don't know what you're talking about lewix

jballanc20:06:30

dnolen: oh I know, I've seen it in action...I just think in the balance between hammock time and itteration, sometimes core errs a bit on the side of hammocks

lewix20:06:35

I'm talking about the way you argue

bbloom20:06:10

i’m not a core team member - i’m a third party

jballanc20:06:21

(I guess I should clarify that I meant "lazy" as in "3 virtues of a good coder" lazy)

dnolen20:06:28

the sky is not falling - it’s exhausting to listen to critiques that use this kind of rhetoric

hans20:06:02

and who does it help, except the OP who lets off steam?

jballanc20:06:34

dnolen: I don't mean any disrespect, but I do think that critiques of the process should be as much part of language development as critiques of the code

dnolen20:06:19

people are critiquing a process that has worked for 9 years

dnolen20:06:28

it is what it is

bbloom20:06:56

my problem is that it’s a shitty critique 😛

ghadi20:06:11

(also not core team)

bbloom20:06:17

there’s a genuinely good discussion to have about how to lead a community

bbloom20:06:29

calling dnolen “shabby” is not a way to go about it

bbloom20:06:32

among other things

dnolen20:06:48

it’s incredibly obnoxious

dnolen20:06:56

definitely an enthusiasm killer

jballanc20:06:12

that I can agree with...some of the language was definitely over the top

bbloom20:06:13

“i want the core team to do shit my way, so i’m going to call them names and expect them to fall in line"

hans20:06:18

@dnolen: remember, it is a random internet comment 🙂

dnolen20:06:08

@jballanc: that was my problem with the post I think people can air their concerns about the process without loading the language

jballanc20:06:54

@dnolen: the internet (and probably the world in general) would be such a nicer place if people just read everything they wrote twice before hitting "send/post"

ghadi20:06:56

i'm not offended by the word fuck, and don't mind when it's applied, but it doesn't bulk up a weak case. Probably felt good to type

donaldball20:06:43

It seems like fixing any of the erstwhile show-stopping bugs would involve potentially breaking extant code. Clojure core is famously averse to doing that. This contrasts wildly with e.g. the rails philosophy, so I find the critique from a rubyist that clojure doesn’t put humans first a bit wanting.

donaldball21:06:40

See in particular Rich’s thoughts in the spec cognicast re: the desirability of stable named contracts, and the inadequacy of version numbers to convey novelty

alexmiller21:06:42

I replied on the post btw, won't repeat all that here. I don't think Ashton is a hater and he's welcome to air his opinions. And to file tickets! I hope he does.

drewverlee21:06:19

@alexmiller I found your response equal parts educational, intriguing and respectful. Thanks for taking the time to write all that!

ghadi21:06:33

me too 👍

plexus21:06:20

@donaldball: I do value stable interfaces. There's a reason I'm here now and no longer do Ruby, some aspects of building software systems are much better understood in the Clojure world.

plexus21:06:32

@alexmiller thanks for the extremely well reasoned and constructive reply! Really great to see that level of transparency.

sander21:06:11

is there a built-in function that behaves like map-merge-with in this example?

(defn map-merge-with
  [coll f-key f-val f-merge]
  (->> coll
       (map (fn [v] {(f-key v) (f-val v)}))
       (apply merge-with f-merge)))

;; example
(map-merge-with
  [{:type :apple :amount 3} {:type :pear :amount 14} {:type :apple :amount 15}]
  :type :amount +) ;; -> {:apple 18, :pear 14}

uxcolumbo22:06:17

@alexmiller I'm a beginner in Clojure and reading Ashton's post made me question my choice investing my time in Clojure longer term. Your reply completely removed my doubt, so thanks for the detailed reply and transparency. This reply on reddit is also very well put https://www.reddit.com/r/Clojure/comments/4nlhgn/my_increasing_frustration_with_clojure/d4543dt

alexmiller22:06:22

I hope you stick with Clojure!

verma23:06:53

hmm, can’t seem to find @alexmiller’s response, is it on HN or reddit? 😕

verma23:06:59

oh its on the article itself 🙂

nha23:06:33

I feel clojure as a language and the community is on the right direction generally . Meaning when I want something it is usually in core or in a library, or people are working on it. There are even things I did not know I wanted (ex. figwheel). Not saying that I am 100 percent happy all the time but this the best I found so far, considering language/tooling/community/libs.

nha23:06:18

Well figwheel is clojurescript also I guess. But component/onyx/specter/schema/boot/yada and some I forget - amazing. Curious about spec as well (even if it is not a type system - this is probably the one thing I don't get, in part because I never programmed in haskell/scala/...).

nha23:06:04

The things on my curious list right now are: will there be a Clojure-with-types (I know about Lux) or a Clojure-on-BEAM someday (even if it is not really Clojure). Mostly because I find it amazing that the Scala community went through language breaks without being hurt more (and it looks like it has to do with types) and because elixir/erlang seem to have a good deployment story (edeliver looks amazing). That being said - again I have picked Clojure and am investing in it, as a very pragmatic choice.

nha23:06:47

/end-of-lonely-night-comment 😅

zentrope23:06:57

Maybe people should take the “language” metaphor more literally.