Show HN: Buttermilk Supply – knives from Japanese masters - <AUTHOR> http://www.buttermilksupply.com/ <comment><AUTHOR> I know e-commerce might not get a ton of love here, but I'd really appreciate any feedback you might have for me. I've been a fine-dining chef for years and recently left my restaurant to build a business around my love of Japanese knives. I've been working on the site slowly over four months. I think it's good, but I'd happily accept anything you can say about it. Thank you!

<comment><USER2> Just some shitty comments:

I clicked two knife categories and both said "This has no western equivalent!" True or false I am getting some twinges of "wowee, so foreign, must be amazing, ancient secrets that somehow never crossed the ocean are here at last."

Similarly I am unconvinced that we need specific knife forging masters whose fathers were knife forging masters to forge these knives. Do they have magical techniques that nobody else knows? Do you have to do it for 100 years to be able to make a good knife, or is the bar in fact lower?

Your "why carbon steel?" page seems to indicate that carbon steel knives are better than stainless steel in all ways. Is that really true? Another poster here seemed to summarize that the carbon steel ones need more frequent sharpening (i.e. stay sharp less long, contrary to what you said).

<comment><USER3> The shape and design of Japanese knives is indeed quite different in use than the typical western chef's knife. It takes a little adjustment, but personally I do prefer a good santoku blade when I can get one, unless I'm doing something that needs the extra length.

The thing about Japanese knife making is that they're just about the only ones left doing it that way, and there _are_ advantages to hand-forged steel. You can't get the same results from machine stamping, and yeah, centuries of experience is not to be sneezed at in any profession. You'd be surprised how much of the working knowledge of a whole range of fields dates back to the middle ages. One of the holy grails of Western smithing books came out in the time of woodcuts.

Using high carbon steel increases the tensile strength and hardness of the blade. It's true that crafted Japanese knives do require more regular care and maintenance, but the durability in the long term if properly treated is dramatically greater than stamped stainless knives. There are sushi chefs in Japan using 100+ year old knives.

I was a cook professionally for many years, and I've tried a whole range of knives from the lowest to the highest end, and no knife I have ever used has been as pleasant to work with as a good Japanese forged knife. I'd still buy one in a heartbeat if I could both spare the cash and justify it for simple home use.

<comment><USER2> > centuries of experience is not to be sneezed at in any profession. You'd be > surprised how much of the working knowledge of a whole range of fields dates > back to the middle ages. One of the holy grails of Western smithing books > came out in the time of woodcuts.

I totally agree, it's just that, are zero people in the US good enough to make these knives? Does it require such expertise that if your father wasn't a knife forging expert, it's inconceivable that you could otherwise learn or be taught how to do this to make a good enough knife? Why can't I (say, a decent smith in the US) read a book on this technique, do it for a couple of years and churn out the same quality knives? I'm sure the 100 year old Japanese artisan smiths of Lothlorien make more subtly elegant knives, but a chef, or at least the general market of in-the-know chefs who want a strongass knife, should not care about that to the point of needing to import them from Japan.

<comment><AUTHOR> Again, what @jarcane said.

There are more than zero people in the US making great kitchen knives. The number is, fortunately, growing. I'm in talks with two US makers and a Canadian, in addition to a couple from Europe.

As has already been said, it is a matter of economics and culture. High-end American makers are able to consistently get more money from outdoor knives. Not to discredit that category of knives, but rough outdoor knives can be made much more easily and emphasize toughness and wear resistance and aesthetics at the upper end, with subtle elements of cutting performance being difficult to evaluate. We have a long history of sought-after outdoor and pocket knives in the US. For this, Japanese knifemakers turn to the US and studied with people like Bob Loveless.

Despite outdoor and pocket knives being cherished, the orientation to kitchen knives in the US has long been held as utilitarian. My guess as to why? Because kitchen knives were tools for women, and chefs (a class of people long thought of as outcasts) bought from Europe when they cared. The client base of most all custom or upgraded or modified consumable tools/vehicles/electronics/etc. is male dominated. We don't have a strong history of swordmaking and we readily abandoned them in favor of guns. Guns not being a significant part of Japan's industrial history, the Japanese continued their craft of swords until public carry was outlawed. A lot of these multi-generational swordmaking families found a market in making kitchen knives.

I would totally support you in learning knifemaking. I think it's an awesome craft. Reading about how to make high-performing kitchen knives though, might first require learning to read Japanese. Great kitchen knives can be made within your first few years, but it's rare, and at the end your knives will be more expensive than their Japanese counterparts.

Chefs don't need to import knives from Japan, they can get them all over the US. Sure we want a strong knife in our restaurant kitchens, but it's a tool that we're attached to for 16 hours a day. It's an extension of who we are as chefs, and you can tell a lot about one based on their knives. I demanded finesse from my cooks, and it's hard to understand finesse with a hamhanded tool.

</comment></comment></comment></comment></comment><comment><USER4> So much of this copy seems to be "other knives suck" rather than "our knives are cool". Why would I ever want to go through the purchase process if I'm on the fence and see this?

Also, just personal but I don't think "Buttermilk Supply" is a super name for a knife vendor, but naming is tricky. The wording is a major turnoff for me

<comment><USER5> I agree. Target should be foodie/ home chef types who are willing to invest in the best. "Our knives are cool" is a better message for them.

<comment><AUTHOR> That, along with pros, certainly is my target. That's the message that I hope to make clear. Do you have any specific copy that stands out as not saying this?

</comment></comment></comment><comment><USER6> It's worth you doing a pass across your product descriptions. Randomly clicking on one, I found this statement [1]:

"You can read more about Shigehiro knives under the tab to the left."

Except that there's no tab to the left; the tab you refer to is actually across the top of the page. Also, it took me 3 or so attempts to find which tab you meant specifically.

People are paying hundreds of dollars for a knife. They expect the experience to be flawless, not just the product shipped to them.

