Ask HN: Pricing dead zone: 300$-3000$ - <AUTHOR> Recently, we launched a product with the following pricing: Free, 500$/m, 1000$/m, Enterprise (more info http://rolepoint.io/price.html)
I read somewhere there is very little software products in range 300$-3000$. It's too expensive to use a credit card, too cheap for enterprise sales. I think it was Joel Spolsky's comment to some article. I can't find it, because probably I'm using an incorrect term.
Can someone provide some resources? <comment><USER2> [http://www.joelonsoftware.com/articles/CamelsandRubberDuckie...](http://www.joelonsoftware.com/articles/CamelsandRubberDuckies.html) :

> Notice the gap? There's no software priced between $1000 and $75,000. I'll > tell you why. The minute you charge more than $1000 you need to get serious > corporate signoffs. You need a line item in their budget. You need > purchasing managers and CEO approval and competitive bids and paperwork. So > you need to send a salesperson out to the customer to do PowerPoint, with > his airfare, golf course memberships, and $19.95 porn movies at the Ritz > Carlton. And with all this, the cost of making one successful sale is going > to average about $50,000. If you're sending salespeople out to customers and > charging less than $75,000, you're losing money.</comment>


Ask HN: How do I leave a startup on philosophical grounds? - <AUTHOR> (I want to apologize for the length of the text below, if I had more time I would have made it shorter)
I have been working for a startup here in beautiful San Francisco for a little while now as a programmer and mathematician, I was drawn to the startup because I thought the idea was valuable and wanted to be a part of something that was going to impact a lot of people's lives, in addition, one of the founders has a considerable social media presence that I thought would be able to bring us to new heights. I was also the first technical hire and was excited to be applying a lot of statistics and machine learning theory to my job as well as shaping the technical future of the company. Only one catch - I would be paid nothing until the company went through Round A financing, which was said at the time I was brought on to be closing, at the latest, the first week of October.
I started out by working on an machine learning algorithm for automatically parsing and constructing tweets, under the guise that we would be targeting people who were obviously interested in the services our startup offered. Using a structured learning approach (and thorough application of k-means :), the accuracy and ability of the program to mass-message interested parties grew exponentially, I noticed potential for abuse, and I talked to a casual friend at twitter to verify this was OK - indeed it was as long as it didn't get out of hand, ever confident in my ability to 'keep things from getting out of hand'. As time grew on, the CEO of the company pressured me into using it to the ends of spamming people and (effictively) asking me get around twitter's spam detection algorithms and in general make twitter a worse place to be. I voiced objections and the CEO of the company basically told me I was naive and that everyone in the space was doing this.
As time went on, the work environment became more stressful, despite the fact that I had only committed to evenings 3 days a week, I came in a few extra times during the past weeks in order to meet some deadlines for the site. When I took a day off (In reality, not a day off, it was a day I was slated to have off), the CEO of the company was very upset with me because I had given her 'the impression' that I would be working all the time from there on out.
I should also reiterate at this point that I'm the only technical employee, but not the only employee. We have a 'community manager', 'Product Manager', 'CFO' and a number of writers. I should note that our startup has nothing to do with writing, and is actually in the social discovery space. I don't feel this is an optimum organization for a company, but I haven't said anything about it.
One night, the CEO and CFO of the company wanted to make a Gantt chart of our progress, we went through various development scenarios (Rather, what various non-programmer's impression of how development works scenarios), and I was continually asked how long certain events ranging from how long it would take to "warm up" our MCMC algorithm in the site's recommendation engine to how long certain programming tasks would take. Unfortunately I didn't have a whole lot of solid data at the time, so I told them the only thing I knew - "I'm sorry, I don't have a way of making a good estimate". After two or three times, the CEO was visibly irritated that I couldn't tell how long it would take and we decided to break.
The next day the CEO brought me into a conference room and told me I was being uncooperative, I was a little taken aback by this but I asked her to explain. She was concerned that I wasn't working full-time (I've deceived the reader a bit here, because full-time implies you're being paid), even though I had worked just one week full-time, out of the kindness of my heart in order to meet deadlines. She continued to explain that my philosophical objections to some things that were happening in the company were only slowing us down and weren't productive, as well as the fact that "As an engineer, you know how to do math and computers, on't tell me how to do my job", this tidbit referenced a suggestion that our site's "metrics" that were being reported to me were flawed, and that I could prove it with statistics, unfortunately my argument based on principle component analysis and cross validation fell on deaf ears (I'll let you guess who was right, a Berkeley design graduate or Thomas Bayes).
After this, I felt it was imperative that I look for a new position, but to be frank I'm a little bit intimidated by interviewing processes, as well I'm very young without a university degree. I hack on NoSQL database internals for my open source project (A granular riak derivative) and am very active in Machine Learning research and have authored a number of scripts, tools and speak at some ML meetups in the area. Despite all of this, I'm somewhat embarrassed to say I'm intimidated of interviewing at startups, so I resigned myself to my fate and slogged on with the hopes that it would get better or maybe the funding would come through someday.
Our prior site was designed and coded by an Indian firm, and it soon became clear I would redo all of it. I was excited by the opportunity to do some 'real work' rather than running a marketing shell game, and despite an extremely aggressive timeline, I was and am working night and day to get it out the door.
Later down the line, things changed, a few people were reading some pull requests I had made on Github and contacted me about beginning work immediately on a recommendation engine. In addition, a startup I had done contract work for when I first moved to SF (They had just lost their entire Rails team and were already in deep trouble with investors at the time) was able to secure funding based on the product I wrote for them, the CEO saw me in the hallways and insisted to take me out to lunch, and said "*, we are incredibly impressed with your programming ability, we couldn't have launched our startup without you, you are literally our godsend" and proceeded to give me 1k out of thanks for my effort and extended a more permanent offer to me. I know thats not the dolla dolla bills that we're all searching for, but in my situation it made a huge difference and indicates to me that there is a great disparity in the compassion of people involved in startups.
So here I find myself, working extremely hard, all weekend, all last week, and the week before that on this project. I'm blowing off people who are trying to pay me good money and people who I really enjoy speaking with so I can work on this project for which I'm likely to see nothing. It's really my own insecurities about being seen as someone who just backs out. Now I'm sitting in the darkness of my office working on new feature requests as the pour in, about 10 of them came in on pivotal yesterday, they are all "supposed" to be done tomorrow, so that the CEO can show off the product.
So I'm thinking about quitting (Can you quit a job you don't get paid for?), and theres where it gets tricky.
The CEO has a considerable social media following and is a good networker (Which is why I came to work for her in the first place), she's a nice lady and I'm on great terms with everyone I work with. However, I am the only engineer and I don't know if she really has a whole lot of options outside of me, my departure may be relatively devastating to the startup and the fine people that work there at this stage and would be almost entirely without warning, I'm trying to finish up the product she wanted just so she can have SOMETHING to work with and not just be left out in the e-cold but I'm concerned that leaving the company at this point will forever put the mark of the beast upon my forehead. In addition, the company I worked for previously is in the same incubator and it would be really awkward if I left. On top of all of this, I want to let the CEO know that I'm leaving not because I'm not passionate about the product (I am), not because I don't like the people or her, or even the money -- but because frankly this is not an appropriate way to treat an employee and that its not right to act with condescension because someone is younger than you or is "An engineer", instilling these finer philosophical points is assured to only inflame her temper I'm sure.
I've never asked for e-help before, so I implore you for your advice Hacker News, what's a young man like me to do in this situation? Are you hiring? <comment><USER2> You need to get out. "Are you hiring?" _Everyone_ is hiring. Especially in SF. You have absolutely no reason to stay at a "job" that isn't both compensating you extremely well _and_ respecting you, and this one is doing neither.

And don't worry about dooming the company. You owe them absolutely nothing. Zero. Well, negative, since they owe you a lot. If the company thinks it can get by with a single unpaid engineer, they're not going very far anyway, and this will be a good wake-up call that they need to re-evaluate their priorities.

If you really can't keep yourself from feeling bad about leaving them, offer to work for market rate (something like $100/hour as a consultant) for a little while so you can finish up the product and give them some time to find someone else, but don't work another day for them without knowing that you'll be immediately compensated. And set a hard deadline, like 30 days, for when you're out of there, because you shouldn't stay anywhere that doesn't respect you for too long even if they are paying you.

And yes, technical interviews around here are pretty tough, but the only way to see if you can make it through is to try a few. It sounds like you're smart enough to do very well at them.

Shameless plug time: I interned at Cloudera this summer. I had a great time and learned a ton. The people there are extremely smart. A huge proportion of the company are engineers, and pretty much all of the management is highly technical. They'd be very interested in talking to someone who hacks on NoSQL databases and is active in ML research. I could see you on the platform team, contributing to HBase and/or Mahout, and there are some Data Science and Solution Architect roles that could involve your ML experience.

Here's the careers page: <http://www.cloudera.com/company/careers/>

</comment><comment><USER3> ob. disclaimer: I'm not a lawyer, this is not legal advice, if you want legal advice you should contact a labor attorney in San Francisco.

Line up a paying gig, get it confirmed in writing (heck, start if you can since you're working on this "part time") and then resign. Do not get into it with the CEO over appropriateness of treating an employee or the product. Really, truly, do not do this. Do not give the CEO any room to argue with you, or to make a case against you.

Just resign: you found a paying gig. You don't owe them any more explanation than that.

Document everything. Do not sign any termination agreements, you're not an employee and I assume you didn't sign a contract. If you signed an NDA then verbally agree to abide by the NDA for a fixed period of time (make sure you have a printed copy of the NDA stashed away somewhere).

Now, if you did sign a contract or employment agreement, then honestly the first thing you should do tomorrow is find a labor attorney and get some legal advice. This will cost money. This will cost less money than either the pain of continuing at this organization, or the potential litigation.

</comment><comment><USER4> You're not being paid a salary... but you don't have equity?

Get out now. It's a deathtrap.

<comment><AUTHOR> That sums it up.

<comment><USER5> I'm just curious -- why would you agree to "work" at a startup that is not compensating you? Not even vesting equity?

My feeling is the reason they don't have any other engineers is because they couldn't sucker anyone else into this...

<comment><AUTHOR> I'm really passionate about the idea and the technology (that could be behind this), and apparently I'm young and dumb. Basically.

</comment></comment></comment></comment><comment><USER6> Leave as soon as possible. You don't like it. You could easily be employed elsewhere you would like.

It also sounds like an unhealthy situation: imbalanced team, sketchy uncertain compensation (cash/equity), low respect, nothing to help you with where you need to grow (which includes both technical peers and having the confidence to interview elsewhere).

No point in trying to rush something to 'complete' and only then leave. Software is never done. They'll need to get more engineers in any case, those new engineers should do it the way they'll need to.

Respect anything you've signed so far; don't sign anything new; don't directly compete or take anything you wrote for the current unpaid project with you.

Though you say the CEO is nice, it also sounds like you're being a little bullied, and expect to get more 'temper' from people when you leave. Brush it off; it's their situation and emotional reactions, not an objective analysis of things. Don't get into a long discussion, don't accept a 'counter-offer' or promise of change. Go elsewhere definitively.

</comment><comment><USER7> Tons of people are hiring, and anyone that said "you only know computers, so don't tell me how to do my job" is not "a nice lady".

However, your CEO is correct in that you are absolutely, incredibly naive.

You are being taken advantage of, and are being naive by staying. You are also being naive by thinking that your lack of a university degree is an impediment. Gates, Jobs, Zuck were all dropouts.

<comment><AUTHOR> Thank you for your frankness Yuri, I'll take this into consideration.

<comment><USER8> Page & Yang were dropouts too and the list goes on and on... There is something I don't understand in your story. There seem to be a couple of employees and you seem to be the only developer... Did this lady found a way to hire a team without paying anybody or are you the only one? Pay "cuts" usually come with a lager equity grant... very simple equation : share the risk, share the benefit. In your situation it doesn't really matter at this point. The main reason you should leave is the CEO... She seems clueless (based on your description) especially when she says you're naive and "that everybody does it" (spamming twitter) and that's why you guys should do it... If everybody "does it" and it annoys users then it's exactly the reason not to do it. A successfull consumer startup is about doing something new, smart, unexpectedly helpfull to users and surprisingly disruptive to the industry... Spamming users is the naive approach! Lesson learned... The lesson here is that the people you chose to work with are more important then the ideas you will possibly work on... I'm working on a recommendation engine too, I'd love to chat with you...

<comment><AUTHOR> I'm not sure, I have never asked anyone else about their compensation or explained mine, I've always heard that is impolite to do at a company.

However, I do always enjoy talking about technology, if you have any questions you'd like to run by me I'm more than happy to chat!

</comment></comment></comment></comment><comment><USER9> It's during situations like these that I wish the votes could be displayed in HN, just so that you would get a feel of how opinions weigh. There are many answers that I'd vote up in here, but that doesn't convey to you the strength of the message. So we have to resort to reiterating it:

\- You're saying the CEO doesn't share your moral objections and even derides them. Did it cross your mind that maybe she's the type who also wouldn't mind tricking someone to work for her for free? Sounds to me like you're probably being taken advantage of, so get out. Once out, stay out. There isn't much to advocate for, in a relationship that starts with one party taking advantage of another.

\- don't sweat your lack of diploma.

\- I haven't made a cv in a while, but I'd advise you to meet with someone that could help you refine yours and prepare for interviews.

\- try to get an idea of what you would be worth in the current market. I've seen a few posts on HN and some Stack Exchange sites discussing the topic. I believe you're capable of digging up that information, or maybe someone would be kind enough to post some links. That sort of info isn't pinpoint accurate, but having even ballpark numbers is always comforting when making demands and in your case, I feel that you could use the reassurance.

</comment><comment><USER10> _The CEO has a considerable social media following and is a good networker (Which is why I came to work for her in the first place), she's a nice lady..._

Honestly, she doesn't sound very nice. She sounds like the kind of person with good social skills of the sort that allow her to take advantage of people by, say, bullying them into working for free and then putting them in the position that they would feel enormously guilty if they left because they are the only engineer. For people who are very socially astute and also in a position of power, such situations are often planned, not mere coincidence.

I suggest you find a means to deal with your personal weaknesses in terms of not feeling comfortable interviewing and what not.

<comment><USER11> 100% this. The term "sociopath" comes to mind. Even if you didn't have any job prospects, you should get out. Since you do, it's an absolute no-brainer. No two weeks notice either; the most I'd do is make sure somebody has access to the source.

</comment></comment><comment><USER12> Be upfront with your current CEO. Tell her that you've received an offer that pays good money, and you'd be working with people you already know and get along with very well, so you would be a great fit in that team. Try not to burn bridges though.

Oh, and if you're going with the job offer you got (and you should), don't offer to "help out" for the current job a few hours a week. They'll still have expectations from you to work more than you can.

</comment><comment><USER13> There are a ton of jobs that will respect what you can bring to the company. You should be properly compensated for the value you bring, and handsomely if the company is pre-revenue (more risky = more equity). Email your resume (or link to a portfolio site) to firstname.lastname@example.com - I know of a company that may be interested.

</comment><comment><USER14> Can you put an email address in your HN profile or in a comment here? I'm sure there are lots of great startups that can treat you much better and are interested in talking to you.

<comment><AUTHOR> It is done my good sir!

</comment></comment><comment><USER15> Don't burn bridges - be polite, give at least two weeks' notice, don't get into arguments. Smile, thank them for the learning opportunity and wish them all the best.

<comment><USER11> _give at least two weeks' notice_

There's no reason to work a single minute more for free for these people.

<comment><USER16> I would at least give them an honest, non-emotional resignation letter, so they know what the cause is, and whatever notice you want to make it. Considering they're not paying you, 2 weeks is probably not fair, but at least a day or two, whatever you think is fair. And then leave.

This may be beyond the scope of "business," but I agree with the don't burn bridges comments. It is your responsibility to get yourself out of a bad situation as soon as you can, but as long as you have the power to do it gracefully, and with respect, that's the right thing to do - or rather, it will bring you good karma ;)</comment></comment></comment>


Rust is surprisingly expressive - <AUTHOR> http://words.steveklabnik.com/rust-is-surprisingly-expressive <comment><USER2> I don't think the ability to write expressions similar to natural language like "2.days.from_now" should be called "expresiveness". Real expresiveness is about what SICP calls "means of abstraction" and "means of combination", not necessarily about having very nice syntax. In general I think those considerations would benefit from distinguishing a bit more between syntax and semantics. As another example, I have been doing Ruby professionally for almost 10 years now, and despite this I have to strongly disagree with the conclusion of this quotation:

 _Python is a beautiful, clean language. But the same restrictions that make it nice and clean mean that it's hard to write beautiful, clean libraries. Ruby, on the other hand, is a complicated, ugly language. But that complexity allows you to write really clean, nice, easy-to-use libraries._

The Ruby metaprogramming magic makes for really nice syntax, which is what made me choose it over Python all those years ago, but it complicates understanding of what's going on - as I matured as an engineer, maintained a codebase over several years, several times spend long hours debugging issues coming from metaprogramming pitfalls, I shift more and more to the Python approach of building APIs in the simplest possible way, as much as possible sticking to simple function calls and no really fancy metaprogramming just to get a cleaner syntax, e.g. compare Rails has_many :foo with Django's models.ForeignKey(Foo) and the internal implementations of those. Same thing with using "BDD" testing frameworks like RSpec vs. traditional assert stuff, what is the nice syntax worth if tricky bugs hit you where you most want to avoid it, in tests. Libraries like RSpec might be "nice", but they are certainly not "easy-to-use", and I don't think I would call them quite "clean", if I look at their source code.

In other words, while clean syntax is luring, in the long run clean and simple semantics is what I think is really important.

<comment><USER3> Cannot upvote enough!

Rubyists try too hard to emulate natural language syntax, but in the process forget that natural languages are not particularly clean - in fact, more often than not they are highly dependent on contextual information, not just semantically, but even syntactically.

Ultimately, natural languages and programming languages serve very different purposes: communication in natural languages is highly dependent on context for resolving ambiguity (e.g., if we took this discussion to a non-programming forum, everybody else would be like "WTF is going on?"), while programming languages are all about making it possible to be pedantically precise without reducing convenience.

<comment><USER4> What kind of people still get excited over a language's ability to do this?

* Category functions in Objective-C

* .NET extension methods

</comment></comment></comment><comment><USER5> Sometimes I think I must be a humongous idiot because adding a "days" method to Fixnum smells like the stupidest, most counterproductive, cutesy bullshit to me, but some pretty smart folks think it's great (that's a compliment btw).

