Ask HN: Is humanity going towards vegetarianism? - <AUTHOR> From a neutral observer point of view it would look like there are more and more vegetarians and vegetarian food in the supermarkets. Certainly this is true only for a small subset of the western world. Why do you think is this happening? <comment><USER2> At least in North America, one thing I have seen is an increasing number of restaurants that have a vegetarian option that is decent. In the past it was always just a regular meat dish minus the meat, but it costs the same. Or worse, take a dish that gets most of it's flavor from the meat and then substitute tofu or some basic (e.g. carrots/potatoes) boiled/steamed vegetables, making a dish that is extremely bland. It's not a surprise that lots of people cannot even fathom how anybody could be vegetarian.

It seems to me that thanks to immigrants, fusion food, and cuisine from countries like India, people are starting to realize that you can add spices and flavors to any cuisine and make these dishes tasty without meat. In this way you have dishes that everybody can eat without feeling like the vegetarian options at restaurants are horrible. Instead, they can see something on a menu that actually looks appetizing and be willing to try it. There are more choices than just a meat-substitute.

Note that I'm referring at non-chain restaurants in more populated areas, or newer or smaller-chains. The large chains still think a baked potato with cheese is a vegetarian entree.

I also think that a lot of times vegetarian/vegan American food has been synonymous with things like raw, super-healthy, vegetable smoothies, etc. So it's bland and basically only for people who specifically want that kind of food. Even that changing, and you can find 100% vegetarian restaurants with food that is fried, has salt/sugar/spices, and is just generally super tasty while not being that healthy. Basically, the reason why I like to eat out in the first place :)

</comment><comment><USER3> * It's not a necessity in a modern world. You can just choose to receive as good proteins other ways.

* Carbon footprint of the animal products is significant. It's roughly equal to cars.

* Question about animal suffering and treatment in when eating mass produced meat. Cheap meat comes from mistreating animals. Equating human cognition with the consciousness that is able to suffer does not seem like solid argument. There is 'naturalness' argument but it's not solid moral argument.

* Meat versus 'meat'. On the other hand it's ecologically good to eat highly processed meat (as much of the animal is used as possible) including pink slime, sinew and chicken skin that most people eat as meat, but on the other had it's not exactly meat.

* Proud carnivores realize that they are actually scavengers at the meat market. Hunters and fishers may reduce their meat eating because they prefer to actually eat things they catch themselves. There is no social status in eating meat as it used to be.

<comment><USER4> Emissions footprint is being improved every day - you might remember an article from a month ago discussing that giving seaweed to cows reduces their emissions by a huge amount.

If everyone went veg, we would need more farms right? How many more field mice/rabbits/snakes/whatever will suffer/get squashed from this? Is this number comparable to the amount of cows that suffer for steak? It seems like smaller creatures treatment never get considered.

<comment><USER5> > If everyone went veg, we would need more farms right?