[1]: [http://www.buttermilksupply.com/shop/knives/shigehiro- kasumi...](http://www.buttermilksupply.com/shop/knives/shigehiro-kasumi- santoku-180mm/)

</comment><comment><USER7> > "WE DON'T SELL BULLSHIT. EVER."

I am sure some people will object to that being on the front page, but it gave me a great feeling as a potential customer. And, being that such blunt language is pretty rare on a customer-facing landing page, it immediately created some memorability that wouldn't have been there otherwise. (Somewhat the same as if I had said out loud, "Buttermilk Supply. Buttermilk Supply.")

I advise that you keep it, even though many will inevitably advise you that it seems unprofessional.

As a dilettante home cook with a somewhat deficient ratio of financial responsibility to disposable income, I find myself buying fairly high-end kitchen knives online often. I just like using them, even though my 'cooking' really mostly amounts to slicing tomatoes and cucumbers to eat with (Ajinomoto MSG-coated) salt.

That may not be what you are going for in terms of your customer base, but if it is, I would additionally recommend solving the sharpening problem, and the cleaning problem, really well.

I never graduated beyond stuff like the Shun knives commonly available on Amazon, and those things were a big reason why. (Shun offers easy mail-in sharpening.)

Sell the knives with a cardboard return shipping box for sharpening, and then send them back with a shipping box that can be re-used the next time.

And if you want to get fancy, include a simple knife cleaning tool. I historically would never consider buying any kitchen item that can't go in the dishwasher -- except a knife, because I like the idea of a blade so sharp that detergents will damage the molecular structure of the super-fine edge.

Still, I confess to saying "fuck it" on many occasions and putting my $150 Shun santoku or paring knives in the dishwasher. That is because I sometimes find myself looking at a gross dishpan full of dirty dishes in brackish water, and the sponge is somewhere in the bottom... I just don't always feel like sticking my hand in there.

I finally curbed that habit by crafting my own knife cleaning tool from a nylon-brush dishwashing brush and a folded-over sponge, that I keep separate from the normal dish washing gear. It is janky, but you could actually make something along those lines pretty cool and very cheap, and then include/sell that. And the cleaning tool itself would be something you could throw in the dishwasher whenever needed.

Good luck! I will remember your site on my next birthday.

<comment><USER8> As far as I know there is only one solution to the knife sharpening problem: you have to sharpen it yourself. Carbon steel knives sharpen really easily. Buy a sharpening stone. While it takes practice to do it well, it is not exactly rocket science. I'm sure there are more than a few good videos on the internet. Many people also sharpen with sand paper.

Carbon steel is completely different than stainless steel which is very difficult to sharpen well. That is the entire point of buying a good carbon steel knife. If you send your knife in to the shop to be sharpened, it will basically be dull (or in transit) all of the time.

Also, get in the habit of cleaning your knife and putting it away immediately. I put my knife away at least 20 times when I'm cooking. Never leave it wet -- ever. Keep a towel available. Again, this is the price of a good knife.

<comment><USER9> Wow. Thankyou for making me think of my knives like I think of my climbing harness, or skis. I will never leave my knife wet for longer than 10 seconds again. I just went from "Clean every time you cook" to "Clean every time you use".

<comment><USER3> For the sushi chefs I knew, a towel by the cutting board was absolutely mandatory. The chefs wiped their knives after every roll or cutting task, and they were always sharpened every night with a stone like the ones sold on Buttermilk.

<comment><USER8> Absolutely. One thing I forgot to mention is that most chefs have 2 knives because they find that after you sharpen the knife it leaves a bit of flavour when cutting for 24 hours. So the idea is to sharpen it at the end of the evening and then use the other knife the next day. Personally, I have never noticed it in my cooking but that's probably because I'm not that good.

</comment></comment></comment></comment></comment><comment><USER10> I am no knife expert but these knives look lovely.

If anyone is interested in Knifes, here is a fascinating article from New Yorker (2008):

[http://www.newyorker.com/magazine/2008/11/24/sharper](http://www.newyorker.com/magazine/2008/11/24/sharper)

I got one of the Japanese knives gifted to me. I think it is in the same price range as your lineup.

I use a Kyocera Ceramic knife for about 10 years and they have a free sharpening service (which I used once). It has been chopping like a champ.

What I found stunning was the metal knife was lighter (in a very good way) than the ceramic knife. I am a vegetarian and hence ceramic works better (no metallic tang), but I understand you buy lovely knives as the ones you carry for its epicurean value as much as its utilitarian value.

Of all the formats of knives I have, I use the Santoku the most. It hits the sweet spot between a paring knife and Chef's knife.

All the best.

</comment><comment><USER11> (In the Knives 101 section, first place I went for and first place I expect other folks may go to:) Wow, this is really offputting:

 _They feed you bullshit in culinary school, bullshit on tv. Here are some knives to not buy:_

...<snip>...

 _There are many reasons to avoid these knives. I will not go into all of them here as I believe it would only be fair to address them individually, which seems really boring._

At least some portion of this advice is misguided--I have a Global bread knife that has done me no wrong, is comfortable and has stayed sharp a long time, and I've bought plenty of good knives at "not a knife store" (ironically, a few in Japan including a nice Misono de-boning knife).

But the bigger issue I have with it is that it is dismissive and reads like a hipster sneering at us common folks..."Oh, you have a Shun...? Well, I use a Japanese Gyuto...you probably haven't heard of it." At least show me the respect of not insulting my intelligence and justify why you think we should avoid the things you list. Otherwise you should just omit this section.

Because I can tell you, as someone who likes to cook as an amateur and would like to learn more about Japanese knives, I am exactly in your target market (assuming you aren't actually a douchebag hipster who doesn't want to sell to anyone who has transgressed by violating your verboten list before in their lives), and I can tell you that you would do a lot better to change your tone here and simply start with the positives, explaining why I should care about Japanese knives at all and why I should buy them from you. Frankly, no one likes to be insulted implicitly or otherwise as their first exposure to a subject, and it is especially damaging if you are trying to sell something.

(More specifically, I would start with the "Styles and Shapes" section, as that has the most actionable advice--tells me right away what a suggested "starter set" would be, and then goes into the functions of the different types in perfect detail--not too much, not too little. I care less about the details of the materials used, although I still think that is useful information. And if you _are_ insistent on keeping a "what not to buy section," you'd do far better by leading with themes and then giving examples, something like "Mass-produced, stamped knives are bad for reason X...some examples of these are A, B and C, although the D line from B is not too bad..."

Another tip--I clicked on the "learn more" link on the top page hero expecting to get information about knives, not to be dropped into the page of knives with no information--I would suggest linking that to the "Knives 101," and further more I think you would do well to link to some good product examples directly from your "Knives 101" page, so I can immediately read through your suggestions and pick some good knives to go with. You may even want to offer some "starter sets," like a Gyuto with a Funayuki as a package together...but I know you think sets are bullshit, so... ;-)

EDIT: And in general I would say to highlight the "Knives 101" page--it strikes me from reading some of the other responses in this thread that dropping people into the knife selection with little guidance to go on is causing confusion. You could probably kill it if you help guide us ignorant foreigners through buying a Japanese knife--seriously, I really think this could really take off with the right approach.

<comment><AUTHOR> Hi! I really appreciate your response!

I feel bad about the leading section of that article. A few others commented on this as well, and I quickly realized it was misguided. I am re-working that section, and page as a whole. I want to clarify that I in no way meant offense or shame or to express elitism (or hipster bullshit). The Global bread knife is totally worthwhile and an exception to my feeling on the rest of their line. Globals are, if they work for the user, acceptable knives but twice the price of their value. Thank you for the feedback. My apologies.

Building a better landing page for the video button is high on my to-do list. You're totally right about that. When you clicked that button, what information would you have liked to see? Information on our selection of makers and knives? Knives separated by maker?

I'm not opposed to sets as a whole, I'm opposed to pre-determined manufacturer sets. I guess I should say box sets? Would you theoretically be more interested in two knives that I've paired as a set than you would be in selecting those two knives individually?

Thanks for the kind words. I've had a hard time determining appropriate places to insert broadly educational info like Knives 101. I don't want people to get stuck on text walls and give up, but I certainly see how it would be helpful to have pieces be a part of your path through the shop. Any suggestions as to placement?

<comment><USER11> Hey, you don't have to apologize to me, I was just transmitting my feeling as a potential customer reading the page...I actually assumed that the feeling I got from that page was _not_ what you intended to express--so no worries! On the contrary, sorry if my criticism was too strongly worded, and kudos to you for taking it so graciously.

 _Building a better landing page for the video button is high on my to-do list. You 're totally right about that. When you clicked that button, what information would you have liked to see?_

Good question. Generally speaking I was interested in learning more about the knives. Seeing the animated blacksmith I wasn't sure if I would get a video or not...not sure if others had that impression as well. Specifically though, I was expecting either a video about knives (not saying this is good, would prefer not to have a video actually) or a page _like_ the "Knives 101" page-- something to guide me a bit as to 1) why I want Japanese knives vs. (or in addition) to anything else, and 2) which ones in particular I may be interested in.

 _Would you theoretically be more interested in two knives that I 've paired as a set than you would be in selecting those two knives individually?_

Well, my main point in suggesting the knives as a set is that overall, I don't have a great sense of what to look for in Japanese knives--do I want a Gyuto only? Gyuto + Santoku? Etc. And your suggestions in the "Styles..." section in the "Knives 101" page were really awesome--I would love to immediately be able to say, "okay, they are suggesting a A and a B knife, and these two are in the low/mid/high-range and that's what I'm willing to pay, so let me directly click on this and they are both added to my shopping cart and here's my credit card thank you very much." That is, I think you could potentially sell the shit out of these simply by making it easy for people to understand what a good single choice and a good pair and a good threesome is and to add to their cart directly from the "Knives 101" page (or a page like it...maybe a better/alternate way is to have some kind of guidance directly on the knives product listing itself? "Looking for a general use knife? Try this Santoku for a mid-range option, or this higher-end version, and pair it with..." etc.)

 _I don 't want people to get stuck on text walls and give up, but I certainly see how it would be helpful to have pieces be a part of your path through the shop. Any suggestions as to placement?_

Yeah, that's a fair point...I don't have a great sense of that. My instinct here is to do some testing/experimenting--see how some kind of guidance on the knife listing itself works, see what kind of results you get when you let people directly add knives to the shopping cart from the "Knives 101" page, etc. Maybe you have a separate "Start Here" page that simply gives people some examples of good options in various ranges and a way to add them directly to their cart. It's worth assuming that there are people like me who go right to the "Knives 101" page to learn more, and there are people who want to browse right away but would respond to guidance on the product listings themselves...and probably stuff I'm not thinking of as well.

In any case, good luck with this and I hope my responses were helpful. I'll be keeping my eye out for your site and I look forward to seeing it grow and succeed further!

</comment></comment></comment><comment><USER12> For a knife noobie like me, I can't really see the difference between the your knives and those you mentioned in here[0]. Would be nice if you could add a couple of the major differences to your post.

Having said that, your knives look amazing from an functional art perspective. Well done on sourcing these knives.

[0] - [http://www.buttermilksupply.com/what-kind-of-knife- should-i-...](http://www.buttermilksupply.com/what-kind-of-knife-should-i- get/)

<comment><USER8> I have only had time to browse the website _very_ quickly (and I have to say that my eyebrowse are raised when a vender of quality carbon steel knives offers a sharpening service since you should sharpen the knife every day or so). Here is a quick summary.

Carbon steel is very soft. It is really easy to sharpen. It dulls quickly. It also can bend (which is very important in some fish knives, but not so desirable for some other knives). Very high quality knives are made by folding the metal and there is an outer layer of a harder steel (that's why you get that pretty pattern).

Basically such a knife is easy to get wickedly sharp, but you need to sharpen it a _lot_.

A stainless steel knife is harder steel (and doesn't discolor). It is comparatively difficult to get very, very sharp, but it will hold its edge for quite a while (a few weeks anyway). You use a "sharpening steel" to rebend the edge of the knife to keep the sharp side facing down.

If you want a super sharp knife to do very precise work, nothing beats carbon steel. Japanese knives in particular are (IMHO) the best because there is a huge variety of knives with very particular properties. Stainless steel knives a beginner friendly, but apart from that there is virtually no advantages. Hence they "suck".

Top of the line carbon steel knives are often much cheaper than "top of the line" stainless knives. Personally, I would never spend huge amounts of money on a stainless knive because you are already pretty limited. However, I think that they are still useful for many people since carbon steel requires quite a lot of time and skill to look after properly.

And since I said "hard" and "soft" with respect to steel, I am aware that I am almost certainly wrong in my usage of the words, so I invite someone with metalurgy knowledge to correct me :-)

</comment></comment><comment><USER13> Very timely. I just moved house and am looking to buy some new knives (avid amateur chef!).

I am no knife expert, but I thought that at this price level, steel hardness (HRC) is a property that a prospective buyer looks at? I don't see this listed anywhere for these knives.

Edit: I noticed that it's in the body text of some knives. You might want to add that info to the data table under each knife - that's where I looked first :)

</comment><comment><USER14> For one thing, your site scales downward quite cleanly to minibrowsers (I tried it with Opera on my GS5) - many major sites really screw that up.

<comment><AUTHOR> Thanks! I tried to make it largely compatible. I'm still working on making the mobile version load real cleanly. Thanks again.

</comment></comment><comment><USER15> Only cutlery/kitchen knives is limiting your market. The custom tactical and custom outdoor knife market is huge and the customers can never get enough.

The best "pocket knife" I own sells for $500, and this is considered mid- range. You are missing out on this action.

<comment><AUTHOR> Well, both of you are right. The kitchen knife market in larger by way of necessity. However, I suspect that the market for outdoor knives >$500 is larger than that of kitchen knives. I do have kitchen knives showing up soon above $800 and am talking to makers that produce knives around $1500.

Still, I'm interested in outdoor and pocket knives. I plan on integrating them within a year. For now though, I'm trying to find a great EDC knife <$100. If you've got any suggestions on any of these fronts, I'd be happy to hear them!

</comment></comment><comment><USER16> Here's an entertaining talk by someone who created a similar site, although not out of a love of knives.

[http://www.primeconf.com/talks/pete- duncanson](http://www.primeconf.com/talks/pete-duncanson)

</comment><comment><USER17> what do you have against ceramics? obviously you're not going to get one from an old japanese dude that's been making them for decades, but they seem like they'd be way harder and hold and edge for longer.

<comment><AUTHOR> There are a few problems with ceramic knives. The problems that I see personally are:

-Not sharp enough and no way to sharpen them at home without diamond, or potentially aluminum oxide, stones -They're chippy and breaky. One of the reasons most makers produce them without a pointed tip. The high hardness of a material that is inherently not tough, reduces the toughness further. This material has the ability to take a razor edge, but it would be uselessly brittle. Under light use though, I can see them working really well for some users. -The geometry is terrible. The bad geometry of the blade sacrifices cutting performance, the bad geometry of the handle is just uncomfortable. Their near weightlessness is also a detriment for anything beyond small tasks. -They're typically only small and, again, lack pointed tips -I find them to be particularly unattractive

Again, if they work for you, great! I got nothing against that and nobody should think less of you. They just don't work for me.

</comment></comment><comment><USER18> Worth pointing out the current place that almost every cook and chef in NYC make their source for knives: Korin ([http://www.korin.com](http://www.korin.com))

<comment><AUTHOR> Korin has definitely got a huge marketshare. I appreciate what they've done for the industry and the exposure they've given to crafted knives. Their website used to drive me crazy though and it was rare for me to find an exciting double-bevel knife. Love to them though.

</comment></comment><comment><USER19> I live right off Logan Square. I always wondered what that Butterfat store was! Is this where you're based out of?

Love the site. What are you using for the payment gateway? Stripe?

</comment><comment><USER20> On my iPhone 6 (8.4) a short video of what seems to be a metalworker pops up and loops when I open your link from the HN iOS app. Just thought you may want to know.

</comment><comment><AUTHOR> Wow. Thank you so much for all of the feedback and response. I appreciate this so much. I'll be going through each comment today with a response.

</comment><comment><USER21> Not a single Sakai made laser. Shame on you.

Anyway it is good to see new players coming. Although your site a slightly hipsterish feel to it. Good luck ...

<comment><AUTHOR> Ha! I appreciate fingerpointing with some knowledge behind it. You're right, I don't currently have any Sakai lasers. Though some of my knives are made in Sakai. The two reasons I'm not stockpiling lasers are: -they're typically manufactured and not hand-forged (most of the better ones are hand-ground, however) and though I have no significant opposition to this, it's not where I wanted to start. I have limited resources and I'd prefer to support to individual craftsmen for now. -I've used a good handful, and I've loved very few. People lose their shit over the Sakai Yusuke, but I can't get into the samples I have. That said, I've owned and loved some Tanaka R2 knives. Crazy thin and also high performing. I'm working on stocking some soon.

The hipsterish feel was not an accident. I wanted clean and hip with both modern and traditional elements. The other side of this spectrum has been done already!

</comment></comment><comment><USER22> I love the quality of the site - top notch implementation of e-commerce portal.

Could you forward me the coordinates of the person who built the site?

gesman at mensk.com

<comment><AUTHOR> Hi Gesman. Thanks for the kind words! I was the one that built the site. What can I do for you?

<comment><USER22> My wife wants to revamp poodleit.com - to make it look luxurious brand (everything is hand-made top quality items).

She likes wordpress but does not use WooCommerce - she uses ecwid.com and wants to keep using it.

Any ideas?

gesman at mensk.com

PS: i love everything about your site.

</comment></comment></comment><comment><USER23> WTF are random ads about webshops on HN page one?

<comment><AUTHOR> Not an ad! I was looking for any input, which so many people have been kind enough to offer me. Though I understand your irritation. My apologies.

</comment></comment><comment><USER24> Friday, November 13th is upon us, folks.</comment>


Show HN: Send password securely to a friend through any IM - <AUTHOR> http://tanin.nanakorn.com/labs/secureMessage?1 <comment><USER2> Two points: 1\. Would you have my password / private key / both? 2\. Why does it say 'As of now in 2014'?.... Instead of 2015?

Perhaps you could provide a Privacy Policy and tell us what jurisdiction it would be enforceable for?

<comment><AUTHOR> > 1\. Would you have my password / private key / both?

The public and private keys are randomly generated on the client side with JSEncrypt (Javascript).

I don't have your private key and your password, as they never leave your machines. (And if you reload the page, then the private key is lost forever)

I might have the public key in the log because it is a part of the URL for encryption.

> 2\. Why does it say 'As of now in 2014'?.... Instead of 2015?

It was built in 2014. I haven't updated it.

> Perhaps you could provide a Privacy Policy and tell us what jurisdiction it > would be enforceable for?

I'm not sure what this means or how to make one. Could you explain more?

Thanks for the good questions!

<comment><USER2> I asked about the privacy policy because I assumed that you also had visibility of my private key (I assumed you were generating it on your server). Usually I look to the privacy policy to see what information you're receiving and storing. Re jurisdiction: privacy policy agreements are appendages of the terms of use - which is subject to law only in defined jurisdictions.

<comment><AUTHOR> Ah, got it now. That's a good thing to have.

</comment></comment></comment></comment><comment><USER3> Why did you decide to use JSEncrypt?

<comment><AUTHOR> No particular reason. It just looks like a good one (e.g. high fork number, a lot of opened and closed issues).

I'm open to suggestion though, if you have a better one.</comment></comment>


Codem Ipsum: Lorem Ipsum but for Code - <AUTHOR> https://codemipsum.pomb.us/ <comment><USER2> Why code in faux Latin when you can use the real thing: [http://users.monash.edu/~damian/papers/HTML/Perligata.html](http://users.monash.edu/~damian/papers/HTML/Perligata.html)

<comment><USER3> I didn't expect it, but I thought Perligata is more readable than Perl.

<comment><USER4> At least, apart from numbers, which all are rendered in Roman numerals.

</comment></comment></comment><comment><USER5> The name is kind of misleading. I expected it to generate random lines of code, instead of just replacing identifiers with lorem ipsum.

<comment><USER6> Same thought here. I thought something along the lines of hackertyper. Something that looks like real code, but isn't.

<comment><USER7> > I thought something along the lines of hackertyper. Something that looks > like real code, but isn't.

Hackertyper is absolutely using real code.

Specifically, it's using groups.c from the Linux kernel:

[https://github.com/torvalds/linux/blob/master/kernel/groups....](https://github.com/torvalds/linux/blob/master/kernel/groups.c)

Compare that to the code used by Hackertyper:

[http://hackertyper.com/code.txt](http://hackertyper.com/code.txt)

</comment></comment></comment><comment><USER8> Hey, I made this. I needed dummy but syntactically valid code to show in demos like this one: [https://github.com/pomber/code-surfer/blob/code- surfer-v2/re...](https://github.com/pomber/code-surfer/blob/code- surfer-v2/readme.md)

<comment><USER9> Wait, this is just for dummy code for demos? I've been using at work for our production system. I figured the compiler would catch any mistakes...

<comment> john-radio Let me know how it goes with the compiler, I've got too much angel capital invested in this by now for it not to work!

</comment></comment></comment><comment><USER10> As some others in this thread, I feel bamboozled.

What I was hoping for is a "Lorem Ipsum"-style generator for code for like 10 different languages. So you'd have a Lorem Ipsum for JS, C++, Rust, etc.

This is just find/replacing identifiers with lorem ipsum, which doesn't really mask the underlying code that well.

</comment><comment><USER11> Lorem Ipsum but for javascript __ _

</comment><comment><USER12> Unfortunately, this doesn't lorem ipsum code comments.

I also wonder how large such an obfuscated code fragment would need to be to be able to find back the original code on GitHub/GitLab.

</comment><comment><USER13> The "lorem ipsum" identifier names are foo, bar, baz, qux, quux, etc.

<comment><USER14> There's even a fancy umbrella term:

[https://en.m.wikipedia.org/wiki/Metasyntactic_variable](https://en.m.wikipedia.org/wiki/Metasyntactic_variable)

</comment></comment><comment><USER15> No description of what's happening (on mobile anyway), but it looks like the variables are being replaced?

<comment><USER16> Identifiers too. It's using the babel.js compiler so the approach is pretty straightforward: [https://github.com/pomber/codem- ipsum/blob/master/index.html](https://github.com/pomber/codem- ipsum/blob/master/index.html)

</comment></comment><comment><USER17> I think it should not replace the `length` property of an intentional array.

</comment><comment><USER18> It looks like dolor is assigned without first being initialized.

<comment><USER19> No, it's passed in as a parameter with a default value of 1

<comment><USER18> I see, the two columns are hard to read on mobile.

</comment></comment></comment><comment><USER20> It keeps throwing me

"SyntaxError: unknown: Unexpected token (1:20)"

on valid code

</comment><comment><USER21> Where would one use this ?</comment>


Show HN: Linux server skills for newbies - a new online course - <AUTHOR>

Actually first launched GREP101.com here at HN almost a year ago as a beta. Now starting For Real in August - with a little discount offer this week <comment><USER2> Is there any way I can see the beta content before signing up? It does sound useful - and interesting - but I'd really like to see something more than this landing page before paying anything.

EDIT: I checked the blog to see if there was any old content there, I didn't find any but I did notice you mentioned the signup discount would be mailed separately. Maybe I'm a particularly fickle customer, but I didn't even submit the form before realising that because the copy to me implied I'd be sent to a payment form.

</comment><comment><USER3> [http://grep101.com](http://grep101.com)

</comment><comment><USER4> If you don't mind, I would be curious to know how many signed up? Want to know the traction level of such a concept.

</comment><comment><USER5> You should probably submit the link.

<comment><AUTHOR> I think most people here will figure it out :-)

<comment><USER6> Is it www.grep101.com ? Because that site is down.</comment></comment></comment>


Should you fire the voice mail guy? - <AUTHOR> http://sethgodin.typepad.com/seths_blog/2008/06/should-you-fire.html

<comment><USER2> Man, I love Godin. He's all about the showing, not the telling. He could have said: "Your employees could be silently sabotaging your business. Take time to review all systems and processes."

Instead he gives an elaborate story and really makes the concept stick.</comment>


Anonymous Audio Message Board - <AUTHOR> http://beecaster.com/

<comment><USER2> Anyone here cool enough to remember the OK Soda hotline?

Of course nowadays it would all be spam and viral promo stuff. Sad!

</comment><comment><USER3> Anonymous but requires a login? Cool idea but no thanks =/</comment>


Those who know science are less likely to accept it if it's controversial (2017) - <AUTHOR> https://arstechnica.com/science/2017/08/when-it-comes-to-controversial-science-a-little-knowledge-is-a-problem/ <comment><USER2> I would say that there is difference between understanding the scientific method and knowing about scientific results. People who do not understand the scientific method will value scientific results differently than those who do. Doing science is very hard, and there are very few people in the general population who are able to do it properly. Even in STEM there are many people having troubles with applied statistics.

<comment><USER3> I think it gets harder the more the data seems to support your claim. You get to a point where being wrong becomes personal, which it really shouldn't, or money and business interests gets involved. I've seen data get ignored because it would have implicated a golf course loved by the community in polluting fish habitat. I've personally worked on a project where data we collected was not allowed to be publicly released, as was actually the terms of our original proposal and part of the stipulation behind us getting our grant, was that we publicly release our data. Once we found an endangered species living in an active mine though things changed.

I've also worked with scientists who basically work their data and write their papers in such a way that it ensures continued funding.

My time in school was interesting. The first couple years we learned the scientific method and how to apply it properly and how it made science great. But in the last couple years we had to take a philosophy of science course. That was totally different than everything we'd been learning up until that point. We talked about real world examples and hoe the scientific method is followed far less vigorously how the meaning of science has changed over hundreds of years and no one really agrees what science is. Then we got to go take part in a few different studies. The above mentioned golf course one was one of them. The day that happened we all sat down to talk about what the fuck just happened when the biologist decided there would be no more water samples taken around the golf course when it started to show massive pH increases from every pond leading off the golf course. It was then decided a salt spill somewhere a few km away was the problem and no more work would be done around the golf course.

Then of course a bunch of money was spent building a few more ponds around the golf course and restoring it....as far as I know there's still problems with the fish there.</comment></comment>


Ask HN:Would you hire a seasoned Devops Engineer to WFH from an African country? - <AUTHOR>

I am a reasonably experienced devops engineer working for a leading US cloud services provider. I am looking to relocate to a UTC +2 to UTC +4 African country; which coincides with US night time. It's incredibly hard to find local opportunities so I am open to opportunities elsewhere. Would you be willing to hire someone to handle your night ops? <comment><USER2> What country are you relocating to?. Nigeria has a fast growing tech industry with a dearth of experience devs. Examples include konga.com, jumia.com.ng, Irokotv.com, hotels.ng,jobberman.com and many more. Send in your application to any of them. Nigeria is a +1 UTC country though</comment>


Why computer color is broken - <AUTHOR> http://digg.com/video/why-computer-color-is-broken

<comment><AUTHOR> Is there a reason the applications mentioned in this video do blurring in the way the video presents as incorrect?</comment>


New Amazon EC2 Feature: Idempotent Instance Creation - <AUTHOR> http://aws.typepad.com/aws/2010/09/new-amazon-ec2-feature-idempotent-instance-creation.html

<comment><USER2> 4 posts from the same blog within 30 seconds? Flagged x 4. One is plenty. Please be more considerate.

<comment><USER3> Better yet, <http://news.ycombinator.com/item?id=1708014> already linked to them.</comment></comment>


Ask HN: What to cover in a MongoDB case study talk - <AUTHOR>

I'm going to be presenting at the upcoming MongoSF conference on MongoDB with a title "Humongous Data at Server Density: Approaching 1 Billion Documents in MongoDB".
If you were attending this, what would you like to hear talked about?
Database: http://www.mongodb.org Conference: http://mongosf.eventbrite.com/ Reference articles:
"Choosing a non-relational database; why we migrated from MySQL to MongoDB" http://blog.boxedice.com/2009/07/25/choosing-a-non-relational-database-why-we-migrated-from-mysql-to-mongodb/
"Notes from a production MongoDB deployment" http://blog.boxedice.com/2010/02/28/notes-from-a-production-mongodb-deployment/ <comment><USER2> I would prefer "notes from a production deployment" -- I don't think anyone needs to hear the SQL vs. NoSQL arguments yet another time.</comment>


Dive into GHC: Intermediate Forms - <AUTHOR> http://www.stephendiehl.com/posts/ghc_02.html <comment><USER2> I am getting a 403 Forbidden error when visiting the link. Same thing when visiting stephendiehl.com

EDIT: the link is working again.</comment>


Pure Maths in Crisis? - <AUTHOR> https://plus.maths.org/content/pure-maths-crisis <comment><USER3> As a computational mathematician... I should clarify; I write programs to construct and verify proofs in discrete mathematics, and also I'm a hacker obsessed with high performance code... I agree that mathematics is in crisis. Why? Because I'm an oddball rarity. My first supervisor was a hacker too, but my PhD supervisor thought I was a wizard. Professors, by and large, can't hack. Those who could, abandoned the field for CS. Students are rarely hackers - often the celebrated kids are groomed through Olympiad, then Putnam, and jump straight into grad school with nary a glance towards a computer -- until they are broken against the only language seen as practical: latex.

Mathematics is innately about computation; every "proof" is an algorithm in disguise, and yet the field fails to attract talent because computation itself is treated with such disdain. Math has its own reproducibility crisis -- we don't write code that performs the tedious operations "left to the reader" and even when we do, journals won't post it.

And I don't see a ton of progress. My old department has hired a few young professors since I graduated... none can hack. It's sad

<comment><USER4> I have no idea what you mean with hacking or hacker in this context

<comment><USER3> This is literally Hacker News, I assumed that would be obvious. There's more to the culture than programming. There's two types of programmers: those who learn the grammar, and those who learn the interpreter / compiler.

<comment><USER5> Best description I've seen! Can sometimes see it in the bimodality of the types of comments too.

</comment></comment></comment></comment><comment><USER6> I think articles like this are hilarious because they act like written down proofs are a gold standard of unassailable logic. Of course they aren't - <USER2> constitutes proof to one person (or in one age) may or may not constitute proof to others. Look at Mochizuki's work - someone so convinced they are right, and yet no one else can understand it:

[https://www.nature.com/news/the-biggest-mystery-in- mathemati...](https://www.nature.com/news/the-biggest-mystery-in-mathematics- shinichi-mochizuki-and-the-impenetrable-proof-1.18509)

Another good example: Euler's proofs in his day would be failed in even a basic real analysis class now.

Having known many many pure mathematicians, I believe that they don't want to use computers for the simple reason that many of them don't know how to, and thus denying the legitimacy of computer-generated (or assisted) proofs protects their livelihood/careers.

<comment><USER7> >denying the legitimacy of computer-generated proofs protects their livelihood/careers.

While this might be an issue, the bigger problem is that there are no interesting new theorems that were obtained in this way yet.

What is true is that there is still serious prejudice against theorems verified by reducing to a finite (yet large) number of concrete cases, which are then verified by an algorithm. This is the case even after the whole brouhaha over and resolution of the 4 colors theorem by Hales.

<comment><USER8> Hales didn't resolve the 4 colors theorem, Gonthier did that. Hales proved the Kepler Conjecture and afterwards facilitated its formal verification via the Flyspeck project.

<comment><USER9> > Hales didn't resolve the 4 colors theorem, Gonthier did that.

Gonthier didn't resolve the 4 colors theorem, Appel and Haken did that. Gonthier just created the first computer-checked proof for the Four-color theorem.

</comment></comment></comment></comment><comment><USER10> Mathematics has always been like that.

The Fundamental Theorem of Algebra went through many "proofs" over decades before settling on one we accept as rigorous.

And rigor itself? A relatively modem requirement. Calculus was put on a rigorous basis only in the 19th century. It existed, and was applied, for centuries before that.

The real truth about mathematics is that it's way more about intuition than rigor, and that things that most people think are true are taken as such. It's human nature, and mathematics is a human endeavor.

Moreover, math itself resists rigor in a fundamental way, as Godel showed us. Machine proofs? Eh. Ultimately, everything is up to humans, even the axioms. Will the computer _believe_ in the axiom of choice?

And stuff that's too complex to be understood except for the select few? So be it. It means nobody really cares about that stuff. Maybe someone will discover a better proof later. Maybe someone will stumble upon a counterexample. Maybe nobody will touch that for a thousand years. Math will go on.

Not that all math is accessible, but all _good_ math is _not_ limited to in- groups.

For an extreme example, Grigori Perelman's famous work is surely not accessible, and is famously incomplete. It didn't matter. The ideas were clear to enough people around the world that it didn't take long for them to spread, and for others to step up and close the gaps.

I've always said that mathematics is a form of art, perhaps with a smaller audience than most. The only criterion in mathematics is _beauty_ : whether the work is _interesting_ or not. Some works lack in that aspect, as it happens in all arts, and will not be appreciated by future generations. And it's fine.

Disclaimer: I do math, sometimes.

<comment><USER11> > And rigor itself? A relatively modern requirement.

Perhaps. I would argue that it is _LONG_ overdue.

> Moreover, math itself resists rigor in a fundamental way, as Godel showed > us.

This merely shows that some things cannot be proved, be it by machine or computer. That's not the issue. The issue is whether or not we should be moving towards machine-verified proofs, since "proofs" verified only by humans often turn out to be wrong.

> Machine proofs? Eh. Ultimately, everything is up to humans, even the axioms. > Will the computer believe in the axiom of choice?

A computer will "believe" the axiom of choice if it is told that it is an axiom. I agree that the humans get to decide what is an axiom (at least in their system), but it should be immediately obvious exactly what axioms are being accepted, and then rigorously shown that _only_ those accepted axioms are being used.

I can even point to a demonstration. One of the mathematical formalization tools available today is Metamath ( [http://us.metamath.org/](http://us.metamath.org/) ). In Metamath you can state the axioms you wish to accept, and then generate proofs that are automatically checked; every step must lead back to a previously-proved theorem or an axiom.

There are several existing Metamath databases. The "set.mm" database (Metamath Proof Explorer) is based on classical logic, ZFC, and the axiom of choice. Since the axiom of choice is included as an axiom, you can use it. See here: [http://us.metamath.org/mpeuni/mmset.html](http://us.metamath.org/mpeuni/mmset.html)

In contrast, the "iset.mm" database (Intuitionistic Logic Explorer) is based on intuitionistic logic and does _not_ include the axiom of choice. Since the axiom of choice is not included, you cannot verify a proof that tries to use it - the verifier will simply complain that the step is invalid if you try to do it. See here: [http://us.metamath.org/ileuni/mmil.html](http://us.metamath.org/ileuni/mmil.html)

</comment></comment><comment><USER12> For people not familiar with the subject (or Buzzard and his cohort) I recommend checking out the Zulip archive [https://leanprover- community.github.io/archive/116395maths/i...](https://leanprover- community.github.io/archive/116395maths/index.html) Some of the (esp. earlier) threads are very illuminating on the process of constructing proofs using ITPs (interactive theorem provers).

My personal experience is that modeling a suitable domain of math formally can be a very good pedagogical exercise. There are many fine points that are easy to ignore when doing math informally but a formal tool would not let you. This is particularly helpful when working on foundational subjects. When successful you are rewarded with the feeling of possessing the understanding at a level deeper than everyone else (most likely untrue, but certainly a typical expository paper or book could not cover the subject as thoroughly).

That said note my use of the word "modeling". In a formalization attempt you may have in your head an isomorphism between the code and the mathematical objects under study but the isomorphism is not necessarily apparent or universally recognized. Beyond the most quotidian matters other people's modeling code (think of it as an API) may or may not fit with your conceptual models. Just like there are different programming languages and libraries, there is no universally accepted approach to encode mathematical constructs. Your claim of correctness is only as good as your axioms and definitions. Your theorem, with all definitions completely unfolded, will be an unreadable tangle of first order logic formulas that anyone would be hard pressed to recognize as universally meaningful -- though it is extremely likely to be logically sound. Even if no one questions the soundness of your logic there is no tool that can certify that your formal expression actually means what you say it means in a mathematical domain.

</comment><comment><USER13> There's not much that's new here - Freek Wedijk estimated the cost of formalizing the undergrad math curriculum in its entirety at 140 man-years, for a rough monetary cost well above the millions-of-dollars range - link @ [https://www.cs.ru.nl/~freek/notes/index.html](https://www.cs.ru.nl/~freek/notes/index.html) Expensive to be sure, but not excessively so for a mostly one-time effort. Part of the problem though is that we are still far from having a reasonably- standard platform for formal math that could be expected to fully unlock its benefits. Most of the effort in formalization so far seems to be occurring in domains of "synthetic mathematics", which seem to be mostly self-contained and don't take much formalization effort to reach close to the research frontier.

<comment><USER14> Billions of dollars? If it only takes 140 man-years that implies more than $14 million per man-year.

<comment><USER13> Yup, I suppose that it's closer to the hundreds-of-millions range for the _undergrad curriculum only_ , in a _single_ system - maybe even a bit less than that. But that then leaves open the question of how to go the rest of the way to the actual research frontier in whatever domains of math you care about, plus the inherent uncertainty as to whether these efforts will in fact be useful, since these systems are in such an early state. You're right though that the way I phrased that was a bit confusing, so thanks!

</comment></comment></comment><comment><USER15> > Proof is the essence of mathematics.

Proof may be essential, but it is not the essence of mathematics. Like many things, the essence of mathematics is beauty.

In this mad world, of which academia is a part, we only seek to measure things. And how can you measure beauty? You cannot, or, at best, it is subjective. So, in place of beauty we have big complicated proofs, that no-one understands.

John Conway, later on in life, decided to quit being a "real mathematician" and focus instead on trying to _understand_ mathematics. His student Borcherds came up with a proof of Conway & Norton's moonshine conjecture, but Conway himself never accepted it. Why? Because it was too complicated, it couldn't possibly be the right explanation for moonshine. What a dude.

</comment><comment><USER16> As an aside, "The Endoscopic Classification of Representations: Orthogonal and Symplectic Groups" is a _damn_ good title. I'll assume it means something to someone, but all I can say is that I expect it to make a _big_ hole in the ground.

</comment><comment> F-0X I cannot understand this "solution" of turning to machine-verified proofs. Coq, Isabelle, etc. invariably contain bugs. Even if they didn't, you can still run into hardware bugs. Computers are not a source of perfect computation and software is certainly not a source of perfect logic.

<comment><USER17> They're not, but they're spectacularly good at spotting dumb errors that humans are spectacularly bad at spotting.

Me, I still haven't got my head around how to prove something on a computer, but the principle is sound. Theoretically one could build the proof as some form of literate program.

<comment><USER18> A computer just does symbolic manipulation according to a list of rules (axioms) and the human/programmer specifies which sequence of symbolic manipulations to apply and then the computer simply states whether or not the specified manipulations transform the theorem in to the truth symbol.

[http://us.metamath.org/mpegif/mmcomplex.html](http://us.metamath.org/mpegif/mmcomplex.html)

(Warning: I've never actually done much of this before so some details might be wrong.)

<comment><USER11> I _have_ done some, thanks for pointing to that page!

Here's a prettier version for most people (the "mpegif" version uses GIFs for math symbols, which works everywhere but doesn't look at nice):

[http://us.metamath.org/mpeuni/mmcomplex.html](http://us.metamath.org/mpeuni/mmcomplex.html)</comment></comment></comment></comment>


Show HN: SpaceNeovim – Spacemacs for Neovim - <AUTHOR> Switching back-and-forth a bit between Spacemacs and Neovim, I got inspired by https://github.com/ctjhoa/spacevim and thought to myself "Hey, that's a great idea!", and so I went into my first time actually toying with vim script (love-hate relationship atm).
The result of the last couple of days so far is the ground work for a Neovim specific port of Spacemacs, located here https://github.com/Tehnix/spaceneovim. The major difference between that and the existing spacevim is that the layers are separated out from the core, and can be updated via an editor command (calling git pull). It makes it a lot nicer to add new layers later on (oh, and of course also the fact that I've dropped any though of vim support).
Contributions or feedback are more than welcome! :) The easiest way, if you want, is probably to contribute a layer, or expand on an existing one at https://github.com/Tehnix/spaceneovim-layers. One of the goals is to match Spacemacs more-or-less, so switching isn't annoying (hence why buffer/filetype specific keybindings are behind a '+major-mode-cmd'). <comment><USER2> Posts without urls are penalized. You'd be better off reposting this using the url, then adding your text as a comment in the thread. Good luck!

<comment><AUTHOR> Thanks! :)

If anyone should stumble upon this one, the new URL is at [https://news.ycombinator.com/item?id=12525448](https://news.ycombinator.com/item?id=12525448) then.</comment></comment>


Ask HN: What do you need help with in your side project or startup right now? - <AUTHOR> What is it that you need help with. Let me or someone else point you in the right direction or solve it for you. <comment><USER2> I've made my new year's incentive to grow a tiny service to at least 50$ MRR and publically document it.

My current problem is that I need a problem to solve. What do people actually require? What sort of value can I provide?</comment>


Raylib: a simple and easy-to-use library to enjoy game programming - <AUTHOR> https://www.raylib.com/ <comment><USER2> I use it for playing around with some game ideas, really liked the ease of it. Clean, compact API.

Only nuisance is that SUPPORT_BUSY_WAIT_LOOP is defined in the defaults, so I can't use the package from my distribution but have to compile it myself – as I don't want 100% CPU usage when prototyping (where I can happily live with inaccuracies of the timers). I considered opening an issue and forgot about it. But you, Ray, seem to be reading this thread anyway. :-) Thanks, by the way!

<comment><USER3> Hey, yeah, actually there have been a couple of issues about it... Using a busy wait loop is the only way to keep a quite stable timming measure, depending on OS, clock granularity could be up to 10 ms (despite raylib tries to enable a hi-res clock with granularity of 1ms), it means, some undesired timming issues...

In any case, you can just comment that line in src/config.h (or even uncomment SUPPORT_EVENTS_WAITING) and recompile the lib. raylib has been designed with customization in mind.

</comment></comment><comment><USER4> Loving the minimal aesthetic. Will give it a try this weekend ;)

Full API:

[https://www.raylib.com/cheatsheet/cheatsheet.html](https://www.raylib.com/cheatsheet/cheatsheet.html)

<comment><USER3> Actually cheatsheet is a bit outdated, raylib is growing fast, several functions have been added in latest version 2.4-dev, you can check current API directly in raylib.h: [https://github.com/raysan5/raylib/blob/master/src/raylib.h](https://github.com/raysan5/raylib/blob/master/src/raylib.h)

</comment></comment><comment><USER5> Prefer the use of types over preprocessor defines - ex: static const vs #define PI, RAD2DEG, etc. ([https://github.com/raysan5/raylib/blob/master/src/raymath.h](https://github.com/raysan5/raylib/blob/master/src/raymath.h)). Also, take a look at using the GLSL data types for vectors and matrices - [https://www.khronos.org/opengl/wiki/Data_Type_(GLSL)](https://www.khronos.org/opengl/wiki/Data_Type_\(GLSL\)) along with explicit use of SSE when appropriate and supported.

</comment><comment><USER6> Could you use this for bigger projects? Or would I run into (performance?) problems and have to port the project to another engine?

<comment><USER3> raylib is not an engine. It's a quite low level library intended to enjoy coding, probably better small games. You can use for a big project but it lacks lots of required elements that engines have, to name some: Screen Manager, Content Manager, Objects Manager. In any case, you can test it and evaluate if it could fit your needs.

</comment></comment><comment><USER7> >Bindings to Lua (raylib-lua), Go (raylib-go) and more!

Is there a list of other bindings somewhere? I didn't see one in my admittedly cursory look.

<comment><USER3> yes, actually there are bindings to +15 languages, here it is a list: [https://github.com/raysan5/raylib/blob/master/CONTRIBUTING.m...](https://github.com/raysan5/raylib/blob/master/CONTRIBUTING.md#raylib- bindings)

<comment><USER7> Cool, thanks!

</comment></comment></comment><comment><USER8> Looks awesome, but unfortunately a few of the examples don't work for me. Is Firefox not supported?

<comment><USER3> Web examples are not updated, still using raylib 1.8. But all should work on any browser, which ones fail on Firefox?

</comment></comment><comment><USER9> Very cool - the syntax reminds me of Blitz3D, the language of choice for 15 year old me :)

Does this work with Swift and iOS - namely, is embedding this library as a dependency likely to pass Apple's App Store review process?

<comment><USER3> Sorry, no iOS support, it can be ported but I don't have an iOS or a MAC. raylib is plain C and uses OpenGL, lately Apple ecosystem doesn't like those techs.

</comment></comment><comment><USER10> Looks fun! I have been moving towards using Go for everything so this might be a good excuse for me to figure out how to use C libraries.

</comment><comment><USER11> Sorry, but this site is illegible on mobile.

<comment><USER3> Sorry, already working on an updated web.

</comment></comment><comment><USER12> What would be the similar cross-platform (including mobile) lib in C++?

<comment><USER13> I think this library, is exactly that. Cross platform in (C), and works on mobile, browsers, as well as desktop environments.

<comment><USER12> Yes, but I'd prefer something similar in C++, not C :)

<comment><USER14> SFML is great and has a rather big community.

</comment></comment></comment></comment><comment><USER15> Does anyone know how the C code is ported to the web in the examples?

<comment><USER16> Looks like emscripten:

[https://github.com/raysan5/raylib/blob/master/games/Makefile](https://github.com/raysan5/raylib/blob/master/games/Makefile)

<comment><USER3> yes, emscriptem, compiled to WASM... but current web examples are still asm.js. Web needs some update...</comment></comment></comment>


Mutexes are faster than Spinlocks - <AUTHOR> https://matklad.github.io/2020/01/04/mutexes-are-faster-than-spinlocks.html <comment><USER2> The author has an implicit definition of "faster" which it is important to be aware of.

The main use of spinlocks that i'm aware of is minimising _latency_ in inter- processor communication.

That is, if you have a worker task which is waiting for a supervisor task to tell it to do something, then to minimise the time between the supervisor giving the order and the worker getting to work, use a spinlock.

For this to really work, you need to implement both tasks as threads pinned to dedicated cores, so they won't be preeempted. You will burn a huge amount of CPU doing this, and so it won't be "faster" from a throughput point of view. But the latency will be as low as it's possible to go.

<comment><USER3> >The main use of spinlocks that i'm aware of is minimising latency in inter- processor communication.

The main use of spinlocks that I'm aware of is dealing with interrupt handlers in driver code. In this situation you generally can't go to sleep (sleeping with interrupts disabled is generally a good way of never waking up) so calling "mutex_lock" is simply out of the question. That's probably a niche use but that's literally the only situation I've ever used actual spin locks instead of mutexes, mainly for the reasons outlined by TFA.

<comment><USER4> TFA? Tried to google but unsuccessful

<comment><USER5> The aForementioned Article

the F is usually something else though ...

<comment><USER6> My OS professor in college told us "RTFM means read the manual; the 'f' is silent"

</comment></comment></comment></comment></comment><comment><USER7> This experiment is a bit weird. If you look at [https://github.com/matklad/lock-bench](https://github.com/matklad/lock- bench), this was run on a machine with 8 logical CPUs, but the test is using 32 threads. It's not that surprising that running 4x as many threads as there are CPUs doesn't make sense for spin locks.

I did a quick test on my Mac using 4 threads instead. At "heavy contention" the spin lock is actually 22% faster than parking_lot::Mutex. At "extreme contention", the spin lock is 22% slower than parking_lot::Mutex.

Heavy contention run:

      $ cargo run --release 4 64 10000 100
          Finished release [optimized] target(s) in 0.01s
          Running `target/release/lock-bench 4 64 10000 100`
      Options {
          n_threads: 4,
          n_locks: 64,
          n_ops: 10000,
          n_rounds: 100,
      }

      std::sync::Mutex     avg 2.822382ms   min 1.459601ms   max 3.342966ms
      parking_lot::Mutex   avg 1.070323ms   min 760.52µs     max 1.212874ms
      spin::Mutex          avg 879.457µs    min 681.836µs    max 990.38µs
      AmdSpinlock          avg 915.096µs    min 445.494µs    max 1.003548ms

      std::sync::Mutex     avg 2.832905ms   min 2.227285ms   max 3.46791ms
      parking_lot::Mutex   avg 1.059368ms   min 507.346µs    max 1.263203ms
      spin::Mutex          avg 873.197µs    min 432.016µs    max 1.062487ms
      AmdSpinlock          avg 916.393µs    min 568.889µs    max 1.024317ms

Extreme contention run:

      $ cargo run --release 4 2 10000 100
          Finished release [optimized] target(s) in 0.01s
          Running `target/release/lock-bench 4 2 10000 100`
      Options {
          n_threads: 4,
          n_locks: 2,
          n_ops: 10000,
          n_rounds: 100,
      }

      std::sync::Mutex     avg 4.552701ms   min 2.699316ms   max 5.42634ms
      parking_lot::Mutex   avg 2.802124ms   min 1.398002ms   max 4.798426ms
      spin::Mutex          avg 3.596568ms   min 1.66903ms    max 4.290803ms
      AmdSpinlock          avg 3.470115ms   min 1.707714ms   max 4.118536ms

      std::sync::Mutex     avg 4.486896ms   min 2.536907ms   max 5.821404ms
      parking_lot::Mutex   avg 2.712171ms   min 1.508037ms   max 5.44592ms
      spin::Mutex          avg 3.563192ms   min 1.700003ms   max 4.264851ms
      AmdSpinlock          avg 3.643592ms   min 2.208522ms   max 4.856297ms

<comment><USER8> If you only have 4 threads it is likely that all your CPUs are sharing caches and you won't see the real downside of the spinlock. They don't really fall apart until you have several sockets.

<comment><USER7> Note that I get a similar speedup with 6 and 8 threads on my Mac (which has 8 logical CPUs)

</comment></comment></comment><comment><USER9> Modern day user-mode pthread mutex uses the futex kernel syscall [1] to implement the lock, which avoids the syscall in the non-contended case, so it can be very fast, acquiring the lock in the user-mode code entirely. I'm not sure whether the Rust's mutex API is a wrapper on the pthread mutex or calling the old kernel's mutex syscall directly.

Basically the user mode mutex lock is implemented as:

        // In user-mode, if the lock flag is free as 0, lock it to 1 and exit
        while !atomic_compare_and_swap(&lock, 0, 1)
            // Lock not free, sleeps until the flag is changed back to 0
            futex_wait(&lock, 0)  // syscall to kernel

When futex_wait() returns, it means the flag has been set back to 0 by the other thread's unlock, and the kernel wakes my thread up so I can check it again. However, another thread can come in and grab the lock in the meantime, so I need to loop back to check again. The atomic CAS operation is the one acquiring the lock.

[1] [https://github.com/lattera/glibc/blob/master/nptl/pthread_mu...](https://github.com/lattera/glibc/blob/master/nptl/pthread_mutex_lock.c#L168)

Edit: the atomic_compare_and_swap can be just a macro to the assembly CMPXCHG, so it's very fast to acquire a lock if no one else holding the lock.

<comment><USER10> [https://github.com/rust- lang/rust/blob/master/src/libstd/sys...](https://github.com/rust- lang/rust/blob/master/src/libstd/sys/unix/mutex.rs#L26)

Looks like it's relying glibc for lock elision.

Mind you the parking_lot::Mutex in the article is not the stdlib implementation, documented here: [https://docs.rs/parking_lot/0.10.0/parking_lot/type.Mutex.ht...](https://docs.rs/parking_lot/0.10.0/parking_lot/type.Mutex.html)

And that looks like it's not using pthread, instead relying on primitives: [https://github.com/Amanieu/parking_lot/blob/master/src/raw_m...](https://github.com/Amanieu/parking_lot/blob/master/src/raw_mutex.rs)

<comment><USER9> Then it's using the futex implementation. It's very efficient.

<comment><USER10> I updated my comment. The fastest impl, parking_lot, appears to be a ground up atomic based mutex that doesn't rely on pthread at all.

<comment><USER9> It seems to be doing similar logic.

1\. Does a CAS with compare_exchange_weak() at line 69.

2\. Then call lock_slow() at line 72 to do spinlocking (Guh!).

3\. The call to parking_lot_core::park() at line 256 seems to sleep wait.

<comment><USER11> So this it acquires fully in userspace if there's no contention, it even spins if there is contention, and then if that wasn't enough it lets the thread sleep with the timeout.

Which matches the description of that library:

[https://github.com/Amanieu/parking_lot](https://github.com/Amanieu/parking_lot)

"This library provides implementations of Mutex, RwLock, Condvar and Once that are smaller, faster and more flexible than those in the Rust standard library"

"Uncontended lock acquisition and release is done through fast inline paths which only require a single atomic operation.

Microcontention (a contended lock with a short critical section) is efficiently handled by spinning a few times while trying to acquire a lock.

The locks are adaptive and will suspend a thread after a few failed spin attempts."

The only thing that I'm missing is how often the sleeping threads wake, as a bad constant can increase the CPU use.

<comment><USER12> Does it really sleep for a specified period instead of doing directed wake- ups? If so that's very far from ideal...

<comment><USER13> No, a thread that fails to acquire the mutex sleeps until the thread that is releasing the mutex explicitly wakes it. On Linux this is achieved via FUTEX_WAIT / FUTEX_WAKE.

</comment></comment></comment></comment></comment></comment></comment></comment><comment><USER14> This is pretty much the conclusion in this game related post on spinlocks: [https://probablydance.com/2019/12/30/measuring-mutexes- spinl...](https://probablydance.com/2019/12/30/measuring-mutexes-spinlocks- and-how-bad-the-linux-scheduler-really-is/)

<comment><USER15> Oh wow/yikes, Linus Torvalds commented on that recently: [https://www.realworldtech.com/forum/?threadid=189711&curpost...](https://www.realworldtech.com/forum/?threadid=189711&curpostid=189723)

"So you might want to look into not the standard library implementation, but specific locking implentations for your particular needs. Which is admittedly very very annoying indeed. But don't write your own. Find somebody else that wrote one, and spent the decades actually tuning it and making it work.

Because you should never ever think that you're clever enough to write your own locking routines.. Because the likelihood is that you aren't (and by that "you" I very much include myself - we've tweaked all the in-kernel locking over decades, and gone through the simple test-and-set to ticket locks to cacheline-efficient queuing locks, and even people who know what they are doing tend to get it wrong several times).

There's a reason why you can find decades of academic papers on locking. Really. It's hard."

<comment><USER16> We've been arguing about concurrency primitives literally for decades and the 'worst' part is that for most of that time, all of the competing solutions were documented by the same individual - Tony Hoare - within a narrow period in the early 1970's. Soon that will be 50 years ago. Watching people argue is like the People's Liberation Front of Judea scene in Life of Brian. As far as I know, borrow checking may be the first real change in that arena in decades, and I bet even that is older than most of us know.

I was getting heckled recently about my allergy to trying to negotiate interprocess consensus through the filesystem. I've seen similar conversations about how hard it is to 'know' the state of files, especially in a cross platform or cross filesystem way (see also the decade old fsync bug in PostgreSQL we were talking about early last year). In our case several dozen machines all have to come to the same decision at the same time (because round robin) and I was having none of it. I eventually had to tell him, in the nicest way possible, to fuck off, I'm doing this through Consul.

The thing is that people who generally don't learn from their mistakes absolutely do not learn from their _old_ mistakes. So for any bug they introduce (like a locking problem) that takes months or quarters to materialize, they will not internalize any lessons from that experience. Not only wasn't I gonna solve the problem the way he wanted, but if he tried to take over it, we'd have broken code at some arbitrary future date and he'd learn nothing. He could not understand why I in particular and people in general were willing to die on such a hill.

Anger is not the best tool for communication, but as someone once put it, it's the last signal you have available that your boundaries are being violated and this needs to stop. Especially if you're the one who will have to maintain a bad decision. As often as I critique Linus for the way he handles sticky problems, on some level he is not wrong.

<comment><USER17> Back around 2012 I worked with a guy, a FreeBSD kernel committer, who insisted volatile was sufficient as a thread synchronization primitive. He convinced our boss.

<comment><USER18> Wouldn't that depend on the case? There is a nonzero amount of things in the universe for which volatile with no locking will do.

Although, any particular thing happening to be one of those is a pretty rare event, so odds are good that this wasn't one.

<comment><USER19> Volatile doesn't even guarantee that data is written atomically in one step and not e.g. byte-wise. Also it allows both the compiler as well as the CPU to reorder it with any read or write. I can't think of anything that would it could be used for in a multithreaded environment.

<comment><USER17> Right.

There is really only a single place volatile actually works, and that is for memory-mapped hardware registers. Anybody who says it is useful for anything else is badly mistaken.

Except in MSVC, where it kinda/sorta means atomic.

</comment></comment></comment></comment></comment></comment></comment><comment><USER20> > Second, the uncontended case looks like > Parking_lot::Mutex avg 6ms min 4ms > max 9ms

This estimate is way too high for the uncontested mutex case. On a modern Linux/Xeon system using GCC, an uncontested mutex lock/unlock is well under 1 _microsecond_.

I have a lot of experience here from writing low-latency financial systems. The hot path we use is littered with uncontested mutex lock/unlock, and the whole path still runs under 20 microseconds. (With the vast majority of that time unrelated to mutex acquisition.)

The benchmark used in the blog post must be spending the vast majority of its time in some section of code that has nothing to do with lock/unlock.

<comment><USER21> You're misreading the benchmark, that's 6ms for 10,000 lock/unlocks per thread, 320,000 lock/unlocks total. In other words 0.6 microseconds per thread per lock.

<comment><USER8> That's still unreasonably high, isn't it? Even a Go sync.Mutex, not exactly a hot-rod implementation, can be acquired and released in < 50ns on the garbage hardware I have before me.

<comment><USER22> On Intel (and probably very similar on AMD) the cost of a completely uncontented, cache hit, simple spin lock acquisition is ~20 clock cycles while the release is almost free.

</comment></comment></comment></comment><comment><USER23> This absolutely makes sense in userspace. The most important part of a spinlock in an OS is that you can yield to the scheduler instead of taking up CPU time on the core. But that defeats the purpose of using a spinlock when in userspace because you still have to syscall

<comment><USER12> A spinlock in the kernel typically only spins. You use it for the cases when you can't schedule... So it better will be for a short time only.

But the concept of short time does not even exist deterministically in userspace, usually, because it can always be preempted. So don't use pure spinlocks in userspace, unless you _really_ _really_ know what you are doing (and that includes knowing how your kernel works in great details, in the context of how you use it).

</comment></comment><comment><USER24> How about a new opcode wait till memory address read equals? That would allow implementing a power efficient spinlock.

Oh there is one already. Meet PAUSE: [https://www.felixcloutier.com/x86/pause](https://www.felixcloutier.com/x86/pause)

Edit: related post from 2018 [https://news.ycombinator.com/item?id=17336853](https://news.ycombinator.com/item?id=17336853)

<comment><USER25> The benchmarked spin-locks are using it, via [https://doc.rust- lang.org/std/sync/atomic/fn.spin_loop_hint....](https://doc.rust- lang.org/std/sync/atomic/fn.spin_loop_hint.html)

Implementation: [https://doc.rust- lang.org/src/core/hint.rs.html#64-93](https://doc.rust- lang.org/src/core/hint.rs.html#64-93)

</comment></comment><comment><USER26> Note that all of the locks tested here are unfair, which is why they all show very high waiting variance. Until recently many mutex implementations aimed for fairness, which made them much slower than spinlocks in microbenchmarks like this.

<comment><USER27> Actually, the parking_lot mutex is fair: [https://docs.rs/parking_lot/0.10.0/parking_lot/type.Mutex.ht...](https://docs.rs/parking_lot/0.10.0/parking_lot/type.Mutex.html#fairness)

The high waiting variance is because the benchmark randomly decides which locks to take, meaning that the amount of contention is variable.

<comment><USER28> Note that fair locking is still expensive. parking_lot achieves both speed and fairness by starting with unfair locking and falling back to fair locking.

</comment></comment></comment><comment><USER29> This comes around every so often, and it isn't very interesting in that the best mutexes basically spins 1 or a couple times then falls back to a lock. It isn't a true pure spinlock vs pure lock (mutex/futex) fight.

I think the linux futex can be implemented through the VDSO (can somebody correct me on this), so that eliminates the worse of the sycall costs.

His benchmark is weird, but maybe I'm reading it wrong:

* Instead of reducing thread count to reduce contention he appears to increase the number of locks available. This is still a bad scenario for spinlocks since they will still have bad interactions with scheduler (they will use a large amount of cpu time when and get evicted from the run queue and need to be rescheduled).

* Also, I didn't see him pin any of the threads, so all those threads will start sharing some cpus since the OS does need to be doing some work on a them too.

* And Rust can be a little hard to read, but it seem he packed his locks on the same cache line? I don't see any padding in his AmdSpinlock struct. That would be a huge blow for the spinlock because of the false sharing issues. He's getting all the cache coherence traffic still because of it.

The worst cases for the spinlock are not understanding scheduling costs and the cache thrashing that can occur.

What they call the AMD spinlock (basically just a regular sane spinlock that tries to prevent cache thrashing) has its best performace with a low number of threads, assigned to different cores under the same L3 segment.

(Does anybody know if AMD's new microarchitecture went away from the MOESI/directory based cache towards Intel's MESIF/snoop model?)

The MOESI model might have performed better in this regard under worse case scenario since it doesn't need to write the cache line back and can just forward around the dirty line as it keeps track of who owns it.

And if you run under an MESIF-based cache and you can keep your traffic local to your L3 segment, you are backstopped there and never need to go anywhere else.

A spinlock is a performance optimization and should be treated as one. You need to have intimate knowledge of the architecture you are running under and the resources being used.

(edit: answered my own question, apparently the vdso is still pretty limited in what it exports, so no. it isn't happening at this time from what i can tell.)

<comment><USER30> The locks should be on separate cachelines, that's what the CachePadded::new is for.

futex cannot be implemented in the VDSO since it needs to call into the scheduler.

Another way to think about this: VDSO is used for syscalls that are (mostly) read-only and can avoid the kernel mode switch on a common fast path. The futex syscall is already the raw interface that is designed on the assumption that the caller only uses it in the slow path of whatever higher-level synchronization primitive they're implementing, so trying to use VDSO tricks to implement futex would be redundant.

<comment><USER29> > The locks should be on separate cachelines, that's what the CachePadded::new > is for

I see that now. I looking for it in the AmdSpinlock struct, but that kind of makes sense.

> The futex syscall is already the raw interface that is designed on the > assumption that the caller only uses it in the slow path of whatever higher- > level synchronization primitive they're implementing, so trying to use VDSO > tricks to implement futex would be redundant.

Ah. Thanks. I didn't know how far you could get with MWAIT, but I guess you still need to deschedule. I also didn't realize futex was a direct syscall and there was no user level api going on around it.

Is he running 32 threads even in the low contention case? And not pinning? There's something about his numbers that just seem a little too high for what I would expect. I've seen this around a lot, and the reason the mutex usually wins is that is basically does a spin of 1 or more then goes into a mutex (the pthread code appers to spin 100 times before falling back to a futex).

At work I use a spin lock on a shared memory region because it does test out to be lower latency than std::mutex and we're not under much contention. I've though about replacing it with a light futex-based library, but doesn't seem to be quicker.

He still seems to be getting some contention, and I'm trying figure out how.

</comment></comment></comment><comment><USER31> Not an expert here.

In a spin lock, the lock state is checked in a tight loop by all waiters. This will be using some sort of memory fence. FWIK, memory fence or barriers flush the CPU cache and would initiate reading the variable (spin lock state) for evaluation. I would expect spin locking overheads to increase with number of cores.

On NUMA, I think flushing is more expensive. Hence, spin locks have an additional overhead of having to load and evaluate on every spin as against being woken up for mutexes (like a callback)

<comment><USER32> > checked in a tight loop by all waiters

This actually does not have to be this way. You could have a linked list of spinlocks, one for each waiter. Each waiter spins on its own, unique spinlock. When the previous waiter is done it unlocks the next spinlock, and so on. The implementation gets a bit complicated on non-GC languages, since there are races between insertion/removal on the linked list. If the number of threads is fixed and long-lived then it becomes easier, since instead of a linked list you can have an array of spinlocks.

Note: in some architectures (x86?) you could possibly do away with atomics, since (I believe) int updates are atomic by default. Not really sure though.

<comment><USER33> Yep, that's the underlying principle behind Mellor-Crummey Spinlock: [https://lwn.net/Articles/590243/](https://lwn.net/Articles/590243/).

<comment><USER32> Yes! The MCS spinlock, the name eluded me. The paper is actually a pretty good read (it is linked in the lwn article).

</comment></comment></comment></comment><comment><USER34> TFA makes the point that modern "mutex" implementations actually use spinlocks first and only fall back to heavy, kernel Mutexes if there is contention. So the title is click-baity. Mutexes _are_ slower than spinlocks. The "faster than spinlocks" mutexes in this article are actually spinlocks that fallback to mutexes.

Then the benchmark uses spinlocks in situations that spinlocks aren't great for. And, surprise, spinlocks are slower, than spinlocks-with-mutexes.

Spinlocks are great in situations such as:

      * There are far more resources than threads,
      * The probability of actually having to spin is small,
        ideally if the time spent in the lock is a few instructions
      * When you can't use optimistic concurrency*

* because perhaps the number of memory locations to track is too complicated for my poor brain and I can't be arsed to remember how TLA+ works

There's plenty of linked list implementations, for example, that use optimistic concurrency. At that point you've got yourself a thread-safe message queue and that might be better than mutexes, too.

</comment><comment><USER15> Coming as a ruby developer who dabbles in async rust in my free time, these posts/threads/links have been my best read of 2020 so far. My CS curriculum barely covered real-world lock usage, much less the ties to linux/windows schedulers + modern CPU caching. Big thanks all around to these internet commentators.

</comment><comment><USER35> As the person that added a bunch of functionality to spin-rs making it roughly match the std API, yes you should not use spinlocks in scheduled code.

That said, I see why Rust makes things so annoying. I want lots of code to work in no-std so have a robust embedded and kernel ecosystem. It would be really nice to abstract over the locking implementation with type parameters, but that required "higher kinded types" which Rust doesn't have. The alternative is relying on carefully coordinated Cargo features, which is much more flaky and hard to audit (e.g. with the type system). Given that, I am not sure people over-use spin locks.

</comment><comment><USER36> I'm really curious how macOS's os_unfair_lock compares here.

<comment><USER37> Is that implementation open source? Don't remember which dyld contains it.

<comment><USER26> [https://github.com/apple/darwin- libplatform/blob/master/src/...](https://github.com/apple/darwin- libplatform/blob/master/src/os/lock.c)

</comment></comment></comment><comment><USER38> Thread scheduling (or waking up cores) is slow. Because of this, mutexes will look better on dumb benchmarks, as the contending threads keep going to sleep, while the single succesful owner has practically uncontended access

<comment><USER39> There are various degrees of slow, in addition to kernel being smarter about multiple cores and SMT siblings than your application.

Kernel can run your code on a cooled core, giving it higher clock, for example. Ultimately making it run faster.

Of course this won't show in a benchmark where all the threads do mostly calculation rather than contention, but that's not the typical case. That mostly shows up in compute such as multithreaded video where latency does not matter one bit.

Typically you have more of a producer/consumer pattern where consumer sleeps, and it's beneficial to run it on a cold CPU, assuming the kernel woke it up beforehand.

Source: hit some latency issues with an ancient kernel on a nastily hacked big little architecture ARM machine. It liked to overheat cores and put heavy tasks on the overheated ones for alleged power saving. (Whereas running a task quicker saves power.)

</comment></comment><comment><USER40> couldn't you eliminate the bad spinlock behavior by coding them to be go into an efficient wait if to much spinning is going on ?

<comment><USER8> That's what virtually all battle-hardened lock libraries do: spin for a bit (but not too tightly, using a pause in the loop) then fall back to waiter lists and futex.

</comment></comment><comment><USER41> Most mutexes implementations spin before truly acquiring the lock.

Also, there are better spinlock implementations, such as speculative spinlocks, and queued locks.

</comment><comment><USER42> .

<comment><USER30> This is the time for whole benchmark run, not for an individual lock/unlock. The article is quite clear on that.

</comment></comment><comment><USER43> Fun explanation of what a Mutex is: [https://stackoverflow.com/questions/34524/what-is-a- mutex](https://stackoverflow.com/questions/34524/what-is-a-mutex)</comment>


Ask HN: Good developers to follow on github? - <AUTHOR>

Hi all,
I wanted to get some general HN opinions about who has good and well-commented code that I could check out on github? I'm looking for people who primarily develop in Javascript, Ruby, and/or PHP. I'm currently looking at the "Explore Github" -> Languages page, and will dive in from there - just wanted some personal opinions.
Thanks! <comment><USER2> Feel free to follow me. I'd like to think I comment the hell out of my code.

<http://github.com/ryanmcgrath>

<comment><AUTHOR> Followed. You really do have a lot of great stuff - I'll be up tonight checking it out. Thank you!

</comment></comment><comment><USER3> The best developer you can follow on github is _yourself_.

<comment><AUTHOR> I agree - I just need to get more stuff up there!</comment></comment>