Stuff like this is the opposite of expressive to me because cute expressions that read like english scream "please take a moment to analyze this and make sure it does what it sounds like." I am instantly suspicious of code that is so expressive that you can just intuit out its purpose without thinking it through. Code is too subtle for treating it that way.

<comment><USER6> I think I agree with the thrust of what you are saying here. Just as English has rules with what you do with nouns and verbs etc, code has rules too that are different to English.

2.days().from_now()

says that we are performing the action 'days' on the object '2'. What could that possibly do? Well there're a bunch of options and none of them are obvious. It's weird and counter-intuitive. And then we go and perform the action 'from_now' on whatever the result of that was.

I don't mind 'fluent' style interfaces as long as they don't mess up the normal meanings of what objects and methods are, but sadly they usually do. Another classic sign of a bad interface is that with many of these fluent interfaces it's not obvious whether a particular thing should be a chained method call or argument, and if it's an argument, whether it should be got by calling a method, using a field or what.

Code should read like clear _code_. English should read like clear _English_. These are not the same things, and efforts to make them the same usually make a mess of both.

<comment><USER7> _Code should read like clear code. English should read like clear English. These are not the same things, and efforts to make them the same usually make a mess of both._

This stinks of principle over pragmatism.

Using the sugar offered by expressions like this requires a bit of knowledge of the development environment. I accept that it's a bit of a different syntax from some other languages, but that doesn't make it unclear at all.

