HIV as you've never seen it before - <AUTHOR> http://digg.com/news/lifestyle/new_scientist_tv_hiv_as_you_ve_never_seen_it_before

<comment><USER2> [http://www.newscientist.com/blogs/nstv/2011/02/hiv-as- youve-...](http://www.newscientist.com/blogs/nstv/2011/02/hiv-as-youve-never- seen-it-before.html) for those that don't feel like making the detour through digg</comment>


Law Matters – Less Than We Thought - <AUTHOR> https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3439526&dgcid=ejournal_htmlemail_law:psychology:ejournal_abstractlink <comment><USER2> Nice abstract.

Being a judge is a career and an incredibly competitive one at that.

Being a scientist is very similar.

Better to play it safe than to risk looking incompetent. Or worse, politically vulnerable.

Authoritarian technocracies require experts and "consensus" to overwhelm people into popular complacency.

Laws matter less, so Judges matter more.</comment>


Got Hit by "Not Provided"? Grab Your Organic Keyword Data While you still can - <AUTHOR> http://www.searchenginejournal.com/got-hit-provided-grab-organic-keyword-data/86911/ Will this be the next feature that Google will kill? <comment><USER2> Shameless plug: We are developing a tool to try to analyse the not provided keyword. You can use for free here: [https://keyseo.io/users/sign_up?plan=demo](https://keyseo.io/users/sign_up?plan=demo) (Don't mind the landing page, still a awful draft, we are working on a different one.)

</comment><comment><USER3> To me it seems that all this talk of "Google took away my data" is rather silly. From what I can tell, Google Analytics previously would get keyword data from referrer data, which is not passed on when using https. Thus the lack of keyword data is attributable to Google improving their search experience.

I have heard arguments suggesting that Google does indeed have the search referral data, but it is not as easily attributable as when you could rely on http referrers, since it requires matching clicks on a SERP (which powers the webmaster tools data which you get) with people landing on your site. Not impossible, but not trivial either.

It would be really nice to know which search terms people are converting on (for reasons othan SEO). Unfortunately, we don't have that luxury at the moment.

</comment><comment><USER4> Isn't Google Webmaster Tool data even better? It shows you exactly how many clicks for each keyword as well as the number of impressions and its CTR. It's even integrated into Google Analytics.</comment>


Prediction: This Statement Is Going To Come Back To Bite Microsoft In The Ass - <AUTHOR> http://techcrunch.com/2010/07/14/iphone-4-microsoft/

<comment><USER2> Comment in question

"It looks like the iPhone 4 might be their Vista, and I'm okay with that." -Microsoft COO Kevin Turner

for people who like me aren't fan of TC

Source: [http://www.computerworld.com/s/article/9179164/Microsoft_exe...](http://www.computerworld.com/s/article/9179164/Microsoft_exec_mocks_iPhone_4_dubs_it_Apple_s_Vista)

</comment><comment><USER3> A more apt comparison would be Red Ring of Death on the Xbox 360. An annoyance but the product is compelling enough for people to put up with it. There are lots of other fun parallels like Microsoft's slow response to admit there was a problem and their suggestion to put the 360 into a vertical position for better cooling ( _your entertainment center is holding it wrong_ )

</comment><comment><USER4> Apple has 25%, Microsoft has 15%, RIM has 43% of the smartphone platform market share.

That comment will only ever "bite microsoft in the ass" on techcrunch where consumers gossip about the cool new gizmos, and nobody cares about market share.

[http://www.comscore.com/Press_Events/Press_Releases/2010/3/c...](http://www.comscore.com/Press_Events/Press_Releases/2010/3/comScore_Reports_January_2010_U.S._Mobile_Subscriber_Market_Share)

<comment><USER5> At the rate the smartphone market is changing, you need a more current report than that.

[http://www.changewaveresearch.com/articles/2010/07/smart_pho...](http://www.changewaveresearch.com/articles/2010/07/smart_phones_20100714.html)

[http://www.tuaw.com/2010/07/15/millennial-media-report- has-a...](http://www.tuaw.com/2010/07/15/millennial-media-report-has-apple- with-56-of-smartphone-market/)

Apple now has at least half the market and customer satisfaction surveys indicate that Apple is blowing everyone away.

</comment></comment><comment><USER6> The real wtf in this article is the incredibly sexist comparison.

<comment><USER7> I actually feel confused here. While they obviously make comment from the point of view of heterosexual male, they do not degrade or defame women. Granted, they imply that heterosexual male can have feelings and be in relationship with female, but does it constitute "incredibly sexist comparison" to you?

Would it be not sexist for you if it's phrased like this: _"The iPhone 4 antenna issue is a scar on a beautiful significant other. You don't break up with the significant other because of it, you work around it because of her or his other attributes. She or he might even put on some coverup (the bumper) so you don't even notice it"_?

<comment><USER8> Because it's saying 'well, it's good enough to own despite the flaws', it's objectification, and no it wouldn't be alright worded that way - it'd actually be ridiculous worded like that, but it wouldn't be alright worded any other way without completely rewriting it without the male privilege.

</comment></comment></comment><comment><USER9> Hardly. People will mostly forget that statement, if they even heard it in the first place.

</comment><comment><USER10> Fantastic analogy. I guess it was a slow day on the geek blogs for objectifying women.</comment>


Goldman's Mutual Friend - <AUTHOR> http://opinionator.blogs.nytimes.com/2011/01/04/friends-with-benefits/?hp

<comment><USER3> Wow, I've really got to hand it to Goldman. From the article:

 _Thanks to Goldman's imprimatur, Facebook's value increased 20 percent virtually overnight....The other benefit for Goldman in leading the public offering — aside from major bragging rights — is that it can use its marketing, sales and distribution muscle to make sure the value of Facebook at the time of the offering exceeds the $50 billion valuation at which Goldman invested._

Increasing the value of the firm they are investing in? Great job guys.

 _While on paper it seems that these high rollers would be foolish to invest in Facebook at such a lofty valuation, they will still most certainly feel increased loyalty to Goldman for making such an exclusive opportunity available to them._

Giving their other clients investment opportunities not available elsewhere? Awesome. Wish I were Goldman's client. (Note: all of Goldman's clients are accredited or institutional investors, and are fully capable of making their own decisions on whether to buy this Facebook SIV.)

Further, if the value at IPO will be at least $52B ($50B + 4%) (as an earlier paragraph suggests it might), all the clients who purchase this SIV will at least break even.

Overall, it looks like Goldman is doing a great job for all their clients. Keep up the good work guys.

Also, the conflict of interest is nonexistent. Goldman holds a long position in Facebook. So do all their clients. Everyone has the same goal here: increase the value of Facebook.

As for the "average investors" who the article claims will be hurt by all this, there is a very simple way to avoid that: _don't buy FB_. If everyone does this, the IPO will be a failure, and Goldman + Zuckerberg + Goldman's clients will all lose money. If you are very sure FB is overvalued, short it. If you are right you will be taking money from Goldman and Zuckerberg.

<comment><USER4> I can understand Apple, Xbox, PS3, iPad, Linux, Solaris, etc. fanbois ... but can't understand the Goldman Sachs variety.

GS is one of the scummiest of Wall Street's firms, which is saying something.

That they were selling MBS tranches to clients, then simultaneously taking out options that would pay GS money when those exact same tranches failed, really tells you all you need to know.

GS' crimes are so varied and so well documented, I find it hard to believe you could not be aware of them.

Simply asking yourself "what part of this investment is something you would expect a commercial bank to invest in" as you reflect that GS is classed as a commercial bank in order to have access to Fed lending at essentially 0% interest, should perhaps give you pause.

EDIT: note for clarification, that the MBS tranches were assembled/packaged by GS themselves; GS was not simply selling a third-party product.

<comment><USER5> "That they were selling MBS tranches to clients"

Did they tell their clients that these investments were sound? In 1999, I could have called my financial advisor and told him I wanted to buy Pets.com (or whatever) stock. He might advise me against it, but would have sold it to me. And, he might have had it shorted in his personal portfolio at that time without disclosing this to me. Does that make him a bad guy?

<comment><USER4> I believe the best known of the ones that failed was called "Abacus" - <USER2> is a lot of documentation publicly available.

From my viewpoint, representing an investment aas having a particular rating from Moody's or S&P would indicate that they told their clients the investments had a certain ratio of risk/reward.

Common stocks have no ratings from Moody's or S&P; these are interest-bearing investments that supposedly have a certain rate of return per year; though unlike CD's they do not have a fixed lifetime as mortgagees can repay a mortgage early, or refinance, without penalty.

<comment><USER5> I wasn't so concerned with the specific nature of the investment vehicle in question as it seemed the complaint about GS was simply that they had sold to a client a product which they implicitly had deemed a poor choice.

<comment><USER4> Not being a securities lawyer I don't have a 100% accurate answer for you; however I would say there is a difference between common stocks which have no performance guarantees and bonds/warrants/etc which do have guarantees (with risk/reward taken into consideration of course).

</comment></comment></comment></comment></comment></comment><comment><USER6> There's an engineering principle, if you address a complex problem (or any problem) with a complex system, it's going to be buggy. Addressing complex social issues with complex legislation (Dodd-Frank, Sarbox, etc.) results in loopholes (bugs). Many lawmakers surely realize this, but their main goal is re-election, and _doing something_ (the equivalent of Dilbert moving his mouse around) gives the media something to report, which in turn keeps the lawmakers' names in front of the public and feeds the perception of positive action.

The equivalent of engineers are the staff lawyers who actually write the legislation, and cycle between government and industry positions, much like contract programmers; but in their case they get rewarded for the bugs they write in their code by advising industry clients on how to exploit them. (That of course is a simplification. Goldman is using lawyers experienced in parsing complex security laws, not necessarily the same ones who wrote the laws.)

<comment><USER7> "Many lawmakers surely realize this"

I'm not sure. They're lawyers, not engineers, and I don't see any reason for lawyers to conclude "It's fundamentally complex, impossible to get right, and going to have problems" rather than "Well, they just didn't try hard enough to make a good law". And certainly the belief that they can create a solid law through sheer staggering complexity rather than _despite_ sheer staggering complexity is a more parsimonious explanation of what has been happening lately than the idea that they know that simpler laws are better.

There are few enough computer programmers who figure this out even with the math staring them in the face and great engineers all but spoonfeeding these tidbits of wisdom; I can't imagine this is anything like the common perception of law in lawmaker circles, and especially not in circles where people believe activist government is on average the solution to everything.

<comment><USER8> If there's even a debate about having a law, it's because there's a real or perceived failure by the market to do the right thing. In this case, it'd be because Goldman's activities have nothing to do with the proper role of finance and everything to do with exploiting the already existing bugs in the market system.

Nobody's saying that the government should write laws regarding toilet paper manufacturing, for example. There's a difference between "make a working complex system even more complex", and "attempt to fix a completely broken system, with full knowledge that your fix won't be perfect either".

</comment></comment></comment><comment><USER9> I see a lot of people crying "bubble". By my calculations, it doesn't look like a bubble price; it looks like a relatively conservative price, one incorporating a substantial risk that Facebook will collapse. I posted them at <http://news.ycombinator.com/item?id=2062222> a couple of days ago.

My calculations could, of course, be wrong. But I'd like to see comparable calculations from the "it's a bubble" crowd, instead of just sneers at the idea that Facebook could really be more valuable than Time Warner, Du Pont, and Morgan Stanley.

To me, _of course_ Facebook is more valuable than Time Warner. It already intermediates the friendships and owns the private information of almost 10% of the world's population, including nearly its entire upper class, and it's an unregulated monopoly. The question is only _how much_ more valuable.

</comment><comment><USER10> _First, Goldman's cost of capital is close to zero as a bank holding company, it can borrow from the Federal Reserve at negligible interest rates so any capital gain it makes on its venture in Facebook will be sheer profit._

And here we have a very interesting data point reminiscent of an era preceding a previous .com valuation implosion.

Does not compute. Weighted Average Cost of Capital (WACC) is one of the most important metrics for determining a value of a company. This free capital is equivalent to giving Goldman Sachs preferred stock in a pre-IPO. If Goldman- Sachs is given unrestrained liberty to not only determine the "market value" of the company AND the "insider's trading" right to determine the value of individual shares, we have most of the ingredients for another recipe for disaster.

</comment><comment><USER11> I believe facebook shares will be the biggest share rise ever in history. You know why? Because it will run across facebook virally. Anyone who makes money on facebook stocks will announce it to his 450 friends, and so on. The facebook IPO will be huge.

</comment><comment><USER12> It bothers me that the sentiment of this article seems to be "this sort of transaction needs to be illegal" rather than "this isn't a good investment; don't invest".

<comment><USER8> I read the sentiment as "this sector is hopelessly corrupt", which, assuming they're not making stuff up, seems to be the case.

Where'd you get to "should be illegal" from?

</comment></comment><comment><USER13> "Goldman will be creating a "special purpose vehicle" to sell the stock to its wealthy clients and then will charge them a 4 percent initial fee plus 5 percent of any profits."

hahaha what a shitty trade, sounds like standard goldman to me.

</comment><comment><USER14> So how can Facebook's IPO affect chumps like me who are not silly enough to try to buy either Goldman or Facebook stock? How likely is this to blow up on Wall Street? Or when the dust settles will it be just the "private wealth" investors that will have lost some of their fortunes?

<comment><USER15> It looks like you weren't paying attention to the last time Wall Street blew up and tax payers footed the bill to the tune of hundreds of billions of dollars.

<comment><USER14> Oh, I did. I was just wondering if others thought that a second bailout was a likely scenario.

</comment></comment></comment><comment><USER16> So buy Goldman and short Facebook. Since shorting Facebook can't be done, maybe Goldman can create a derivative to facilitate it.

</comment><comment><USER17> Everyone seems to ignore Facebook Credits as a revenue source. That market is still in the very early stages of development, but it doesn't take a lot of imagination to see some very profitable directions for it to go.

In the short run, how much is FB extracting from Zynga alone with the Credits scheme?

</comment><comment><USER18> Wait, isn't investing in something and then making a huge announcement like this called 'insider trading'? The same people who are investing are also purposefully changing the value of the stock through non-market means.

<comment><USER19> Insider trading is a legal term, and is not always illegal. This issue is more about the election of public versus private status (another legal issue) and the rules about who can invest in various forms of private investment (yet another legal issue).

It would be nice if we could ever get to discuss the economic issues of information and efficiency as it relates to investing, but the amount of heat around these issues these days prevents a lot of calculated reasoning about what is best for our economy.

</comment></comment><comment><USER20> The good news: it's the last bubble.

The bad news: it's the last bubble.

The ugly news: massive failures across startups, high unemployment for programmers, dried up funding for years to come.</comment>


Ask HN: Where do you find quality content writers? - <AUTHOR> Let's say you want to create the best available content on one particular topic based on a small set of well-researched keywords. Initially, the task is to develop a corpus of 100 articles of at least 1,000 words each.
How would you go about getting help to research and write the content if you had a budget of...
1. $1k 2. $10k 3. Unlimited resources <comment><USER2> Quality likes quality: you need to source some to attract others. So invest in some and then aim to acquire merit to attract more.

Duration is key. Look at aldaily which has transitioned from one curator to another and remained valuable.

Do not mistake discussion channels for free speech spaces. Your publication can and should moderate feedback and declare upfront you moderate.

By all means have a CoC but don't get sidetracked into CoC wars.

Professional writing is not cheap. Do not attempt to undercut the market nor claim "you will get coverage and acquire merit by giving me a freebie" to authors.

Pay per word and pay per article are not comparable.

Hire good lawyers. You are exposed to contact law issues, IPR issues and libel issues.

Advertising requires it's own policy. You won't retain liberal minded readers with NRA gun shilling.

Avoid cheap markup tricks.

Learn from the long reads trend.</comment>


'Radical change' needed after latest neutron star collision - <AUTHOR> https://www.quantamagazine.org/radical-change-needed-after-latest-neutron-star-collision-20200220/ <comment><USER2> > Based on the recent observation, LIGO scientists estimate that these heavy > pairings should be almost as common as the lighter binary star systems that > astronomers have been studying for decades. Big neutron star pairs should be > all over the universe, including our own Milky Way. Why, then, have they > never been spotted before?

I don't understand this part. Observations: lots of light neutron star pairs, one heavy pair. This implies heavy pairs are as common as light pairs? How? I would've thought it implied heavy pairs exist but are much less common. What am I missing?

<comment><USER3> The observation of lots of light pairs was from directionally focused visible light telescopes, which is a very heavily biased estimator.

LIGO has flipped a weighted coin twice. It came up heads once, tails once. That suggests that the weighting is probably not 999999 to 1 (or whatever 5 sigma works out to) in favor of heads, as the current models (based on visible light observations) predict.

<comment><USER4> Your second paragraph is an excellent summary of why this data is super impactful.

Curious about the "but the sample size" crowd.

<comment><USER5> I was thinking the other day along these lines - statistically, I am most likely to be born when the world's population is at its peak. But apparently it is still growing and has been since I was born. Is this surprising? Is it more surprising if it continues?

<comment><USER6> Prior probability will tell you a lot about populations, but very little or nothing about individuals.

For example the prior probability of someone being born with your specific genetics is so close to zero it's not worth mentioning. That's true of any specific combination, yet humans exist and so it's guaranteed that some combinations get to 'win the lottery'. It's just not knowable beforehand which ones. In the context of a specific outcome though, and only that context, prior probability just doesn't matter.

I think the problem is our brains can't help 'polluting' the context of an outcome with unrelated contingent information. This makes it very hard for us to reason about these questions.

<comment><USER5> "For example the prior probability of someone being born with your specific genetics is so close to zero it's not worth mentioning."

I don't understand what this has to do with distinguishing between individuals and populations. You could just as well say that the probability of a whole population being exactly as it is, is even lower.

You reference "polluting the context of an outcome with unrelated contingent information", but isn't that what you just did? If you think that confuses the issue, then what's the point?

</comment></comment></comment></comment></comment></comment><comment><USER7> This presumes that the merger was a neutron-star binary. If the progenitors were black holes, there's no need to rethink nuclear physics.

One would then have to contend with estimating the rate of stellar-mass black- hole mergers, but at least there's no need to break our understanding of QCD at the same time...

Time will tell. As the gravitational-wave detectors trigger on more neutron- star mergers with optical counterparts, the answers will become clear. If there are lots of events without optical counterparts, they're more apt to be black holes.

</comment><comment><USER8> Not an astrophysicist so it might be a stupid question. If the combined mass of the pair is calculated to be well outside the range of what we find in our galaxy, could it be that it is not the mass but some other inputs to the calculation? From what I understand there is still a challenge to determine distances to the very far objects (that is one of the reasons for recent news about "Hubble not so constant")

<comment><USER9> In this[1] article, they show how one can estimate the distance using only measurements of the gravitational wave signal. It uses the fact that we can estimate the masses[2] based on the change in frequency of the chirp signal.

[1]: [https://arxiv.org/abs/1602.04666](https://arxiv.org/abs/1602.04666) (pages 15-16)

[2]: [https://en.wikipedia.org/wiki/Chirp_mass](https://en.wikipedia.org/wiki/Chirp_mass)

</comment></comment><comment><USER10> We are barely beginning to understand things about the universe, based almost entirely on wholly local observations. Nothing seen in the wider world should be considered surprising or out of bounds. Expecting to be able to simulate the development of the whole universe accurately with our primitive sticks- and-rocks equipment is nothing short of foolish. Do we see things different from what we predicted? Fine, we see them. It's a big universe, and we have another billion years to figure it out, provided we manage not to blow ourselves up first. The next generation will not lack for mysteries. Savor them.

</comment><comment><USER11> Can't the larger number of massive pairs be explained by a third star that was torn apart and fed the pair, rather than limiting to supermassive originating stars?

The other implication of the article is that they want to consider a supernova that spawns two neutron stars, or just bigger neutron stars?</comment>


Ask HN: Hackathon ideas - <AUTHOR>

Hi, I and my friend at face palming over ideas for a hackathon. Any ideas would be appreciated. Crazier it is, better. Thanks. <comment><USER2> Six degrees of separation / mutual mutual friends app.</comment>


SXSW 2006 podcasts - <AUTHOR> http://2006.sxsw.com/coverage/podcasts/ <comment><USER2> Wouldn't these be a little bit more interesting?

<http://2007.sxsw.com/coverage/podcasts/>

<comment><AUTHOR> Yes, but they're not all up yet. In the meantime I thought people might enjoy some of last years talks</comment></comment>


All That Remains - <AUTHOR> https://www.linkedin.com/pulse/all-remains-dr-jessica-brandes/ <comment><USER2> Damn. I think we all need reminders like this to savor our own personal status quo, because it can be taken away from us without warning. Somebody has to be the end of the bell surve and sooner or later it's going to be you.</comment>


The Grep Test - <AUTHOR> http://jamie-wong.com/2013/07/12/grep-test/ <comment><USER2> So basically I can't commit anything containing the slightest form of metaprogramming? Seems a bit extreme to me. A solution is to go for the more concise and robust metaprogrammed piece of code (the example of the form with the User object is a good one) and add a comment mentioning the methods called in there.

The "smartass" way of programming is sometimes overused but it does have its benefits. When you're metaprogramatically setting the attributes on the User, you're also avoiding needless and error-prone repetition and making sure that this central piece of code will either crash all the time or work all the time for all attributes. This has tremendous value.

So while I understand the point about this article, I might want to add a pinch of salt to the dogma underlying it.

<comment><AUTHOR> Your example of adding a comment mentioning the methods called in there would indeed pass the Grep Test, and is a reasonable compromise when there is a real call for dynamic declaration.

I think there are definite ways of adding metaprogramming functionality without breaking this test. For instance, in the first JavaScript counterexample, if the iteration was over [{attr: "position", fn: "getPosition"}, {attr: "direction", fn: "getDirection"}] instead, the Grep Test passes, and you get much of the same benefits, with a very minor duplication that I'd argue is worth the cost.

<comment><USER3> So update your blog post to say that. I had the same reaction as GP.

<comment><AUTHOR> Done.

</comment></comment></comment></comment><comment><USER4> The point here is not that metaprogramming is universally bad, it's that it should be used as a last resort (or second-to-last resort to codegen, depending on your platform/application) and you should feel bad when you need to use it.

Simply using it to save keystrokes is pretty lame since you'll spend much more time maintaining code than typing out the original and explicitness is valuable when returning to a piece of code. Additionally, if you find yourself that you need a lot of metaprogramming for a lot of things it's often an indication that you could just refactor your code using static idioms and be better off.

Not to mention that the more you use metaprogramming, the more likely it is that you or someone else will kill some runtime optimizations of the JIT.

IMO, syntax matters way less than people tend to think it does, and the additional implementation complexity and astonishment cute syntax introduces tends to make the trade-off not worth it.

<comment><USER5> _The point here is not that metaprogramming is universally bad, it 's that it should be used as a last resort ... and you should feel bad_

 _you could just refactor your code using static idioms_

 _you or someone else will kill some runtime optimizations of the JIT._

 _syntax matters way less than people tend to think ... astonishment [sic] cute syntax_

Many intelligent, design-savvy people would strongly disagree with you. Besides the obvious gains in the ability to create DSLs, there is a power and fluidity in metaprogramming that is not possible any other way.

Speed (as, say, provided by runtime optimizations from a JIT compiler) is not always critical. If it was, one probably should be using a language other than Ruby or Javascript; they're meant to be flexible, powerful languages, and their emphasis is not on pure speed.

Syntax is not "cute." Humans are going to read and use this code, and the more it reads like English, the more likely it is to be understood.

<comment><USER4> Unsure why you [sic]'d astonishment; I was referring to [https://en.wikipedia.org/wiki/Principle_of_least_astonishmen...](https://en.wikipedia.org/wiki/Principle_of_least_astonishment), a well-accepted principle of UX which certainly applies to the UX of languages and APIs.

I am unsure what you mean by the "obvious gains" you get from DSLs. I see many DSLs as a code smell -- that the runtime environment is _almost_ expressive enough to express the syntax construct the DSL creator wants, but not quite.

The implementation of DSLs tends to judiciously use closures, operator overloading, dynamic getters and proxies such that it's non-obvious what's going on under the hood. Sometimes that trade-off is worth it. Usually it isn't, in my experience.

I believe (I could be wrong) that DSLs were coined around 2004. I don't think that is a long enough history for us to even think about simply accepting that they are a good idea in and of themselves -- garbage collection was invented in 1959 and is still being debated!

I see the speed argument all over the internet being presented as a binary argument: either you care about speed or you don't. That's simply false -- I care about order of magnitudes for speed. I personally don't care if I can encode h264 faster in JS than I can another way, but I do care that my event handlers execute within 16ms so I don't drop frames in the browser.

Some syntax is certainly cute. Additionally, making syntax readable like English should be a non-goal IMO; for many people, Lisp is far more readable than SQL, which is much closer to English.

<comment><USER6> 2004 seems really late for the inception (or possibly formalisation) of Domain Specific Language, I assume that you're talking specifically about embedded (also called internal) DSLs, otherwise SQL at least is from 1986.

As an earlier example of an Embedded DSL, the book PAIP[1] included prolog embedded in common lisp in 1992.

It could be argued that the loop macro in Common Lisp is a DSL for describing iteration. If not loop, then certainly regular expressions are a common EDSL for describing a regular language, and performing operations with those languages against strings?

I found this snippet from Computers in Crisis [2] which seems to describe domain-specific languages in familiar terms from 1975

        Most domain-specific programming languages can be categorized in one
        of two ways; either as a "sugared" general ... of programming, in
        fact the style of problem solving, embedded in and supported by that
        language remains unchanged.

[1] [http://www.norvig.com/paip/README.html](http://www.norvig.com/paip/README.html) [2] [http://books.google.co.nz/books?id=QndQAAAAMAAJ&q=%22Embedde...](http://books.google.co.nz/books?id=QndQAAAAMAAJ&q=%22Embedded+Domain+Specific+Language%22&dq=%22Embedded+Domain+Specific+Language%22&hl=en&sa=X&ei=fq3gUfOmG8e_kQX59YG4AQ&ved=0CDkQ6AEwAg)

<comment><USER4> Yes, you're right, I did mean embedded DSL.

<comment><USER7> Smalltalk has been doing embedded DSL's since its creation in the 70's; they are not a new phenomenon.

</comment></comment></comment></comment></comment></comment><comment><USER8> > _I'm sure by this point, a few of you have thought "Hey, but Rails fails the > Grep Test!". This is absolutely true, most notable due to the dynamic > find_by__ finders, and the dynamic __path URL path generators._

OK, sure, but after you've grokked the first "find_by" usecase...do you really need documentation for all the other kinds of "find_by"'s that you'll use?

In any case, I'd agree that meta-programming is too often abused, but the proposed grep test is far too strict. And, inability to create complete documentation for every single kind of method token is not really the main reason to avoid meta-programming...I'd say performance and the propensity for abuse are better motives.

This pull request re: removing most of Rails' dynamic finders in 4.x covers the topic nicely:

[https://github.com/rails/rails/pull/5639](https://github.com/rails/rails/pull/5639)

<comment><USER9> _> In any case, I'd agree that meta-programming is too often abused, but the proposed grep test is far too strict._

I agree. In a CMS I'm coding, the core MVC-like mark up tags work by using function tables in Go. Such code would fail the grep test - but it makes a lot of sense in the project and it actually very readable as well. In fact in that particularly use case, not only is the code _more_ readable, but it's also more efficient.

But this is the age old problem with having rules in languages (both human and programming) - more often than not, there are exceptions that are perfectly legitimate use cases.

</comment></comment><comment><USER10> Yes, grepping for a function and not finding it anywhere in the codebase is very annoying. I've had to maintain this sort of thing before. It's like in bash saying `${FOO_$BAR}` (if such a thing is possible). It gives me shudders.

I also agree that Rails gets a pass. It's a little different when you have a stable (well, sort of :-) API with dozens of books and thousands of blog posts. It was annoying to learn what was going on at first, but that knowledge is more long-lasting so worth a bit more pain.

<comment><USER11> Agreed, though I would say that if you take away the well known Rails idioms that fail the test, there are still some pretty egregious violations.

For example, try to step through the code that figures out which validation callbacks to trigger for an ActiveRecord model. You'll be led through at least 3 dynamically eval'd methods.

I had to do this recently and probably would have given up had there not been Foo.method(:bar).source_location to point me in the right direction.

</comment></comment><comment><USER12> The examples shown in the post aren't wrong because they fail the grep test, they are wrong because they A) capture an uninteresting abstraction that is not likely to see much usage as the program gets more complex, B) mix up domain code with tooling code that if at all gets developed should end up being part of a framework, plugin, base class etc.

The general underlying problem is that a lot of people stick with those "principles" (which are rules of thumb, often weak ones at that) they have read somewhere without developing a real understanding of software design. Slogans like DRY or SRP seem to blind people to often simple forseeable consequences of their design decisions.

Software design boils down roughly to two abilities: one is imagining a great many ways of structuring a program, the other is the understanding of practical consequences of a given program structure. So a good software designer must ask him- or herself: why code repetition is a bad thing? And the answer is that there is absolutely _nothing_ wrong. What is wrong is that a logically or structurally common aspect of the problem didn't receive the recognition in the form of an abstraction (a method, class, variable, interface ...). Then you waste time by not being able to reuse this abstraction, when something about this common aspect changes you are forced to go through fifty places and modify the code, but the worst thing is that there is a limit of the amount of details a programmer can keep in his or her head, and the less you are able to structure your program the more restrictive will be limit of the problem complexity you will be able to tackle. That's the reason software design is at all important.

There are cases however when there is no real logical common denominator to two pieces of code and they are similar practically by accident. It is just as wrong to abstract an accidental similarity as it is not abstract an existing one; soon the requirements change and the abstraction will have to be abandoned, code copied and developed in divergent ways.

Finally, people start attempting metaprogramming way before they had learnt enough about structuring programs using basic means, like breaking things down into classes and methods appropriately, data-driving your programs etc. Yes, this is actually a skill, and unless you rewrite some of your own programs 5-10 times and compare their structure you won't learn it. I also recommend reading some classical books: SICP, Refactoring, Refactoring To Patterns, Effective Java, Programming Pearls.

And the ultimate lessons come from maintaining your own code for a few years.

<comment><USER13> So you're saying that code duplication is only (usually) a symptom of failing to factor out a relevant abstraction, rather than something to be fought in itself? On the first reading, it looks like you say "there's nothing wrong with code repetition" and then immediately list all the things wrong with it; instinctively, "a logically or structurally common aspect of the problem didn't receive the recognition in the form of an abstraction" is synonymous with code repetition.

<comment><USER12> Talking about code repetition is focusing on the wrong thing, consider how metaprogramming is used in the article: it mechanically generates the same code that previously was simply in place in the class. It doesn't make anything simpler to understand, it doesn't allow to modify common logic in one place and in the future it is likely those common "behaviours" will diverge anyway because the similarity is just very weak and superficial. I would instead advise to strive to extract all possible interesting abstractions and if you pushed yourself really hard to do it and there is some repeated code left at the end, it might just be fine to leave it as it is - the cost of removing duplication might outweigh the benefit.

In the example posted, position and direction are both vectors, recognizing them as such would provide a much better way of checking for "zeroness" and for negation. It's a nice educational aspect of this toy problem the author seems to not have noticed himself. There is often a similar elegant way out of real-world complex problems that doesn't involve fancy meta-programming but just good abstractions, putting right data in the right place etc.

</comment></comment></comment><comment><USER14> No, this is wrong, wrong, wrong.

Ok, it's actually right under one false assumption: that we are limited to using our existing text-based tools like text editors, grep and so on. As long as we use these existing tools, this advice is quite valid.

However, we are absolutely not limited to existing tools, we can and should make new ones that augment how we work and allow us to reach more dryness without compromises. You could have tools that let you work with ASTs, that expand code on the fly, show you higher level information, let you debug and step through sections of code effortlessly.

In the end, dryness is good, because it means you have less repetitive work to do when things change (and software is all about changing, unless you don't want to make progress). So it's very well worth investing into being able to achieve dryness more naturally without the downsides.

To quote Bret Victor, stop "blindly manipulating symbols." (You don't have to do do so overnight, just as long as it's a goal you work on achieving as time goes on.)

<comment><USER15> yes, it's right, right, right. Because your clever AST savvy tools will _fail_ in the presence of metaprogramming, unless you restrict it to patterns the tool knows. And then you're halfway towards static typing with inference.

Yes, grep is primitive for this task. We have much better tools for static languages, and they are great. It will be great to get them for dynamic languages. But they will fail in pretty much exactly these cases where this primitive test fails. Because halting problem.

<comment><USER16> If your metaprogramming is happening at compile time, and your AST savvy tools are savvy enough to work on the final (all macros evaluated) form of the code, then I don't see why they should fail?

<comment><USER17> If you wait until the final form of the code, it would seem very difficult to trace back from function symbol to its generating/binding macro. That is, how do you know which macro bound a specific function? Hope for no ambiguities, I suppose. Maybe it's not a problem, but I'd think the main point of such a grep tool is to point back to the originating code, right? Merely detecting that a specific function symbol is bound is not quite the same.

</comment></comment></comment></comment><comment><USER18> Yes yes yes. It's important to have code standards that enable code to be easy to understand easy to navigate.

I work in C++ all day and loathe when functions are fully implemented in the class declaration. Keeping them seperate with full ClassName::FunctionName(...) scoping makes finding functions exceedingly simple and friendly. Keep implementations separate means the full class declaration is easy to read, parse, and understand. I don't want to scroll through hundreds of lines of code just to see what functions are available.

<comment><USER19> Aren't there circumstances in C++ when this isn't possible? e.g. some uses of templates

<comment><USER20> No, you can implement methods outside the class declaration even with templates. It just has to be in the header file rather than the cpp.

</comment></comment></comment><comment><USER21> Sorry, don't buy it.

A published & concise interface wins over an undocumented redundant interface. Explicit-only just takes you down the path towards Java and COBOL.

<comment><USER22> While I agree with this idealistically and wish that all the code I've come across adhered to published interfaces, unfortunately that hasn't been the case.

Published interfaces may also not be possible in certain code bases or frameworks -- think of a Chef recipe for instance where most (ruby) code is being written to directly interact with the system rather than provide a service to other parts of the system. Dynamically generating variable names and key/value pairs in Chef recipes is a common pattern I've seen which makes grepping and isolating issues difficult if not impossible.

</comment></comment><comment><USER23> Ehhhhhhhh not really. If you're using metaprogramming or abstract programming of any kind, it's _usually_ for a good reason, and DRY in itself is worth simply not being able to find every single reference to your metaprogrammed item in your codebase.

It's an artefact of the design. You simply need to know how the abstraction is done, and then you look for invocations of that abstract more general form. It's not that difficult, and if it's being done, it is almost without exception a better way to do the thing.

If metaprogramming is not a better way to do the thing being done, and adds confusion and decreases reusability, then you shouldn't do it, but that's a tautology and doesn't mean we have to be able to grep for everything we ever write.

<comment><USER24> Honestly, in my professional opinion probably 60% of the usages of metaprogramming seen in the wild fail the "for a good reason" test pretty badly. Most of the time it's just the author being clever to save a few lines.

But I don't see why metaprogramming should inherently fail the grep test anyway. Sure, your property/thingy/whatever (an access method for a field automatically generated from a database, say) might be generic and generated at runtime, but its name should still be written down somewhere authoritative, even if it's in a schema or (if nothing else) a documentation file. That stuff should still be in your tree and greppable, and if it's not your code has discoverability problems.

</comment></comment><comment><USER25> This is the second time this week I've seen "counterexample" used to mean "something that is bad because it breaks the rule, thus showing why the rule is good" rather than "something that invalidates the rule, thus showing that the rule is bad". Is this a real trend in usage or have I just been unlucky recently?

<comment><AUTHOR> I agree that this usage isn't really in line with how it's used in mathematical proofs. Do you have a better concise suggestion I can keep in mind for next time?

<comment><USER26> anti-pattern?

</comment></comment></comment><comment><USER27> One thing that can often help with this is to have a good REPL. With it you can dive into and explore the code as it is at runtime. For example, a common way that I figured out Rails was to open the console and use obj.methods to see what methods are available.

Other languages in which I've enjoyed REPLs include Python, JavaScript and Haskell. Two languages I have not found a good REPL for are Java and C++. Is anything of this sort available there?

<comment><USER28> Yes there is Cling for c++. Its really awesome. [http://blog.coldflake.com/posts/2012-08-09-On-the- fly-C%2B%2...](http://blog.coldflake.com/posts/2012-08-09-On-the- fly-C%2B%2B.html)

</comment></comment><comment><USER29> If you think this is good, wait until you find out about statically typed languages and IDEs with code navigation features.

<comment><USER24> No, you can do this sort of madness in C too via function pointer tables. Give the function pointer field in your struct a commonly-grep-spammed name like "close" and watch your readers go mad trying to figure out what xxx->close() does.

<comment><USER30> Virtual tables are not quite the same thing.

You can grep for every instantiation of the struct in the code-base.

If anything, macros are more problematic:

      #define VTABLE_INIT(prefix) \
        (struct vtable){ .add = &prefix##_add, .sub = &prefix##_sub, and so forth }

</comment></comment></comment><comment><USER31> An important distinction is between mature (or matur-ish) library code and your consuming code base:

      - library code publishes an interface and can do what it wants
      - your client/application code should be greppable

There isn't a sharp distinction between the two, but it's a pretty big headache if developers are using heavy metaprogramming everywhere in your project.

<comment><AUTHOR> Agreed. I suppose the more important test for library code is "googleability" rather than "greppability".

</comment></comment><comment><USER32> I must be pedantic and separate the definition of "metaprogramming," and "dynamic programming;" of which this is the latter.

The reason this difference is important is that _metaprogramming_ is structured and explicitly defines the change in the program's semantics.

Thankfully I have never seen code like what was posted in my experience with Python so far. _Explicit is better than implicit_ which the code example in this post would fail to pass IMO. Dynamically dispatching to names that don't exist in a class' published interface at call-time is a big no-no in my book.

 _Although practicality beats purity._

I haven't seen it yet but that doesn't mean there is a practical reason to use this method of dynamic dispatch. If there were one and it gets a problem solved NOW rather than waiting to find a better solution -- it might be worthwhile.

However it's a price you have to pay.

I think the grep-test is at least a good way to test the waters with a bit of code. I don't think it's a universal end-all-discussions rule.

<comment><USER33> Dynamic programming already has a meaning: [https://en.wikipedia.org/wiki/Dynamic_programming](https://en.wikipedia.org/wiki/Dynamic_programming)

<comment><USER32> Right, thanks for pointing that out. That makes this what, then? Hash-blob programming? :)

</comment></comment></comment><comment><USER34> I totally agree with this. It's one of my pet peeves... dynamically generating method names so you can't actually search for them. Personally, I think code readability is one of the greatest goods in programming, and in general I would tend to place it above DRY as a priority (within reason)... particularly for mature, large, complex projects that require large teams (meaning lots of new people). And for the most part that's what I'm always hoping I'm building.

</comment><comment><USER35> I don't necessarily disagree with the article, but maybe the solution is a new kind of search. One which understands languages, statically analyzes a source tree, and searches the ASTs for the tokens you're interested in.

This would also have the side benefit of being able to produce better designed search results.

EDIT: I suppose searching the AST wouldn't be enough, you would have to evaluate the code to some extent to be able to search these properties.

<comment><USER36> Yeah. This is my biggest gripe working with dynamically-typed languages, especially if the project is at all large. If I have SublimeText or Vim, I'll be equally productive in Python as I'd be in Java. But give me Eclipse/IntelliJ, and I can blow the pants off myself in terms of efficiency working in Java compared to working in Python with any Python IDE (that I'm aware of). There are just so few good tools for dynamic languages compared to static languages.

The situation is uniquely bad in JavaScript, since JavaScript doesn't formally have modules, functions can take any number of arguments, there's the funky scoping, and so forth. Not that good tools don't exist, but it makes it difficult for a JS IDE to enable working across files like a Java IDE can.

<comment><USER35> Agreed, maybe that's why fewer tools (if any) exist to do things like programmatic refactoring in JavaScript (does WebStorm do that at all?)

That being said, I've found the language a pleasure to work with (aside from browser incompatibility issues) and with the proper application of design principles such as modularity (check out require.js and the r.js optimizer) and, yes, DRY, I can be just as productive, if not more so, in JavaScript as I am in any statically-typed language.

<comment><USER30> Which statically-typed languages have you tried?

<comment><USER35> I've got varying degrees of experience (some professional, some not) with C++, C, Objective-C, Java, ActionScript 3.

EDIT: Also C# (so many languages, I can't even remember which ones I've used sometimes). I'm also not including TypeScript or Dart (optional static typing), which I've technically "tried", but don't know much about.

<comment><USER30> The ml style statically typed languages are very different from all of these (in good ways).

For example, in Haskell you can write code as if you're in a dynamic language without annotating all the types and yet you get all of the benefits of types. It's the best of both worlds.

Concluding that static languages suck after using java and c++ et al is a common mistake, and is understandable.

<comment><USER35> Well, I never said static languages suck :) I really like static typing actually, and have seriously thought about using TypeScript or Dart. I've also got years of professional experience with C++ and AS3 and I love them both. I think Java is a fantastic language. And Objective-C...is growing on me ;)

What I did say was that _I_ can be just as productive in those languages as _I_ am in JavaScript, if not more so. It remains to be seen whether I can gain more productivity with TypeScript or Dart.

</comment></comment></comment></comment></comment></comment></comment><comment><USER37> _When working with dynamic code, it's an incredible boon to productivity to be able to quickly locate the definition of functions so you can build a complete mental context about what's going on._

Imagine the 'incredible boon to productivity' you could get from tools (text editors, IDEs) that can deterministically show you all references or definitions of any method, variable, or class throughout your codebase whenever you want. (Hint: this isn't a dream--this is a huge plus of working with statically typed languages.)

For all of the pop-trendy love that dynamic languages seem to get for 'being fast for development,' (read: hacking) it's tragic how much they slow you down when you need to start hunting down where the hell something was magically (or meta-) declared or changed, especially when you're working with someone else's code (read: real life.)

The grep test seems like a great approach if you're stuck with a dynamic language. Of course, we don't always have the luxury to choose the technologies or platforms that we work with, but you've got the choice, a statically typed language solves this problem out of the box.

<comment><USER21> Sorry, my Common Lisp system does this quite well. Other dynlangs should be able to do it too....

<comment><USER30> Doesn't CL also fail the grep test? You can generate function names on-the- fly, can't you?

<comment><USER21> Separate compile-time from run-time....

(DESCRIBE #'functionname) from the REPL will give you information about the function; you can also pick up source if you configure it right.

The key idea is that software as written only loosely defines software images as they are live. 'Static' languages attempt to ensure that there is a tight correspondence, but dynamic linking defeats that in part.

Image based software ideas take this idea and run with it: that's why you download Smalltalk images, not smalltalk source.

Anyway, food for thought. :-)

</comment></comment></comment></comment><comment><USER38> I think this is a legitimate issue, though I'm not sure I really agree...there just seem to be too many places where it provides too much utility. That said, I tend to change my opinion on the topic fairly frequently, based upon whether I was last writing something where dynamic function declaration was convenient or last looking for where a function was declared.

One thing I think the post might emphasize more thoroughly is that dynamic function invocation (at least when the function is defined in the project scope), is probably _far_ more problematic than dynamic function declaration, particularly if sometimes the function is explicitly invoked, and sometimes dynamically. In this situation, I'll generally try to document that the function is dynamically invoked with the function declaration, but I'm always unsure what exact information I should put there. Simply saying something like "Dynamically invoked -- grep will not find all usages" is a minimum, but I often want to add more than just that.

<comment><AUTHOR> Agreed. I do comment on dynamic invocation being more problematic when I say "As a broad generalization, I would say dynamic declaration is occasionally worth the tradeoff, but dynamic invocation is almost never worthwhile.", but it perhaps should've been a larger part of the thesis.

</comment></comment><comment><USER39> Another one of those things you never have to worry about if you use a statically typed language.

<comment><USER40> That's actually not true. For instance, the game Alpha Centauri generated custom dynamic functions in RAM at runtime to draw user created units.

<comment><USER41> How do you know that? I'm not saying you're wrong, I'm just curious. Did you work on the game? Are you a hardcore modder?

<comment><USER40> "When I first came onboard with Loki, the Alpha Centauri Plantary Pack was my first porting project. I didn't know what to expect from commercial game code, but I sure wasn't expecting what I found in the SMAC codebase. Tens of thousands of lines of assembly code was in SMAC, some of which was self- modifying. I spent most of my time looking at memory in the debugger and flipping bits."

</comment></comment></comment></comment><comment><USER42> My first impulse is this is stupid. It means your tools aren't smart enough. Use an IDE, use aigrep, some tool that knows what to look for.

A better title would be "Don't use a fastening device if it fails the hammer test."

Are you don't use a tool that generates SetFunkyColumnName from funky_column_name data spec ? Or "I can't find the click handler in the .html, quit using jQuery" ?

I have been at the bottom of steep learning curves multiple times where I couldn't figure out where stuff was coming from. In most cases I got over it

Use the appropriate tools that get the job done and make you and your team productive. Tools and ideas evolve at different rates. Not all tools or ideas are implemented properly the first time, and not all tools or ideas are necessarily good/useful. But we'll never get any further if we don't try...

</comment><comment><USER43> The "grep test" doesn't just help humans and IDE's. Closure Compiler's ADVANCED_OPTIMIZATIONS mode ([https://developers.google.com/closure/compiler/docs/api- tuto...](https://developers.google.com/closure/compiler/docs/api-tutorial3) ) only works with JS code that can pass the "grep test". Setting or getting properties using dynamically generated property names won't work (even if Closure Compiler could understand your intent, it would have to know at runtime which minified name the concatenated parts should result in).

So in this case, writing longer, "grep-friendly" JS code can actually reduce the size of the JS payload you serve to your users.

</comment><comment><USER44> There is always going to be code that takes more than grep and a glance to understand. Sometimes you won't fully grok it until you've stepped through it line by line, even without "tricks" like metaprogramming. And more often than not the "tricks" make it more concise, less prone to bugs, and easier to understand.

It's madness to classify all use of metaprogramming as abuse. Perhaps you need to pour a glass of wine and learn to savor the source code, and to appreciate the power of modern programming languages.

</comment><comment><USER45> Or... we improve the tools, instead of limiting the expressiveness of languages we use just to make grep happy.

(See Yegge's grok project, unfortunately he doesn't blog anymore)

</comment><comment><USER40> Can't say I agree with this. A decent IDE has no problem tracing usage of dynamically generated methods etc. I know the JetBrains stuff can for Python and Ruby.

<comment><USER46> I don't want to be dependent on a single IDE to write or maintain code. Besides the annoyance of not getting to use what I want, what happens when the IDE stops being supported, but you still have to maintain the code?

<comment><USER47> thats a common argument against IDEs but i think it doesnt reflect reality. The most powerful IDEs like Visual Studio, Eclipse, XCode, IntelliJ IDEA have all been around for more than a decade and wont be going anywhere. Of course if you use some less popular product it might get abandoned, but the same can happen to less popular open source projects.

All the Textmate users now seem to be burned and always fear the software they use will die, so they stick to open source tools only. Those are okay for dynamic languages and smaller scope projects but i still find IDEs indispensable for large codebases and languages like C# or Java.

<comment><USER40> Not sure why TextMate users would feel burned. SublimeText is fully compatible with textmate bundles and cross-platform to boot.

</comment></comment></comment></comment><comment><USER48> Why not use a system of (unified) comments interspersed in the code to demarcate various elements? A sort of index.

The idea is that programming languages allow too much flexibility in form and syntax for any indexing system to accomodate the full range of possibilities. And "coding style" rules are apparently too restrictive on creativity: they are too difficult to enforce. And hence a solution would be better to focus not on the code, but on the comments. Force programmers to adhere to a uniform commenting system.

The OP mentions ctags. It's not a perfect system, but it's still in the BSD base systems so everyone who has BSD has a copy of the needed programs. That's a start.

What about cxref? Another old system that's probably not perfect, but seems like it was aiming in the right direction.

I've never understood why programmers obsess about things like verbose function names (that make lines go way over 80 chars and bend across the page... with identation it becomes almost unreadable to my eyes) instead of just providing an index of all functions and including the verbose information in the index, not the code. vi (and no doubt emacs too) allows you to jump around easily so you could look things up in an index quite quickly.

Why do Wikipedia pages have an index of footnotes and references at the bottom? Why not stuff all this information into the words in the body of the article? Why do books have indexes? Why do academic papers use footnotes? I don't know. But I'm accustomed to these conventions.

I also don't know why code uses verbose function names and generally lacks an index or footnotes. But I guess programmers have just become accustomed to these conventions.

</comment><comment><USER49> "As a broad generalization, I would say dynamic declaration is occasionally worth the tradeoff, but dynamic invocation is almost never worthwhile." <\-- huh? What does this even mean?

This entire post is silly.

1\. Not being able to grep for code has nothing to do with being DRY.

2\. Being able to grep for something doesn't make it correct. Nor does it make it less maintainable if you don't used named functions.

Moving on...

</comment><comment><USER50> This is a little silly. My game engine dynamically invokes lambdas, and script files dynamically added to Actors at runtime with reflection, and such all the time, and it's well-documented and maintainable. I can't think of a reasonable way to implement this stuff that passes this grep test. Unity development fails it too I guess?

</comment><comment><USER51> _The Grep Test_ is interesting, but it is too extreme for me. I have this thing I call the 'No Lie Principle.'

The idea is that when you look at code, the computations you see are the ones actually executed. Meta-programming may be used but only to add behavior to existing code, not to nullify it.

A good example is an 'execute around' method. The method you see in the code _is_ executed, but some things may happen before it and some things may happen after it. What you can't do is replace the body with something else.

An interesting thing about the 'No Lie Principle' is that aligns with good practice around inheritance also. It's better to override abstract methods than it is to override concrete ones for a number of reasons.

</comment><comment><USER52> Things are even worse in the PHP world than the languages described in the article. You get variable variables and you can use variable as the function/class names so this is totally valid:

      function do($class, $action, $param, $value) {
        $method = $action.$param
        $obj = new $class();
        $obj->$method($value);
        return $obj
      }

      $my_name = 'Arnor';

      $$my_name = do('Entity', 'set', 'Name', $my_name);

      // The entity is now stored in the variable $Arnor

Thanks PHP... Don't even get me started on __call.

It's fun to come up with clever solutions and puzzles, but it harms your code base. If you're proud of how new and clever your last 10 lines were, you _probably_ need to refactor it.

</comment><comment><USER53> This is dumb. Most languages support some way of autoloading classes. If you don't understand that then you won't be grepping the right file. As such this is not a valid test for readability because understanding how classes is loaded is assumed.

<comment><AUTHOR> I have no problem with autoloading classes (though I suppose me including "modules" in the list might've implied that). If a class is autoloaded, I can still find its declaration and implementation using grep.

As for "Not grepping the right file", I meant it should be findable in a project-wide grep, not in the file I assume it to be in.

</comment></comment><comment><USER54> It's a noble concept, but a bit weak. Really what you want is a static analysis tool that an keep up with your programmers.

For example, Guice fails the Grep Test hard, but it incredibly helpful.

All data-driven fail the Grep test. Your browser fails the Grep test (you can't grep for javascript content)

You just need to replace Grep with an xref tool that _understands your programming language_ , including your metaprogramming. This may require you to commit your configuration files and standard data objects into your source control, or build an indexer that can read your CMS as well as your code.

</comment><comment><USER55> what about functions passed as arguments? quite a basic technique and I don't think it passes this test.

<comment><AUTHOR> functions passed as arguments are fine, because something needs to be passing them. While the function invocation site itself is dynamic, the source of the call isn't.

Basically the important aspect is that even if you have higher order functions, the things passing the functions to these higher order functions will still be greppable.

<comment><USER56> I have unfortunately created an annoying case of this, in which a bunch of thunks are put in a list and invoked en masse. If any one of them has a problem, it's a bit of a problem to sort out where it was created. This is exasperated by the fact that functions do not know their own names in Lua.

      Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
      > function f(g) g[1]() end
      > function thisFunctionCrashes() undefinedVariable() end
      > f({thisFunctionCrashes})
      stdin:1: attempt to call global 'undefinedVariable' (a nil value)
      stack traceback:
      	stdin:1: in function '?'
      	stdin:1: in function 'f'
      	stdin:1: in main chunk
      	[C]: ?

In the example, the source line is available, but in the genuine article the thunks are for native functions.

</comment></comment></comment><comment><USER57> One should not get too dependent on just one tool as Grep, sacrificing some useful features of dynamic languages... In the Javascript example, (and possibly others), it is still possible to easily find where the method was defined - open a debugger, add a break point on console.log(ray.getPosition()); and step in to it. there are many other tools to help you, for example, many modern IDEs have powerful inspection features these days.

</comment><comment><USER58> now I have a test for the "too abstract" problem. Also - bonus points to the author for pointing out at the end that general practice != abolute truth

</comment><comment><USER59> This seems like a great case for solid comments in the code, as long as they're up-to-date and you don't have a huge number of permutations. I know we all like to crap on code comments here, but if you had say 5 possible permutations that this code supported, a programmer could easily throw a comment above it with each of the supported functions, comma-separated. Then grepping would indeed find them.

</comment><comment><USER60> So, basically, everyone who is capable of producing excellent code is bared from using a powerful technique, largely because some people can't understand the code they produce.

It's a difficult trade-off, one one I've had to make calls on several times. Do you use the full capabilities of incredibly gifted and talented programmers, and then allow code into your codebase that maintenance programmers can't understand?

Tricky.

<comment><USER61> I think the best solution is to have the better ones mentor the lesser ones. It takes time away from coding in the short-term, but it is a good investment in your people in the long-term. Metaprogramming is something that any good programmer can understand if they are just taught well, just like all the other difficult parts of programming that people routinely like to ban: pointers, goto, lambdas and functional programming, C macros, Lisp macros, etc. Using them correctly really helps a lot, using them incorrectly can hurt a lot.

The solution is to learn how to hit the nail with the hammer, not your thumb.

</comment></comment><comment><USER62> I think the grep test is inappropriate as a blind requirement for commit acceptance, but I do think it gets at an interesting issue. If your code fails the grep test, _pay attention_ , make sure what you're doing makes sense, and make sure it's documented somewhere that's accessible to those new to the code base (in terms of work flow as well as technical access).

</comment><comment><USER63> This assumes you don't write any tests. In that case your system has more problems than the scope of this article.

There's nothing wrong with using metaprogramming to generate methods, as long as you are writing tests for those methods.

Grepping the application code is usually much less useful than grepping the tests to see how the system is intended to behave.

</comment><comment><USER64> I wrote a utility ages ago to find orphaned Ruby methods. It greps (actually, acks) for method names. Naturally this only goes so far with a non-trivial Ruby codebase, which limited its usefulness. [https://github.com/built/funk](https://github.com/built/funk)

</comment><comment><USER65> I wrote about this a while ago: [http://aaronblohowiak.com/blog_posts/rails- maintainability-m...](http://aaronblohowiak.com/blog_posts/rails- maintainability-metric)

</comment><comment><USER66> Erm, what about first-class functions in general? This doesn't just make metaprogramming harder, it also stops you from saving functions in lists or hash tables and any sort of higher-order programming.

</comment><comment><USER67> This obviously only applies when grep is all you have to find-who-calls and find-definition.

</comment><comment><USER68> C macros can cause the same issue when used to concat function names using ##.

</comment><comment><USER69> In a sane language you could just ask the function where it is defined.

        user=> (meta #'leiningen.gnome/uuid)
        {:arglists ([project]), :ns #<Namespace leiningen.gnome>, :name uuid, :column 1, :line 10, :file "leiningen/gnome.clj"}

</comment><comment><USER70> choosing module and function names is an acquired art in python. I usually grep my entire code base (and ensure nothing matches) before I add a new public name.

</comment><comment><USER71> I like the idea of the Grep Test, but this is not a great illustration of it. These refactorings are bad not because they hide names from the developer but because they use the wrong abstractions.

The point of DRY isn't to mindlessly remove code duplication. It's to remind us to look for code duplication and keep us mindful of coupling between the various parts of our code.

Where two identical chunks of code that represent the same kind of work are used in multiple places we introduce "algorithmic coupling." That is, whenever the work being done in one location changes, we have to make sure to change the work being done in the other location. Anyone reading this code -- whether the author, the author's future self, or teammates -- has to remember this extra fact, increasing the surface area for bugs.

There's also "name coupling," viz., for every vector _foo_ associated with the Ray we want methods like foo_is_zero?, negative_foo, etc. Here it's important that the naming convention be consistent, so there's coupling there, too. If the names aren't consistent anyone else reading the code would then have to remember _that_ fact, and anyone changing the names would have to remember to update all the other names, too.

The irony of his example is that style of metaprogramming is a great way to get rid of name coupling, but he did nothing to get rid of the much worse algorithmic coupling. Indeed, algorithmic coupling screams for DRY whereas name coupling requires it on a more case-by-case basis.

That is, when all the names are highly localized, e.g., three short methods that share some naming pattern are all defined in succession, it's much less important to remove the duplication. Anyone reading or editing that code will quickly see what the pattern is and why it exists.

Here's a comment I left on the blog:

Hmm. I don't think the lesson here is about to-DRY-or-not-to-DRY your code. Instead, it's about using the appropriate abstractions.

Using the Ray example, both position and direction are vectors, not points. Make them vectors! Then you'd be able to say things like

      ray.position.zero?
      # We'd usually say "the inverse of" not "the negative of"
      ray.position.inverse

Furthermore, if you wanted to define the same methods, well...

      class Ray
        def position_is_zero?
          position.zero?
        end

        def direction_is_zero?
          direction.zero?
        end
     end

There's less repetition, now, because you're only repeating names, not logic. This means the code will only break when the names change, i.e., zero? becomes is_zero? or something.

In a world where all of your logic is also duplicated in the Ray class, the code would break when either the names or the logic changed.

</comment><comment><USER72> This is a standard case of what I like to call a tradeoff.

Making code that passes the grep test allows many more programmers who are vaguely familiar with the codebase to make changes.

Making code that fails the grep test allows a team of a few highly skilled developers who know the codebase inside and out to do the work of hundreds.

It's like mathematical notation, you generally need experience in that sub- branch of mathematics to understand the notation.

<comment><USER73> I think "do the work of hundreds" is a little bit generous. It does save a little time, but does it really save so much time as to boost productivity 100x?

</comment></comment><comment><USER74> The big elephant in the room is that this isn't really about metaprogramming. It's about the failure of the text as a means for manipulating of computer programs (e.g. eval on strings, reflection, method_missing, _getattr_, etc). It would be as if we represented and manipulated numbers as text strings.

Much like languages have more successful ways of representing numbers, some languages are more successful at metaprogramming. In particular, Lisp takes the view that the act of metaprogramming is really the act of writing application-specific compiler extensions. The default behavior simply doesn't involve ripping apart strings and concating them back together.

</comment><comment><USER75> Come on.. Anonymous functions (lambdas) have the simple rule - use them when you need a function as an argument to a high-order function (such as filter or map) right here, in this call, because giving it a name and, especially place where you can't see its code, is less concise. If a function, it turns out, should be called more than once, it deserves a name.

The practice of placing any general functionality in lambdas or blocks will make thing more messy.

</comment><comment><USER76> More ways in which code is being made "approachable" to those who have no business reading code can pretend they have valuable input managing developers.</comment>


Show HN: EduClan – Start Teaching Online at Lowest Cost - <AUTHOR> https://educlan.com/en <comment><USER2> Neither there Link for 'Privacy Policy' or 'Terms of Use' at the bottom is working. Also this Site is HTTP not HTTPS.

Sorry but this is not very trustworthy.</comment>


Behind the Scenes: My Angel Checklist - <AUTHOR> https://dsdoes.com/behind-the-scenes-my-angel-investor-checklist-c266135b2bbd <comment><AUTHOR> Dave is a friend, he's now mentoring SAAS founders in the 517 area code in Michigan if anyone is interested.</comment>


Things I'm loving about derbyjs - <AUTHOR> http://micknelson.wordpress.com/2012/07/27/6-things-im-loving-about-derbyjs/

<comment><USER2> Derby is absolutely amazing, but when I tried to build something with it 6+ months ago, I was stymied by the complete lack of authentication features. The majority of apps (and games) require the ability to show one user X+Y and another user Y+Z, and it seems like a ludicrous oversight.

Looking now, I see a vague reference to server-side logic (in the context of recommending against it!), but nothing about auth specifically. Has anything changed or improved on this front, or are there any plans to do so?

<comment><USER3> I believe that auth is in Derby, although it has just yet to be documented formally...

<comment><AUTHOR> This is correct. We have been developing and testing auth with our own app, and we'll publish a simple example using it soon.

</comment></comment></comment><comment><USER4> vs. Meteor, Derby has server-side rendering (need REST?) and uses NPM.

</comment><comment><USER5> Also, the conflict resolution library (<https://github.com/codeparty/racer>) that is used looks to be very cool.</comment>


How does SSL work? - <AUTHOR> http://security.stackexchange.com/questions/20803/how-does-ssl-work

<comment><USER2> Writer of the top answer here. I haven't looked at the post in a while, it might be that the answer is slightly outdated. BREACH has been released after writing the answer and RC4 hasn't gotten anymore secure, but besides that I don't think it misses that much. Let me know or do suggested edits if there is anything you think should be added!

<comment><USER3> One could argue RC4 could have gotten more insecure. 2013 saw a theoretical attack that would yield the RC4 key within real connection time frames.

</comment></comment><comment><USER4> This is another awesome article on the topic: [http://www.moserware.com/2009/06/first-few-milliseconds- of-h...](http://www.moserware.com/2009/06/first-few-milliseconds-of- https.html)

More on the "technical" side (and it's a bit old), but it's still totally worth a read.

</comment><comment><USER5> Sorry to post this but why not read up at [http://en.wikipedia.org/wiki/Transport_Layer_Security#Protoc...](http://en.wikipedia.org/wiki/Transport_Layer_Security#Protocol_details) ?

<comment><USER6> Wikipedia articles tend to be written in a rather impenetrable style† that take a lot longer to convey the answer to a basic question like this than a good Stack Exchange answer would.

† Often they alternate between being completely cryptic until you have read 14 other articles and going into full-on infovomit mode.

</comment></comment><comment><USER7> Side question: what about an active MITM attack which changes the ciphersuite preferences?

So e.g. if I know as an attacker of a weakness in scheme X (which is advertised by both server and client), but server and client would prefer scheme Y, then I'd just have to manipulate the initial handshake to include only scheme X, right?

<comment><USER8> >> Side question: what about an active MITM attack which changes the ciphersuite preferences?

Part of the protocol involves exchanging checksums of all data passed between the server and client. Can't remember off the top of my head exactly when this takes place, but effectively the whole handshake process is fed into a hash algorithm and if they don't match then the connection won't be established. The hash itself will be protected from MITM by some sort of signing/MAC.

<comment><USER9> It happens during the Finished messages. The OP covers the handshake about halfway down, and 72deluxe's Wikipedia link covers it nicely, too:

[https://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_h...](https://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_handshake)

In TLS 1.0 and 1.1, the Finished message is protected by HMAC-MD5 and HMAC- SHA1. (RFC 2246, sections 5 and 7.4.9.) (By the way, while there are attacks against MD5 and SHA-1, there are no known attacks against HMAC-MD5 or HMAC- SHA1. Don't freak out.)

TLS 1.1 is the same as TLS 1.0. (RFC 4346, sections 5 and 7.4.9.)

For TLS 1.2, I am uncertain which algorithm is used. See RFC 5246, sections 5 and 7.4.9. It's either HMAC-SHA256 or the MAC defined by the chosen cipher suite, which would currently be one of HMAC-MD5, HMAC-SHA1, HMAC-SHA256 or HMAC-SHA384. (As long as your weakest cipher suite's MAC can't be broken in half a second, this doesn't help an attacker.)

Edit: Staring at RFC 5246 a bit longer, I am almost certain that TLS 1.2 will always use HMAC-SHA256. Future cipher suites may define a different algorithm, but no such cipher suites yet exist.

(Edits: This post was basically written one sentence at a time in a dozen different edits.)

<comment><USER8> >> In TLS 1.0 and 1.1, the Finished message is protected by HMAC-MD5 and HMAC- SHA1. (RFC 2246, sections 5 and 7.4.9.) (By the way, while there are attacks against MD5 and SHA-1, there are no known attacks against HMAC-MD5 or HMAC- SHA1. Don't freak out.)

Yeah, been reading up on HMAC lately. I had to implement a MAC algorithm due to a weird failing by an embedded platform vendor. HMAC(sha256) was it, until at the last minute we switched out for iso9797 algorithm 3, pad 3* because a second vendor we have to work with couldn't support 32 byte keys. It's always a bit sad to write beautiful code and then discard it again within days...

(*why yes, it is a retail application)

</comment></comment></comment></comment><comment><USER10> I remember using gmail and having a mixed warning (telling me it would use both http and https). It doesn't anymore.

</comment><comment><USER11> Will it make my client more unique (so identifiable) for a third-party passive attacker (who can sniff traffic) if I tune my browser's settings for example to support only TLS 1.2 and by removing all the RC4 encryption methods?

</comment><comment><USER12> I like posts like these, there was one on REST that explained it pretty well too.

I would like to see if there's more folks have found which are somewhat high level but are thorough as well like this post.

</comment><comment><USER13> People who can't read Wikipedia ask questions on Stackexchange.

I always assumed, if you are on Stackexchange you have at least some knowledge and also be competent enough to look for information yourself in the first place.

<comment><USER14> > People who can't read Wikipedia ask questions on Stackexchange.

Not saying this is an example of this behaviour but there are also groups of people kudos whoring on SE/SO by shill posting questions and then providing very thorough/researched answers shortly afterwards from their real account(s).

<comment><USER15> Why would you need to do this (use 'shill' accounts, that is) and why would you care? You are allowed (encouraged, even) to answer your own questions on these sites - [http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and- answ...](http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your- own-questions/)

<comment><USER16> You cannot do that right away unless you have enough reputation (I've been bitten by it, and it's terribly frustrating)

btw, I agree that such behavior is actually positive: more thoroughly researched answers are a plus, not a downside

</comment></comment></comment></comment><comment><USER17> Awesome information. It looks easier to digest than Wiki:

[http://en.wikipedia.org/wiki/Secure_Sockets_Layer](http://en.wikipedia.org/wiki/Secure_Sockets_Layer)

I've got hands-on experience 10 years ago, I thoroughly understand how SSL handshaking is working. But it's still not enough, especially with the latest upgrades and attacks.

I'll save it somewhere. BTW, where do you guys save the important information? Or just let it passed? Can never remember enough detail about it. And next time when I need it, it's hard to find any more.

Let's save it. [http://kck.st/JNqv8z](http://kck.st/JNqv8z)

<comment><USER18> Oh my god, give it a rest, man!

[https://news.ycombinator.com/submitted?id=dclara](https://news.ycombinator.com/submitted?id=dclara)

<comment><USER17> Thank you for showing the list, which is part of the marketing campaign I'm running on both Kickstarter and Hacker News. Since those posts are not on the first page, they disappeared quickly, and I'm afraid that not many people have visited.

Is there anything wrong with it? Do you mean I cannot or should not post the series of blog posts here for people to visit?

Instead, I'd like to hear from you how you like it or why you hate it.

You may check out if I only commented on my own project from all my comments:

[https://news.ycombinator.com/threads?id=dclara](https://news.ycombinator.com/threads?id=dclara)</comment></comment></comment>