Canada's Economic Slide in Five Charts - <AUTHOR> http://www.bloombergview.com/articles/2015-09-02/canada-s-economic-slide-in-five-charts

<comment><USER3> Those are some pretty depressing charts. It's actually somewhat surreal that we pay $0.75CAD to $1 USD these days, since as I recall several years ago the CAD was actually around the same as USD (even higher at one point).

Also, let's not forget the terrible domestic policies Harper has had, not just economic. Bill C-51 comes to mind. If you view the Wikipedia page on it, you can see how a couple of deaths loosely related to "terrorism" (just a lone maniac with a gun, really) was used to drum up fear and ram through sweeping new powers to various agencies. All at the expense of the privacy of the average citizen of course.

I'll be quite surprised if Harper gains another term. But with 2 left-leaning parties splitting the vote, anything can happen.

<comment><USER4> I agree that the charts are unfortunate. (Also with your stance on C-51 FWIW.) I wouldn't necessarily agree that the reduction in the CAD/USD recently is a symptom of poor policy though. For one thing, the CAD has remained more stable compared to most other currencies; it's mostly that the USD has gained, likely due to its status as the 'safe' reserve currency. For another, a lower dollar isn't necessarily objectively 'bad'. Yes, it reduces the Canadian GDP as measured in USD (as per that one chart), but that doesn't necessarily translate into a reduced average quality of life for Canadians. (It's good for some, bad for others, and probably not hugely impactful for most.)

<comment><USER5> CAD has a very high correlation with oil prices, according to [1] it's 0.78.

[1] [http://www.investopedia.com/articles/investing/021315/how- wh...](http://www.investopedia.com/articles/investing/021315/how-why-oil- impacts-canadian-dollar-cad.asp)

<comment><USER4> Thank you, yes, another great point. Of course, that doesn't necessarily mean a lower CAD isn't 'bad', but it does suggest it isn't really the government's fault. (Unless you feel the government should be working harder to reduce that correlation (and more generally the economy's reliance on natural resources).)

</comment></comment></comment></comment><comment><USER6> I live in Alberta and feeling the pain. In my opinion, the only industry that might be doing well in Canada is lumber (mainly, BC). With high USD, lumber exporters are making good money and with low crude, they spend less on their machinery.

The entire service industry in Alberta is in chaos and it impacts the whole country. We were the biggest contributors to the over all GDP and employment growth in Canada. Unfortunately businesses are now putting their equipment up for auction, people are losing their jobs and not sure what might happen next.

I am optimistic though - in periods of down turn and recession, people tend to get more entrepreneurial and find ways to bring innovation to their work. For long term prospect, this recession may be helping us in diversifying our portfolio and minimizing our dependency on just one industry.

<comment><USER7> >In my opinion, the only industry that might be doing well in Canada is lumber (mainly, BC).

I think you're underestimating the strength of the auto industry in Ontario. Canada is actually ahead of UK and France in terms of vehicle production [0].

[0] [https://en.wikipedia.org/wiki/List_of_countries_by_motor_veh...](https://en.wikipedia.org/wiki/List_of_countries_by_motor_vehicle_production)

<comment><USER6> oooh .. very interesting. Thanks for that !

</comment></comment></comment><comment><USER8> As a recent Waterloo grad, I can't help but feel that the tech industry in Canada has been losing _a lot_ of talent to the US, even from our own top schools. Just about everyone I know who's good enough to have offers from US companies have taken the offers and left.

And it's not hard to imagine why: the average "highly competitive" salary in Canada is pathetic compared to what you could be making in the US for a similar position.

I think Blackberry has been a prime example of a company hit by this. Even with the advantage of being literally next door to the Waterloo campus, most students I know treated it as nothing more than a "safety" in their co-op and grad job search. So in the end, the only students Blackberry ever had access to were the ones who weren't good enough for the US companies, and the few good ones that didn't want to go to the US for what ever reason.

I can't see this trend slowing any time soon, unless Canadian companies start offering salaries competitive with companies across the border, rather than just with their other Canadian neighbors.

<comment><USER9> So true. Every one of my highly educated family members are in the US. I'm going to be looking at jobs in many parts of the world, most of them not Canada. There's nothing here right now, except sub par wages and ridiculous house prices.

</comment></comment><comment><USER10> Even though those charts are framed in economy-neutral terms (positions in global indices, instead of absolute indicators), I still wonder whether setting the comparison year to 2006—right before the beginning of a global recession—has anything to do with the results. Did Canada, perhaps, slip all the way to its current positions in 2007, and then simply not recover? There's no way to tell from the representation used.

<comment><USER11> 2007 was a relatively good year for Canada. Due to a combination of luck and good regulation, our banks did not need bailouts. So Canada weathered that recession better than our peers. Contrast that with now, where we are the only G7 country in recession.

<comment><USER12> [http://www.cbc.ca/news/business/banks-got-114b-from- governme...](http://www.cbc.ca/news/business/banks-got-114b-from-governments- during-recession-1.1145997)

Our banks did get bailed out. Even more than the American banks on a per- capita basis.

</comment></comment></comment><comment><USER13> "[The author] was a senior policy analyst for Bloomberg Government and chief speechwriter for the leader of Canada's Liberal Party."

Why does this belong on HN, especially given the relatively low resolution of the data being presented (ordinal vs. cardinal)?

<comment><USER14> Because the Liberals are trying to win an election against the ruling Conservatives right now.

</comment></comment><comment><USER15> One has to consider the sharp fall in crude oil price with it. A worse performing government might have shown better graphs had crude oil price been rising.

</comment><comment><USER12> We've gutted productive jobs in central Canada. The federal gov't should have taken a more direct role in energy policy at least in Ontario.

</comment><comment><USER16> Why do people blame governments for these kinds of downturns?

The global oil price took a dive.

Sure, you want a diversified economy, but Canada has not many comparative advantages other than resources and being adjacent to the US.

How do people expect Parliament to just make up successful industries out of thin air?

Is there something stopping a Toronto resident from starting the next big fintech startup? Is there something stopping Vancouver residents from starting the next Salesforce?

Nope. Comes down to the culture.

<comment><USER9> It's part culture, part lack of capital. In the US you can get funding for just about anything. In Canada it's nearly impossible, and investors impose ridiculous terms. Government grants help, but its not enough.

As for culture, you're right. Canadians go for the safe, sure bet. Get a job as an accountant or (non-CS) engineer, and enjoy a safe, steady life in the middle class.

</comment></comment><comment><USER17> Well I am not a Canadian, but this news piece seems like part of the election campaign. In more honest words,a paid news this seems to me.

<comment><USER18> Not just seems: it was witten by the chief speechwriter for the leader of Canada's Liberal Party (= the opposition).

<comment><USER17> That's why. :}

</comment></comment></comment><comment><USER19> Five mentions of the word "conservative". Zero of "commodities" which, in the form of their crashing prices, is 100 percent of what ails Canada. When Bloomberg decided to publish opinion pieces was there any question it would be nothing but shameless liberal propaganda?

<comment><USER9> We're (Canada, to be clear) one of the richest countries in the world. One of the most educated. One of the most cosmopolitan.

So why is it that we're limited to being a petro-state? We live next to the biggest economy in the world, we're their largest trading partner (and vice versa). They're growing ~4% a year and we're in a recession.

I don't know about you, but I'd like to think that we could do better. The reason the conservatives are mentioned is that they've been in power for 9 years and there's an election coming up. Their only plan seems to be to deny that there's a problem and hope people believe them...

<comment><USER20> But when they were in a recession and their banking industry had to be bailed out and their housing market crashes and their unemployment hit the roof we didn't get all of that.

It sounds like you want to have your cake and eat it.

I'm probably not voting for the conservatives but at the same time I don't think they're to blame for the current situation. It's not like the Canadian economy used to be more diversified when the conservatives weren't in power, if anything it's the other way around. We're resource rich and naturally that is something that influences the economy.

<comment><USER21> It's not as if Norway is tanking right now; it is possible to have resources and not be a banana republic. But the Conservatives didn't make that transition in Alberta during the decades of power that they enjoyed there, and they didn't federally over the last decade - and they had the mandate to do it (Canadians, contrary to all evidence, believe that the Conservatives are competent stewards of the economy). They absolutely deserve blame here - <USER2> current downturn in demand was not even unlikely.

With the Conservatives there's an unspoken deal: we'll cut social programs, which will hurt, but the economic benefit will be worth it. Canadians in this case neither get their cake (economic growth) nor eat it (social spending), so what exactly have the Conservatives delivered?

<comment><USER20> Let's see, delivered: TFSA, income splitting (limited), lower taxes, balanced budget, startup visa. At least that's off the top off my head.

Which social programs are we talking about here and what would not cutting them have done to counter the current depression?

Like some other comment said the government can not create an alternative economy. It can only try to product the right conditions. If you have a startup in Canada your expenses are significantly lower than e.g. SV. There are a lot of programs to help you. What more are you asking for? The weak dollar, while sucks for me and you, is great for Canadian businesses that are not resource related, but even when the dollar was at its strongest it was still cheaper to start a business here.

</comment></comment></comment></comment></comment><comment><USER22> It comes from a very ancient democracy, you see..."

"You mean, it comes from a world of lizards?"

"No," said Ford, who by this time was a little more rational and coherent than he had been, having finally had the coffee forced down him, "nothing so simple. Nothing anything like so straightforward. On its world, the people are people. The leaders are lizards. The people hate the lizards and the lizards rule the people."

"Odd," said Arthur, "I thought you said it was a democracy."

"I did," said Ford. "It is."

"So," said Arthur, hoping he wasn't sounding ridiculously obtuse, "why don't people get rid of the lizards?"

"It honestly doesn't occur to them," said Ford. "They've all got the vote, so they all pretty much assume that the government they've voted in more or less approximates to the government they want."

"You mean they actually vote for the lizards?"

"Oh yes," said Ford with a shrug, "of course."

"But," said Arthur, going for the big one again, "why?"

"Because if they didn't vote for a lizard," said Ford, "the wrong lizard might get in. Got any gin?"

<comment><USER23> I have a laugh every time I read this, but it's not a very good analogy for modern politics.

You can't distinguish between good leaders and bad leaders quite as easily as you can distinguish lizards and people. Especially when both kinds spend millions of dollars trying to convince you that they're good and others are bad. Not to mention that this story kinda assumes/implies that people would somehow be better rulers.

We didn't get to the current system in a revolution. It's not like it was designed to work well. All the laws that allow things like massive surveillance, civil forfeiture, gerrymandering, lying in official capacity, obvious corporate bribery ("lobbying", what a nice word), self-favorably changing elections rules for the next election – all of this has been created gradually over decades, often by different parties and people, each of whom put self-interest ahead of their duty to the people and walked away from the disaster at a leisurely pace.

Given complete lack of accountability of individuals properly positioned in the state machine, we will not see any improvements in how the state works. People everywhere are trained to think "if only we elect the Bernie Sanders of the day, everything will change for the better", then either of the two things happen – a) they get elected and don't fulfill even a tiny fraction of their promises, if not the opposite, or b) they don't get elected ("oh well, let's try again in 4-5 years").

Just to clarify, this is not a call to arms to overthrow the government or anything. It's kinda too late for that to work. And that would be grossly illegal. For some reason.</comment></comment>


Email Active Content and Smart Contract: The new digital decentralized economy - <AUTHOR> https://at.appinmail.io/3aDnFzTio1w5K9p66bjyVr <comment><USER2> Interesting idea. Feedback:

* You need to get yourself a decent copywriter. I could tell you were French within a couple of paragraphs. Based on the French version of your site, you're an established team and not two guys working out of a garage in Ukraine (where that kind of shortcoming could be excused), so the poor level of English comes off as lazy.

* Your page is broken on mobile (Android/Chrome). The rightmost columns and the graphics are partially off-screen.

Also that kind of submission would fit in the "Show HN" category, where it could get you better coverage.

<comment><AUTHOR> Thanks a lots for your feedback. We'll work on that.

Regards again</comment></comment>


Happstack 0.5.0 released (Innovative web application server written in Haskell) - <AUTHOR> http://www.haskell.org/pipermail/haskell-cafe/2010-May/077218.html <comment><USER2> I'm glad to see a haskell web framework. I'd be very happy to use Haskell rather than Python.

But, why pair Happstack with Macid, some haskell serialization format that appears to not work very well?

<http://tutorial.happstack.com/tutorial/why-happstack-is-cool>

<http://tutorial.happstack.com/tutorial/macid-stress-test>

It's not a major issue, since it looks like you don't need to use it. However, once Happstack gets a few batteries included (e.g., authentication), I don't want them to be tied to Macid.

<comment><AUTHOR> _you're not locked in to using Happstack's state management system, MACID, for everything._

<comment><USER2> I realize that. What I said: "It's not a major issue, _since it looks like you don't need to use it._ "

My issue with MACID is that when Happstack starts including features like authentication, I don't want them to be tied to MACID.

</comment></comment></comment><comment><USER3> This is very cool, and it brings a question to mind:

I've been using GWT a lot lately, and thought to google around to see if anybody had done a Haskell-to-JavaScript compiler:

[http://haskell.org/haskellwiki/Yhc/Javascript/Programmers_gu...](http://haskell.org/haskellwiki/Yhc/Javascript/Programmers_guide)

While GWT is independent of what you have on the back-end, a lot of good comes from being able to use java objects as shared currency between the client & server over the RPC mechanism.

So, as an OO practitioner who is curious about better languages, I have a question: If one were to have haskell on the server side, and haskell as a source language on the client side, how would an RPC mechanism look for communicating between the two?

In GWT, the object serialization and Command Pattern works very nicely. What would you do in the purely functional world?

<comment><USER4> Ocaml has ocamljs and orpc:

<http://code.google.com/p/ocamljs/>

Haskell has a couple of haskell->js compilers but I'm not aware of any rpc mechanisms.

Clojure has clojurescipt:

[http://github.com/richhickey/clojure- contrib/tree/master/clo...](http://github.com/richhickey/clojure- contrib/tree/master/clojurescript/)

Presumably rpc would be easy given the mostly uniform data representation.

<comment><USER4> Also check out Nitrogen which is an interesting approach to the problem:

<http://nitrogenproject.com/>

</comment></comment></comment><comment><USER5> XKCD is powered by Happstack - <http://dynamic.xkcd.com/comic/random>

Back when I submitted <http://news.ycombinator.com/item?id=1186025>, you could insert any path any level deep inside dynamic.xkcd.com and it'd take you to a random comic - looks like that's changed now :-|

</comment><comment><AUTHOR> site url

<http://happstack.com/index.html>

<comment><USER6> What's up with the rendering of html on said site:

      ><head
        ><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"
          ><link rel="stylesheet" type="text/css" href="/theme/default.css"
          ><title
          >Happstack - Frequently Asked Questions</title
          ></head
        ><body

Is the reason for this behavior to make markup like:

      a
      <a href="#">
        link
      </a>
      .

to render as "a _link_." in stead of "a _link_ ."? Either way, it looks awful.

<comment><USER7> It prevents spurious whitespace from showing up in text nodes.

</comment></comment></comment><comment><USER8> Is there anything that actually explains what it is and does?

What exactly is MACID? Can I swap in my own preferred DB? What does it use for templating? Do I have a choice of template tools? Does it work with Hack? Can I add in middleware?</comment>


My Increasing Frustration with Clojure - village-idiot http://ashtonkemerling.com/blog/2016/06/11/my-increasing-frustration-with-clojure/ <comment><USER2> The thing to realise about Clojure is that it isn't an open source language like Python. It is a language controlled very tightly by Rich Hickey and Cognitect. Major work is done in secret (transducers, reducers, spec), then announced to the world as a "Here it is!" and then suggestions are taken. This goes well mostly, though it took a lot of outside persuasion that Feature Expressions weren't the best idea, and to come up with Reader Conditionals instead.

The underlying problem Clojure/Core has is their communication. If they would come out and explain their philosophy then people wouldn't get frustrated and confused when they expect the language development to work like other open source projects. Clojure's development is functioning exactly as planned. It's not a mistake.

A better way to treat Clojure is closer to a project at Apple (except for Swift). You can submit bugs, and make suggestions for future improvements, and if you really want to provide a patch. But go into it realising that it's not a community project, and you're much less likely to get frustrated.

With all that said, the proof of the pudding is in the eating, and for the most part Clojure has developed pretty well from Rich's tight control. I'd love it if there was a Snow Leopard year for Clojure where the focus was fixing longstanding bugs and feature requests, and more focus on those in general, but the language is developing well.

<comment><USER3> Please everyone, upvote dantiberian's answer. He nails it.

The moment you get over expecting Clojure to behave like a typical "open source" project and understand it is Rich Hickey's personal project (+ Cognitect's), which happens to also be available to you, if you want to use it, then the whole thing makes more sense. Some frustration disappears. You know where you stand, and what to expect.

Hickey and Cognitect have every right to run it the way they like. IMO, the only thing they don't do right is to communicate their intentions. There's a pretense maintained around it being an "open source" project, when it really isn't, not in the way that python is open source.

Use it if it works for you. Otherwise don't. Don't expect to have a voice, and don't expect you'll be able to contribute much, and don't expect that something will be fixed unless it suits Hickey's Cognitect's agenda.

I use ClojureScript, knowing and accepting these things (with some sadness), because I think the language gives me a competitive edge.

<comment><USER4> I agree - this is the only right answer. Like you, I'm sad to have to accept it, but it's the only way to a frustration-free (or lower-frustration) Clojure experience.

</comment></comment></comment><comment><USER5> Something that is often very hard to understand (it took me years to do so). Is that maintaining a language is insanely hard. Everything has a cost. Let me give a good example: A few years back someone submitted a patch that improved the error messages in Clojure. Worked great, just a single extra "if" and a message. It was committed to master.

Then people's code got way slower. Why? Well this was a often used function and that single if blew the JVM inline budget causing that function to never be inlined. And that improvement had to he yanked out.

When we talk about patches for a language, we have to realize that if we don't want constantly breaking APIs we have to test that a patch doesn't break existing code, that it also doesn't slow down existing code (or at least not enough that users would care), that in all sorts of cases the JVM won't freak out and do something bad. Then we also have to make sure that the change doesn't restrict the language in the future. Does making some interface public mean it will always be public? Are we happy to keep it that way for all time?

Taking all that into consideration, I have to sit back and say , yeah, maybe I'll just remember to only hand sets to the functions in `clojure.set`. Or maybe I'll help out by adding clojure.spec annotations for these functions so I can turn them on during testing.

In the end, I'd much rather have a rough-around-the-edges language that takes a garbage-in-garbage-out approach, than one that breaks the API at every turn. Perhaps they aren't mutually exclusive, but it certainly takes a heroic effort, and a lot of prioritization.

<comment><USER6> Sounds like there might be a potential for a dev and production codebase?

<comment><USER7> This is in a sense what the clojure.spec work would allow -- dev time exceptions when you violate a function's contract that have no impact on production speed.

For some reason the blog's author dismisses spec as irrelevant greenfield development, when it would quite neatly solve many of his complaints

</comment></comment></comment><comment><USER8> Clojure is a language for people who know what they are doing by people who know what they are doing.

If you're giving sequences to the set functions, you either (A) don't know what you're doing or (B) have yet to discover that clojure.set is not what you want.

Set union can't be done efficiently on arbitrarily sized sequences. At least one of the two arguments needs to offer fast set membership; ideally the larger one, hence the requirement that all arguments be actual sets. If you have sequences, you need to make an explicit decision to pay the cost of indexing (eg. via set or into functions) or you need custom code for your use case.

Sure, static or dynamic enforcement could help catch silly errors here, but then the author goes and poo poos on "greenfield" development of things like spec, despite the fact that would "fix the bug" exactly as requested by throwing when you gave non-sets to the set functions.

I've followed a lot of the discussion around the supposedly horrible way the Clojure community is run. So far, the absolutely only complaint that I can sympathize with is that communication could be faster, clearer, and softer. Alex Miller has made dramatic strides in improving this, but he's just one man. Cut these guys some slack, they work crazy hard to build and shepherd something awesome for free.

<comment><USER9> > they work crazy hard to build and shepherd something awesome for free.

I'm not so sure about that. I'd say that Clojure now exists and thrives to help Cognitect make money. This is no way a bad thing, only a reminder that there is no such thing as a free lunch.

In a similar vein, Go exists to help make Google money. The original purpose of open sourcing it was different for Google (make the language more robust/better) than it was for Hickey (grow the language/community).

<comment><USER8> I anticipated this response to the word "free", but I stand by my statement.

Clojure is _free_. If you don't want Cognitect stuff, don't use it. If you don't like how Rich/Cognitect et al are running the project, take your EPL licensed ball and go home. Similarly, in the case of Go: Substitute Rob/Google and BSD-ish license.

Just because these languages serve the interests of their respective maintainers does not make them any less free to you. It may make the community less useful to _you_, but hey, they created these things to be useful to them. There's an implicitly mutually beneficial social contract around contributions and community. If you don't like that contract, don't use the language.

In the very unlikely case that Cognitect or Google puts some company-specific stuff in the language in a way that actively destroys the good will of this social contract, then and only then do you have any right to complain.

<comment><USER9> > does not make them any less free to you

Of course not, but it does make them unencumbered. And I'm not complaining. I'm just saying that's cost (i.e. not free) of doing business with a sponsored open source language.

<comment><USER8> If you take the stance of "nothing is free", then the word "free" isn't particularly useful.

<comment><USER9> A+ extreme reductionism.

I never said "nothing is free", nor implied that, but merely that users need to cognizant of the goals of "free" language maintainers (especially when there is a corporation rather than a person as BDFL) that do not necessarily align with the goals of the median or average user.

Now that we are on this topic, I'm starting to think maybe it's worth paying for a programming language so that the goals of the maintainers are better aligned with the goals of the users. That being said, there is real value to the ability inspect the source. As such, it's very difficult to do open source as a paid product.

<comment><USER10> There is a history here. Please read:

1\. [https://web.archive.org/web/20100220100027/http://clojure.or...](https://web.archive.org/web/20100220100027/http://clojure.org/funding)

2\. [https://web.archive.org/web/20140704050611/http://clojure.or...](https://web.archive.org/web/20140704050611/http://clojure.org/funding)

My own interpretation: programmer culture has such problems that someone actually considered corporate funding healthier than user donations.

<comment><USER11> There are many definitions of the term 'healthier'. But the links are pretty amusing. And now we have a first fork [https://github.com/jaunt- lang/jaunt](https://github.com/jaunt-lang/jaunt)

</comment></comment></comment></comment></comment></comment></comment></comment><comment><USER12> Clojure is not a community-driven language. It belongs to Rich Hickey and by extension Cognitect. The bugs that will be fixed and the features that will be added are the ones Hickey cares about. Not saying this is good or bad. It's just how Clojure development is ran.

<comment> aaron-lebo This is the most realistic answer.

Steve Yegge was making similar criticisms years back, saying Clojure was "user-hostile". That's probably not fair and largely a matter of opinion (see the link for a back and forth), but it is another piece of evidence that says the Clojure community does things their own way. Not shocking, it's a lisp!

[https://www.reddit.com/r/Clojure/comments/3jjit5/what_does_s...](https://www.reddit.com/r/Clojure/comments/3jjit5/what_does_steve_yegge_mean_by_clojure_being/)

Clojure development is opinionated, for good and bad.

<comment><USER11> There's nothing wrong to be user-friendly or user-hostile. But it helps to be clear about that up front. Good example, from not user-friendly (but developers-friendly) Linux distro - [http://exherbo.org/docs/expectations.html](http://exherbo.org/docs/expectations.html)

</comment></comment></comment><comment><USER13> As a dev programming in Clojure professionally day to day this complaint (core team not fixing/prioritizing bugs) seems absurd to me.

The only example given for a bug is not even a bug but undefined behavior triggered by undocumented API usage.

If the author means clojure.spec by "greenfield development" (I don't see what else he could mean) he should really reconsider his complaint since clojure.spec is going to do what he is asking for (throwing a runtime error during development if you use clojure.set with the wrong datatypes).

My impression over the last few years is that the core team became truly excellent in reacting to users needs and reports often instantaneously, especially Alex Miller and David Nolen on the CLJS side.

<comment><USER14> " _The only example given for a bug is not even a bug but undefined behavior triggered by undocumented API usage._ "

C gets a lot of grief about that sort of thing. It's interesting to see current languages taking the same approach.

<comment><USER13> Could you elaborate why? (Haven't done much C) - Is the point of view that it is the languages job to prevent the programmer from relying on uncertainties?

<comment><USER14> The C standards take the rather unique approach of dividing behavior into 4 categories:

* _standard-defined_. You can rely on this; if the code you write is limited to this, you're good to go.

* _erroneous_. The compiler is supposed to give you an error message when you write code like this.

* _implementation-defined_. A particular compiler can do something reasonable with the code. If you write code depending on implementation-defined behavior, you're ok, but your code is not portable. A compiler that doesn't do something reasonable in an I-D situation _isn 't_ required to generate an error, IIRC. On the other hand, whatever it does is supposed to be consistent.

* _undefined_. There are explicitly no requirements on the compiler. Whatever it feels like doing is fine with the committee. There's no requirement for a compiler warning or error (and by default, there probably won't be one).

The reason for the different categories is twofold:

1\. C is a systems language. It's frequently used to do things that depend entirely on the specific hardware the code is running on. The result isn't portable, but in this case, it isn't supposed to be.

2\. Performance. The idea is that the compiler can take _portable_ code and produce a program that runs very quickly on the specific hardware. As long as the code doesn't do anything non-standard, the results are guaranteed to be good.

An example of the latter is signed integer overflow. (I can't remember whether it's I-D or undefined, but...) If you do MAXINT + 1, the resulting value can differ on different hardware; it could be the most-negative integer, it could be zero, it could cause a hardware trap. Now, the C standard could specify what the behavior should be, say generating a signal that kills the program with an error. But that would be very expensive on hardware that doesn't trap signed integer overflow---it would require a check after every arithmetic operation. So the standard doesn't say what should happen.

Another example is poking at memory that isn't allocated by your program (on the stack, or the result of malloc, say). You need to be able to express that for systems programming, but a general standard can't say anything reasonable about it.

As a result, C has a lot of unsafe corners where you can unintentionally invoke I-D or undefined behavior. In the first situation, your program will break if you try to port it. In the second, your program might work, most of the time. Or it might toss a runtime error. Or it could generate mangled results.

Or it could have a really nasty and embarrassing security hole.

As a result, C is regarded as a difficult and (unnecessarily?) dangerous language. And most languages that aren't C and aren't aimed at systems programming try very hard to avoid undefined behavior. Even if you manage to avoid security holes, the bugs resulting from mangled results are a royal pain in the ass to track down.

<comment><USER13> Thanks for this long and elaborate reply.

Clojure tries to put as many user faults into "erroneous" as possible but in the OPs complaint it doesn't have the required information at compile time because it is typed dynamically. This is the fundamental problem with dynamic typing that more problems keep ending up in runtime. Behavioral concerns like security etc. are then often addressed by runtime checks.

Clojure avoids those runtime checks everywhere for performance reasons - It is a clear design choice. So your observation seems correct that the "C approach" is used in the dynamic parts of Clojure.

Since we don't have a standard, the official documentation is the contract we should rely on and very soon clojure.spec, which is intended as a "standard as data", is going to be.

<comment><USER4> _Clojure tries to put as many user faults into "erroneous" as possible_

I would absolutely disagree with this. Clojure has long had a Garbage-In- Garbage-Out philosophy, which puts it clearly into "undefined" territory. The examples with clojure.set are pretty clearly GIGO in my opinion, but "erroneous" would mean a runtime check and an exception clearly stating which invariant was violated, not returning something totally unexpected.

You could argue that it's under "implementation-defined", where the number of implementations is one, but I don't see how you could consider the set operations accepting and returning non-set things as consistent.

<comment><USER13> As I said, the GIGO approach is only used where costly runtime checks would be the alternative. Macros check their arguments at compile time a lot.

<comment><USER4> I disagree on both points there, I don't think that an instanceof check is that costly compared to many of the other performance hits we're willing to accept with Clojure for saner behaviour. For example, persistent data structures are slower than mutable ones, but I'd never go back to using mutable ones in most cases. Why is one performance hit acceptable for better behaviour and the other isn't?

I also disagree about macros, too - I spoke at the conj last year about that, and that talk seems to have been at least part of the motivation for developing spec. I hope that things will improve as spec becomes more widely used, but right now the situation for macro error messages is pretty bad.

</comment></comment></comment></comment></comment></comment></comment></comment><comment><USER15> I love Clojure, and I use it in every project where I have control over the technology, but I do agree with the points raised by Ashton Kemerling.

Clojure is beautiful, and backed by beautiful theories, but its implementation needs to be clean or it will eventually develop enough special cases that its beauty will be ruined. In some sense, you could say this is what happened to Ruby, though there the allowance of "special cases" was more deliberate. I recall, back in 2003, reading the interview between Matsumoto and Bill Venners: [http://www.artima.com/intv/ruby.html](http://www.artima.com/intv/ruby.html) \-- and I thought that Ruby had a beautiful philosophy. But having worked with Ruby for many years, I now see how much it is undermined by the many special cases it allows, and the wild ambushes that its most imaginative features allow (monkey patching).

I don't want to see Clojure go down that path. I want Clojure to remain beautiful, and that means the implementations must also be beautiful. There is a limit on how much the core team can say "That bug is only an implementation detail". If you take away all the implementation details, then Clojure is only a theory, not a real technology that can be used by real people to do real things.

In a truly ideal world, Clojure could be the practical Lisp that pushes itself to bring in as much of the experimental Lisp's beauty as is practical. I would love to see the best ideas from Racket and what Fogus refers to as the Fluchtpunkt Lisps:

[http://blog.fogus.me/2011/05/03/the-german-school-of- lisp-2/](http://blog.fogus.me/2011/05/03/the-german-school-of-lisp-2/)

These are ideas that can make the world better. I have high hopes that Clojure will be the project that makes some of these beautiful ideas practical. I will be very sad if Clojure ends up like Ruby or Groovy or Scala, becoming a bit too muddy to reach its full potential.

<comment><USER16> I don't see what Ruby's "beautiful philosophy" is. Here are some examples of philosophies I actually consider beautiful, regardless of the result they led to:

(0) Lisp, Scheme, Forth: "A small extensible core language beats a fixed large language." (While Common Lisp is actually pretty large, there's a rather small subset of it from which the rest can be built.)

(1) ML, Haskell: "Let's see how much we can do using types as our primary abstraction enforcement mechanism."

(2) C++, Rust: "Abstraction isn't at odds with efficiency and fine-grained control." (Runtime enforcement is, though.)

What does Ruby have to offer? Matsumoto claims to prioritize "developer happiness", but allowing arbitrary modifications to arbitrary parts of any program doesn't make everyone happy. And, even if it did, "developer happiness" isn't a technical criterion anyway.

<comment><USER17> I'm not a Ruby user, but its dynamic OO nature reminds me of the Smalltalk and Self tradition, and those languages certainly do stick to a "beautiful philosophy", something like 'it's method calls all the way down'.

Other beautiful philosophies include:

\- Logic programming. Although Prolog strayed from the path in the name of efficiency, approaches like minikanren seem more "philosophically pure".

\- Term rewriting. I've only used it in the form of Maude, but Pure looks like a more practical implementation.

\- Proof assistants. The (tongue in cheek) philosophy is something like "once it compiles, we don't even need to run it". Agda is probably the most "pure" example which is still maintained. Less elegant examples are Coq, which uses imperative metaprogramming, and Idris which has no qualms with switching off checks in the name of pragmatism.

<comment><USER16> Agreed about Prolog. I missed that one.

I know neither Maude nor Pure, so I can't comment.

Coq is ridiculously powerful, but hardly beautiful.

<comment><USER17> > Coq is ridiculously powerful, but hardly beautiful.

I agree, hence my qualification that it relies on an imperative layer (Ltac) to do anything useful, like dependent pattern-matching. I've edited my potentially ambiguous phrasing.

</comment></comment></comment></comment></comment><comment><USER18> I think this article is spot on. But. I think the root cause here is that many of the tools are build by the community. Great tools cost a lot of money to build, and you need to build the right thing at the right time, the cost needs to be spread across the comminuty. The community is growing and tools are improving. The first generation tools with all their rough edges are being replaced by simpler tools that have incorporated lessons of the first gen. Improvement is accelerating. So when the core team focuses on new features like CLJC, Spec, Transit, Transducers, Datomic, ClojureScript, they are doing things that only the core team can do. There are other more opinionated things (like frameworks) that the core team isn't suited to do, everyone's app is too different.

The thing i love most about clojure is that all the pieces seem to fit together and be working towards a grander architectural vision much larger than just a language or just a database. I use Clojure not because it lets me code my java/javascript stuff a little better, but because this grander vision makes impossible things possible. The thing I am trying to build is not possible in any other ecosystem today.

So I am willing to eat the many little pains described in the article, pains I feel every day, because the grand vision is so powerful, and hope that one day the little stuff will be better.

<comment><USER19> I couldn't agree with you more. I've been wanting to learn Clojure for years now, but I'm not going to fight with an IDE for hours to do so.

<comment><USER20> 1)install leiningen 2)install lighttable 3)??? 4)Clojure

Edit: You really don't need an IDE for clojure. A repl and a text editor are your best friends IMO

</comment></comment></comment><comment><USER21> I'm a big fan of Clojure and have been since 2009. I'm such a big fan that I run the local Clojure meetup.

I do think that Cognitects interaction with the community could be friendlier in terms of bug reports and community patches. They have a bit of a history of not communicating what they're doing (for example, the Zach Tellman thing someone else mentioned). I don't think they need to change much to fix this, they just need to communicate what they plan to do sooner (in the Zach case, they could have told him sooner _" hey stop working on that, we'll think about it but aren't sure, it might take some time"_ so that he knows not to spend a year on it before it gets rejected/NIH-implemented). A tiny change in behaviour would go a long way. Having said all of that, I still <3 Cognitect and Rich and think they're doing great work.

I also think that Clojure has a bit of a stability/quality image problem that could be easily fixed: They should put a feature freeze on the language for ONE release and then spend 6 months or so resolving JIRA issues (bugs, stability, quality; not feature or performance tickets). By spending one release cycle on a "bug bash", I think would show the world that they care and that yes, Clojure IS solid.

I've never personally been bitten by any Clojure bugs and don't think it actually has of a quality problem at all. In my experience, Clojure is of excellent quality. Its just a perception thing, really. Sure there of course are bugs, but so does every other language.

After the 1.9 release is out would actually be an ideal time: spend 6 months on quality and call it Clojure 2.0 ;-)

After that, I think people would be much happier to receive new features.

I don't think Cognitect will do that though, at least, going by how they've worked in the past and honestly I won't lose sleep if they don't - I'll still love Clojure and will still have buckets of respect for Rich and his team. However, I do think it would benefit the community (and by extension the ecosystem and language).

<comment><USER22> > I've never personally been bitten by any Clojure bugs

I actually have encountered one; the cl-format function is documented as "implements the common lisp format function", but does not comply with that function's spec. (Unless they've fixed it since I ran into the problem in 1.4, which is sounding unlikely.)

</comment></comment><comment><USER23> Once I tried to make a union of a sorted set and an unsorted one. Result set inherits behaviour of a bigger input set so when i first got my sometimes- sorted set i thought like loosing my mind.

<comment><USER24> Avoiding madness like this is why I have come to really prefer statically typed languages.

<comment><USER25> The issue doesn't have much to do with dynamic typing, any subtyping support can trigger it. Take Java, if Set had a `Set union(Collection)` method a SortedSet could return a new SortedSet (cast as a set, but still with the actual behaviour of a sorted set).

<comment><USER26> But you would not be able to pass it to a method that takes a SortedSet, which means you can't rely on the sorted behavior. Incorrectly using behavior that your implementation doesn't support is where the confusion comes from, it doesn't come from your implantation having extra behavior that you can't use.

</comment></comment></comment></comment><comment><USER27> Alex Miller is the person primarily responsible for triaging Clojure tickets. For a thoughtful, balanced assessment of the issues Ashton raises, read Alex's detailed comment on the original post: [http://ashtonkemerling.com/blog/2016/06/11/my-increasing- fru...](http://ashtonkemerling.com/blog/2016/06/11/my-increasing-frustration- with-clojure/#comment-2725501771)

</comment><comment><USER16> There are basically four possible attitudes to abstraction:

(0) We don't need no stinkin' abstractions! Obviously not befitting a high- level language like Clojure, move along.

(1) We enforce abstractions in our heads. Running into an undocumented scenario is undefined behavior. (Yes, in the C sense.)

(2) We enforce abstractions via compile-time checks. Clojure won't have this anytime soon, move along.

(3) We enforce abstractions via sensible coercions (whenever possible, if desired) or runtime exceptions (anywhere else).

Like the author, I find (3) the most sensible choice, and I'm surprised that the Clojure team would rather choose (1), which is known to be a major productivity killer.

<comment><USER28> It seems disingenuous (in the blog post) to act as if Rich was saying that the results of applying union to a list were correct when he was clearly saying that the fact that it produced any value at all was an implementation detail.

<comment><USER16> I think you misread the author's complaint. He's complaining that the `union` abstraction is leaky - it exposes its own ad-hoc implementation choices.

<comment><USER28> I think you may have misread it - he's pretty clear that he considers these bugs that clojure core chooses to ignore because they either a) don't understand them b) want to do cool new stuff

<comment><USER16> > he's pretty clear that he considers these bugs

 _Design_ bugs, not implementation ones. In other words, the author of the post acknowledges that the existing implementation does what Hickey wants, but the author would prefer that it did something else.

<comment><USER28> If that's true this blog post is just whining. He knows that Clojure core made a decision he disagrees with and he's just really upset that after 7 years they still haven't changed their opinion to match his.

<comment><USER16> Of course he's whining. And I don't blame him - I'd whine too if I had to use programming tools that make it unnecessarily difficult to detect programming mistakes. Conceptually, there are three very different operations:

(0) Concatenation, which acts on sequences, and is neither commutative nor idempotent.

(1) Merging, which acts on priority queues and multisets, and is commutative but not idempotent.

(2) Union, which acts on sets, and is both commutative and idempotent.

There are some sensible coercions:

(0) Every set can be coerced into a multiset in which every element occurs exactly once.

(1) Every priority queue can be coerced into a sequence by lazily removing the minimum element until the heap is empty.

(2) Every sorted multiset can be coerced into a sequence by traversing its elements in order.

(3) Compatible coercions, like (0) and (2), may be composed.

But there's no sensible way to coerce a sequence into a set. The elements of a sequence might not even have decidable equality testing, which the set abstraction needs to ensure that no element is duplicated. The union of two things that are neither sets nor coercible to sets should be treated as an error, to be caught either at compile-time (which Clojure won't do, and that's fine) or at runtime (which any sensible dynamic language should do). Protecting abstractions is fundamental if you want to avoid bugs.

</comment></comment></comment></comment></comment></comment></comment><comment><USER29> I'm not a clojure user but I am a fan of Rich's talks so I am kinda taken aback by this - this is just not the kind of Clojure I was expecting from what I know of the principles Rich preaches.

I really was expecting belt and braces defensive error checking and never ever giving a dud result.

<comment><USER14> It's a somewhat common problem with Lisps specifically and dynamically typed languages in general.

Because the bottom-level operations won't let you do things that are completely idiotic, everything is "safe", so maintaining the _sanctity_ [1] of higher level abstractions sometimes gets lost in the shuffle.

I once wrote a blog post about related issues.[2]

[1] Ok, so there are lots of terms with just slightly the wrong meanings. I came up with a new one. Sue me.

[2] [http://maniagnosis.crsr.net/2011/06/some-lisp- suggestions.ht...](http://maniagnosis.crsr.net/2011/06/some-lisp- suggestions.html?m=1)

</comment></comment><comment><USER30> Odd, in two years I've never been bit by a single one of these bugs. And if I had, I could probably pretty easily shrug them off.

My frustration came from the lack of a type system, and that there's no "myThing." (myThing-dot) to give you intellisense. Even many dynamic language editors have some variant of this now. So coding in Clojure involves too much looking stuff up and memorizing stuff, and is way slower than it should be in 2016.

<comment><USER31> What editor do you use? Emacs Cider does this, and does it much better than IDEs (IMO).

<comment><USER30> I use Cursive, and yes it has intellisense equivalent to Cider, but still not good enough.

In Scala, Java, C#, F#, C++, I can do `myArray.` and it shows all methods available to arrays. No Clojure editor has anything like this. JetBrains editors take it a step farther and even include "code template" options that apply. So typing "myArray." will also include options for "foreach, for, for- reverse" templates. This, in addition to automatically importing any required library for the method you select.

With Clojure, there's no "dot". You're stuck hunting through documentation, trying to figure out first which namespace your function belongs to, then requiring it, then figuring out which function you want. Cursive only helps out with that last step, and even then, it displays _every_ function in the namespace, when generally you only want to see the functions that apply to your variable.

While I'm all about immutability and structured data types, I've grown slightly away from functional-first languages in general for that reason. Even in F#, you've got to do `myList |> List.map ... |> List.filter ...` etc, requiring more lookup than C#'s `myList.Select(...).Where(...)`. The "dot" is an underappreciated aspect of OOP.

</comment></comment></comment><comment><USER32> Respect and treatment of people is a real concern. I made a decision not to pick a certain library after seeing people being shut down in the issue tracker in the most unnecessarily abrasive way possible.

Clojure does have a lot of amazing people though, and I've been very welcome reaching out to people for help as a whole.

<comment><USER33> This is my exact sentiment in many areas of life, being an adult who've seen many different ways of treatment of both myself and many others.

This exact HN discussion (and the original article) actually made me stay away from Clojure for good. I was curious, I wanted to learn the LISP way of doing things but I'm not gonna pretend that I am OK with people dismissing the possible irrelevance of their language by a death of 1000 paper cuts -- of which several were outlined the by the original article's author.

Same thing like the game Mortal Kombat X. Bought it for both myself and my girlfriend and we love it but it turns out Warner Brothers & Nether Realm Studios figured they'll support it only on the console almost immediately after it was released on PC.

I have enough money to buy 5 PS4 machines if I want to, and to buy one MKX copy for each. But I won't. I won't support people who treat their users/customers like that.

Same goes to Clojure. Same goes for Rails in the recent months when DHH actually has to write articles defending his strong opinions.

</comment></comment><comment><USER34> Just saw this tweet from Rich Hickey [1]:

> If you think you know how I ought to spend my time, come over and mow my > lawn while I expound on the problems of dev entitlement culture.

All due respect, but I don't think Rich gets it.

Other people are spending _their own_ time as well, researching, writing and reporting issues, and in many cases, would be perfectly happy to submit fixes for those issues (and in some cases, they have). It doesn't take any more work for Rich or someone else to look at an issue and say, yes, this is a problem and thank you for fixing it, then it does to say screw you, WontFix. And that is where Clojure has a problem.

Rich's argument is really a strawman. Nobody is telling him what to fix, but neither can anyone force him to recognize the importance of fixing long outstanding bugs _in his own work_, even if, thanks to a great community, fixing those bugs wouldn't require him to lift a finger.

1: [https://twitter.com/richhickey/status/741982205392617472](https://twitter.com/richhickey/status/741982205392617472)

<comment><USER35> i saw that too. it seems to be a rather childish response. i have recently become very excited about clojure as someone new to it since there are some greatn resources for the language in the form of books (even one on frp), but this ordeal and the clojure people's response has turned me off of it.

it seems all peopme are really crying out for is clear and accurate communication. i mentioned this in another comment that this attitude is a stark contrast to the f# and racket communities.

</comment></comment><comment><USER36> I'm not a Clojure user, but this article reads to me like complaints about the language's faults, and frustration it isn't solved a particular way. He may be right in some or all of these cases, but some of the phrasing used does not encourage anyone to look at it further. Attitudes like this make me want to quit open source when I encounter it in projects I maintain and/or contribute to.

</comment><comment><USER37> I'm sad to see someone so clearly disappointed by this interesting and innovative product. But considering his frustration, I think it's fair he get a refund. But that's not possible, because it is free. In his own words, he writes Clojure all day and loves his job, all because of this interesting and free product called Clojure.

Clojure is far from a perfect language, but what language is? I also love C++ and you'd be hard-pressed to find anyone who thinks it is perfect.

There are flaws and unique quirks with any programming language. A good language is like a person: it has a personality with all the good and bad that come with its unique bundle of traits.

<comment><USER38> Just because something is free do not make it holy and free from critique.

I left Clojure because its inherit both Java and Lisp flaws: memory hungry, difficult setup, enterprise frameworks and hard to read, impure and slow.

I believe that there still chance for Lisp in Web Assembly.

</comment></comment><comment><USER39> > To say that I was treated pretty shabbily by David Nolen on this issue > almost goes without saying

He maintains projects by trying to triage issues in an efficient and emotionless manner. I wouldn't take it as rude though.

</comment><comment><USER40> I'm having trouble finding much value in this post. It seems to be a combination of the author picking apart very specific aspects of Clojure (clojure.set? clojure.test fixtures?) in a highly opinionated fashion to represent issues with overall project focus, combined with not acknowledging the project's history (maybe that can explain the inconsistency with Protocol usage--as far as I know Protocols only got added in 1.2), combined with not acknowledging the size of the team and what they have to support, combined with not acknowledging how much time is spent on dealing with real, important bugs and performance issues (please see release 1.8's changelog, for example: [https://github.com/clojure/clojure/blob/master/changes.md](https://github.com/clojure/clojure/blob/master/changes.md)), combined with not acknowledging how much new development is actually about features that users really want (see clojure.spec or reader conditionals in 1.7, both of which address long-standing issues previously solved by third- party libraries, as just two things that immediately come to mind).

As someone who has been using it professionally for more than three years, there is a ton I have to gripe about in Clojure. Personally I find the hodge- podge type system and inconsistency with how certain core functions handle associative data structures infuriating, and schema/clojure.spec on some level I see as a hacky half-measure, and yes parts of clojure.test are semantically inconsistent and awkward to use in ways that bug me. But: as a language allowing me to get things done in a professional context, as a community of developers with actual adult leadership who are generally welcoming and share a practical, thoughtful philosophy, I think it holds up just fine against other language ecosystems.

It would have been quite reasonable to write a blog post about the deficiencies in clojure.set and clojure.test. Write a post about how Protocols could be better used throughout the Clojure codebase itself, and maybe even push some patches up via Jira and see what responses you get. And sure, I've had some prickly interactions with David Nolen myself; he can be that way--he also addresses bugs quickly, is constantly providing answers to questions on IRC and Slack, and is pushing ClojureScript in new and interesting directions while acting as the primary maintainer of the CLJS codebase (I believe?).

Point being, some of the issues raised in the piece may be real issues. But they do not represent some kind of overarching deficiency in the team as the author seems to suggest, nor are they necessarily relevant to the majority of developers using Clojure professionally.

<comment> village-idiot Let me get this straight, you agree with every single gripe I have, have some more of your own, agree that writing a post on this would be reasonable, but I'm wrong?

</comment></comment><comment><USER41> Hickey's latest tweet:

If you think you know how I ought to spend my time, come over and mow my lawn while I expound on the problems of dev entitlement culture.

[https://twitter.com/richhickey/status/741982205392617472](https://twitter.com/richhickey/status/741982205392617472)

</comment><comment> daniel-levin Do you have any experience with attempting to fix these bugs and then submitting patches / pull-requests? Yes, the core team should just fix these bugs. But if they're receptive to upstream changes you want made, then that makes this much less of an issue, in my mind. An open source project's openness depends critically on the core team's acceptance of user patches.

</comment><comment><USER42> Interesting bit to me is the communication problems, not so much the technical ones, we live with tradeoffs.

The thing is communicating takes time and busy people are entitled to prioritise "doing" over "talking".

As a community, Clojure is defined by the promises made and the processes established. I think "Brand Clojure" is defined by some truly wonderful attributes but it could be improved.

Perhaps this could this be fixed with process? For example

* Document architectural decisions [1] [2]

* Close tickets WONTFIX with a link to the relevant architectural decisions

Make that a process/promise so that it becomes a consistently applied approach and it would give the community confidence they are being treated well, heard and respected. "Brand Clojure" becomes more lovable.

But these processes also take time and we don't want to burden Clojure core devs. (More realistically, I doubt they'd allow us to impose on their precious time.)

So, can this happen without adding overhead for the core developers? I don't know. It's an interesting question though. Can we learn from others online communities on this topic? Are those who do this well based on dev leads who are naturally inclined to communicate? Are any using community funded positions to deliver on communication" outcomes?

Sounds like a community advocate/support role:

* Triaging tickets ensures inbound communication is effective and helpful. That helps by saving core dev effort. That helps avoid confusion on both sides.

* Generate architectural decision docs which can be linked from tickets

* Ensure WONTFIX doesn't feel like a dead end. Link to ADs, blog topical workarounds.

* Keep architectural decision docs fresh as consequences become more apparent over time.

Few ideas in there. Just a thought exercise.

\--

[1] See Documenting Architecture Decisions [http://thinkrelevance.com/blog/2011/11/15/documenting- archit...](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture- decisions)

[2] Is the 'garbage in/garbage out' architectural decision documented?

<comment><USER43> I actually would love to have ADRs for Clojure - that's an exceptional idea. The design wiki pages often record much of the decision record, but it's quite common for them to be out of date by the time something is done. Will consider more.

</comment></comment><comment><USER44> The OP creates tickets with titles like "Clojure.Set Does the Wrong Thing" and then calls people out for poor communication?

</comment><comment><USER45> [https://www.reddit.com/r/programming/comments/4nlhih/my_incr...](https://www.reddit.com/r/programming/comments/4nlhih/my_increasing_frustration_with_clojure/)

</comment><comment><USER46> This particular complaint feels like a typing issue. If functions can accept anything and use lots of partial duck typing then they might partially accept anything and not quite work.

There's just an unstated precondition: the arguments are sets.

</comment><comment><USER47> this is the experience you'll have with any unityped language, because they explicitly move responsibility from library designers to end users

and these undefined-behavior bugs are hard to fix because someone somewhere already depends on that on undefined behavior, and it's just a snowball which understandably leaves library designers unresponsive

</comment><comment><USER48> > 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.

to be clear I assume he is taking about this:

``` try-spec.core=> (clojure.set/union [1,2] [1,2]) [1 2 1 2] ```

Though im not sure what "depending on their length means".

> 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 prolific in any dynamic language? What is the union of anything besides sets?

> coerce lists and vectors to sets before continuing

This only works for very similar data. How do you coerce a map into a set? Is it based on keys or values? What about a string? is it based on the whole string or the characters. I loaded up python3 to see how it was handled...

``` In [7]: set(["hello"]).union(["hello"]) Out[7]: {'hello'}```

is that what you would expect? Maybe. But honestly it should have thrown an error imo. Python is just skirting the issue. A set needs a hashable type. A list isn't one because its mutable. So python knew you "meant" a set of the items in the list... It throws up its hands if you force the issue further:

``` In [8]: x = [1,2,3]

In [9]: set(x) Out[9]: {1, 2, 3}

In [10]: set([x]) \</comment><comment></comment><comment></comment><comment></comment><comment></comment><comment></comment><comment></comment><comment></comment><comment></comment><comment></comment><comment></comment><comment></comment><comment>--- TypeError Traceback (most recent call last) <ipython-input-10-0b079714f02c> in <module>() \----> 1 set([x])

TypeError: unhashable type: 'list'```

The problem is that we have handed the union function the wrong type of arguments. That it fails in further down stream is the trade off we make with dynamic languages. The community seems to admit the trade off and alleviate it with things like clojure.spec. Im not mental equipped to argue type theory here. But i suppose i feel this is an _ancient_ argument and saying its a "bug" seems simplistic.

> How you define getting the wrong type with nonsense values counts as > "working" is beyond me. Is it just because it doesn't throw an Exception? > Anyone here prefer bad data instead of exceptions when dealing with > functions like this? I doubt it.

This is maybe the deeper problem. You would expect union to fail given the wrong types. Sure the failure wont be a type error but it will be contained inside the function. Leaking out the wrong data means its harder to debug. I'm generally curious how and why set would work on lists at all.

As to the rest of the arguments made here. I don't know enough to hazard a guess. But i would appreciate any feedback on my interoperation of the above situation.

<comment><USER49> I'm a bit confused by your example. Python has different design goals than Clojure. Clojure competes with rather high performance languages, Java and Scala, on the JVM and it appears from the OP that its implementors have decided that it can't afford to spend too much time at run-time checking.

Python on the other hand at least attempts to adhere to a principle of least surprise and enforces strong type requirements at run-time. It does this because consistency is generally more important than performance considerations in Python, one of the reasons that Python is _much_ slower than Clojure.

The API for the set constructor in Python accepts any iterable as an argument. Furthermore the elements of a set must be objects that are hashable.

Consequentially, Python sets rule out mutable members, such as Lists, Maps, and other Sets. Sets of Set Objects aren't allowed since Set Objects can be modified. Strings are immutable so Sets of strings are allowed and even frozensets (an immutable kind of set object) and tuples (which happen to be immutable in Python) can be members of sets in Python. I believe that this is all spelled out in the documentation pretty clearly, and the language's built ins and standard library enforce this simple model at the cost of run-time type checking.

Thus,

        set([1,2,3,2]) == {1,2,3}

        # the tuple (10,20) is immutable and hashable
        set([1,2,"abc",(10,20)]) == {1,2,"abc",(10,20)}

        # strings are iterables
        set("abc") == {"a", "b", "c"}

        # lists are iterable and strings immutable and hashable
        set(["abc"]) == {"abc"}

        # comprehensions and generators are iterable
        set(i*2 for i in range(5)) == {0,2,4,6,8}

        # sets are iterable
        set({2,4,6}) == {2,4,6}

        # int 14 is not an iterable
        set(14) <--- error

        # and [2,3] is a list and so mutable and not hashable
        set([1,[2,3]]) <--- error

The interface to the union method for sets also takes an interable so,

        set([1,2,3]).union(["a", "bc"]) == {1,2,3,"bc","a"}
        set({1,2,3}).union({3,4,5}) == {1,2,3,4,5}

<comment><USER48> I'm not questioning that python api isn't clear. Neither is clojure one. Both require the user to read them in order to properly apply them.

I think pythons resolutes only seem less surprising because someone would be used to them? Maybe that coercion is easier to reason about. Im honestly not sure. Like this example:

       In [19]: s = set([1, 2, 3])

       In [20]: s.union({"x", "y"})
       Out[20]: {1, 2, 3, 'y', 'x'}

Is that more clear then explicitly requiring only sets be unioned?

Why the key and the value? The meaning of the key and value have been drastically change now. Maybe this is what all languages do?

anyway, I think i gained a lot thinking this through. Thanks everyone :)

*One error Is I mistakenly said that strings weren't hashable.

<comment><USER49> Oh, I think I understand your question. This is a set literal, not a map literal:

        {"a", "b", "c"}

This is a map:

        {"name": "Fido", "age": 8}

Note the colons.

The point I was making is that Python doesn't make performance trade offs with these set APIs. Set union is in no way surprising. It either gives the correct intuitive result or raises an exception because of incorrect argument types.

<comment><USER48> I'm having quite the day. I think switching between clojure and python is frying my circuit. I know the difference between a map syntax and set and somehow managed to use set in place of map. I think this happened in part because my point is that any output of union(set, dict) is up to the language designer and has no basis in set theory (though i would be interested to here other wise)

        >>> s = set([1, 2])
        >>> d = dict(x="hi")
        >>> s.union(d)
        set([1, 2, 'x'])

apologies for the confusion... I need to proof read my comments more throughly.

</comment></comment></comment></comment></comment><comment><USER10> I did not see the link to the intersection issue. Is it this? ([http://dev.clojure.org/jira/browse/CLJ-1682?page=com.atlassi...](http://dev.clojure.org/jira/browse/CLJ-1682?page=com.atlassian.jira.plugin.system.issuetabpanels:all- tabpanel#issue-tabs))

So "nonsense values" returned by `intersection` means it returns a seq when you pass in a seq? So `(:key_1)` rather than `#{:key_1}`?

</comment><comment><USER50> > The thing I am trying to build is not possible in any other ecosystem today

Umm... what? I'm afraid I don't understand how the "grand vision" behind Clojure adds pixie dust that makes it capable of something another Turing complete language isn't. Care to elaborate?

<comment><USER51> This is the sort of generic programming language flamewar comment we can do without. If you want to discuss questions like this on HN, please pose them without snark.

We detached this subthread from [https://news.ycombinator.com/item?id=11883875](https://news.ycombinator.com/item?id=11883875) and marked it off-topic.

<comment><USER50> As an aside, I don't think this thread turned into a flamewar, there's some good discussion.

Also, s/he started it ;)

<comment><USER51> I take both points but the combination of snark and genericness is still an explosives-handling violation.

Thanks for the friendly responses.

<comment><USER50> > still an explosives-handling violation.

Haha, what a fantastic way to word it. Duly noted.

</comment></comment></comment></comment></comment><comment><USER52> And that he is a well known troll.

<comment><USER51> Not so well known that this doesn't cross into personal attack. Please don't like this here.

We detached this comment from [https://news.ycombinator.com/item?id=11884356](https://news.ycombinator.com/item?id=11884356) and marked it off-topic.

<comment><USER52> It is in his post history here, I didn't know "look at the other things this person says" was considered a personal attack.

</comment></comment></comment><comment><USER53> Time to go back to Tcl.

</comment><comment><USER54> I think elixir is a better choice.

<comment><USER55> I was thinking of learning a modern language for the web back end. After analysing elixir, go and clojure I decided to go for clojure. Uhmmm, maybe go? I don't know :X. Stick with php? Meehhh

<comment><USER56> You could do worse than learning modern php. Esp. if you have some experience with it and as long as you are ready to leave bad habits behind. (Going for a full stack framework might help here by more or less forcing you to do things the right way.)

<comment><USER57> As far as jobs are concerned you can't go wrong with PHP. Clojure jobs are virtually non-existent outside London and even in London Clojure they are scarce. As far as Indeed.co.uk goes even Rails is pretty thin on the ground outside the capital. PHP, JS and Java, on the other hand, are a bag of tricks you can take anywhere and always find work. Keep Clojure for your own projects.

</comment></comment></comment></comment><comment><USER58> _" Basically I want Clojure to be a simple to use language backed by a friendly and active community. What I see now is drifting in the wrong direction, and I'd like to see that corrected."_

Opportunity here to create a company, fix the bugs, improve the broken bits, build an editor and release a better clojure and _charge_ accordingly.

</comment><comment><USER59> The underlying issue to me seems to be that Clojure is still not developed by a team, but by a single developer, who cannot think out of the box.

union and intersect not doing the same thing as in common lisp (accepting lists and vectors), and returning buggy values instead is just a bug, even if the developer didn't have that in mind originally, and doesn't like to support that.

<comment><USER60> Of all the people in the world I can think of with the inability to think outside the box, Rich Hickey has to be at the bottom of the list :)

<comment><USER14> Different people have different boxes.

</comment></comment></comment><comment><USER61> what an annoying post. no real content, but an author desperately trying to prove he's smart.

"To say that I was treated pretty shabbily by David Nolen on this issue almost goes without saying."

<comment><USER62> I would say he backs up his claims quite well, unlike your comment. He gave ample evidence at his frustrations with the progress of the language - <AUTHOR> did you find annoying about it?

<comment><USER63> I see a lot of issues but not a lot of PRs. As a maintainer there is a lot of prioritization going on, and it seems that the things that bother the blog author are not things that bother the maintainers. I also agree with some of the replies on the issues - garbage in garbage out for a function is ok behavior.

One of the cool things about clojure and other languages like this is that these things can often be fixed at runtime - so even if your fix doesn't get accepted you can have a "my-better-fixes" lib you pull in for yourself. A "consistent-set-opts" lib you add to your project.cls for example.

<comment><USER64> In what way is "garbage in garbage out" better than consistent handling and explicit failure, especially for something so well-defined mathematically? That's sort of a lazy argument, imo.

I shouldn't need to pull in more libs for baseline language expectations, either. Core libraries are what languages really are, much more important than just syntax.

<comment><USER31> Because checks to avoid some kinds of garbage can incure significant performance penalty. There is always a tradeoff in that sense, and I think Clojure is pretty well balanced in that way. So, read the docs, try the functions out to see how they work, write tests, and sanitize the data at the appropriate place.

<comment><USER64> Matters so rarely that it's far better to rewrite in those cases when necessary.

<comment><USER31> In core libraries? If low-level functions checked the inputs for each odd case, they'd (often unnecessarily) spend 90% of time doing those checks.</comment></comment></comment></comment></comment></comment></comment>


Professional Air Traffic Controllers Organization - <AUTHOR> https://en.wikipedia.org/wiki/Professional_Air_Traffic_Controllers_Organization_(1968) <comment><USER2> [https://www.nytimes.com/roomfordebate/2011/02/18/the- first-b...](https://www.nytimes.com/roomfordebate/2011/02/18/the-first-blow- against-public-employees/fdr-warned-us-about-public-sector-unions)

> "It is impossible to bargain collectively with the government."

> That wasn't Newt Gingrich, or Ron Paul, or Ronald Reagan talking. That was > George Meany -- the former president of the A.F.L.-C.I.O -- in 1955. > Government unions are unremarkable today, but the labor movement once > thought the idea absurd.

> The founders of the labor movement viewed unions as a vehicle to get workers > more of the profits they help create. Government workers, however, don't > generate profits. They merely negotiate for more tax money. When government > unions strike, they strike against taxpayers. F.D.R. considered this > "unthinkable and intolerable."

People make Reagan out to be some sort of extremist for firing the striking Air Traffic Controllers. The strike, however, was illegal. Federal employees are not allowed to strike. Such bans on public employee strikes are not unique to the US. For example, Germany's constitutional court recently reaffirmed the country's ban on strikes by public employees: [https://www.dw.com/en/german- teachers-cannot-strike-says-con...](https://www.dw.com/en/german-teachers- cannot-strike-says-constitutional-court-in-karlsruhe/a-44171589).

<comment><USER3> The recent WV teacher strike was also illegal. And effective. [https://en.wikipedia.org/wiki/2018_West_Virginia_teachers%27...](https://en.wikipedia.org/wiki/2018_West_Virginia_teachers%27_strike)</comment></comment>


Here's What The Large Hadron Collider Looks Like Through Google Glass - <AUTHOR> http://techcrunch.com/2013/05/03/heres-what-the-large-hadron-collider-looks-like-through-google-glass/

<comment><USER2> That video feels very manufactured.</comment>


Your WiFi is using a stronger encryption than the tech behind 2 factor auth - <AUTHOR> https://hackernoon.com/is-your-2-factor-auth-based-on-a-pinky-swear-and-late-90s-it-security-859f50f25c8b <comment><USER2> If I remember correctly SS7 was proved ridiculously insecure ages ago by a guy who did a talk at DefCon it was quite the interesting talk, will see if I can find it and add it to my comment

EDIT: wasn't a defcon talk I remembered, but a 25c3 talk: [https://www.youtube.com/watch?v=OEcW4HlrpYE](https://www.youtube.com/watch?v=OEcW4HlrpYE) from 2010 :)

EDIT2: [https://www.youtube.com/watch?v=-wu_pO5Z7Pk](https://www.youtube.com/watch?v=-wu_pO5Z7Pk) newer version of the talk</comment>


Technologist: A new magazine from a consortium of European universities - <AUTHOR> http://www.technologist.eu/

<comment><USER2> I'm probably not as squeamish as some others when it comes to marketing disguised as news, as even news with a positive spin can still be informative, but it seems they still have a ways the go if they really want to publish something that doesn't look like press releases. E.g. "Schlundt explains that the efforts have been successful because they are based on a solid scientific foundation and bold policy action."

</comment><comment><USER3> They should employ a proof reader + seems pretty much a public relations department from the universities ... the Augmented Human section mentions none of the really cool tech (and none of the leading researchers in the field). Jun Rekimoto, Pattie Maes, Joe Paradiso, Masahiko Inami, Albrecht Schmidt, Andreas Bulling ... just to name a view (some are actually European). The research they are describing is pretty much boring not even remotely state of the art.</comment>


TorrentNet – Peer-To-peer Sites Using BitTorrent and SQLite - <AUTHOR> https://medium.com/@lmatteis/torrentnet-bd4f6dab15e4 <comment><USER2> Is this inspired by silicon valley season 4? Seems like a cool new Internet idea.

On a more serious note, I love the idea of making the Internet more free, but the issue with this is it serves people who use the Internet illicitly much more than it serves people with more standard use cases. However, it also serves political activists, so it can be good for that reason. I think ultimately that these projects are often so disconnected from the any non developer use case that they fail to meet the needs of people who are trying to get away from censorship.

In other words, who wants this? Are they getting user feedback from people who need it? Could these peoples needs be met with something simpler? If these questions aren't asked, then this project is purely academic at best and at worst empowers criminals.

<comment><AUTHOR> There are benefits other than censorship resistance. For instance, these kind of sites are cheaper to run and are more resilient to DDoS attacks.

</comment></comment><comment><USER3> This is a pretty cool solution for de-centralized web.</comment>


Show HN: A volunteer group to be your sustainability solution advocates - r--man https://en4s.bcsea.org <comment> r--man Calling all entrepreneurs out there who are in the British Columbia sustainable energy market or would like to enter it. We are ENFORS (Entrepreneurs for Sustainability), a volunteer group active since 2017 in the BC Sustainable Energy Association with experience in the local startup, tech, and sustainability ecosystems. We are looking for innovative products or business initiatives in the field of sustainability to help launch or grow.

Think of us as your supporters, advisors, or potential early power users. We start with sharing our first impressions of your website or business idea and extend this all the way to helping you access the right resources to keep your momentum.

If that sounds interesting, head to [https://en4s.bcsea.org](https://en4s.bcsea.org) and fill out our contact form.

Looking forward to hearing about your great ideas!</comment>


Ask HN: Any chatbots capable of remembering context? - <AUTHOR> Anytime I see a chat bot I try asking it to tell me what I just said or tell me what my last message was. They all fail.
With recent GPT-3 hype, I tried it with AI Dungeon and found it even more dumb. It's only a clever like a clever talker who can jump into any discussion and become the center of attention following the pattern of what's being discussed and adding more to it which sounds intersting despite not making any sense.
Is there any system capable of understanding what is being asked? just a simple question like repeating what you have told it? <comment><USER2> With all the hype surrounding GPT-3, super interesting question.

Yesterday I read an article listed in HN, stating that the brain process spacial information together with visual information.

I would like to know if a transformer model is capable of learning current context: Maybe using some other form of neural net combined with other Bidirectional Transformer. That would work as a chatbot engine, though.

<comment><AUTHOR> I found GPT-3 to be dumb. Great conversation artist, but dumb.

When studying, I tried picking up this exact problem, add context in chatbots as a research topic and was advised by my professor to stay away from chatbots because he already tried it and found them super complex.</comment></comment>