Speaking to Ruby (where ActiveSupport is from), we all know that it's a language that focuses on providing flexible syntax and "multiple ways of doing things", in contrast to some other languages which restrict flexibility to provide more consistently structured code. I don't think it's a bad thing at all to have these options available, and I often find my intentions are much clearer when writing, say:

      if post.created_at < 5.minutes.ago

as opposed to Python:

      if(post.created_at < (datetime.now() - timedelta(minutes=5)))

or Objective C:

      NSDate *now = [NSDate date];
      NSDateComponents *delta = [[NSDateComponents alloc] init];
      [delta setMinute:-5];
      NSDate *fiveMinutesAgo = [[NSCalendar currentCalendar] dateByAddingComponents:delta toDate:now options:0];
      if ([[post created_at] compare: fiveMinutesAgo] == NSOrderedAscending)

That's where the magic comes in, and it makes Ruby ideal for things like web templating, while perhaps making it less suitable for other uses.

TLDR: various constructs like this have their place, they're not inherently bad, but do require knowledge of the tools.

<comment><USER8>
        if post.created_at < 5.minutes.ago

That reads like "if post was created less than five minutes ago", i.e. if the post is more recent than five minutes. However, if "5.minutes.ago" gives you a timestamp, as is reasonable, then that actually means "if post was created _more_ than five minutes ago", i.e. the very opposite of what it would mean in English. Whoops!

A more sensible syntax might be:

        if post.creation_date < now - 5*minutes

"ago", "from_now", "since_now" etc. are especially despicable in a language where you can just use + and -.

<comment><USER9> I'd prefer:

        if post.editable?

to everything I've seen. There's a concept behind the if statement that should go in the model. I realize this is sort of off-topic, but it kind of negates the whole discussion since you can wrap up the cute/ugly and test it alone. :)

<comment><USER10> And what would the definition of `editable?` look like?

        fn editable(&self) -> bool {
            self.created_at < 5.minutes().ago()
        }

Yes, it's wrong. No amount of unit testing or isolation is going to change the fact that whenever you read code like that, your brain will come up with two conflicting meanings, because these cutesy methods make it look too much like English, and English has _different rules_.

English parse tree is: ((less than (five minutes)) ago), whereas code parse tree is (less than ((five minutes) ago)).

</comment></comment></comment></comment></comment></comment><comment><USER11> Extension methods in C# do the same thing and have been around, what 5ish years now? Since .Net 3.5.

Here's an example implementation:

        public static class DateExtension
        {
            public static TimeSpan Days(this int daysCount)
            {
                return new TimeSpan(daysCount, 0, 0, 0); //days, hours, mins, secs for those wondering
            }

            public static DateTime FromNow(this TimeSpan addTime)
            {
                return DateTime.Now.Add(addTime);
            }
        }

usage is the same as Rust:

        2.Days().FromNow();

Basically if this impresses you, you really should give modern C# a whirl as there's a lot more you can do than that.

Much of how it does stuff now is how my perfect language would do it. There are bits of Ruby I love, and Rust is looking more exciting to me than Go, but the C# team really have done some amazing work.

<comment><AUTHOR> I am certainly not implying that Rust is the only language that supports this kind of thing. Haskell is where I first saw some of this. I'm just happy that Rust is doing it well.

C# is a great language, but I don't use Microsoft technology, and it's effectively Windows only.

<comment><USER12> I run C# in production on Mac OSX, IOS and Android phones. What do you mean by Windows only?

<comment><AUTHOR> If you work hard enough, you can do anything. Mono is slow, doesn't support everything, and most of the help you'll get is Windows specific.

<comment><USER12> That is just FUD im my opinion. I havent har any issues with getting my applications working on multiple platforms. Have you har performance issues with C# on IOS?

<comment><USER11> Be practical. I've had to support wordpress on IIS before, it's always a lot of hassle not using the tech in its native environment. Same with MySQL + .Net. The EF, for example, played really poorly with MySQL.

I can't imagine using mono is for the faint hearted. For example in the new MS programming language thread [1] today someone mentioned they ended up giving up on the .Net GUI controls and using GTK# instead because it was so unreliable. Another mentioned that the transition from one SQL driver to another had left a lot of projects hanging in the wind with SQL breaking on mono but working on Windows.

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

<comment><USER13> I don't think that's a fair comparison. Rust doesn't come with a set of functioning, well-tested and cross-platform GUI libraries and database drivers either.

Running C# the language with the BCL on mono is pretty painless, and offers a ton of functionality.

</comment></comment></comment></comment></comment></comment></comment><comment><USER14> The example presented in this post is neither a great example of what Rust can do nor an elegant solution to the particular problem of dealing with dates and times.

For a much further-reaching solution to this problem look at C++ user-defined literals, combined with what Bjarne Stroustrup calls "type rich programming".

now() + 3days + 21s + 102ms

This is not to say that c++ is the only language that can do this (although it does do it very well).