No, cows eat too. Think about it this way: to get 1000 calories worth of energy from a cow, that cow has to consume more than 1000 calories due to maintenance (BMR) alone. Moreover, one acre of land producing soybeans, rice, or legumes _much_ more protein and _much_ more calories per year: [https://en.wikipedia.org/wiki/Edible_protein_per_unit_area_o...](https://en.wikipedia.org/wiki/Edible_protein_per_unit_area_of_land)

> How many more field mice/rabbits/snakes/whatever will suffer/get squashed > from this?

Fewer as shown from the previous point proving that we could feed more people on less acreage of land

> Is this number comparable to the amount of cows that suffer for steak?

No, it's smaller and we get to cut out the cool parts like raping cows to produce milk and then ripping their children away from them.

<comment><USER4> According to: [https://www.nrs.fs.fed.us/pubs/sp/sp_ne153.pdf](https://www.nrs.fs.fed.us/pubs/sp/sp_ne153.pdf)

it is not smaller. 12 mice per acre average. That's a lot more animal lives being ruined per acre IMO - and that's just the mice.

If you want to convince people of your cause, you need to be willing to be honest about the pros and cons instead of going for an emotional argument.

<comment><USER5> It's not an emotional argument, if a vegan diet requires 1/10th of the acreage, then it requires 12 dead mice as opposed to the 120 dead mice + _whatever animals you're eating_ of the meat-eating diet.

A meat eating diet inherently requires more acreage due to thermodynamics. It works like this: 20 acres of grain feeds 10 cows which feeds 1 person for a year, therefore 240 dead mice and 10 dead cows. An omnivore's diet inherently requires more acreage, therefore more dead mice and all the cows, chicken, fish, &c. you're eating.

<comment><USER4> I think the mice can usually run out of a way of a cow slowly grazing along pasture.

<comment><USER5> it's not just cows grazing on grass--78% of cows in the us are factory farmed, and 97% are grain fed which means they're force fed cheap grain to fatten them up for slaughter. Moreover, only 3% of cattle can be considered grass fed, and, for those cattle, we're deforesting the amazon rainforest--so probably more than your 12 mice.

If you want to throw global warming on top of it, your lifestyle will contribute to the mass Exodus (and most likely death) of millions to billions from the global south.

It's kinda ironic you said I'm arguing from emotion, but all it took for you to be complicit in rape, torture, and slaughter is a smiling cow on the side of a fucking cheese package.

<comment><USER4> Wait until you read about how animals treat each other, and you'll pretty much think we are angels (obviously factory farms and what not are bad).

And before you say "yea but I choose to not contribute to their suffering", well what does that matter? You're still standing by while innocent creatures have all those things done to them by other creatures.

Aren't they entitled to not be tortured and slaughtered as well? Or does it just not matter if you're not the one doing it?

</comment></comment></comment></comment></comment></comment></comment></comment><comment><USER6> I'm vegetarian, I've turned a few years ago, when I've moved to Berlin, a city with a lot of vegetarian options everywhere, also full of vegetarians(and vegans).

Before, I lived in a third world country called Brazil. There, it's mandatory you eat meat. And it's very very tasty. I used to eat A LOT of meat there.

In Germany(Berlin), meat is very expensive. Well, at least good meat, like I used to. If I wanted to eat the same amount of meat, I probably would spend thousand of euros a month to eat the same quality/kind of meat.

So we started to eat tofu and vegetarian food and discovered it is tasty as well, but then you need to add some nice sauce and cook it well, instead of just frying some meat.

I think factors like the one I've mentioned could be a reason. A city with a lot of vegetarian restaurants, will make you eventually go into one of them and see the food is tasty, then you start to play with the idea, then you change and see no difference... apart that you don't eat animals anymore.

</comment><comment><USER7> I can't speak for others but yes personally I've started reducing meat and added veg.

I think my shift came after reading "How not to die"[1]. This book has a lot of scientific info about the benefits of veg diet over non veg and it really changed my perception of food and nutrition and the effect of all dieseases being caused by bad food choices.

[1] [https://www.google.com/search?q=How+not+to+die&oq=How+not+to...](https://www.google.com/search?q=How+not+to+die&oq=How+not+to+die)

</comment><comment><USER8> No, not really. I think more people see the value in not eating meat every day, which I think is a good thing, both for your health and the environment.

Going completely away from meat for the long term, isn't ideal for your health (for most people) and so I don't think it's going to become very popular.

This along with meat being such a big part of culture on top of the health component means meat will stay around for the forseeable future.

</comment><comment> yoz-y I think human society tend to get more tolerant over time (at a large scale). Recent and not so recent events such as acceptance of marriage for everyone, fight for gender equality and so on. Clearly there is a long way to go but eventually, when human problems are resolved people will probably turn their focus on animals as well.

The process is slow and may take centuries but I think we'll get there.

</comment><comment><USER9> I don't think so. In the western world I wouldn't be shocked if the numbers have crept up in the past few decades and will continue to do so -- but there are billions of people in the non western world and others who just prefer meat. Meat is obviously a huge part of food culture and I don't see that changing drastically soon.

</comment><comment><USER10> Meat is much more expensive than vegetables. Wage stagnation and increased housing costs mean people don't buy meat as much.

<comment><USER11> _Meat is much more expensive than vegetables._

Perhaps in aggregate, but there are a lot of vegetables that cost a lot more than a lot of meat.

Locally raised steak is more expensive than potatoes. Imported low quality pork is a lot cheaper than locally grown asparagus.

<comment><USER12> Likewise, the quality of the produce varies quite a lot. It wasn't until I started growing my own cucumbers and I noticed that they stayed fresh a _lot_ longer than the store bought variety that I realized that a cucumber I bought in the store was probably already at least a month old.

There's not much that costs less than potatoes, though. They are so cheap, it amazes me that farmers can make money on them.

</comment></comment></comment><comment><USER13> I think businesses adapt to the demand and a lot of people get influenced by a bunch of various diets these days. Migration of people around the world (different cultures) and the fact that we have access to more data (Internet, etc.), probably explain why this is happening.

<comment><AUTHOR> Do you think that people that become vegetarians in their lives plus the ones born in vegetarian families are gonna be more people combined than meat eaters eventually?

<comment><USER13> I believe so, the number of vegetarians will certainly increase in the future due to the awareness. Though, might no be true that the whole world will turn vegeterian in thousands or millions of years from now. Unless meat disappears.

<comment><AUTHOR> I think the same. I ate meat for for 33 years but I changed so I think that if the change is there maybe the humanity is gonna move that direction.

</comment></comment></comment></comment><comment><USER14> im vegetarian, but not by choice, i cant say i advocate it nor can i see why people would willingly restrict their diet so much

</comment><comment><USER15> I'd say you are wrong. Where are you looking? For instance in India a lot of people mainly eat vegetarian, but that has always been the case. In the west outside of the well off left wing most people eat more meat than ever. Look at fast food and cheap restaurants which most (esp poorer people) aspire to eat. Breakfasts are often meat heavy and McDonald's, KFC, etc etc are mainly churning out cheap low quality meat products. Personally, it's the more well off and better educated people I know who are reducing the meat in their diet and thinking about food sourcing.

<comment><AUTHOR> Well, maybe I'm wrong but the trend is there and if the low end restaurants have vegetarian options now that certainly mean something.

</comment></comment><comment><USER16> I've been a vegetarian for a bit over a decade. (Ovo-lacto, not pescatarian, so I'll eat dairy and eggs but not fish) insects are undecided, but I try to avoid foods that would force a decision (good bye, junior mints). I try to pay attention to labels, but when eating out will often go for the basics. (If they offer a veggie burger, I won't try to find out if the cheese used animal- rennet, and I'm sure there has been lots of sugar bleached with animal bones)

I think I'm a decent example as I loved the taste of meats and wasn't (and still am not) into many veggies outside of basic staples. A kale and quinoa sandwich with sprouts and bell peppers with fresh tomato sounds like a wonderful thing...for some other than me to eat. My family has lots of fishermen and hunters, so meat was an unquestioned norm while growing up.

For me the cause was empathy...if I couldn't kill the animal because of emotions, why is it okay to make others do it? The various other logics of sustainability didn't hurt, but that was the deciding issue. I think that will resonate with people in the future who do switch, but I dont think it will particularly convince anyone TO switch.

I tried cold-turkey (awkward word choice) but found I was seeing stars constantly after a few months. (My guess is that my college go-to's of ramen and mac and cheese weren't a full nutritional load) After that I returned to meat eating, but I had lost the taste for red meat - it now just tasted oily and gross. After a few years I noticed that my tastes had slightly expanded (salad bars were still full of things I disliked, but lettuce itself was now okay). I started dropping a meat category each year (pork, turkey, chicken, seafood) to allow me time to find the right substitutes. I completed the list 10+ years ago and I've not had particular troubles, though I use a lot of meat substitutes while cooking.

Eating out and shopping have become easier over time, but only gradually - finding a vegetarian meal that doesn't assume you want ALL THE VEGETABLES is hard at the average place, and people dont all define vegetarian the same way (Indians seem to share my norm, but Chinese and Japanese use oyster and fish sauces in the "vegetarian" foods all the time, Thai is a toss up on that, plus it is hard to know if their curry paste is shrimp based, and Americans often seem to think every vegetarian eats fish, particularly in some regions. Plus the US south uses pork as a seasoning - a good portion of the vegetable sides menu at, say, Cracker Barrel is non vegetarian.

So while I think vegetarian will become the norm...I dont think it is on the cusp of being the norm. Plus vat-grown meat could totally change the equation, though it still has a long way to go. For now though, the gradual increase I've seen since the 80s has continued, and meat eaters vilify it less often because more of us are vegetarian WITHOUT trying to shame/blame other people for their choices/scenarios.

</comment><comment><USER17> not me</comment>


Blacksocks.com: An infinite supply of black socks - <AUTHOR> http://www.crunchgear.com/2009/05/15/blacksockscom-an-infinite-supply-of-black-socks/ <comment><USER2> I wish there was this for regular clothes. I virtually never go out and buy clothes (lack of time, interest etc.) until my old ones starts to wear, it's pretty much a maintenance thing for me. I'd just like to put in my measurements, maybe rate a few clothes I so it knows what I like and then have stuff magically appear every now and again. I'm sure a random fashionable person would improve my looks by actually having taste. :P

<http://shirt.woot.com> is nice for T's at least but I don't think it would work well for anything more expensive or less expressive than that.

<comment><USER3> I have a similar problem.

When I decide that my old clothes are worn/stained/horribly unfashionable and set out to refresh the wardrobe a bit, I set out to buy a few new ones. After settling on which store to patronize (Am I too old for AE et al.? Am I too young for Brooks Brothers? Would I be just as happy with something from Target?), I go to that store. At that point, I browse around for a bit, get overwhelmed by the number of options, become unsure about what would look good (or even what's in style), and leave without buying anything.

I'd really like to see some sort of online or in-store system with a super- simple way of finding new clothes. Maybe three variables: age, desired style (hipster? MBA? stereotypical engineer?), and body type. The output could be something like, "OK, buy this, this, and that. You'll look good."

<comment><USER4> This is difficult for a number of reasons. As I mentioned in a previous post, the big reason is that sizes are not standardized. A size 32 waisted pant can be a true size 32, or really a size 38. Also, people's sizes fluctuate, usually increasing.

The 2nd part of your question, simply defining what style of clothing to wear is even more difficult and probably impossible to automate. However, there are professionals you can hire which will solve the problem for you. It's not cheap, but if you're single and make a good programming salary it may be a better investment than the latest digital camera or gaming system.

</comment></comment></comment><comment><AUTHOR> the prices seem a little big high, sure they are probably some good material, but still. And sure you get to save money if you get a subscription, but its not much. I mean sure its convenient, but its just socks/underwear/tshirts, its not something people splurge on

      Calf Socks - $10/pair
      Knee Socks - $13/pair
      Sneaker Socks - $10/pair
      Silk Socks - $27/pair
      Boxers 1st type - $45/pair
      Boxers 2nd type - $39/pair
      Briefs 1st type - $32/pair
      Briefs 2nd type - $24/pair
      Tshirts 1st type - $47/pair
      Tshirts 2nd type - $55/pair

<comment><USER5> I don't get this either...I seems like the most they send you is 3 pairs of socks every 14 days? Something seems a bit off there.

This is why this sort of thing would never work for me...My routine when I get home is:

Come in the door, pet the dog. Set the laptop down on the table, grab a beer from the refrigerator, walk out to the back yard, sit on the patio, kick my socks off, and start playing fetch with the dog. My socks end up in a pile on the patio and end up getting thrown away. If this place was 7 socks for 7 dollars delivered weekly I would sign up today.

It is tough to justify the cost for this, especially when i can go to walmart and get ~10 pairs of black socks for $4.

Maybe this is not aimed at nerds? (I'm thinking not).

Cool idea though. I'm with the person below here that says they get their shirts from woot. So do I. Woot is so amazingly perfect, I wish they did dress clothes as well...there are no choices to make, yes, or no. That is it. You say yes and you have a shirt at your door (or in my case, my office) the next day.

<comment><USER6> I can't ever see myself spending more than $1/pair of socks. That just seems ridiculously frivolous.

<comment><USER7> Who cares? There's already a market for expensive socks. The question is - does that market value the convinience of getting them delivered to their door.

</comment></comment></comment></comment><comment><USER8> Blacksocks had come up earlier on HN, with some interesting comments. <http://news.ycombinator.com/item?id=534330>

</comment><comment><USER9> Reminds me of the Amazon efficiency expert who "optimized" her family's laundry by creating a common pool of white socks. Most females would not pick white socks.

</comment><comment><USER10> This site is both ridiculous and awesome</comment>


So you can't work 16 hours a day for years? SpaceX folks can - <AUTHOR> http://uk.businessinsider.com/elon-musk-doesnt-believe-in-impossible-2015-5?utm_content=buffer0af63&utm_medium=social&utm_source=athnshah&utm_campaign=buffer

<comment><AUTHOR> > And SpaceX employees do work incredibly hard. One employee, Steve Davis, > director of advanced projects, has reportedly been putting in 16-hour days > every day for years.</comment>


JQuery plugin for Twitter - <AUTHOR> http://coda.co.za/blog/2008/10/26/jquery-plugin-for-twitter <comment><USER2> Personally I love Tweet (<http://tweet.seaofclouds.com/>).

</comment><comment><USER3> Isn't this achieved by simply using twitter badges and a custom callback function?

      <script type="text/javascript" src="http://twitter.com/statuses/user_timeline/nirmalpatel.json?callback=twitterCallback2&count=5"></script>

</comment><comment><USER4> Why is this a jQuery plugin? This is the sort of thing that should be library agnostic.</comment>


Synthetic jellyfish a hybrid of rat hearts and plastic - <AUTHOR> http://arstechnica.com/science/2012/07/synthetic-jellyfish-a-hybrid-of-rat-hearts-and-plastic/ <comment><USER2> In case you're interested, the same story, from other sources:

<http://news.ycombinator.com/item?id=4278142> <\- Comments

<http://news.ycombinator.com/item?id=4279457>

<http://news.ycombinator.com/item?id=4280887></comment>


Help Revive Hitchbot, the Canadian Robot that Americans Destroyed - <AUTHOR> https://www.thehacktory.org/hitchbot-meets-demise-in-philly-no-way/

<comment><USER2> Please don't lump all "Americans" into the group that destroyed this robot. There are assholes in every country, and that doesn't excuse them. It also isn't a reason to be bigoted against everyone in a very very large country.

<comment><USER3> It's not like the hacktory isn't in America too. I wonder why they gave their blog post such an inflammatory title...

</comment></comment><comment><USER4> Assuming the OP wasn't changed, this title breaks the HN guidelines. Please don't use the title field of HN submissions to editorialize. This was a bad case since the provocation derailed the discussion immediately.

<comment><AUTHOR> Sorry! I'll keep that in mind next time.

</comment></comment><comment><USER5> So, this is the sad yet inevitable outcome that we've known about from Sci-Fi for some time. When you combine the darker side of human nature and anthropomorphized robots that cannot defend themselves, malicious vandalism and destruction is a given.

The philosophical question remains - when does it cross over from being classified as destruction of property to something like assault.

<comment><USER6> > When you combine the darker side of human nature and anthropomorphized > robots

People have been defacing and destroying property since forever, regardless of what it looks like.

> when does it cross over from being classified as destruction of property to > something like assault.

When it becomes sentient and capable of protesting whatever is happening to it?

Whoever did that to the robot would shit a brick if the robot started screaming.

<comment><AUTHOR> > Whoever did that to the robot would shit a brick if the robot started > screaming.

I would assume so, but the robot looked vaguely humanoid, with a smiley face and all. Someone of a sane mind should feel bad defacing such a thing, but seeing as they didn't, they perhaps wouldn't have batted an eye if it had started screaming.

Now if it had pulled a gun, on the other hand...

</comment></comment></comment><comment><USER7> It would have been destroyed in Boston anyways [1]

[1] [https://en.wikipedia.org/wiki/2007_Boston_bomb_scare](https://en.wikipedia.org/wiki/2007_Boston_bomb_scare)</comment>


A question for web developers. - <AUTHOR>

It is not a secret that a huge problem has grown larger in the world of web development. And I'd like to hear your opinion about it.
What problem am I speaking of?
The soon to become over-talked issue of web apps developed to work correctly only on one browser(Usually Chrome) without even a reliable fallback to other browsers. I've seen many flavors of this issue in the wild, ranging from the "Proof of concept" sites that make clear their content only works or shows on X Browser, to sites changing landing pages depending on the User-Agent browser where only the chosen browser will have all functionality and the others will simply avoid being "too ugly", and to the extreme case of websites not rendering at all if you do not use whatever browser you are told to.
This is not a new problem, I believe anyone who has developed for some time with MicroStrategy, Appian, SAP or any other JAVA based ERP, BI or BMP, has also encountered this quickly annoying issue of being FORCED to work with Internet Explorer.
However, I do believe there is another side to the coin. A side where, for example, developers that only work for Chrome are able to push the bounds of the available tools and create really neat new web apps.
What I'd like to know is not only your point of view of how good or how bad this issue is. But if you have any ideas on if and how it could be fixed.
Personally, I'm so tired of meeting with clients asking "Why can't we do it if everyone uses (EG) Chrome" or being too afraid to hire new developers because themselves or someone near them has a spooky story involving one of this developers. <comment><USER2> Experience tells me this is not a huge problem and my personal opinion is that it won't become one - don't have any references though just IMO. What I mean to say is that basically if you're making a production level app, you just build it to work cross-browser that's the way it is, you rarely do things based on UA if you know what you're doing and opt for feature testing instead. Maybe some provide neat little extras if a browser has a specific feature like webgl, but you're going to make sure all functionality is provided for every browser so you hit the widest audience.

I find it hard to believe you get clients that think everyone uses Chrome, that's never happened to me. I've also rarely had a client ask for something to only work in a specific browser, the few exceptions have been making things work for IE6 or older browsers that were used internally by larger corps.

These are just my thoughts, discussion is welcomed :)

<comment><AUTHOR> Well yes, I completely agree with you. That is what we should do. But each time I see more developers that leave production level apps like this. And not even small websites like <http://absolutmexico.com> (Has a fallback to other browsers but the developer consciously decided to not offer the same functionality for browsers other than Chrome, even after been pointed to a few plug ins that would do it for him); but also huge Frameworks, like Appian, which forces you to use IE for administration.

And there's another side of the story, in both of the above scenarios, the product/site where developed by Engineers and Web Developers. But each time, plug ins make it easier for "non-code-savy" people to implement (for example) effects on their websites that would be really complicated any other way; which is cool until the moment you notice most of those plug ins are poorly coded. The problem grows as this people sell themselves as web developers and usually charge (as freelancers) much less than the full implementation of the job would be worth. I know this happens a lot, and by a lot I mean that 85% of the independent projects I had this year were about fixing this websites or making them bigger.

I think the problem might be that, in general, we talk about all the marvels of the internet and our work with it that it just makes people want to jump in. We give tutorials, plug ins, API's, and any other tool that makes the job easier, without really pointing out all that should be needed to actually deploy to production.</comment></comment>


The Hacker News Effect - <AUTHOR> http://blog.nodule.io/blog/2015/08/17/2015-08-17-the-hacker-news-effect.html

<comment><AUTHOR> Thought some people might find this interesting - we got on the front page of hacker news the other day and I thought I'd share some stats.</comment>


Giving up on wlroots-rs - <AUTHOR> http://way-cooler.org/blog/2019/04/29/rewriting-way-cooler-in-c.html <comment><USER2> A good post, thanks for sharing.

> I want to make one (mildly controversial) thing clear: rewriting a library > for the sake of only using Rust is not good engineering.

Strong agree.

> A literal rewrite of a project to Rust is not interesting, it's not useful, > it just causes churn and splits ecosystems. Time would be better spent > either working with existing solutions that already have the effort put in > to make them correct or to come up with new green-field projects.

This... I'm not so sure about. It really depends on what your objective is. For example, if your goal is to learn, you're not going to cause churn, and you're not going to split ecosystems. Working on project you already know well is a good way to learn, because you can focus on the language, not the project.

This also isn't _exactly_ a re-write, in my mind. I mean it is, and it isn't. This is because...

> The biggest problem when wrapping wlroots was defining the ownership model > of the objects that wlroots exposes.

The pain here isn't a re-write, it's an integration with an existing system. That's a good reason to not use something different! I also think this is interesting because it demonstrates something that's often said in discussions about Rust, but mostly in the abstract, and that's that Rust's rules influence the design of your system. It will guide you away from designs where the ownership of components is unclear. To many people, this is a benefit, but it can often cause struggles when learning. And, it can often cause struggles in situations like this: where you _can 't_ really re-write some external component to fit in the rules.

That being said, there should be a way to do the ownership part that makes sense, but I don't know wlroots well enough to comment.

 _That_ being said

> Currently there is 11 THOUSAND lines of Rust in wlroots-rs. All of this code > is just wrapper code, it doesn't do anything but memory management.

is also super legit. Managing this kind of thing is a pain. I can certainly understand not wanting to do it.

<comment><USER3> I agree and was going to say the same. That there was a huge challenge in writing code to manage memory ownership, is not surprising because memory ownership is so fluid and adhoc in C and its derivatives. And when you are asked to make that ownership explicit, if the original designers hadn't been thinking about it, you get a lot of cases which they would not have considered.

I would like to see a compositor written in Rust, I think it would make for a robust window system. I also know that starting from the position of "this will be written in Rust" would force the issue of memory ownership to the fore and result in a different architecture from the start.

<comment><USER4> Not a wayland, wlroots or rust expert, but dollars to donuts says that it's not "memory" management[1] at issue, but resource allocation on the other side of the graphics driver. Vertex arrays, textures, framebuffers, shaders et. al. all need some kind of allocation strategy, can in the modern world often be shared between process contexts, and they really don't fit well into the metaphors of either C or Rust.

But where in C you can just do it anyway, Rust is likely to flip out over your wrapper object abstractions.

[1] I mean sure, technically it is memory management, but you know what I mean.

<comment><USER5> This is also something that causes some pain when using C++ with RAII. Logically it makes some amount of sense that you have e.g. a C++ wrapper for a texture in OpenGL, and it knows to call glDeleteTextures in its destructor.

 _HOWEVER,_ the destructor can now only be called if the OpenGL context is active, and the texture may be deleted if the context is lost (which can happen). At some point anybody who's tried to wrap an OpenGL texture with a C++ class either decides to accept that RAII doesn't completely work here, or refactors it so that you manage something like handles to textures, which is a bit silly because you are really at that point managing handles _to handles_ to textures.

<comment><USER6> re: the handles to handles stuff ... I don't think that's so silly really, when you are talking about a resource that in some fundamental sense belongs to a different system (in this case OpenGL). Sure, that system gave you a handle, but if the semantics of managing that handle aren't 1:1 matched with your languages model of things, another level of indirection is a clean way to handle it.

<comment><USER7> And just think about what most file and I/O wrappers, that are part of the standard library in most higher level languages, e.g. file objects in python, streams in C++ etc., naturally do: They also just wrap (for example) POSIX file descriptors, which are handles, with their own handles, i.e. the file object/Stream/whatever.

<comment><USER5> Maybe I didn't explain what's happening in OpenGL properly, because that comparison doesn't work at all.

With e.g. std::ofstream, you are wrapping a handle, such as a POSIX file descriptor. So that part of your description is accurate.

However, this is different from what happens with OpenGL. The problem is that if you wrap an OpenGL texture (which is a handle), you end up with some problems because you can only free it with the correct context active, and it might become free for other reasons besides the wrapper being destroyed. So you are no longer wrapping a handle (like std::ofstream), but you are actually creating a new handle-to-handle, and wrapping that, and explicitly managing the lifetime OpenGL resources with a separate object somewhere else.

Of course, you could just wrap an OpenGL texture, explicitly decide not to handle context invalidation, and then be careful to ensure that your objects get destroyed with the OpenGL context active. You lose some flexibility and you have to babysit RAII to be sure it "does the right thing".

So what I'm saying here is that OpenGL textures are not like file handles.

<comment><USER6> They don't behave like file handles - but at a certain distance if you squint at it looks like the same problem. The real issue isn't that OpenGL textures don't behave like file handles, but that neither of them behave quite like objects in your language, which can lead to problems. The specifics of how the behavior differs is I think less important that the fact that it differs. Of course, file handles are not the best example because the language designers often had to put some thought into it early on; less true of something like OpenGL textures.

<comment><USER5> > …but at a certain distance if you squint at it looks like the same problem…

The whole discussion here is about how these things differ in subtle ways. The problem with "squinting" at the problem is you end up e.g. using RAII and then having to redesign your system because RAII doesn't match, and the problems weren't obvious when you started out.

Not to make too fine a point about it here, but file handles are perfect matches for RAII / Rust lifetimes, unlike OpenGL textures. You just close the handle at end of object lifetime. You can get errors when you close but current recommendation is to ignore errors when cleaning up and have a separate path for closing/committing data on close when writing, so on most paths the destructor will nop. This works well.

An example of a mismatch with the language semantics and file handles is with GC. If you close a file handle in a C++ destructor or Rust drop(), it's fine, those are run deterministically. If you use a JVM finalizer to close your file handle that might not happen soon enough (cue EMFILE).

Again, the reason why textures don't work this way is because you have to release them in a certain context and they might be released outside your control.

<comment><USER8> > Not to make too fine a point about it here, but file handles are perfect > matches for RAII / Rust lifetimes, unlike OpenGL textures.

Agreed, something like an FD matches RAII very well, but you can open one file multiple times, dup fds and multiple processes can do all this. So the FDs end up mapping in some non-trivial, probably refcounted way to other objects in the kernel.

So it seems with OpenGL, this kind of mapping / bookkeeping layer gets hoisted up into the application framework -- which might be a reasonable choice.

<comment><USER5> OpenGL textures point to some refcounted thing, but the handle table is not per-process but per-context, and the contexts are not thread-safe, and the contexts can become invalidated. So it is similar in many ways but there are too many differences in general.

</comment></comment></comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER9> I know very little about Rust or Wayland (I suppose I'm not the target audience) but I got lost very quickly here:

> A Wayland "output" is the resource that represents a display device. > Commonly this means it handles a computer monitor. This resource could > disappear at any time in the life cycle of the application. This is easy > enough to imagine: all it takes is a yank of the display's power cord and > the monitor goes away.

Surely even if a physical monitor is connected from a computer, the object representing it doesn't instantly go away? If it literally got freed as soon as the user disconnected the monitor then any access to such an object would be dangerous as you could be accessing an object after it's freed, or even another valid display object that got allocated into that space in the mean time.

Instead, I would expect an object in that situation to go into some error state, and even that might only be picked up when you perform certain operations. If that were the case, I don't really see how Rust lifetimes are a problem.

Since this was the main summary of the problem for laypeople like me, it made the rest of the article quite hard to follow.

<comment><USER10> I think you missed this part:

> [the resource handle] can only be dropped between event callbacks, > wlroots/Wayland is callback based

So "at any time" means between any two user callbacks, but not during them.

Error states really aren't a solution IMO, as they tend to pollute the entire interface in that methods that would be expected to work unconditionally can now fail or panic. Either you have to check each method invocation (entirely unnecessarily, since if a resource isn't in an error state at the start of your callback it won't go into one during it) or you make the absence of error state a precondition, in which case you're guaranteed to miss one or two cases and panic when the user yanks out the cord.

<comment><USER9> > > [the resource handle] can only be dropped between event callbacks, > wlroots/Wayland is callback based

Thanks, that certainly makes a hell of a lot more sense.

</comment></comment></comment><comment><USER11> I can't speak to every issue which the author might have encountered, but there is a better solution to the lifetime management problem than the two mentioned in the article.

Instead of this:

        fn some_wlroots_callback(output_handle: OutputHandle,
                                 surface_handle: SurfaceHandle) {
            output_handle.run(|output| {
                surface_handle.run(|surface| {
                    // maybe some more nested layers...
                }).unwrap()
            }).unwrap()
        }

One can do this:

        fn some_wlroots_callback(
            ctx: CallbackContext,
            output_handle: OutputHandle,
            surface_handle: SurfaceHandle
        ) {
            let output = ctx.get(output_handle);
            let surface = ctx.get(surface_handle);
        }

This is safe, because the lifetime of "output" and "surface" can be bound to the lifetime of the "ctx" (whose lifetime is controlled by the library: the library simply has to make sure that "ctx" is not accessible outside of a callback).

edit: Realised you can't tell that there's an implicit lifetime in `CallbackContext` here:

        struct CallbackContext<'a> { ... };

OR

        type CallbackContext<'a> = &'a CallbackContextImpl;

<comment><USER12> Author here.

The problem with that design (which is a great design given what I presented in the article by the way!) is that it doesn't allow you to share handles across callbacks, which is mandatory to do anything interesting. I'm assuming here that you can't use the handles except for that callback context. If you can, then that presents a different problem.

[https://play.rust- lang.org/?version=stable&mode=debug&editio...](https://play.rust- lang.org/?version=stable&mode=debug&edition=2018&gist=1a010f34fdb6886d41145eecc2963280)

If you can own a context, even with a lifetime parameter it's possible to leak it using the Box api. That allows you to have access to a &'static CallbackContext. This will break that assumption that it only lives as long as the callback itself.

<comment><USER11> The intent is that _handles_ can be used across contexts (as long as both contexts are from the same instance of wlroots) - the context checks that the handle is valid before unwrapping it. Could you clarify what you mean by it presenting a different problem?

With regards to the leaking issue - that's not actually correct. `Box::leak` does not give you access to the context with the `'static` lifetime, assuming the lifetime of the context is not 'static (that would fundamentally break rust's safety guarantees).

The only potential problem is that the destructor for the context may not run (cf. leakpocalypse). If the implementation requires the destructor to run, then you are right, you should never give ownership of the context object, it should be passed into the callback by reference. If you need access to a context outside of a callback, then you should use the callback-style:

        with_context(|ctx| {
            ... do stuff ...
        }

The nice thing is that `with_context` can enforce any threading constraints you might have (like contexts being accessed from a single thread), can ensure that the context is safely dropped at the end, and it's only required once - once you have a context you can use it as many times as you need.

<comment><USER12> Your edit to your original comment was important information I was missing - you are correct that that would probably work.

With how wlroots-rs is setup it does require the upgraded resources to not be leaked because their drop impl decrements the reference count.

Regardless, this was obviously only one part of the problem I was running into. As well, as can be seen, it's very complicated trying to ensure this is all sound and it's no longer worth the headache.

</comment></comment></comment></comment><comment><USER13> Interesting to see someone's reasons for moving back from rust to C. Normally it's the other way round.

Speaking as a C developer who has dabbled in Rust, It's always good to see the thoughts of someone who has spent a fair amount of time with the language who can give it a fair assessment.

</comment><comment><USER14> > Way Cooler is a Wayland compositor that was written in Rust using wlc

I know it is not easy, but I wish the author could have started with a paragraph that could help someone like me know whether or not the rest of the article would be something I would like to read.

How about something like this (and of course I may some of the facts wrong, but I want to be as constructive as I can):

"Wayland is a Windows manager developed as a better alternative to X-Windows. Way Cooler is a tiling Wayland manager, written in Rust, and designed to be easily extendible. In this article I describe my experience in trying to refactor it, for reasons that will be described below. I will also explain why, in certain instances, C was a better choice for this project than Rust."

<comment><USER15> You weren't the audience of this article. Since he wrote it as a blog post on way-cooler.com he surely was expecting his audience to be people familiar with Way Cooler, Wayland and Rust. He doesn't have a responsibility to dumb it down for you. And anyway it only takes a few minutes for you to get the context. Which you did, good job.

<comment><USER16> So it's way-cooler.com's fault for not explaining what their library/website is about.

Which unfortunately is par for the course on 99% of company blogs, which never explain what the company does without going onto the homepage (which even then is often confusing).

<comment><USER17> It's not a company blog. It's a some guy's open source side project. Ya' know... free... open source... side project... that's he's voluntarily sharing technical information on.

Really, it's not the guy's responsibility to over-inflate the article because some people need their hand held. It's a blog about about Rust, Wayland, and window managers. If you don't know what those things are then, like, Wikipedia is there for you, man.

It's like going to a programming languages website and going "well, gee, these guys suck for not explaining what a programming language is on their homepage what is with everyone being so discourteous!?"

And it's not like a paragraph of context would have mattered anyways; if you don't know what Rust is, what Wayland is, or what tiling window managers are then you'll need a lot more background knowledge before the article's content begins to be assailable.

</comment></comment></comment></comment><comment><USER18> I may be missing something, but what's wrong with the first example? The fact that you can leak an object shouldn't really matter for memory safety if it's just a handle to an object that the server manages. Yeah, it could go _wrong_ , but it won't be _unsafe_. Object handles are essentially file descriptors, right?

In general I think there's a tendency to overcomplicate safety features in Rust. The solution to an overly-complicated system isn't to throw the whole notion of safety out the window: it's to look at exactly what the complexity is buying you. If intricate combinations of Rust features are one extreme of the safety spectrum and C is the other extreme, there's frequently a happy design medium somewhere in the middle.

Edit: Looks like oconnor663 over on Reddit had a similar but more specific proposal, which probably works: [https://www.reddit.com/r/rust/comments/biq864/comment/em2kip...](https://www.reddit.com/r/rust/comments/biq864/comment/em2kipe)

<comment><USER19> Yes, the same concept is discussed in [https://news.ycombinator.com/item?id=19779243](https://news.ycombinator.com/item?id=19779243)

</comment></comment><comment><USER20> " _A Wayland "output" is the resource that represents a display device. Commonly this means it handles a computer monitor. This resource could disappear at any time in the life cycle of the application. This is easy enough to imagine: all it takes is a yank of the display's power cord and the monitor goes away._ [Except it can't; it can only disappear between callbacks?] _This is basically the exact opposite of the Rust memory model. Rust likes to own things and give compile-time defined borrows of that memory. This is runtime lifetime management that must be managed in some way._ "

Something leads me to believe that there is something very wrong with the architecture of wlroots-rs. The output should be attached to a callback parameter or something, maybe? I don't know enough about Wayland to say, but something ain't right.

<comment><USER12> Author here.

This output is attached to a callback parameter, but you can takes this resource from the callback in C (because it's just a pointer you copy around) and use it in other callbacks. Eventually a "special" callback that will trigger to indicate that the data the pointer refer to will be cleaned up and you need to remove all of your references to that resource because otherwise they will be dangling.

</comment></comment><comment><USER21> This code

        fn some_wlroots_callback(output_handle: OutputHandle,
                                 surface_handle: SurfaceHandle) {
            output_handle.run(|output| {
                surface_handle.run(|surface| {
                    // maybe some more nested layers...
                }).unwrap()
            }).unwrap()
        }

is just screaming continuation monad. You see the same code pattern in early Node.js code (sometimes leading to callback hell). In the JavaScript world, the problem was solved using Promises, and then async/await syntax. But more fundamentally, this is an instance of the continuation monad at work.

The continuation monad transformer is defined as

        newtype ContT r m a = ContT { runContT :: (a -> m r) -> m r }

and is nothing more than just a function that takes a callback. If this were Haskell, one could just write

        stuff = runContT $ do
          output <- ContT (run outputHandle)
          surface <- ContT (run surfaceHandle)
          -- and then maybe some more nested layers
          -- etc

Granted, continuation code can easily be misused to produce an incomprehensible mess in Haskell (its full generality can be compared with goto), but with Rust's FnOnce trait, the scope for misuse is considerably reduced.

<comment><USER22> JavaScript and Haskell get to enjoy the productivity of using a tracing GC though.

<comment><USER21> This doesn't really have much to do with the runtime. Certainly with a GC, programming would be easier, but I'm really talking about abstractions within the language. Rust already has language-integrated support for the Result monad. Rust doesn't have a general `do` syntax, but it has `?` which has made programming with the Result monad much easier. Can we think about the continuation monad and arrive at a new syntax that can ease this style of programming?

<comment><USER23> i don't really know Rust apart from some curious onlooking, but afaik expressing monads (i.e. the Monad typeclass) in Rust is tricky – something to do with the lifetimes of closures and the objects they close over, i think. ([Idiomatic Monads in Rust] probably touches on that). it might be possible to just build it into the language a la Result or async/await though.

[Idiomatic Monads in Rust] [https://varkor.github.io/blog/2019/03/28/idiomatic-monads- in...](https://varkor.github.io/blog/2019/03/28/idiomatic-monads-in-rust.html)

</comment></comment></comment></comment><comment><USER24> Question (for any more knowledgable readers here) from someone with a somewhat shallow understanding of the topics discussed:

Does this end up being primarily a negative reflection on the general structure of:

(a) Rust

(b) wl-roots

(c) Wayland

(d) all three

(e) none of the above, it's merely the incidental reality of trying to write code that's compatible/usable across multiple language ecosystems and none of the 3 projects can do much to improve this situation.

<comment><USER25> > Does this end up being primarily a negative reflection on the general > structure of

A core problem in this case is wlroots using a memory management paradigm that isn't easily modeled in Rust. This isn't unexpected per se, since C leaves MM entirely to the developer, while Rust is opinionated.

<comment><USER2> I would say it's a bit more subtle than that. Rust _can_ express this, but not safely. This is what the end bit is about.

The question then becomes, is it worth it if it's largely unsafe? That's a complex question. Unsafe Rust still does give you a lot of advantages, namely that the checked constructs are still safe, even in an unsafe block. Unsafe Rust is slightly more annoying to write than safe Rust, and so that's a downside.

It's also possible, and again, this is more in theory since I know nothing about wayland internals, that the safe abstraction was chosen to be a bit too low-level. That is, rather than trying to make the primitive operations safer, designing an external API you'd want users to use, rather than one defined in terms of some of the primitives, may make sense. This has a lot of pros and cons, as you'd imagine. And that's also more work to do.

<comment><USER12> Author here.

Ignoring the social impetus in the Rust community to not use unsafe, I also don't feel like unsafe Rust is something I want to program in all the time.

When I program in safe Rust I can be happy once it compiles because I can ignore all of the safety problems that come from C and C++.

However in unsafe Rust not only is it much more difficult to express what I want syntatically (the lack of auto deref is very annoying, having to write (*base).value all the time gets very old) and semantically (there is no standard for the unsafe parts of the language - not so much a problem if only smallish parts of this usage is used (because once a standard comes out just that can be updated) but a problem if a whole program is written in it).

Unsafe Rust is "good enough" to try to encode these abstractions but I would not use it over C or C++.

</comment></comment></comment></comment><comment><USER26> Interesting post that show some current limitations of Rust, especially when not being able to control the design entirely.

Rust's ownership system makes it harder to deal with the kind of dynamics wlroots exposes... It seems to me that the issue here is that there is no consensus (e.g library) on how Rust should deal with those issues, so if you want to just to provide bindings to a dynamic system you end up writing middle-ware that deals with that kind of dynamics in a Rust idiomatic fashion (taking advantage of ownership) instead of focusing on the task at hand. It somehow destroys Rust's promise of productivity.

A Rust project of mine[1], in an early stage and currently paused, deals with those issues (probably in a way similar to the Handles described in the post) by providing Service smart pointers (i.e, Svc<T>) and a component-framework that helps deal with the dynamics of a service being unregistered (e.g, a monitor unplugged, or a dynamic library unloaded) ; that component framework helps you be sure that if your struct contains a Svc<Foo>, that service is still available when you're called, or the component reaches an invalid state.

In general, it seems to be an area where Rust's ecosystem is still very early and would benefit from more input (such as this post) and consensus.

Regarding the callback-hell issue, that "dehandle" macro looks very much like async/await, and it looks like it could be implemented either in terms of async/await (still unstable) or generators (even more unstable).

Hopefully similar projects will be more likely to succeed as Rust and its ecosystem mature.

[1] [https://github.com/magnet/socrates- rs](https://github.com/magnet/socrates-rs)

</comment><comment><USER27> How does Rust handle these problems in the context of file I/O? I'm sure there is an axiomatically idiomatic (official) implementation of it as part of the language distribution, and at the same time file handles seem conceptually very similar to display handles and should have similar failure patterns (space can run out, a disk can fail, a plug-and-play disk can be yanked out at any time...).

<comment><USER2> That is all here: [https://doc.rust- lang.org/stable/std/fs/struct.File.html](https://doc.rust- lang.org/stable/std/fs/struct.File.html)

These failure patterns are handled by each method, for example,

      pub fn open<P: AsRef<Path>>(path: P) -> Result<File>

that Result will return an error if the file can't be opened, etc. Let's say you want to write some bytes, that's

      fn write(&mut self, buf: &[u8]) -> Result<usize>

This also returns Result, so if you've opened the file, but the disk is now out of space, this will return an error, etc.

</comment></comment><comment><USER28> I only skimmed the article, but the description of outputs and their asynchronous lifecycle making things complicated just made me think of what's become known as the ECS pattern in game development.

Your outputs sound just like entities in a game. They come and go as they please, and you often have multiple references to them from myriad places since entities may interact with many parts of the game.

I suspect if you investigated the established techniques for implementing ECS- style games in rust, you might find some simpler and established solutions for your troubles.

</comment><comment><USER29> Personally I think Rust is a great language. That said it may not be great for everyone nor a great fit for every problem.

Sometimes trying and admitting failure is a perfectly rational and valid option.

</comment><comment><USER30> Everything the author and the commentors here have said is completely legit. I'm not looking to start a war. And I completely acknowledge that what I'm about to say might be wrong as I haven't seen the author's code or the code of wlroots.

But I have to wonder if the design decisions of wlroots itself may be dubious. If it's this hard to manage memory safely when you're trying to wrap the API in a language that demands you're kept accountable for memory safety....

</comment><comment><USER31> Does wlroots itself present good code quality or it is basically a horrible wrapper to support every Xorg use case?

<comment><USER32> wlroots is generally highly regarded in the Wayland community, both in terms of technical design and code quality. There's a reason that every Wayland project which started _since_ wlroots has used wlroots, and those who didn't at first eventually rewrote their code to use wlroots.

<comment><USER33> I get the sense that most adopted wlroots because Wayland is a complex protocol. There's no alternative to wlroots so part of the reason everybody uses it is because there's no choice if you don't want to start from nothing.

<comment><USER32> Wayland is a simple protocol. The complicated part is everything else, like graphics and input and X11 compatibility.

<comment><USER33> Right, but that still means that getting to a point most end-users would consider 'usable' is quite complex. Especially because the documentation around these things can be lacking.

P.S. I like Wayland and use it everywhere for the record.

</comment></comment></comment></comment></comment><comment><USER34> good ol C :). Thanks for sharing these experiences. Happy to see some example of the places where rust still falls a little short / is a bit too restrictive for system programming. a lot of people deny this, but there's plenty of situations where you just want plain old C for it's straightforwardness to implement your own design. if you want to do it the 'rust' way, you find yourself restricted in all kinds of ways. if you can live with those restrictions it's great, but sometimes you just get stuck. Good luck on the rebuild in C!

</comment><comment><USER35> I have had the view that safety is typically not the most important goal of a project (user satisfaction is). I have often said that safety can get in the way of writing software that is useful. It's great to see a real-life case with Rust from someone who obviously tried very hard but ultimately had safety get in the way of writing the software they wanted. Hopefully, Rust will evolve to interface with the "unsafe" world in a more ergonomic way.

</comment><comment><USER36> A pity wlroots itself isn't written in Rust.

<comment><USER37> C is the lingra franca of programming. By writing wlroots in C, we make it easy for a half dozen projects to make bindings to other programming languages. Rust is the only one that seems to have failed, and it's not surprising given the constraints of the language.

wlroots brings together over a dozen different libraries and interfaces which are implemented in C. You'd have to repeat this process a dozen times over, running into the same problems which caused Timidger to abandon wlroots-rs, only more so. And for what? wlroots works great and didn't require shaving a thosuand yaks.

<comment><USER22> C is the lingua franca of UNIX based platforms.

Thankfully not all OSes bow to it.

<comment><USER32> >Thankfully not all OSes bow to it.

Right, just the successful ones.

<comment><USER38> Not Windows.

<comment><USER32> Right, because Win32 is a shining beacon of good design. Thank god it's not C, right?

<comment><USER22> Meanwhwile Linux is still trying to catchup with the security level of mainframes.

68% of out of bound kernel expoloits in 2018, nice.

</comment></comment></comment></comment></comment></comment></comment><comment><USER39> > When the benefit at the end of the day is just so I don't have to write C, > that doesn't really make it worth it.

This line not only summarizes the content of the article, but I'm afraid it may also describe the actual situation of porting C/C++ code to Rust.</comment>


Hacker News is really Hacker Discussions - <AUTHOR>

The number of "this is not news" comments seem to be increasing lately. This site might be called Hacker News but it has developed into a community of smart people who like discussing interesting things. From the first sentence of PG's Guidelines (http://ycombinator.com/newsguidelines.html):

   On-Topic: Anything that good hackers would find
   interesting. That includes more than hacking and
   startups. If you had to reduce it to a sentence, the
   answer might be: anything that gratifies one's
   intellectual curiosity.
 While this site is, and should be, dominated by recent developments, recency alone should not be grounds for down-voting or complaints. If a submitted link is not "news" but is novel enough to elicit an intellectually simulating conversation, for me at least, it's relevant. (The novel part disqualifies most political conversations; not only is this the wrong venue, but slinging dogmatic comments is really mundane.)
This is how I see it, anyway. I'd really like it if PG weighed in. He might allow this place to run organically, but generally his comments become HN's mores. <comment><USER2> I can see your point, though I think in some (many?) cases "this is not news" stands for "we have discussed this before, and therefore don't be surprised if many people don't weigh in, as the horse has been thrashed already"

<comment><AUTHOR> In those cases, I think the karmic voting system does the job of hiding redundancy more than the comments that say "this is not news." Especially because the submitter and interested commenters usually take it offensively, (even though it is rarely meant that way,) resulting in a lot of meta comments.

</comment></comment><comment><USER3> Hacker Views.</comment>


Hollywood Accounting and SOPA - The Hiltmon - <AUTHOR> http://www.hiltmon.com/blog/2012/01/17/hollywood-accounting/ <comment><AUTHOR> Based on feedback, I just updated the post to clarify my conjectured point.</comment>


Jailbroken iPhones compromised, $5 ransom demanded - <AUTHOR> http://blogs.zdnet.com/security/?p=4805&tag=nl.e539

<comment><USER2> Two things caused this vulnerability:

1\. Every iPhone has the same root password by default. Apple never intended for anyone to SSH into their device or see a shell at all.

2\. Many users install sshd on their jailbroken iPhones without knowing or caring about the implications, and leave it installed and running.

There are a few possible solutions to this problem:

The maintainer of the sshd package should prompt to change the mobile user's password at install time, disable root SSH access, and install sudo. It would also be a good thing to only allow SSH over WiFi (by default).

Maybe a status bar icon to indicate when SSH is enabled should be installed by default, and SSH could not run at startup but require that the user activate it per-boot.

(Actually, BigBoss, the developer of the popular dashboard application SBSettings, REMOVED the option to permanently disable SSH access, arguing that SSH is often the only way to fix up an iPhone that won't boot into the GUI and that it should start unless the user disables it for that boot. I disagree with this decision and think that, at the very least, sshd should shut down after the device boots successfully.)

The root problem here is that the developer of sshd for the iPhone probably released it to be used as a debugging tool by other developers and hackers. No one has the authority to step in and say "wait, this isn't safe for the general population."

</comment><comment><USER3> This is another lesson in the importance of using an unscrupulous credit card processor for unscrupulous business.

</comment><comment><USER4> Anybody else notice he was using mailinator for his paypal address? Unless he has some sort of script that polls mailinator and automatically removes messages instantly, he was likely vulnerable to having his paypal account stolen.

</comment><comment><USER5> _the SSH daemon which unless modified remains running with default users root and mobile, using the same password on each and every device._

I'm not sure I'd want to be known as the elite security expert who exploited this subtle vulnerability.

<comment><USER6> From someone who only unlocked his iphone to use another network, can somebody explain the steps needed to change the default ssh passwords?

<comment><USER7> The article even linked to it: <http://mr09.fileave.com/>

<comment><USER6> Yeah, but I really didn't want to click a link to a known scammer site. I was hoping the instructions could be posted somewhere clean and safe.

</comment></comment></comment></comment><comment><USER8> People who have no technical understanding of jailbreaking should not be doing it.

The Age of The Amateur is upon us and there's no escaping it. From people looking up diagnoses of their ailments to a armchair mechanics who think they know better than a technician with 30 years in the trade, all because they "read it on the internet".

</comment><comment><USER9> I don't know Dutch law, but this SK might be getting a lesson about playing with the bull....</comment>


A Stingray Detector for rooted Android phone released at 31c3 - <AUTHOR> https://play.google.com/store/apps/details?id=de.srlabs.snoopsnitch&hl=en

<comment><USER2> Hmm, been testing something similar, AIMSICD from the FDroid store, in Berlin, London and Dublin in the past month and no hits. I find this strange and not believable.</comment>


Heartbleed: 95% of detection tools 'flawed', claim researchers - <AUTHOR> http://www.theguardian.com/technology/2014/apr/16/heartbleed-bug-detection-tools-flawed <comment><USER2> It would be really useful to explain technically how to find out the flaw</comment>


The Story of Shmetty (1999) - <AUTHOR> https://www.sheldrickwildlifetrust.org/html/the_story_of_shmetty.html <comment><USER2> _Three little ostrich chicks recently brought in by a tourist bus were the main victims, and were ruthlessly hauled in with her whenever they came within trunk range. They were her constant playmates, providing the companionship so vital for a baby elephant, for they had immediately attached themselves to her as a mother figure to be followed: albeit a rather rough one at times, for in her more playful moments they were expected to take part in chasing games and had to put up with being dragged around the orchard by the neck whenever she managed to catch one._

This article apparently begs us to anthropomorphise and empathise with the elephant. We get some ostrich chicks later on that are roughed up.

Elephants come from Africa or India. Ostriches come from Africa. Given the sheer size of Africa does "come from" mean anything?

This is a pretty story.

</comment><comment><AUTHOR> "And then, one day, she was too weak even to get to her feet, although she greeted me with the usual rumble, which tugged at my heartstrings. I again stared at the rows of tins in my store. I had tried them all, and then suddenly one on the shelf caught my eye, which had been given to me some weeks before. My interest rose when I saw that it contained coconut oil added to a fat-free base, for I remembered once being told that coconut oil was probably the nearest substitute for the fat of elephant's milk. This last one I would try, and suddenly I felt a good deal happier, at least all was not lost yet.

It worked. My joy knew no bounds. Finally we had unlocked the mystery of how to bottle-rear a baby elephant." \- Dr. Daphne Sheldrick

This was a real tear-jerker. One of the best short reads I've come across in a while, and an interesting look into the science and experimentation that goes into conservation efforts.

</comment><comment><USER3> Oh that ending :(</comment>


Scroogle down - <AUTHOR> http://www.scroogle.org/cgi-bin/nbbw.cgi

<comment><USER2> Why would Google care about this? The ad uses Google's results and strips ads and cookie data, meaning they are taking from Google and giving nothing in return. Further, they use an unsupported method to scrape Google.

I can see the social value of anonymizing searches but Google shouldn't bear any blame for product changes that break derivative, unsupported third party products.

As a product manager, it's a nightmare when you're afraid to change (or retire an older version of) a successful product because some third party was using it in a unsupported way.

</comment><comment><USER3> Alt: <https://duckduckgo.com/> (<https://duckduckgo.com/privacy.html>)

<comment><USER4> Also see: <https://us2.ixquick.com/> (<https://us2.ixquick.com/eng/protect- privacy.html>)

</comment></comment><comment><USER5> I'm amazed that they have been able to run this service for 5 years - the fact that Google hasn't stopped them in that time says more about Google that it does about Scroogle.

<comment><USER6> That was exactly what I wrote below :)

I figure google doesn't mind scroogle at all, maybe is even amused by it (but that's reading the tealeaves). Someone inside google has had to push some buttons to permit scroogle to continue the scraping for as long as they did, normally they would have been auto-blocked in an eye blink.

<comment><USER7> I think Google wanted to shut them down because Scroogle offer an SSL search service, so all searches are encrypted. Too much privacy, Google would say.

<comment><USER6> The number of searches through scroogle per day compared to google directly is so low that I don't think that was a factor here.

<comment><USER4> How do you know the number of searches that went through Scroogle was so low it wasn't a factor? It may well have been a factor. Or it might not have been. We simply don't know.

<comment><USER6> <http://siteanalytics.compete.com/google.com+scroogle.com/>

</comment></comment></comment></comment></comment></comment><comment><USER8> Why not use something like <http://www.google.com/xhtml?q=google%20mobile%20search> ?

<comment><USER9> I would think that the ajax API could also be twisted to their needs. It requires an API key that Google puts some limits on, limits that they might want to apply to Scroogle in any case. <http://code.google.com/apis/ajaxsearch/>

<comment><USER10> Actually, their docs claim that the limits aren't really related to the API key. The API key is just so they can contact you if they start blocking you:

      http://code.google.com/apis/ajaxsearch/key.html

That may just be disinformation though. For example, if you can spread your usage over multiple IPs, you might be allowed more searches than if you told them your API key for all your requests on multiple IP addresses.

</comment></comment></comment><comment><USER11> It seems like the Slashdot and Hacker News comments have missed perhaps a key point. If any of you know of other search engines that meet these two criteria, please let me know:

1\. Queries are passed as x-www-form-urlencoded via HTTP POST not as plain text strings via HTTP GET e.g. www.example.com/?q=heres+my+query+for+you+to+look+at vs www.example.com/cgi- bin/do.cgi

2\. Queries of numerous diverse users at numerous diverse IP's are aggregated through a small set of IP's (Scroogle's), and Scroogle's servers are not scattered across the globe.

While this may not offer "privacy", it certainly makes it more difficult for a server to filter and/or redirect based on query string and approximated geolocation. Scroogle is obviously not catering to the common marketing platform. Otherwise they would be more interested to know what people are searching for, and where they are are searching from.

Scroogle's design makes it difficult for Google to serve up "personalised" and/or "localised" ads and results. (Even if they did not go through the trouble to scrub the ads and dump all cookies this would still be true.)

Some users may appreciate such _relatively_ "raw" results.

</comment><comment><USER11> Correction: There is no ad scrubbing involved. The results pages Scroogle scrapes (output=ie) have no ads to begin with. And, for whatever it's worth, they trigger less cookies from Google (only the PREF cookie is used, when I checked).

To reiterate what I said before, the difference is Scroogle allows the user query to be submitted via POST and over SSL.

The POST method effectively limits what the server can do with the data and what it can trigger automatically in the browser, without user input. Perhaps this is good for the user (more control), and bad for the marketer (less control). As such, it could be a controversial topic.

RFC 2616 Sec. 15.1.3 discussed the use of POST in the interests of privacy.

It would be nice if the output=ie option worked with Google Scholar/Patents and if Scroogle then supported Scholar searches.

</comment><comment><USER12> It's really too bad. I kind of wish that Google would offer a stripped down, encrypted search page that promises not to store anything.

Kind of like how browsers have a "privacy mode", Google could also offer a "private searching mode".

</comment><comment><USER11> It should be no surprise that Google's API's will never let users use the HTTP POST method. Those HTTP GET query strings are "valuable data"; Google is a business, not a charity. Hence Scroogle is doing something unique (AFAIK) by letting users use HTTP POST.

</comment><comment><USER4> Another HN discussion about the Scroogle outage here: <http://news.ycombinator.com/item?id=1337099></comment>


Yfrog should maintain usability for porn stars to maintain site traffic - <AUTHOR> http://www.katherinepoteri.com/uncategorized/yfrogs-traffic-depends-on-the-usability-opinions-of-their-porn-star-users/

<comment><USER2> What's your startup?</comment>


ML From Scratch, Part 1: Linear Regression - <AUTHOR> http://www.oranlooney.com/post/ml-from-scratch-part-1-linear-regression/ <comment><USER3> I tried to do from scratch AND hands-on in PyTorch:

[https://colab.research.google.com/github/stared/thinking- in-...](https://colab.research.google.com/github/stared/thinking-in-tensors- writing-in-pytorch/blob/master/3%20Linear%20regression.ipynb)

By all means, much more "from scratch".

It is a part of open-source "Thinking in Tensors, Writing in PyTorch": [https://github.com/stared/thinking-in-tensors-writing-in- pyt...](https://github.com/stared/thinking-in-tensors-writing-in-pytorch)

<comment><USER4> I tried the popular Machine Learning course on Coursera, and found myself spending tons of time debugging Octave code because to me it was such an unfamiliar way of expressing things. A widely accepted alternative in a more popular programming language would be a nice thing to exist.

<comment><USER5> It does exist! There are lots of answers to what you're asking for. But here's the best answer:

[https://course.fast.ai/](https://course.fast.ai/)

This course uses python and pytorch and will have you building something that can tell 30+ breeds of cats and dogs apart in the first lesson. While the old course from Andrew ng you mentioned starts with theory and by the end gets to doing something useful, the fastai course starts with best practices and moves into the underlying theory later.

Also Andrew Ng has a newer deeplaearning.ai course on coursera that is all python and doesn't do Octave.

<comment><USER4> Thanks.

</comment></comment></comment></comment><comment><USER6> It says it's from scratch, but it's using a lot of words and math symbols I don't understand when describing Linear Regression.

<comment><USER7> If you want a gentler introduction, I recommend the first module of Andrew Ng's Machine Learning class on Coursera. He also explains things intuitively before jumping into the math. Even when he uses math, he makes sure you understand the notations and what equation means.

</comment></comment><comment><USER8> At first I thought it was about implementing an ML like language. Then the realisation hit pretty fast..

<comment><USER9> This, I wish people wrote Machine Learning in their titles, always confuses me.

</comment></comment><comment><USER10> Understood everything up until this:

            ∇ΘJ=∇Θ(y−XΘ)T(y−XΘ)

expanded into

            ∇ΘJ=∇ΘyTy−(XΘ)Ty−yTXΘ+ΘT(XTX)Θ

Can someone explain why ∇Θ is only applied to the first term? Also i have never seen gradient notation used like that before.

<comment><USER11> Well, personally I prefer a different kind of notation. That said, there are several ways to get the same solution. In the following, apostrophe, ', means transpose and two symbols next to each other means multiplication, Ax = A (times) x. I can't figure out how to stop italics on this forum using a star.

1\. Expansion. Let J(x) = norm(Ax-b)^2. Then,

J(x) = norm(Ax-b)^2 = (Ax-b)'(Ax-b) = (x'A'-b')(Ax-b) = x'A'Ax - b'Ax -x'A'b + b'b = x'A'Ax - 2b'Ax + b'b

Then,

grad J(x) = 2A'Ax-2A'b

Except, how did we know that grad(x'A'Ax) = 2A'Ax or grad(2b'Ax)=2A'b? Well, there are at least two ways to derive it. One, go back to the limit definition. This is tedious. Two, cheat and use a Taylor series. Now, this assumes that we believe Taylor's theorem and it's worthwhile to go through a proof someday. Today's not that day. Taylor series assert that under the proper conditions that:

J(x+dx) = J(x) + J'(x)dx + (1/2)J''(x)dxdx + R(x)

where J'(x) denotes the total derivative of J and R(x) is a remainder term. This is a linear operator where if J:X->Y, then J'(x)\in L(X,Y) where L(X,Y) denotes the space of linear operators that have domain X and codomain Y. This means that J''(x)\in L(X,L(X,Y)) since we can still play this same trick. This means that J''(x)dxdx \in Y. Anyway, why do we care? If we can write something that looks like a Taylor series, then we can read off the derivatives. For example, for K(x) = x'Bx, we have that:

K(x+dx) = (x+dx)'B(x+dx) = x'Bx+dx'Bx+x'Bdx+dx'Bdx = x'Bx+2x'Bdx+dx'Bdx = K(x)+K'(x)dx+1/2K''(x)dxdx

Hence, if we just match the terms:

K(x)=x'Bx K'(x)dx=2x'Bdx (1/2)K''(x)dx=dx'Bdx or K''(x)=2dx'Bdx

Great, except grad K(x)=2B'x and not 2x'B. Why the transpose? Well, it's because K'(x) and grad K(x) are not the same thing. Recall, from above, if K:X->R where R means the real numbers, then K'(x)\in L(X,R). To be clear, this is a function that maps X to R. Say X was something like an m dimensional vector space, R(m). Then, K'(x) : R(m)->R. If we want to represent this as a matrix, the matrix would have size R(1,m). This is a row vector. Normally, the gradient is a column vector. Why? Well, most of the time, people view the gradient as a matrix of partial derivatives and they order them in a magical way. To me, a better way to visualize it is as what's called the Riesz representative of the total derivative. Basically, there's a theorem that states that under certain conditions any linear functional can be represented as the inner product between an element in that space and the argument. Basically, if f is a linear function that maps to the real numbers, then we can write any linear function, under the right conditions, as f(x)=<a,x> where <.,.> denotes inner products. In R(m), this inner product is just the transpose, so any linear functional in R(m) can be written as f(x)=a'x. Going back to the above, K'(x)dx=2x'Bdx=(2B'x)'dx. This means that the linear functional C(dx)=K'(x)dx can be written as C(dx)=K'(x)dx=(2B'x)'dx. That element, 2B'x is the gradient, by definition. It's the Riesz representative of the total derivative. And, again, you _can_ define the gradient differently. I wouldn't since this is clean and generalizes to Hilbert spaces, which are complete inner products spaces, which means we get up to some restriction of infinite dimensions and function spaces.

OK, that was a lot, but then we can realize that we can just apply the Taylor series trick to the whole expansion:

J(x+dx) = norm(A(x+dx)-b)^2 = norm(Ax+b+Adx)^2 = norm(Ax+b)^2 + 2(Ax+b)'Adx + dx'A'Adx = J(x) + J'(x)dx + (1/2)J''(x)dxdx

After matching, we have that

J'(x)dx = 2(Ax+b)'Adx

or that

grad J(x) = 2A'(b+Ax) = 2A'b + 2A'Ax

2\. But, wait, there's more. We could just use the chain rule. Recall, (f o g)'(x) = f'(g(x))g'(x) where o denotes function composition. In the above case, f(x)=norm(x)^2 and g(x)=Ax+b. Also playing Taylor series games, we'd eventually find out that f'(x)dx=2 dx' where I is the identity and g'(x)=A. This means that

f'(g(x))g'(x) = 2(Ax-b)'A

which means the gradient is:

2A'(Ax-b)

3\. If you really don't like this, you could pretend to be a physicist and do everything component wise with 1-D derivatives. That was a joke. This will produce the correct result, but one that I find particularly painful to derive. As such, I will punt and avoid that here.

Anyway, all teasing aside, there are lots of different ways to get the same result. Really, just use what works well for you and potentially adapt if you're working with an audience that views things differently. I don't claim what I wrote above is the best notation or derivations for you, but they work well for me and I wanted to provide some variety on a Saturday afternoon.

<comment><AUTHOR> Yes, using chain rule for the gradient of norm(Ax-b)^2 makes that derivation a lot shorter. Or just citing a theorem for the gradient of the L2 norm would have been fine. I used the FOIL approach because each of the 4 terms can be tackled using very elementary theorems in matrix calculus - a constant term, two linear terms, and a quadratic form. But in retrospect this was probably a mistake seeing as several people have gotten hung up on it.

</comment></comment></comment><comment><USER12> I could balance equations in chemistry and do some algebra and trigonometry at GCSE level. But this blows my mind. Higher tier GCSE Maths. I should have paid more attention. I think I know of what regression is in a simpistic term. It's like taking a rolling graph and predicting the next point on the x / y axis, using the previous data as a training model. I hope.

<comment><USER7> You're exactly right. It's fitting a higher-dimensional line or curve to the data.

</comment></comment><comment><USER13> I found the notation here non-standard and confusing.

In my opinion, the wikipedia article is more concise and provides more intuition (especially the multiple ways to derive the closed form solution).

[https://en.wikipedia.org/wiki/Ordinary_least_squares#Alterna...](https://en.wikipedia.org/wiki/Ordinary_least_squares#Alternative_derivations)

<comment><USER14> The Wikipedia article has lots of nice material, but much easier than that or the OP here is my

[https://news.ycombinator.com/item?id=21301117](https://news.ycombinator.com/item?id=21301117)

also in this thread.

</comment></comment><comment><USER15> For a computer science phd or master student candidate, I think the article or the site overall is very good

<comment><USER14> For any student, middle school or later who knows matrix multiplication, but no calculus or probability, just use my

[https://news.ycombinator.com/item?id=21301117](https://news.ycombinator.com/item?id=21301117)

in this thread. It's really simple!

</comment></comment><comment><USER16> one of the best 'from scratch' articles ive read on LR

</comment><comment><USER14> === Introduction

Here I give some notes for a shorter, simpler, more general, no calculus derivatives derivation of the basics of regression analysis.

=== The Given Data

Let R be the set of real numbers (can use the set of rational numbers instead if wish).

We are given positive integers m and n.

In our typing, character '^' starts a superscript; character '_' starts a subscript.

We regard R^m as the set of all m x 1 matrices (column vectors); that is, each point in R^m is a matrix with m rows and 1 column with its components in set R.

We are given m x 1 y in R^m.

We are given m x n matrix A with components in R.

We will need to know what matrix _transpose_ is: For an intuitive view, the _transpose_ of A is A^T where each column of A becomes a row of A^T. Or to be explicit, for i = 1 to m and j = 1 to n, the component in row i and column j of A becomes the component in row j and column i of A^T.

We notice that each column of A is m x 1 and, thus, a point in R^m.

Suppose b is n x 1 with components in R.

Then the matrix product Ab is m x 1 in R^m and is a _linear combination_ (with _coefficients_ from b) of the columns of A.

=== Real World

So we have data A and y. To get this data, maybe we got some medical record data on m = 100,000 people.

For each person we got data on age, income, years of schooling, height, weight, birth gender (0 for male, 1 for female), years of smoking, blood sugar level, blood cholesterol level, race (1 to 5 from white, black, Hispanic, Asian, other), that is n = 10 variables. We get to select these variables and call them _independent_.

For person i = 1 to m = 100,000, we put the value of variable j = 1 to n = 10 in row i and column j of matrix A.

Or matrix A has one row for each person and one column for each variable.

Vector y has systolic blood pressure: For i = 1 to m = 100,000, row i of y, that is, y_i, has the systolic blood pressure of person i. We regard systolic blood pressure in y as the _dependent_ variable.

What we want to do is use our data to get a mathematical function that for any person, in the m = 100,000 or not, takes in the values of the independent variables, 1 x n v, and returns the corresponding value of the dependent variable 1 x 1 z. To this end we want n x 1 b so that we have

z = vb

So for any person, we take their independent variable values v, apply coefficients b, and get their dependent variable value z.

We seek the b we will use on all people.

=== The _Normal Equations_

So, we have our given m x n A and m x 1 y, and we seek our n x 1 b.

We let

S = { Au | n x 1 u }

That is, S is the set of all the _linear combinations_ of the columns of A, a _hyperplane_ in R^m, a generalization of a plane in three dimensions or a line in two dimensions, a vector _subspace_ of R^m, the vector subspace of R^m _spanned_ by the columns of A.

We seek w in S to minimize the squared _length_

||y - w||^2

= \sum_{i = 1}^m (y_i - w_i)^2

(notation from D. Knuth's math typesetting software TeX), that is the sum (capital letter Greek sigma) from i = 1 to m of

(y_i - w_i)^2

where y_i is component i of m x 1 y in R^m and similarly for w_i.

That is, we seek the w in the hyperplane S that is closest to our dependent variable value y.

Well, from some simple geometry, the vector

y - <USER2>

has to be perpendicular to the hyperplane S.

Also from the geometry, w is unique, the only point in S that minimizes the squared length

||y - w||^2

For the _geometry_ , there is one classic theorem -- in W. Rudin, _Real and Complex Analysis_ \-- that will mostly do: In quite general situations, more general than R^m, every non-empty, closed, convex set has a unique element of minimum norm (length).

Now that we have the definitions and tools we need, we derive the _normal equations_ in just two lines of matrix algebra:

Since (y - w) is perpendicular to each column of A, we have that

A^T (y - w) = 0

where the right side is an n x 1 matrix of 0s.

Then

A^T y = A^T Ab

or with the usual writing order

(A^T A)b = A^T y

the _normal equations_ where we have A and y and solve for b.

=== Results

Since w is in S, the equations do have a solution. Moreover, from the geometry, w is unique.

If the n x n square matrix (A^T A) has an inverse, then the solution, the b is also unique.

Note: Vector w DOES exist and is unique; b DOES exist; if the inverse of (A^T A) exists, then b is unique; otherwise b STILL exists but is not unique. STILL w is unique. How 'bout that!

Since w is in S and since (y - w) is perpendicular to all the vectors in S, we have that

(y - w)^T w = 0

y^T y = (y - w + w)^T (y - w + w)

= (y - w)^T (y - w) + (y - w)^T w + w^T (y \- w) + w^T w

= (y - w)^T (y - w) + w^T w

or

[total sum of squares] = [regression sum of squares] + [error sum of squares]

or the Pythagorean theorem.

So, now that we have found b, for any v, we can get our desired z from vb.

The b we found works _best_ in the least squares sense for the m = 100,000 data we had. If the 100,000 are an appropriate _sample_ of a billion, and if our b works well on our sample, then maybe b will work well on the billion. Ah, maybe could prove some theorems here, theorems with meager or no more assumptions than we have made so far!

"Look, Ma, no calculus! And no mention of the Gaussian distribution. No mention of maximum likelihood.

Except for regarding the m = 100,000 _observations_ as a _sample_ from a billion, we have mentioned no probability concepts. We never asked for a matrix inverse. And we never mentioned _multicollinearity_."

And, maybe the inverse of n x n (A^T A) does exist but is "numerically unstable". Sooooo, we begin to suspect: The b we get may be inaccurate but the w may still be fine and our

z = vb

may also still be accurate. Might want to look into this.

For a start, sure, the matrix (A^T A) being numerically unstable is essentially the same as the ratio of the largest and smallest (positive, they are all positive) eigenvalues being large. That is, roughly, the problem is that the small eigenvalues are, in the _scale_ of the problem, close to 0. Even if they are 0, we have shown that our w is still unique.

</comment><comment><USER17> Hardly 'from scratch', I was expecting an ELI5 article.

<comment><USER18> The submitted title, "Linear Regression from Scratch", was misleading. We've replaced it with the title on the page.

From-scratchness is relative I guess.

<comment><USER19> First you need to create a universe...

<comment><USER20> Easy Biscuits from Scratch:

Step 1) Plant a crop of wheat

</comment></comment></comment></comment><comment><USER21> The LaTeX was LaToast, which is LaShame.

<comment><USER22> Are you blocking one of the JS libs that the page uses? The notation was screwed up for me until I temporarily unblocked them.

<comment><USER21> Ah.</comment></comment></comment>


Ask HN | What kind of PR package did you send to announce your launch? - <AUTHOR>

Just curious on what everyone is doing from a PR perspective when launching their startup.<p>I'd assume the PR package would include a launch article, logos and pictures.  What have you done in the past that worked well? <comment><USER2> Hi, I'm a writer from GigaOM. I can't tell you what works well for other startups, but I can tell you what I look for when weighing whether to profile a startup.

1) A good or at least interesting idea that isn't just mimicking what a dozen other companies are doing. 2) A founder with an impressive resume 3) Backers that know what they're doing. Elon Musk doesn't need to be on your board, but if you're money man is your dentist, you'll have to impress some other way.

I can't tell you how many pitches I get for "the newest startup in mobile advertising". There has to be something different about your startup otherwise you wouldn't be bothering right? (At least i hope so) You really need to identify that point of difference and highlight it in the first sentence. Most of us won't get much further unless you're really impressive in category 2 and 3.

Finally, a good pic of your founder/founders. Not a year book photo. Not a Zuck photo of some kid making faces in hoodie. A decent human shot of person that doesn't look like a canned shot. If someone choses to interview your startup that will be the first thing they ask for. Might as well make the process easier.

<comment><USER3> what's the best way to pitch a writer like yourself? Does email work, or do you prefer twitter?</comment></comment>