See the following video for a simple overview (apologies for toe-curling introduction): [http://channel9.msdn.com/Events/GoingNative/GoingNative-2012...](http://channel9.msdn.com/Events/GoingNative/GoingNative-2012/Keynote- Bjarne-Stroustrup-Cpp11-Style)

...also the video above is worth watching just for the vector vs. list comparison.

</comment><comment><USER15> Good examples:

      2.days().from_now()   (Rust)

vs.

      2.days.from_now       (Ruby)

I'd probably still prefer Smalltalk:

      2 days fromNow.

It seems to me that many distinctions we still suffer from are quite arbitrary. Yes, having numbers be objects (boxed or tagged) is one way of achieving this sort of uniform handling, but you can also achieve it statically.

Just like you don't have to switch to a "scripting" language for expressive file manipulation:

      file:hello.world := 'Hello World!'.

EDIT: typo.

<comment><USER16> I guess we'd call these "type extensions"? F# supports this just fine, and C# can do a bit, too.

Overall, I haven't found I need type extensions that much, if I have flexible function handling. It's the same level of expressiveness to write "fromNow 2 days". (fromNow having signature (int -> (int -> TimeSpan) -> DateTime). Or even "2 |> days |> fromNow" (fromNow being TimeSpan -> DateTime).

Actually, this example is pretty terrible, as even C#'s basic format would be "DateTime.Now.AddDays(2)" which seems pretty fine to me - add a top-level binding for now and it's on the same level of conciseness. Also, adding type extensions to integers for time seems quite ugly. Most 3rd party libraries I've seen don't use type extensions in a graceful manner, and end up slapping members on everything and it's just silly. (And I'm ignoring the fact that using .Now in .NET is rarely correct since it's rare when you don't want to use whatever random timezone the server's configured for, instead of UTC.)

<comment><USER17> "2.days.from_now" is different from DateTime.Now.AddDays(2), because it can be broken in two parts:

\- 2.days is a duration, or a time delta, or time span, or whatever you want to call it

\- from_now is a method called on this duration value

This construct "2.days" is useful on its own. It's actually more useful than "DateTime.Now", as durations are often part of public interfaces, whereas usage of concrete timestamps is very often hidden. The equivalent in C# for it would be "new TimeSpan(2, 0, 0, 0)". That's much more unreadable than just "2.days" and often, instead of thinking about the problem, developers fallback to specifying time spans as Ints in seconds or similar.

On TimeZone, "2.days.from_now" is a timestamp. If the underlying library is not totally fucked up, like "java.util.Date" is, then it does have an attached timezone. Or in case this yields a Unix timestamp, it's really not a Unix timestamp unless it was calculated since 1970-01-01 00:00:00 UTC.

<comment><USER16> You wouldn't write new TimeSpan(2,0,0,0), you'd write TimeSpan.FromDays(2).

There's nothing stopping you from binding a function "days" to wrap TimeSpan.FromDays.

If this is what people consider to be some pinnacle or notable point in expressiveness, yikes.

<comment><USER17> Oh, but we can expand on that ...

        scala> 2.days + 10.minutes
        res: FiniteDuration = 2890 minutes

I just don't get it. So a literal like "0.2f" to denote a Float (and not a Long) is acceptable. A literal like "300.5m" to denote a decimal and not a floating-point is acceptable.

But somehow other kinds of literals for other units of measurement are not, because Dear God, magic, magic!!!

</comment></comment></comment></comment></comment><comment><USER18> I wrote the original implementation.

One thing worth noting is that the implementation isn't globally extending `uint` with `.days()`. In order to write `2.days()`, you need to first import the trait that provides the implementation.

From that perspective, it's not much different from importing a function like `days_from_now` that you call as `days_from_now(2)`.

</comment><comment><USER19> Why is the string representation of:

      2.months().from_now()

printing a date one year in the past?

      date: active_support::date::Date{year: 2013, month: 2u, day: 28u}, hours: 0u, minutes: 59u, seconds: 6u, nanos: 243388962u

</comment><comment><USER20> In other news C# is exactly as expressive as Rust and Ruby...

        void Main()
        {
    	Console.WriteLine(2.Days().Ago());
    	Console.WriteLine(4.Days().FromNow());
        }

        //This can be a library, mmkay?

        public static class Extensions
        {
    	public static TimeSpan Days(this int days){ return new TimeSpan(days, 0,0,0); }
    	public static DateTime FromNow(this TimeSpan howMuch){ return DateTime.Now + howMuch; }
    	public static DateTime Ago(this TimeSpan howMuch){ return DateTime.Now - howMuch; }
        }

Results in:

        26/12/2013 22:05:10
        01/01/2014 22:05:10

Is there a better example?

<comment><USER21>
        public static class Extensions {
            public static void Print(this object o) { Console.WriteLine(o); }
        }

        2.Days().Ago().Print();
        4.Days().FromNow().Print();

</comment></comment><comment><USER22> Why would days be a method of an integer? It feels out of scope shoving date/time stuff into integral datatypes.

<comment><USER23> The basic idea is that objects should know how to represent themselves. In Smalltalk every Object implments writeOn: method, which gets a stream and prints self on this stream.

By extension, if an object knows how to convert itself into another object, it implements a method for doing do. In Smalltalk there is a convention of putting all such methods inside "converting" protocol. For great example of how is this useful you can look at the Collection and it's subclasses in Smalltalk - all collections have many "asOtherKindOfCollection" methds, which are either inherited or implemented, depending on a collection. It's great to be able to send "asSet" to _any_ collection that comes your way and the way Smalltalk does it is natural in purely object oriented languages.

That and the fact that creating IntsToRange or StringToDayOfWeek "static" classes is actually even worse leads to the design where Integers have `to:` and `days` methods.

Actually, there is one more probable cause: in Smalltalk and some other languages extending already defined types is _easy_ , really easy, easier even than creating a new, empty class. The methods are grouped into "protocols", which are grouped into packages and it's - not quite - largely orthogonal to the classes. Combine that with powerful IDE, VC support (Monticello, Metacello) etc. and you have no reason whatsoever _not to_ extend even the most basic classes.

<comment><USER24> The question is what "2.days" actually returns. IIRC, in ActiveSupport it returns an integer number of seconds. Is that a sensible convention? If you had another class representing an span of time (with or without any absolute calendar reference) that an Integer could convert into, that might be a cleaner design. But even in that case you wouldn't necessarily have a method on Integer to confer it to a TimeSpan; you'd initialize a TimeSpan with an integer argument.

In general I find it cleaner when less primitive classes can represent themselves as more or equally primitive classes, but not vice-versa. to_integer, to_float, to_list, to_boolean, etc. But on the other extreme, if your application entails establishing database connections, implementing String#to_database_connection would be ridiculous.

For me, integers are much more primitive than date and time objects. `2.days` would be equivalent to implementing `2.meters` in a CAD application, but I suppose you might be OK with that.

But even granting that an integer can transform itself into a representation of a time span, i.e. `2.days` is okay, `2.days.ago` is right out. That's not just an Integer representing itself as a span of time. Now all of a sudden Integer has to have knowledge and, even worse, opinions about the current date and time (which is one of the most hazardous boundary cases in all of software).

<comment><USER23> > integers are much more primitive than date and time objects

In terms of concepts, yes, but in terms of language syntax and semantics they are the same (in Smalltalk).

> `2.days` is okay, `2.days.ago` is right out

Yeah. But not because it "looks bad", and not because Integer would need to know anything more than it does already (it wouldn't), but because `2 days ago` is actually less flexible and harder to maintain.

Consider:

        Date today - 2 days. "27 December 2013"
        DateAndTime now - 2 days. "2013-12-27T04:43:42.679+01:00"

We can get either Date or DateAndTime without changing anything. With proper planning the superclass of both Date and DateAndTime can have a generic - method which will work for all the cases. With the `2.days.ago` we're tied to one result type. We need to code around it, giving it a default argument with a class or remembering the "kind" of Duration.

Anyway, if it's ok to have a function which takes integer it's equally ok to have an Integer have a method. Especially when you just _can 't_ have a function, like in Smalltalk and the _only_ alternative is writing yet another class with one method in it.

<comment><USER24> > Anyway, if it's ok to have a function which takes integer it's equally ok to > have an Integer have a method.

Seriously? Any function that takes an integer argument? Like, "exit". You want to call 1.exit to terminate a program with a return code of 1? Is there any difference between a function that takes an argument and a method on an object? Shall we implement all functions that take n arguments as multimethods? Are you actually going to implement String#to_database_connection? That was meant as a reductio ad absurdum, I didn't expect anyone to literally follow me there.

If you want some particular Integer to get decorated with additional methods because you're using it in some particular domain context but you're not globally changing the interface of all Integers that's a different story.

> Especially when you just can't have a function, like in Smalltalk and the > only alternative is writing yet another class with one method in it.

There are perfectly same object oriented ways to solve this problem, like instantiating some kind of TimeSpan object, or having a singleton for process status in the case of the "exit" function.

<comment><USER23> > You want to call 1.exit to terminate a program with a return code of 1?

1.exit is a bad idea because it has a side effect outside of it's receiver, I think.

> Are you actually going to implement String#to_database_connection?

Yeah. Or at the very least I won't die when I see this (working code in Pharo 2.0):

        'http://example.com' asZnUrl retrieveContents. "connect to given url and fetch it's contents"

or this:

        'HelloWorld' asMorph openInHand. "create a bitmap representation of string and display it on screen where the cursor is"

or this:

        #asSet value: (Array with: 1 with: 1 with: 3). "Symbol>>value:anObject looks like this: anObject perform: self"

which is especially interesting: how come a Symbol knows how to perform an action it can represent on some given object? I dunno. It just does.

I can't tell you exactly when adding a method to some class begins to be a bad idea and when it's still ok to do. I don't know any hard rule for this. I agree that `1.exit` is a bad idea and I provided a rationale for why I think so. But I'm still convinced that there are many (many more than you seem to think) cases where it's ok, it's acceptable and convenient to extend String, or Object, or any class you don't "own".

I'm actually looking at the system which is built with very many methods like the examples above (although it doesn't have 1.exit) and I see that it works. One of the most basic classes, Object, has this many external (with extension methods) protocols in it:

        *Collections-Abstract-splitjoin, *Fuel, *Fuel-Collections, *Glamour-Helpers, *Graph-ET-Core, *Graphics-Display Objects, *Kernel-Exceptions-debugging, *Monticello-Storing, *Morphic, *NativeBoost-Examples, *NativeBoost-core, *Nautilus, *Polymorph-EventEnhancements, *Polymorph-TaskbarIcons, *Polymorph-Widgets, *Ring-Core-Kernel, *Shout-Parsing, *Soup-core-testing, *Spec-Core, *Spec-Tools, *System-Settings-Browser, *System-Support, *Tools-Base, *Tools-Browser, *Tools-Explorer, *Tools-Finder, *Tools-Inspector, *UIManager, *VMMaker-translation support, *collectionextensions, *deprecated20, *eyesee-support, *grease-core, *grease-pharo20-core, *magritte-model-accessing, *magritte-model-actions, *magritte-model-model, *magritte-model-testing, *magritte-morph-converting, *metacello-core, *mondrian-complexshape, *mondrian-core-accessing, *mondrian-fadelayout, *necompletion-extensions, *neo-json-core, *petitparser-core-converting, *petitparser-core-testing, *roassal-core, *rubric, *tools-debugger

And the system still works. And it's easy to navigate. And to understand. And to use, even. So, once again - I'm not arguing that 1.exit is ok, just that there are many "saner" extension methods which are ok. To get the above list I had to write some code:

        |allProtocolNames externalProtocols|
        allProtocolNames := (Object allMethods collect: [ :x | x category asString]) asSet asSortedCollection.
        externalProtocols := (allProtocolNames select: [ :x | x beginsWith: '*' ])
            inject: Character cr asString
            into: [:acc :x |
                acc , x , Character cr asString
            ].
        Transcript show: externalProtocols.

I may not be very experienced Smalltalker, but I believe this is more or less idiomatic Smalltalk code. Even in this short snippet there are 3 asSomething methods - and the code still works and I still think it's readable. And cute.

Is it Smalltalk specifically which enables this technique or what other rules extension methods need to follow to be sane I don't know. Which is why I'm hesitant to implement those methods myself. But I accept their existence and the fact that they have their place in a sound, sane design, at least if done right (for any acceptable value of "right" we can agree on).

But well, my day to day job is writing Python, where "monkey patching" is considered a sin and the community consensus is pretty much the same as your opinion: don't extend classes, write functions instead. So I kind of understand this position. Although I still think it's not inherently bad idea to extend base classes and that it's the matter of language design, project design and tooling. But I can't say for sure. I'm just telling you what I saw when I went and learned Smalltalk, that's all.

<comment><USER24> This is surprising enough I'm not sure how to respond anymore.

> which is especially interesting: how come a Symbol knows how to perform an > action it can represent on some given object? I dunno. It just does.

Presumably it just sends itself to the object you pass in? This is not something I'm actually bothered by.

I guess it depends on how you extend classes you don't own. If the adapters themselves are modular and are only loaded with the class that they're trying to adapt to, that might be OK. In other words, if I have a DatabaseConnection class that extends other classes with asDatabaseConnection methods, and that extension only happens when I load the DatabaseConnection class, that still satisfies the intention of SRP even though I'm technically implementing methods on other classes.

</comment></comment></comment></comment></comment></comment></comment><comment><USER25> In clojure you could write this.

(-> 2 days from-now)

The great thing is that you don't have the weird semantic problems that the rust or ruby examples have. There are just two functions here, days and from- now.

<comment><USER18> That's essentially how traits work in Rust. You need to import the trait into your scope, and 2.days().from_now() is essentially sugar for days(2).from_now() where days() returns a TimeChange object.

<comment><USER25> Don't get wrong, rust looks fascinating. I realize that the syntax is basically sugar, but from what I understand is that you are still adding a method to a type. Here's a snippet from the code.

        fn days(&self) -> TimeChange {
            TimeChange::new().days(*self as f32)
        }

So while you are right, it is basically sugar for days(2).from_now(), but you couldn't call the function that way. It must be attached to an instance of an uint.

Also in order to get the English looking version you have to implement those function specially using traits. Whereas with the clojure version they are just normal functions, but the threading macro gives you that English readability you are looking for.

<comment><USER26> > So while you are right, it is basically sugar for days(2).from_now(), but > you couldn't call the function that way. It must be attached to an instance > of an uint.

We plan to implement that, it's just not implemented yet: [http://www.reddit.com/r/rust/comments/14pucx/rfc_method_call...](http://www.reddit.com/r/rust/comments/14pucx/rfc_method_call_syntax_as_sugar/)

> Whereas with the clojure version they are just normal functions, but the > threading macro gives you that English readability you are looking for.

You could do that with a macro in Rust as well. We don't make ordinary functions acquire that sugar for namespacing reasons: you can have multiple methods called e.g. "get" in scope as long as they're attached to different types, but that isn't true for functions.

</comment></comment></comment></comment><comment><USER27> In Factor:

      2 days hence

      4 weeks ago

etc. [http://docs.factorcode.org/content/article- calendar.html](http://docs.factorcode.org/content/article-calendar.html)

</comment><comment><USER28> While I don't think that syntax is _that_ important, I am fond of sugar.

Because I've been working in D for a while, here's how you'd do it in D.

        import core.time: Duration, dur;
        import std.datetime: Clock, SysTime;

        Duration days(int number) {
          return dur!"days"(number);
        }

        SysTime from_now(Duration duration) {
          return Clock.currTime + duration;
        }

        void main() {
          import std.stdio: writeln;
          writeln(2.days.from_now);
        }

Runnable pastebin link: [http://dpaste.dzfl.pl/9b84f820](http://dpaste.dzfl.pl/9b84f820)

<comment><USER29> I haven't really looked at D in a long time, so I'm not clear on what's going on here.

Is D allowing you to write the function call "days(2)" as "2.days"?

(As an aside, Nimrod allows you to do specifically that; first-arg.function- name(...) == function-name(first-arg,...).)

</comment></comment><comment><USER30> So it is a demo that you can use Rust metaprogramming to make Rust look like Ruby. I hope this would not become idiomatic Rust.

</comment><comment><USER31> _For the most part, I'd found the complaints about dynamic typing from the static typing camp to be very FUD-y. I very rarely get TypeErrors in my Ruby code. Refactoring generally isn't very difficult._

 _But slowly, this has started to change. I think that it's that I tend to do more infrastructure and plumbing work now. I've run into more and more situations where types would be helpful, or picking the mutable state path has caused headaches._

Explaining the attraction of dynamic debugging to static type die-hards is a lot like explaining the attractions of static typing to dynamic programming die-hards. You can only get a sense of what the other side is talking about through lots of hands-on experience. Where it's really valuable is often an edge-case, but often it's a really expensive edge-case! (Goes both ways.)

This from an old Smalltalker. If you do enough Smalltalk, especially in a large established code base, you eventually see situations where you wish there were type specifications. However, you still wish that more statically compiled language people were more open minded and less knee jerk when you talk about the magic you can do. (Which also means that the open minded ones are particularly valuable.)

</comment><comment><USER32> My personal choice for "statically typed Ruby" is actually Scala or Kotlin. Scala has its drawbacks, especially the compile time, (which is getting better) but both have similar expressiveness when it comes to mind blowing library usage. (Although sometimes arguably in the expense of potentially complexity of the language when it comes to being able to writing such elegant libraries) I found it similar to the OP's argument regarding python vs ruby. Scala as a language might be a very subjective and divided topic, but using it with the right libraries can be very expressive just with added static typing.

</comment><comment><USER33> I dislike all these 'expressive' or how abstract rust as a language can be from what it's trying to achieve which is to be a 'systems programming language' on par with c (c++ is not the same as c). Show the resulting assembly for both a C version and a Rust version, now map both the rust version and c version to the resulting assembly.

<comment><USER34> Rust is meant to replace C++, not C. The original motivation was that the Mozilla devs were sick and tired of all the subtle ways bugs can sneak into a large, complex C++ code base.

The ultimate aim is to write the nextgen browser engine not an operating system kernel or some embedded code for a system with 4kB RAM.

<comment><AUTHOR> ... though you can absolutely do the kernel stuff too.

</comment></comment></comment><comment><USER35> If I read it right and the article cites the ability to add a method to the primitive number type as "expressive", then that's a pretty narrow view of expressivity. More examples would help.

</comment><comment><USER36> Static v. dynamic typing aside, one thing I love about Ruby is the syntactic ambiguity of a local variable versus a method call, in which parentheses are not needed.

</comment><comment><USER37> Objective-C

@(2).days.fromNow;

or

@(2).SH_days.SH_fromNow;</comment>


Handy cheat sheet for 3D films: RealOrFake3D.com - <AUTHOR> http://realorfake3d.com/

<comment><USER2> I predict that 'real' 3D movies will go the way 3D sound did years back. 'Fake' 3D will die out as the camera technology gets cheaper.

When Dolby surround first came onto the scene audiences were wowed by the immersiveness that the surround sound added to movies.

Studios responded by 'faking' 3D sound for movies originally recorded only in stereo. These didn't sound anywhere near as good as true surround sound and audiences weren't impressed.

Eventually the equipment needed to shoot a movie in surround sound became cheap enough that every production could take advantage of it.

I think we're seeing the cycle repeat itself.

Lets not forget that when colour film first came out studios attempted to add colour to existing B&W films, this didn't work too well but eventually colour film became cheap enough that they all used it.

</comment><comment><USER3> "moviegoers' craving for 3D films"

I'd love to see some surveys. I do not go to any 3D viewings and go to the 2D ones instead (of which there are less), but they always seem completely packed full. So presumably I'm not alone in hating the most recent 3D movie craze.

<comment><AUTHOR> Not sure about this year, but last year they accounted for 11% of ticket sales:

[http://www.businessinsider.com/3d-films-helped-boost-the- box...](http://www.businessinsider.com/3d-films-helped-boost-the-box- office-2010-3)

Also, watch Avatar in 3D. It made me a believer.

<comment><USER4> It made you a believer in the 3D technology used in Avatar.

<comment><AUTHOR> Hence the "Real" vs. "Fake" distinction. Although, a lot of natively shot 3D films don't have nowhere near as much stereographic thought as Cameron applied.

</comment></comment></comment></comment><comment><USER5> My advice for haters of 3D: try seeing Toy Story 3 in 3D. It was made for 3D and it doesn't use any of the usual cheap tricks associated with 3D (aka the cliche throwing things at the audience). It mostly just seemed to really enhance the depth of the picture and make it slightly more immersive. I agree that 3D is still mostly a gimmick now, but I think it will eventually be used mostly as a way to make the viewer feel like they're actually there, rather than for the spectacle. Think of it this way: we didn't _need_ color movies, but they tend to look nicer (unless of course you just prefer that old timey look).

</comment><comment><USER6> Having only seen two movies on this list ( _Avatar_ 'Real' and _Alice in Wonderland_ 'Fake') my observation is hardly exhaustive, but there was a definite difference in the 3D experience.

With _Avatar_ , the third dimension seem to come out at you from the screen - I even had a cliched duck for cover at one point. With _Alice_ the third dimension seemed to be depth in the screen - many shots felt like you were figuratively looking down a rabbit hole, rather than being immersed within one.

And for what it's worth, I don't mind paying a few bucks extra for the 3D version, real or fake.

<comment><USER7> I think different 3D technologies could account for the in-ness and out-ness. Where you at the same cinema both times?

<comment><USER6> Actually, it was - same specific cinema. But weeks / months apart which could impact things - good thinking.

</comment></comment></comment><comment><USER8> I've been to a lot of movies and I think this list is very accurate, every movie not originally intended for 3d was obvious on the big screen and the glasses just ended up being extra weight on your nose, wish I had this list earlier

</comment><comment><USER9> Roger Ebert : Why I Hate 3-D (And You Should Too)

[http://www.newsweek.com/2010/04/30/why-i-hate-3-d-and-you- sh...](http://www.newsweek.com/2010/04/30/why-i-hate-3-d-and-you-should- too.html)

<comment><USER10> That's a pretty good critique despite the inflammatory title. The MaxiVision48 process he mentions sounds pretty great as well. I definitely notice the jerkiness in some scenes when in the theatre and it always pulls my attention away from the film.</comment></comment>


The Anamorphic Skull in Holbein's "The Ambassadors" - <AUTHOR> https://en.wikipedia.org/wiki/The_Ambassadors_(Holbein)#Anamorphic_skull <comment><USER2> I remember reading a novel when I was younger which used this painting as a plot point - supposedly there was some huge secret hidden in it. Operation Red Jericho, I think - must reread sometime.

<comment><AUTHOR> I've just gone and had a look at the reviews for that - sounds brilliant.

[http://www.amazon.co.uk/Operation-Red-Jericho-Guild- Speciali...](http://www.amazon.co.uk/Operation-Red-Jericho-Guild- Specialists/dp/0763626341)

Can't find a reference to The Ambassadors, but maybe that just doesn't turn up in the reviews.

Thanks for the pointer.

 _Edit: Found it - it 's mentioned here:_

[http://goodtoread.org/initial/o/operation-red- jericho/](http://goodtoread.org/initial/o/operation-red-jericho/)

Great review.

<comment><USER2> Hope you enjoy it! One suggestion would be definitely read it in print. The book is packed full of diagrams, images and diary entries which I feel wouldn't work well on an e-reader.

</comment></comment></comment><comment><USER3> Obviously this guy didn't properly UV map the skull texture on the quad! Seriously though, this is very impressive trick done by a very talented artist.

</comment><comment><USER4> It's at the National Gallery in London, so I've seen it a fair few times, and I've got to say, the "just showing off" theory is pretty supportable. That entire painting looks like The Da Vinci Code. Laden with symbols and impressive bits of painting.</comment>


ƒu.js - <AUTHOR> http://tsenart.github.com/fu.js/

<comment><USER2> He is sleepy, guys. Let him collect some energy, he'll surely write more about it or destroy it next morning.

</comment><comment><AUTHOR> Transfer your interest to this(<http://news.ycombinator.com/item?id=2157509>) updated post.

</comment><comment><USER3> what does it do?

<comment><USER4> More importantly, what does it do that's worth having to remember how I make a unicode ƒ?

<comment><USER5> ALT + f on a mac, not too hard. but I agree

<comment><USER6> ctrl+shit+u 192 on ubuntu for ƒ.

might as well have used the snow man ☃('body').style.background = '#f4f6f8';

call it brr.js

<comment><USER7> and ALT+0131 on the numpad on windows

</comment></comment></comment></comment></comment><comment><USER8> Oi tsenart, tell us about this!</comment>


A JPEG that becomes a PNG after AES encryption and a PDF after 3DES decryption - <AUTHOR> https://code.google.com/p/corkami/source/detail?r=1906 <comment><USER2> See also The International Journal of Proof-of-Concept Or Get The Fuck Out.

[https://archive.org/details/Pocorgtfo00](https://archive.org/details/Pocorgtfo00)

[https://archive.org/details/Pocorgtfo01](https://archive.org/details/Pocorgtfo01)

[https://archive.org/details/Pocorgtfo02](https://archive.org/details/Pocorgtfo02)

[https://archive.org/details/pocorgtfo03](https://archive.org/details/pocorgtfo03)

[https://archive.org/details/pocorgtfo04](https://archive.org/details/pocorgtfo04)

[https://archive.org/details/pocorgtfo05](https://archive.org/details/pocorgtfo05)

<comment><USER3> For the uninitiated, some of these files are bootable (on x86), or contain other goodies hidden somehow. These are written (or collated) by Travis Goodspeed - travisgoodspeed.blogspot.com

<comment><USER4> This blog is amazing! Very motivating. Thanks for sharing.

</comment></comment></comment><comment><USER5> The file in question: [https://corkami.googlecode.com/svn- history/r1906/trunk/src/a...](https://corkami.googlecode.com/svn- history/r1906/trunk/src/angecryption/PoCs/mrmcd.jpg) (direct download, 173kb)

Imgur mirror: [http://i.imgur.com/jUEAygp.jpg](http://i.imgur.com/jUEAygp.jpg)

<comment><USER6> People are going to be mighty confused if they try to use that, imgur re- encodes all of it's images uploaded.

<comment><USER7> Even JPEGs? That would explain some of the bad quality images on there. Or do they re-encode without recompressing, à la jpegtran?

<comment><USER8> They do compression on big images IIRC

</comment></comment></comment></comment><comment><USER9> How in the hell does one discover that kind of thing? :) I don't really know much about crypto and symmetric ciphers in general, but aren't the odds of discovering something that converts from JPEG to PNG by applying AES extremely small? Let alone something that ALSO goes from JPEG to PDF by applying 3DES.

I presume there is some algorithm based on the nature of ciphers themselves?

<comment><USER10> I didn't check this demo in particular, but I have seen this trick before. The first observation needed is that you can insert an arbitrary block of data into the picture without changing how it renders. The second observation is that AES is a symmetric algorithm, meaning decryption is the same operation as encryption. Using this, you can encrypt the PNG, and embed the result in the unencrypted JPEG. Then, when you encrypt the JPEG, you encrypt the embedded PNG.

There are a couple of complications to this. The major one is that both formats require correct data near the begging of the file. The size of this region is small enough that it is feasible to brute force passwords until you find one that works.

<comment><USER11> You get the definition of "symmetric" wrong. Symmetric encryption refers to using the same key for encryption and decryption, as opposed to asymmetric, aka public-key encryption. By no means AESEncrypt and AESDecrypt are the same functions.

That said, some encryption modes employing AES, like AES in CTR mode, are based on generating a pseudo-random keystream and XORing it with cleartext to get the ciphertext. The inverse of that operation is itself, but that has nothing to do with the term "symmetric encryption". This particular case uses AES in CBC mode, which is not symmetric in that sense.

<comment><USER12> There is a difference between "symmetric _key_ encryption" and "symmetric encryption".

<comment><USER13> Is there? The usual term for what you're describing is a "stream cipher" or a "streaming-mode cipher".

<comment><USER14> I think the objection here comes from not stating that it's AES in CTR mode.

AES is not a symmetric algorithm, AES in CTR mode is.

</comment></comment></comment></comment></comment></comment><comment><USER15> Previous discussion: [https://news.ycombinator.com/item?id=7775015](https://news.ycombinator.com/item?id=7775015)

</comment><comment><USER16> tl:dr I'm a fanboy of Corkami and just wanted to show appreciation.

Ange Albertini does some amazing research and I was orginally introduced to his works after reading POC||GTFO from a Talk Travis Goodspeed gave. Recently Corkami did a giveaway on twitter for a signed mini-poster (Corkami's Posters are amazing as well highly recommended!) Fortunately I have a signed mini- poster en route to my mailbox cannot wait to have that thing framed.

</comment><comment><USER17> The raw file:

* (JPG) [https://corkami.googlecode.com/svn-history/r1906/trunk/src/a...](https://corkami.googlecode.com/svn-history/r1906/trunk/src/angecryption/PoCs/mrmcd.jpg)

</comment><comment><USER18> Does anyone know what block size is needed, IV, cypher mode?

<comment><USER19> The python file in that commit shows you everything you need: [https://code.google.com/p/corkami/source/browse/trunk/src/an...](https://code.google.com/p/corkami/source/browse/trunk/src/angecryption/PoCs/mrmcd.py?spec=svn1906&r=1906)

</comment></comment><comment><USER20> GOD WHERE IS THE PICTURE IM FREAKING OUT</comment>


Why all the pros are leaving Flickr for 500px - <AUTHOR> http://thenextweb.com/apps/2011/07/08/why-all-the-pros-are-leaving-flickr-for-500px/

<comment><USER2> Unfortunately, just by glancing at article, you can see that they made comparisons by picking poor photographs on flickr and beautiful, colorful images for 500px. Bias much?

</comment><comment><USER3> The answer seems to be mainly that this is a service aimed at pros.</comment>


CyanogenMod 9 alpha puts Samsung to shame - <AUTHOR> http://osnews.com/story.php/25694/CyanogenMod_9_alpha_puts_Samsung_to_shame

<comment><USER2> The article reflects my experience with both Samsung and HTC. Ever since, I'd vowed to stick with stock Android, and when the Galaxy Nexus was released I was quick to grab one. Funnily, after a few days with stock Android, I reached out for CM9 Alpha and found it to be superior to stock Android as well. I think this says a lot about the developers behind CyanogenMod - they are definitely doing something right and that opens up all kinds of opportunities for them.

Regarding the manufacturers: I think they are doing a great job producing better and better hardware. However, given the number of new models they churn out, maintaining and upgrading the firmware for each model is practically impossible. If they do still plan to skin their versions of Android, the only practical option would be to minimize the model churn and ensure they upgrade each model in timely fashion. Otherwise they risk turning off their customers big time.

</comment><comment><USER3> Interesting disagreement in the comments from a CM9 on Samsung developer.

<http://www.osnews.com/permalink?511055></comment>


Google Maps, Earth take on full 3D imagery - <AUTHOR> http://www.engadget.com/2012/06/06/google-maps-earth-take-on-full-3d-maps/

<comment><AUTHOR> Sorry for the lack of content. I hoped they would have updated it properly.

antr submitted[0] a better link[1] with video. Seekable press event[2] is also up with more information.

[0] <http://news.ycombinator.com/item?id=4074972>

[1] [http://thenextweb.com/google/2012/06/06/google-maps- launches...](http://thenextweb.com/google/2012/06/06/google-maps-launches- metropolitan-3d-maps-in-google-earth-on-mobile/)

[2] <http://www.youtube.com/watch?v=HMBJ2Hu0NLw#t=4105s>

<comment><USER2> Yours has been updated with the same video.

</comment></comment><comment><USER3> For a demo of what this will look like, try Nokia's WebGL-based mapping demo: <http://maps3d.svc.nokia.com/webgl/index.html>

They only have 3D imagery in a few cities so far (click on the city markers).

</comment><comment><USER4> 3D is awesome, but the better feature is offline maps. Now I can make my older android a dedicated offline GPS unit.

<comment><USER5> Is navigation available offline, though? They didn't mention it.

<comment><USER6> From the CNet live blog I saw, they said GPS will work offline. That doesn't confirm that navigation will work, but at least there's that.

<comment><USER5> GPS already works offline, doesn't it? It just places you on a grid with no tiles.

</comment></comment></comment></comment><comment><USER7> Looks great. A few points:

\- They used new imagery from planes to do this, not the existing streetview imagery - I guess that means optical matching of the kind needed to do this (make a model from streetview imagery) is still a ways off.

\- 3d maps has been done like this already (by bing and others), though this looks a better resolution.

\- As someone who works with city spaces - can I use the 3d data? How can I download it or who do I have to pay?

<comment><USER8> > \- 3d maps has been done like this already (by bing and others), though this > looks a better resolution.

Bing appears to be using a non-scalable approach for Bird's Eye view. E.g., Seattle downtown contains a few 3d buildings in a very confined area. It might even be manually modeled.

What Google has announced is impressive because it is automated and scalable. Small demos are great and all (e.g. C3) but qualitatively different from getting something like this deployed into the real world.

Disclaimer: I work at Google.

<comment><USER9> C3 is a "small demo"? C3's 3D maps have been _deployed_ and are publicly usable and cover at least 25 metropolitan areas. Google may be catching up fast, but there is nothing shown in the video that C3 haven't done already.

<comment><USER5> Plus, let's not forget that Apple bought C3, so I wouldn't be surprised to see them roll this out at an even larger scale next week.

</comment></comment></comment></comment><comment><USER10> This looks incredible but I'm a little put off by this only being available for mobile. Did I actually read that right? I would expect this to also come to the desktop browser but it doesn't sound like that's happening...

<comment><USER11> I'm not sure if this feature can realistically be brought to desktop at this point.

We're talking about a whole lot of 3D rendering, many polygons, and a whole crapload of textures. Easy pickings for a smartphone native app, where just about every major phone on the market has obscene amounts of hardware acceleration under the hood.

Not so easy for desktops - whose graphical performance is often nearly non- existent. Not to mention you take another huge performance hit from WebGL... which also has poor penetration. So not only would most users be unable to use your newfangled 3D maps, many of the ones that _can_ , will have an unusably slow experience.

This is one of those places where native apps really shine.

<comment><USER12> Most desktops, even those with crappy Intel GPUs have superior GPU performance to the best mobile devices. WebGL has poor penetration, but you really don't take much performance hit as long as you don't need to process data in JS, but then again, a modern i5 or i7 is much faster than an ARM on a mobile device, so what you loose in JS performance, you gain in CPU performance.

Current JS and WebGL performance is well within the range needed to make this work. MapsGL is already rendering a quite large workload, in fact, my intuition is that the 2D rendering, especially with rasterizing label text all over the place, is likely more expensive than navigating an octree and rendering a mesh.

</comment></comment></comment><comment><USER13> I'm guessing the "new process" is structure from motion and high-performance bundle adjustment (probably using Ceres, which they just opened). It's fascinating to think what they'll be able to reconstruct with their computing power and hi-res satellite imagery and millions of Picasa photos.

<comment><USER14> Google Maps/Earth is a simply amazing product. I've seen a lot of hype building about what Apple is to unveil in the coming days, but I honestly cannot imagine what they can present that can challenge Google (though it won't be hard for them to challenge the terrible mapping in iOS currently which, while using basic Google tiles, is in an app built by Apple). You mentioned Picasa and that reminded me that a few weeks ago I was showing my children some sights (e.g. the Eiffel tower) from around the world, and all over the place were overlaid, perfectly mapped personal photos.

In the demonstration they discussed how they do this, which is essentially Google Planes getting AirView with special cameras (very similar to Google StreetView).

<comment><USER15> Well based on what I've seen from Google so far it looks like what C3 (whom Apple acquired) has had for a while now. So to be honest it is Google catching up in the 3D space.

And clearly Google is rattled as all of this comes just days before Apple is set to announce their products. I guess losing a significant amount of traffic (all iOS users) will do that to you.

Either way it will be nice for Google to have some honest competition.

<comment><USER16> Does iOS maps show ads from Google?

<comment><USER17> Yup. I was searching for a hotel in Roswell, and a "sponsored link" located the Motel6 with a different pin icon than the others.

Go center the map on Roswell, NM. Search for "motel" and you'll see the ad, and it will come back as the default selected pin.

<comment><USER18> Exactly. Search results for businesses or locations in Gmaps on iOS are broken because of all the irrelevant junk they include, and I can only assume they do it because they got paid.

</comment></comment></comment></comment></comment></comment><comment><USER19> It seems far fetched now, but I actually expect streetview UAVs sooner than most people likely think.

<comment><USER20> This seems incredibly plausible, especially since the pieces are already there (you could probably hack one together in a weekend for $1,000).

The biggest hurdle I foresee is in legislation - how is Joe the Plumber going to feel about a private company flying UAVs over his backyard taking pictures?

</comment></comment><comment><USER18> Am I the only one who expected the waves to be moving in that last scene in the video showing the Cliff House and Seal Rock in SF?

<comment><USER21> This. Since February 2009, when Google released Google Earth 5.0, adding the animated waves [1], I've being thinking that eventually, they could actually make a nicer animated coastline, like in so many games now. But comparing the satellite view, with the map view, maybe the resolution is not currently good enough to make the simulated water overlap perfectly the pictures and make the coast look nice.

[1] <http://www.gearthblog.com/blog/archives/2009/02/post_3.html>

</comment></comment><comment><USER22> Looks awesome. I look forward to playing around with it in Google Earth.

</comment><comment><USER23> What I seriously want? GTA: Google Maps. Even if you can't walk into the buildings or anything. Even if it's top-down only.

I want it. Want want want want.</comment>


Google Apps Users Can Now Get End-to-End Email Encryption - <AUTHOR> http://mashable.com/2014/05/15/google-apps-message-encryption/

<comment><USER2> It's a lie. It's not end-to-end encryption. But nice try, Google.</comment>


Everything You Know About Public-Key Encryption in PHP Is Wrong - <AUTHOR> https://paragonie.com/blog/2016/12/everything-you-know-about-public-key-encryption-in-php-is-wrong <comment><USER2> This is not necessarily a PHP issue. The fact that it's been improved apon by a better library speaks to how powerful php is even with the given native methods.

openssl_public_encrypt() openssl_private_decrypt()

those methods have maintainers, if anything, the people working on this code did a disservice to the php community at large by setting poor default values.

"The only thing I know about public key encryption in PHP is that it sounds like a terrible idea. Am I wrong?" Rhetoric statement. "Yes, you are wrong"

Go write your own C encryption library, doing it yourself, probably an insanely bad idea. But would you call C a shitty language? I bet yes, but everything is written in it that you use everyday. If it's not written in it directly, it's indirectly supported by it in atleast 2-3 different ways. PHP uses C libraries for everything, try compiling any bit of php w/o the native methods their api's provide, nothing will work.

<comment><USER3> > This is not necessarily a PHP issue.

> the people working on this code did a disservice to the php community at > large by setting poor default values.

Those functions are part of PHP. So… you're contradicting yourself, surely?

</comment></comment><comment><USER4> The only thing I know about public key encryption in PHP is that it sounds like a terrible idea. Am I wrong?

<comment><USER5> It isn't necessarily a terrible idea. Where it becomes bad is when unskilled developers implement it.

<comment><USER6> That sounds like the exact same two statements I hear over and over when it comes to PHP

"Doing X in PHP is a bad idea"

"Well it's only a bad idea if done by unskilled developers"</comment></comment></comment>


Show HN: Dog Breed Identifier - <AUTHOR> https://hartator.github.io/dog-breed-identifier/ <comment><USER2> I considered the same thing for flowers, mushrooms, etc. I think an app like this could be great for people who like taking nature walks and learning about plants.

</comment><comment><USER3> This is really cool! Can you give a little more detail about the algorithm used?

<comment><AUTHOR> Thanks! :) It's using Caffe. I've ported the framework to iOS, it wasn't working on iPhone.</comment></comment>


Toward _FORTIFY_SOURCE Parity Between Clang and GCC - <AUTHOR> https://developers.redhat.com/blog/2020/02/11/toward-_fortify_source-parity-between-clang-and-gcc/ <comment><USER2> How does this relate to the address sanitizer? I believe ASan can catch all of the issues caught by _FORTIFY_SOURCE. Does the latter have fewer checks and better runtime performance? I'm guessing it is considered by most to be fine using _FORTIFY_SOURCE in production binaries but too much overhead for ASan?

<comment><USER3> _FORTIFY_SOURCE is a rather weak but fast mitigation for a narrow class of security issues. AddressSanitizer is a bug finding tool (2x CPU overhead!), for a different and much wider class of issues.

Edit: there is some overlap, of course.

</comment></comment><comment><USER4> Is it good for both, Pareto optimal, or is it bad for GCC that Clang is catching up?

But if Clang is catching up, is that really bad?

<comment><USER5> It's bad for GCC, but good for C++ developers. GCC and MSVC will die and there will be only one compiler on all platforms (which is also the best one).

Just have a look at Chrome and Firefox. They already use Clang on all platforms. On Windows they are working on replacing link with lld. Android has deprecated GCC completely. In the future it's gonna be clang + lld + libc++ all the way. And yeah, GDB and WinDbg will also be replaced by LLDB.

<comment><USER6> GCC still generates faster binaries (on average across a wide set of benchmarks) than clang as of last year

<comment><USER7> Not that much faster. Most benchmarks find that GCC is a little ahead, but not much:

[https://www.phoronix.com/scan.php?page=article&item=gcc9-cla...](https://www.phoronix.com/scan.php?page=article&item=gcc9-clang8-hedt&num=6)

[https://medium.com/@alitech_2017/gcc-vs-clang-llvm-an-in- dep...](https://medium.com/@alitech_2017/gcc-vs-clang-llvm-an-in-depth- comparison-of-c-c-compilers-899ede2be378)

Remember that these are both Linux benchmarks; GCC on windows is a bit sketchy with MinGW. Things can usually be made to work, but Clang is the only real competitor to MSVC (unless you're counting Intel's crazy-expensive offering, which is not intended for general use).</comment></comment></comment></comment>


Ask HN: Models for investing in the stock market... - <AUTHOR> For much of early life I hadn't paid much attention to the world of finance and the markets as it seemed very difficult to know who was worth listening to and who was full of it, so I largely dismissed it as an insider's game.
But recent events have sparked my interest I guess and I've started doing a bit of reading and playing catch up.
So far I think I've identified 3 models for investing in the stock market that make some sense to me and everything else I've heard so far seems either a crazy temporary hack, pure luck or some combination of the two.  At the risk of sparking a flame war, I'm curious as to whether people here disagree with my perhaps fairly naive understanding of this world or if you have other reasonable models to add etc...
The models are...
1. The Warren Buffet Berkshire Hathaway model: Place very few bets. Work really hard and be very disciplined in finding the rare opportunity and insight and then bet heavily when you do. As described by Charlie Munger in the second part of this talk http://www.paladinvest.com/pifiles/MungersWorldlyWisdom.htm.
2. Index fund model: Stop taking on risk in trying to beat the market all the time, an unlikely feat, and just go along for the ride. It will be bumpy (very bumpy perhaps) but have some faith that in the long run the market tends to go up as the human race goes about creating more wealth in the world (real wealth hopefully in the future).
3. The Nassim Nicholas Taleb Black Swan model: The world is dominated by large unexpected events (like the recent one) some are positive and some are negative. Limit your exposure to the negative ones by putting the vast majority of your money in extremely secure things like T Bills and then gamble with the remainder hoping to find a large positive event (like the next google). Anyone who thinks they can be exposed to the large negative events and effectively manage that risk is nuts.
Depending on an individuals particular appetite for hard work, risk, emotional rollercoasters and the like I could imagine any of these 3 being argued as a reasonable strategy.
Any thoughts to help me along would be greatly appreciated.
Cheers <comment><USER2> I think the question is a good one, and I think it's clear you did a fair amount of research before writing your post. There are several other philosophies you could have included but didn't, and the three you chose are the only ones that I believe make sense.

I suggest a broader approach to "The Warren Buffet Berkshire Hathaway model." Buffett is a value investor, and frequently cites other value investors who have started with similar assumptions (based on Benjamin Graham's work) but who don't necessarily place few bets (Buffett credits Philip Fisher, and also Munger, with making him a believer in concentrated portfolios).

The value investors I recommend reading, in addition to Buffett, Graham, Fisher, and Munger, are Martin Whitman, Seth Klarman, and Christopher Browne. Browne's letters and studies are available for free on the Tweedy, Browne website, Klarman's book (Margin of Safety) can be found as a pirated PDF, and Whitman's books are relatively inexpensive (and his letters to shareholders are free). Also, in addition to reading shareholder letters by Buffett and Munger, be sure to check out Lowenstein's Buffett biography (and The Snowball, though it's not nearly as good; Janet Lowe's Munger bio is a waste of paper).

</comment><comment><USER3> I am an adherent to the Efficient Market Hypothesis (<http://en.wikipedia.org/wiki/Market_efficiency>) and thus try to capture the market (through index funds) and minimize cost.

Ideally, the best way to do this is own multiple non-correlated indexes (Example: Gold and the S&P500 are negatively correlated). I own my indexes through Vanguard.

A well diversified portfolio that owns stocks (of all capitalization both foreign and domestic), bonds (treasuries and corporate foreign and domestic), real estate, commodities (Gold, Silver etc) and Cash (multiple currencies) will generally provide positive stable returns continually.

In my opinion the big "to-do" with most peoples 401ks is that they are VERY poorly diversified and way to heavy in stocks.

<comment><AUTHOR> Do you believe it to be truly efficient or just the most effective hypothesis? For example perhaps where it is inefficient this is indistinguishable and highly random therefore not terribly useful?

<comment><USER3> I do not believe it to be truly efficient as that would require perfect information for all parties that participate in the market. (discussion of that topic is here: <http://en.wikipedia.org/wiki/Perfect_information>)

I do believe that it is efficient enough that the model works.

<comment><AUTHOR> Is there anyone who doesn't believe that it works though? i.e. It won't lead to a reasonable positive return?

Believing that it works means simply accepting the average return of the market through index funds as you said, which sounds reasonable to me, but it is admitting defeat that you can't beat the market in the long run.

Seems to me everyone would agree it works in general and the trouble starts when you try and do better than it.

Is your reason for not looking for inefficiencies to exploit and do better the fact that it takes more time than you have to devote to it, don't believe its possible in the long run (i.e. largely luck), you require some special insight other people don't have, other?

</comment></comment></comment></comment><comment><USER4> Your best bet is to set up several virtual trading portfolios and see which strategy actually works for _you_. You will learn much quicker and make your first mistakes with fake instead of real money.

Google virtual stock portfolios or virtual investments - there are lots of websites that offer fantasy trading. One of your goals should be to simply find out how much time you can devote to your portfolio... most people find that its' a _job_ and go back to index/mutual fund investments.

<comment><AUTHOR> It's a good suggestion but not so applicable to the strategies I listed for the average investor above I think. These are all long term strategies. Finding the next Google or working hard to find the rare highly valueable opportunity, something which perhaps there is only a handful of great ones in a lifetime doesn't lend well to testing. Starting out with fake money is a great idea though.

</comment></comment><comment><USER5> I just found a Forbes article about a guy who started a small fund that invests in the SP 500 Index while congress is out of session and moves everything to T-Bills when they're in session. He joked about it for a while until he ran some numbers and found that historically the SP returns ~16% while congress is out of session, and sub 1% while in session.

The markets don't like uncertainty, and nothing is more uncertain that the idiocy that congress brings when in session.

</comment><comment><USER6> Those aren't _models_. Those are investing _philosophies_. And they're so general and vague that I really don't understand what point you're trying to make. You asked no concrete question, and you will get no concrete answer.

If you want to educate yourself, don't ask HN, do your homework and read Harris' book: <http://www-rcf.usc.edu/~lharris/Trading/Book>

<comment><AUTHOR> Point taken, they are absolutely philosophies. That was a sloppy question, it's getting late here.

I was curious if people more knowledgeable than myself on this topic took genuine exception to these philosophies and had others to add to the list. Part of doing your homework is asking other smart people questions. Perhaps not the best site for this one but what can I say, I respect the people here more than elsewhere.

<comment><USER6> If you're interested in Finance, I suggest you read / follow Nuclear Phynance ( <http://www.nuclearphynance.com> ), a rather smart forum. Just make sure you don't post questions like this on NP, because those guys will eat you alive if you do.

<comment><AUTHOR> Thanks, I'll check it out. I was deliberately trying to avoid the land of acronymns and unnecessary complexity though.

I find it interesting that almost all of the most truly interesting and valueable things I have read were written in plain english by people that strive to keep it as simple as possible. It's far too rare unfortunately.

</comment></comment></comment></comment><comment><USER7> > 2\. Index fund model:

Which index fund model? Weighted by market cap or some other measure?

Weighted by market cap means that you buy a given stock as the underlying company's market cap increases relative to the market as a whole and sell it as said market cap decreases relative to the market as a whole.

Can you do better?

<comment><USER3> Index funds based on Dividends are available but are not yet mainstream.

The main purpose of an index funds is that it "aims to replicate the movements of an index of a specific financial market"(<http://en.wikipedia.org/wiki/Index_fund>). Since markets are themselves naturally weighted by the largest players in the market, it makes the best sense to weigh the indexes the same way. Example: Swings of Exxon stock will change the market much more than "Jack's Tools."

Index funds capture the market, not beat it. To try to beat the market violates the Efficient Market Hypothesis (<http://en.wikipedia.org/wiki/Market_efficiency>)</comment></comment>


Revenue Contribution, Margin Analysis and Growth Rates of SaaS Companies - <AUTHOR> https://docs.google.com/spreadsheets/d/1lbmiXL_q1MMjeuGu4DTh9dC0DID8moMiD0ZpgC4uhYA/edit#gid=2091663360 <comment><USER2> What jumped out at me about this data was many of these businesses have robust contribution value per customer. (Not just relative to acquisition cost, like in low-end B2B but successfully adapting the model to go after bigger fish)</comment>