How Simple Analytics calculates unique visits without cookies or fingerprinting - <AUTHOR> https://docs.simpleanalytics.com/uniques <comment><AUTHOR> Author here. Just to shine some light on the problem we are having and how this solves that problem. We get more and more customers that are required by law to have an active opt-in for cookies and fingerprinting. They basically can't use those techniques before a visitor actually ticks a checkbox (which has to unchecked by default).

This results in a lot of missed data. They can't run Google Analytics for the visitors that don't check this box. For them it's a big issue because they can't see how their visitors are behaving before checking that box.

Simple Analytics wants to fix this issue by not requiring consent. Customers can use our tool for every visitor that lands on their website.

One other thing that is a common misconception is that unique visits with cookies are accurate. They also have flaws:

\- What if a user uses a different browser

\- What if a user uses a different device

\- What if a user blocks (third-party) cookies

The same goes for using IP based fingerprinting. All techniques have flaws. Although they are flawed they are used to get a number. It's not an accurate number but it's a number. That's also the case with using our technique. It's less accurate then using cookies, yes, but it's a number you can use. You can compare it to a previous period, you can see the unique views of a page, etc.

If you don't need to comply with privacy regulations you can use all the tools you want. We just focus on the companies who do care about those regulations and give them the big picture they are now missing.

<comment><USER2> > They can't run Google Analytics for the visitors that don't check this box

I don't understand. They can. Just anonymize the ip. You can track all their activities. Am I missing something?

<comment><AUTHOR> Google Analytics tracks your visitors with a cookie [1]. You need consent for placing that cookie under the GDPR and other privacy regulations.

[1] [https://developers.google.com/analytics/devguides/collection...](https://developers.google.com/analytics/devguides/collection/analyticsjs/cookie- usage)

<comment><USER3> I don't think GDPR necessarily says that one must get consent for every cookie.

<comment><USER4> Google analytics does use first party cookies for the site stats, but it also s̶e̶t̶s̶ [edit] can set a third party DoubleClick cookie that tracks users across sites. So that anonymizing the IP doesn't anonymize the user.

There's also optional functionality that can track users via the first party cookie. Passing login id, for example, to GA.

<comment><USER5>
        it also sets a third party DoubleClick cookie

I have never witnessed that. Can you link to a site that uses _only_ Google Analytics where that happens?

Maybe you confused Analytics and Adsense?

<comment><USER4> _" For customers that are using Google Analytics' Display Advertiser features, such as remarketing, a third-party DoubleClick cookie is used in addition to the other cookies"_

So, I suppose I should have said "can set", though remarketing is very common.

[https://developers.google.com/analytics/devguides/collection...](https://developers.google.com/analytics/devguides/collection/analyticsjs/cookie- usage)

<comment><USER5> I would think that enabling the "Display advertisers features" only makes sense for webmasters who also use Google Adsense. And then their visitors get bombarded with all kinds of cookies anyhow. So I don't think it applies to the use case at hand. Where a webmaster wants to implement statistics without violating GDPR.

<comment><USER4> It's used for Adwords. That doesn't change anything on your site. You can remarket only on Google searches, for example...no AdSense involved.

</comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER6> > This referrer is very useful to figure out where traffic is coming from.

This is exactly why sending the referrer header is _insane_ [1]. The header betrays the user's privacy _by design_.

Remove it ASAP. If your app breaks, that's unfortunate but necessary.

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

<comment><USER7> Necessary for whom? Privacy purists seem to be surprised that website and app owners want/need analytics to meaningfully improve their app's usability. I praise SA's privacy oriented approach as a meaningful alternative to GA.

This sort of overly-critical hyperbole doesn't help the privacy conversation. If follow SA loses a feature it likely needs to remain competitive, and customers would have another reason to go back to Google Analytics. Hardly a necessary privacy win a my book.

<comment><USER8> > _Privacy purists seem to be surprised that website and app owners want /need > analytics to meaningfully improve their app's usability._

Both "privacy purists" and many other people see this as _expediency_ at best, and a lie at worst (i.e. once marketing gets wind of the tracking built for development purposes; see e.g. recent Gitlab fiasco).

</comment></comment></comment><comment><USER9> As I understand it, this is the method Webalizer has been using to calculate unique visitors for over two decades now. It is mindboggling that we have come full circle and this is now a business model again.

<comment><USER10> It's one of the methods we used when doing logfile analytics in the early 2000s. At the time it just appeared obvious to me. One problem with it (which is why we combined it with other techniques too) is that some browsers even then did not send Referer headers reliably, neither between pages on the same site nor between third party sites, so what they say in the article about "direct visit" is not reliable.

<comment><USER11> > some browsers even then did not send Referer headers reliably

Apart from https/http thing mentioned elsewhere in this thread, there's also Referrer-Policy [1]. I don't know how wide-spread its use is, but I find that most requests I get have no referrer header these days.

[1] [https://developer.mozilla.org/en- US/docs/Web/Security/Refere...](https://developer.mozilla.org/en- US/docs/Web/Security/Referer_header:_privacy_and_security_concerns#How_can_we_fix_this)

</comment></comment></comment><comment><USER12> There's nothing "unique" about those visits, just using the referrer isn't enough to make them unique.

<comment><USER13> The author's comment post discusses how the analytics are going to be flawed, but is emphasizing that the trends in the numbers over time can be very useful, even when we know the exact numbers are not precise.

I think it's a great trade-off to respect user privacy while removing annoying popup garbage from the user's screen about consent. Aren't we all sick and tired of these consent buttons everywhere online now???

</comment></comment><comment><USER14> I think a more robust (and privacy-preserving) way to calculate uniques ( per time-frame as well) is to make use of the local storage / indexDB in the visitor's browser.

This is how it would work:

\- Visitor X lands on your website.

\- With some JavaScript you check local storage if `dailyUnique` for today's date is set.

\- if yes, send `visit` signal

\- if not set, send `unique visit` signal and set `dailyUnique` to local storage.

You can apply this to any analytics use case. Its is private and does not rely on referrers. We have been using this goal-attainment approach to do analytics at my company for quite some years.

<comment><AUTHOR> Author here. Our tool is GDPR compliant out of the box. We can't use local storage (it's legal wise the same as a cookie). Although your suggestion will provide more accurate stats, it's a trade-off we are willing to accept.

<comment><USER15> How about referring from a https site? AFAIK, browsers don't send a referrer from s https site.

<comment><USER16> If the referring site is http and the site being referred to it won't send the referrer header.

http --> https = no referrer header

https --> https = referrer header

<comment><USER17> Actually:

https --> http = no referrer header

</comment></comment></comment></comment></comment><comment><USER18> Very excited by the title, but very disappointed by the content...

This is not true unique visit counting. Which can be achieved using non unique values being set in browser storage, which is privacy friendly in my eyes.

<comment><AUTHOR> I agree with you. It's privacy friendly to have a cookie stored on the browser with a boolean only. Unfortunately it's not allowed by GDPR without asking for consent first. Would be open to other ways without cookies and fingerprinting. I think there is no other way.

<comment><USER19> So even if it's obvious that there is no unique ID in there, you still need to show the notice?

We really need to lobby for a smarter law.

</comment></comment></comment><comment><USER20> I'm just glad someone is focusing on obeying the spirit of the law rather than tacking an ironic "we value your privacy" popup to the website and continue selling my data.

<comment><USER21> Yeah, I always read these popups as "we value your privacy, therefore we take it away from you and sell it to the highest bidder" and hit the back button.

</comment></comment><comment><USER22> A user can land your page from multiple referrers (or the same) more than once and some search engines including Google will hide the referrer information so the calculation will be off IMO.

The regulations are not strict if you're not identifying the individual people from your visitor/user data. If you're collecting user event data into your servers and can prove that you're using the data just for the analytics purposes (i.e. providing a better user experience to your users) there is nothing you can afraid of using cookies.

That may not be the case for third party analytics providers though because if you're using Google Analytics, you're responsible from how Google are using your customer data.

</comment><comment><USER23> The same user will trigger many unique visits if coming from, for example, google search

<comment><AUTHOR> This is true and that's a trade-off for not using fingerprinting or cookies.

</comment></comment><comment><USER24> It really doesn't solve any problems surrounding web analytics, user privacy or user experience. I think it shows the creators lack of industry experience in ecommerce, advertising and user tracking. It's like someone has sprinkled a flawed 20 year old method of tracking in glitter and saas'd it.

I think there is a very small subset of website owners that would be willing to pay for this. Then again he only needs to get a few people that aren't sales focused and are deluded enough to think this is the pinnacle of 'privacy'.

</comment><comment><USER25> I am wondering how they will try to compensate when the browser is actively blocking referrer information. In that case the data will be polluted like the website has received more unique visitors, but it is not the actual.

In earlier times, this kind of tracking was the norm. Big Analytic companies tried to distill this information and add value to the existing data to make sense. So the cookies and fingerprinting were added to distill that data.

<comment><USER26> Given you want discount internal site traffic from being unique, you could add a query param to URLs as the user navigates.

</comment></comment><comment><USER5> This article uses the terms "visit" and "pageview" in unusualy ways.

They give the example that when a user clicks through from yourwebsite.com/ to yourwebsite.com/page then the first is a unique visit while the second is a non-unique visit.

I would neither call a "visit" but rather a "pageview".

In my book, the visit is what started from the first pageview on yourwebsite.com site and continues to the last pageview.

<comment><AUTHOR> Author here. It's technically more correct to call those visits "unique page views" and "page views". I think visit is a very simple word to understand for most people. My tool is targeted at people who want a simple tool, that's why I want to keep the wording also simple.

<comment><USER27> How we used these words 20 years ago, when server logs were cool:

Uniques are visitors not pageviews. Hits, page views, and sessions are decreasingly granular content stats, not people stats. Visits and visitors are people stats. Sessions tend to be the matrix of page views (containing multiple hits) per visitor visit.

</comment></comment></comment><comment><USER28> The article says

> When a user lands on your website without visiting another website (direct > visit) we will record it as a non unique visit

But then the image below says the contrary

> This will be tracked as a unique visit as the current website name is > different from referer (not available).

Which is it?

Anyhow, this seems like this approach unfortunately makes the "unique visits" data completely wrong, since users might tend to visit your website multiple times a day.

<comment><AUTHOR> Thank you. It was a typo, it's now fixed.

Unique visits data is never 100% accurate. What if a user switches from device or browser?

<comment><USER29> Well, your site could require authentication. 100% accurate unique visits data isn't really a good reason to do that, but it is a side effect if you already do.

</comment></comment></comment><comment><USER30> PWA 1px image on top with cache-first show single visits. A cookie without a cookie

<comment><USER31> Creative - I love this solution

<comment><USER30> with cache expire time set to midnight you also can get daily users

</comment></comment></comment><comment><USER32> You could just add a unique value to every link between pages?

<comment><AUTHOR> This way a user is still unique when he/she closes the tab and reopens, right?

<comment><USER33> What if they share the link on social? All the new traffic would seem to be non-unique.

</comment></comment></comment><comment><USER34> > Other analytics businesses use this technique (for example based on IP > address). This seems privacy friendly but is considered fingerprinting. For > which you need consent.

Do you need consent to count unique IPs that visit your site in the UK under GDPR? Aren't there laws that say unique IPs do not correspond directly to an individual (in the context of piracy), and yet for simple website analytics you count IP as uniquely identifying a user? Am I required by law to change the default config of apache or nginx to not log the IPs? Or is it enough if I promise not to analyze the logs?

</comment><comment><USER35> GDPR is just a mess. The bureaucrats who wrote it don't understand it, neither do the enforcers, or the folks under enforcement.

Brussels should just shut itself down.</comment>


A full-featured form software built with love in python - <AUTHOR> https://github.com/shiyanhui/Young <comment><USER2> Can you please change the link to the English version?

[https://github.com/shiyanhui/Young/blob/master/README_EN.md](https://github.com/shiyanhui/Young/blob/master/README_EN.md)

BTW: These colours remind me of something, I can't put my finger on it :)

<comment><AUTHOR> Changed. Haha, the colours come from google logo :)

<comment><USER2> Thank you :)

</comment></comment></comment><comment><USER3> For _um_ software, not form software!

<comment><USER4> Gees, thanks for that! I kept wondering if it was something to build 'forms' ... and the list of features didn't seem to jive with that assumption of mine.

</comment></comment><comment><USER5> Describing some project with phrases such as "built with love" or "from the ground up" really make me cringe.

<comment><USER6> I concur. Yet to see any "Built with hate" projects. Like "Built with hate in Perl!"

<comment><USER7> I have done some work in Java and Javascript. It was all done with hate. If there was any love there, it was for the paychecks I got at the end of each month.

<comment><USER8> You should try working with Salesforce. That makes JavaScript seem like a pleasant experience.

<comment><USER9> At the last company I worked for, we used Salesforce as our database and source of truth in one of our web applications. It was exactly as horrible as it sounds :)

<comment><USER10> I've been there, and I feel your pain. My boss wanted to use it as the source of truth for one of our monitoring systems. It was... ugly.

</comment></comment></comment></comment></comment></comment><comment><USER11> Please don't pay attention to the negativity. It is a nice project. I really like the GUI. Oh and its a tornado based project, which is cool. The logo is really cool also. What font did you use for it?

<comment><USER12> I too would love to know the logo font.

<comment><AUTHOR> The font is monofur, my favourite programming font. You can download here [https://github.com/powerline/fonts](https://github.com/powerline/fonts)

</comment></comment></comment><comment><USER13> Forum not form.

<comment><USER14> They mention Unbuntu amongst the Chinese, too.

So if it's been de-Buntu'd, I guess it would be .... Debian?

</comment></comment><comment><USER15> What is a "form software" ?

It looks like a chat client, nice UI.

<comment><USER16> I think it's supposed to be "forum"

<comment><USER17> Yeah, its supposed to be "forum". I work in a form heavy industry and thought this was going to be a solution aimed at that :/ And I thought it was by Google for a second.

</comment></comment></comment><comment><USER18> A promising alternative is [http://misago-project.org/](http://misago- project.org/)

<comment><USER19> Very nice indeed! Django+DRF and React+redux is like four of my favourite things combined. The frontend build file is gulp, so make that five.

<comment><USER20> working on a similar project, too. github.com/lez/societybuilder (deployed at jovilag.net). Sorry for not being english just yet.

technology: pyramid + peewee + react + redux + postgresql

</comment></comment></comment><comment><USER21> Looks more like Facebook than a forum?

</comment><comment><USER22> Eehh, it's GPL-ed. I was already thinking of a brand to slap on it and sell for big money. shame.

</comment><comment><USER23> Please don't use several megabyte-plus size images on your front page!

<comment><AUTHOR> Yeah, I will optimize it. Thanks.

<comment><USER20> Have you considered AGPL as a license? So that anyone deploying and changing your app will have to give back.

<comment><AUTHOR> Yeah, sounds reasonable. Thanks.</comment></comment></comment></comment>


What to Say When You Get 5 Minutes with a Billionaire - <AUTHOR> https://www.auxoro.com/the-aux-1/you-get-five-minutes-with-a-billionaire <comment><USER2> From the show's summary it seems like this is going to end up being disgusting billionaire worship.

The hope of running into a billionaire and having it change your life is not much different than buying a lotto ticket.

Running into a billionaire isn't going to do jack shit to your life. The household name billionaires heard it all from passers by and don't pay any attention to the little people. What are you gonna do, run up with a slide deck to pitch your jump to conclusions mat?

Billionaires don't live in the same world we do, literally. They have people get things for them. They live in gated communities you cannot access. They vacation on yachts and private islands you cannot see. They go to Lakers games in private box seats with a back entrance. They are members of clubs and gyms you are not allowed to join, even if you could afford it.

What do you do if you see Jeff Bezos scarfing down an Egg McMuffin? Nothing. What he's doing in public is none of your business. He doesn't know you or care what you have to say.

</comment><comment><USER3> " _And two, if you need anything taken care of, and I mean anything, whether it 's a problem you're working on or your arms go numb on the toilet, he needs someone to wipe your ass, call me, and I will make it happen_"

So from Jeff's POV you're offering to do lackey work for free. Or did you mention a price to wipe his ass?

Either way it seems highly probably someone like a Bezos or Branson got to where they are by having an inner circle of friends and advisors helping them out. Not counting the thousands of people already in position to fuel their jets and wipe their asses. And you're not in either circle.</comment>


Physicists' simple spanks economists' complex in economic growth forecasts - <AUTHOR> https://arstechnica.com/science/2018/08/physicists-simple-spanks-economists-complex-in-economic-growth-forecasts/ <comment><USER2> > _So what is the economic fitness? It is, in short, a measure of the > complexity of a country's exports. The idea is that exports represent the > products from a country that are competitive with like products from the > rest of the world. The larger the variety of exported products, the fitter > an economy is._

This is a different approach, I guess, because, more typically, an economist might assess an economy's strength by simply tallying up the total value of its exports in dollars -- or perhaps even by placing rather little weight on the export picture at all, focusing instead upon other aspects?</comment>


12 Must Have Bookmarklets : Google Chrome and IE | The Code Dreamer - <AUTHOR> http://www.nitinh.com/2009/03/12-must-have-bookmarklets-google-chrome-and-ie/ <comment><USER2> Today I figured there is Greasemonkey, Firebug for IE now. Has anyone tried it? Firebug esp helps me a lot to resolve JS/CSS issues in my web development. If I can do the same on IE, esp to sort out infamous IE CSS issues, that'll be great.</comment>


It Will Not Be Feasible to Mine Bitcoin on Other Planets - <AUTHOR> http://imgur.com/hl75two

<comment><USER2> Well let's cancel this whole space exploration thing then.

</comment><comment><USER3> If we evere figure out quantum entanglement communication then it won't be an issue.</comment>


Lisp and Haskell (2017) - <AUTHOR> https://markkarpov.com/post/lisp-and-haskell.html <comment><USER3> My problem with Haskell is that it is not pragmatic and the reason I stopped using it. The philosophy of separating pure and impure code – and to enforce it – does more harm than good. Often its difficult to understand what your "forth level of abstraction code" above the usual abstraction levels really does. Haskell is fun to learn. Haskell has a lot of interesting concepts to explore and it will make you a better programmer. Haskell code can be really dense. And Haskell code can be totally unreadable, using concepts which take weeks to learn – which is... not so great.

Lisp (Common Lisp) is what you get when you reduce the rules and syntax to a minimum and try at the same time to be a maximal flexible programming language. This simplicity and applied pragmatism is what makes it so great. Like the authors in the Lisp books warned, after learning Lisp, coding won't be the same. Now I see everywhere code that could easily be written in Lisp, but is not so great in language XYZ. All those SDL's and stringified API's and code-generators they need to do real things and data formats like JSON... all obsolete, if they would have chosen Lisp (or a language with brackets and Lisp like evaluation rules).

The other thing that is often overlooked regarding Lisp is, that in a Lisp like language there is no need to wait for a new version of the programming language to be released to get new syntax – you can simply add it yourself (or have a library doing it for you). E.g. a lot of the JavaScript mess could be fixed by code transformation, if they would have chosen a Lisp like syntax in the first place.

I don't see Haskell as uber language. If I want super correct code, speed and I'm okay with using a more complex language, then there is Rust – which is probably more correct than Haskell and faster, too.

Haskell, Lisp and C++ would really benefit form a std library 2.0 and a default package manager... one can dream.

<comment><USER4> The ability to come up with new syntax in LISP is in my opinion vastly overrated.

Yes, LISP code can be easily parsed for as long as you stick to lists. However the ability to do anything complicated with LISP code is simply not there because LISP code loses type info, which is extremely important for anything you'd want to do with code, like all kinds of non-superficial transformations and refactorings.

So here are some facts given as examples:

(1) LISP code does not make the job of IDE authors easier; just ask the authors themselves

(2) in terms of macros, anything more complicated than lazy evaluation of thunks and kiddie examples is out of reach; for example .NET's LINQ cannot be expressed in LISP, not unless you add a static type system, but at that point you're no longer talking about LISP ;-)

In my opinion LISP has been vastly romanticized, yet it doesn't live up to expectations. It falls short in every department, from functional programming, to available tooling, to the great enlightenment people are supposed to experience once they learn it.

Whereas Haskell really does live up to expectations, being one of those very few ecosystems that does make developers better, at this point being the lingua franca of FP.

<comment><USER5> >for example .NET's LINQ cannot be expressed in LISP, not unless you add a static type system

Doesn't that imply that Lisp, sans-static typing, is not Turing-Complete? Surely that is not the case.

<comment><USER6> A Turing machine is Turing-complete.

Good luck expressing LINQ syntax, or Lisp syntax, or even Basic-80 syntax on it.

Syntax is important, it's a tool of thought.

<comment><USER5> I understood the post to which I replied to be arguing that LINQ could not be expressed in Lisp, not that Lisp doesn't have the correct syntax.

Surely you can write LINQ in any Turing-complete language.

<comment><USER7> I guess the question you are begging is: how far can Lisp-LINQ go from the syntax, semantics, and ergonomics of C#'s LINQ before you stop calling it LINQ?

Turing completeness doesn't describe expressivity of source code, as far as I understand it - it describes the ability to produce a desired outcome. So yes, you can perform the same operations LINQ allows, in Lisp or any other Turing- complete language. But can you do it while giving the programmer the same (or a similar enough) experience? From the .NET docs:

> Language-integrated query allows query expressions to benefit from the rich > metadata, compile-time syntax checking, static typing and IntelliSense that > was previously available only to imperative code. Language-integrated query > also allows a single general purpose declarative query facility to be > applied to all in-memory information, not just information from external > sources.

Now, to be fair, I'm not sure you can express all that in Haskell either. And it could be reasonable to argue that a few of those benefits (e.g. intellisense) just _haven't_ been done for Lisp, not necessarily that they _can't_ be done.

</comment></comment></comment></comment></comment></comment><comment><USER8> So I put his example into a lisp file and compiled it under SLIME/sbcl, which is how I typically develop:

        1 compiler notes:

        scratch.lisp:10:7:
          warning:
            The function (LAMBDA (X) :IN ADD-TEXT-PADDING) called by MAP-INTO returns NULL but CHARACTER is expected
            See also:
              SBCL Manual, Handling of Types [:node]
            --> TRULY-THE SB-KERNEL:%MAP
            ==>
              (MAP-INTO (MAKE-SEQUENCE SB-C::RESULT-TYPE (MIN (LENGTH #:G51))) SB-C::FUN
                        #:G51)

        Compilation failed.

It's also patently false that quicklisp has no tests; it has no unit tests, but it is tested as a whole thoroughly, both the code _and_ the set of systems it provides.

<comment><USER9> FWIW the first comment in that blog post shows that at the time of writing the post, the compiler could not detect that error.

<comment><USER10> My suspicion is the author just didn't know how to use sbcl for this. I quickly tried this and did not receive any such message.

</comment></comment></comment><comment><USER11> There is no magic in Haskell's strong typing. Axiom, a computer algebra system with extremely strong typing, is written in common lisp. Axiom's language is essentially a domain specific language on top of lisp.

The key difference is "impedence matching". An impedence mismatch occurs when you hook a soda straw to a firehose. There is a lot of friction and lossage. In programming terms, there is an impedence mismatch between your problem and the computer. You use a programming language to bring them together.

In assembler, you have to move your problem all the way to the machine. In Haskell, you have to move your problem all the way to the type system. In lisp you can write at the machine level (e.g. (car x) which is just a pointer fetch) or your can write at the problem leve (e.g. (integrate (sin x)))... or you can do both in the same statement (car (integrate (sin x))).

In other words, lisp allows you to craft a solution that is close to the machine and close to the problem at the same time, in the same language.

<comment><USER12> You have the choice to move as much or as little to the type system in Haskell as you deem beneficial. You do not have to "type it to the max", as is commonly offered as a stereotype.

</comment></comment><comment><USER13> I have worked on fairly large Common Lisp project (around 500k lines of actively managed code). That was the most pleasant experience in my professional life. The refactoring was easy, introduction of new features was simple and clear. I attribute it partially to language itself and partially to the team culture. We had a lot of tests BTW. After this I had quite bad experience with a Clojure project in a different company, so I am not dogmatic about lisp supremacy anymore. Still, Common Lisp definitely can be extremely successful in production given proper environment.

<comment> sahil-kang I've been programming lisp for a few years now (Scheme then CL) and write Clojure daily for my current job. I initially described Clojure as: the worst dialect of lisp I've used, but the only one I've been paid to write in. It's grown a lot on me over the past few months, but I still end up missing CL every now and then at work (I think I mainly like CL's Slime more than Clojure's Cider).

What were some unsettling points about the Clojure project you worked on? One thing I've noticed is that since Clojure is a relatively new language, a lot of newer lispers will start off with it, and I imagine that companies are more likely to try Clojure than CL as a first lisp. Consequently, the Clojure code you run into on the job may be of lower quality.

<comment><USER13> Laziness is quite dangerous given existence of side effects in Clojure - <USER2> would the most common error for new developers. I missed LOOP even it has a bad reputation - nevertheless it covers almost all useful cases in practice. We were misusing AOT compilation, the behavior of that code was surprising sometimes.

But the main failure in my opinion was absence of good development patterns which leverage strengths of the language and mitigate weaknesses. Dynamic languages such as lisp absolutely need REPL as primary development mode, conventions has to be strictly enforced and consistency is much more important than in languages with rich static typing. Clojure can be and is successful in many projects. But if your team is trying write Java with parenthesis everything is hard.

</comment></comment></comment><comment><USER14> For what it's worth, on a fairly recent SBCL, here's what the compiler/interpreter prints when you enter the author's function:

      ~> sbcl
      This is SBCL 1.4.7, an implementation of ANSI Common Lisp.
      More information about SBCL is available at <http://www.sbcl.org/>.

      SBCL is free software, provided as is, with absolutely no warranty.
      It is mostly in the public domain; some portions are provided under
      BSD-style licenses.  See the CREDITS and COPYING files in the
      distribution for more information.
      * (defun add-text-padding (str &key padding newline)
        "Add padding to text STR. Every line except for the first one, will be
      prefixed with PADDING spaces. If NEWLINE is non-NIL, newline character will
      be prepended to the text making it start on the next line with padding
      applied to every single line."
        (let ((str (if newline
                       (concatenate 'string (string #\Newline) str)
                       str)))
          (with-output-to-string (s)
            (map 'string
                 (lambda (x)
                   (princ x s)
                   (when (char= x #\Newline)
                     (dotimes (i padding)
                       (princ #\Space s))))
                 str))))
      ; in: DEFUN ADD-TEXT-PADDING
      ;     (MAP 'STRING
      ;          (LAMBDA (X)
      ;            (PRINC X S)
      ;            (WHEN (CHAR= X #\Newline) (DOTIMES (I PADDING) (PRINC #\  S))))
      ;          STR)
      ; --> TRULY-THE SB-KERNEL:%MAP
      ; ==>
      ;   (MAP-INTO (MAKE-SEQUENCE SB-C::RESULT-TYPE (MIN (LENGTH #:G51))) SB-C::FUN
      ;             #:G51)
      ;
      ; caught WARNING:
      ;   The function (LAMBDA (X) :IN ADD-TEXT-PADDING) called by MAP-INTO returns NULL but CHARACTER is expected
      ;   See also:
      ;     The SBCL Manual, Node "Handling of Types"
      ;
      ; compilation unit finished
      ;   caught 1 WARNING condition

      ADD-TEXT-PADDING
      *

Thus, it identifies the exact problem the author describes at the end.

<comment><USER15> Yeah, just because the language doesn't force you to specify types, doesn't mean that the compiler can't infer them for you.

What was most eye-opening for me about CL was just how helpful the compiler of a dynamically typed programming language can be.

<comment><USER16> Checking dynamic types us not the work of a compiler. Checking types at compile time is static type checking. If a type is wholly dynamic (determined at runtime via something like casting to a type specified in user input), the compiler can't check it.

(Also, type inference is orthogonal to static vs dynamic typing.)

<comment> phoe-krk > Checking dynamic types us not the work of a compiler. Checking types at > compile time is static type checking.

By your logic, Common Lisp is both dynamically and statically typed, because compile-time type checks are done by the compiler and warnings/errors are signaled whenever proper.

More, if you declare (OPTIMIZE SPEED), the compiler is going to print a list of all places where it was unable to infer types on its own and where it expects help from the programmer in form of type declarations for individual variables.

</comment></comment></comment></comment><comment><USER17> Those interested in both should check out Hackett: [https://github.com/lexi- lambda/hackett](https://github.com/lexi-lambda/hackett)

Whilst not "finished", what she's done here is incredible. It's an implementation of Haskell semantics as Racket macros.

<comment><USER18> Totally agreed... I wish I had her talent ;-) Hackett actually inspired me to start a project that goes in the opposite direction, i.e. from LISP to Haskell rather than Haskell to LISP. I'm a PL amateur, so it's been really interesting to implement a macro system on top of an existing language, without it being difficult to use or seeming like a hack.

</comment></comment><comment><USER19> Common Lisp as hackish vs protective is nice way to describe it.

Another way to describe it exploratory vs implementatory.

In some ways Common Lisp is like Mathematica for programming. It's a language for a computer architect to develop and explore high level concept. It's not a accident that early Javascript prototype was done in common lisp or that metaobject protocols, aspect-oriented programming, etc. were first implemented and experimented with Common Lisp.

>Dalinian: Lisp. Java. Which one sounds sexier?

>RevAaron: Definitely Lisp. Lisp conjures up images of hippy coders, drugs, sex, and rock & roll. Late nights at Berkeley, coding in Lisp fueled by LSD. Java evokes a vision of a stereotypical nerd, with no life or social skills.

</comment><comment><USER20> One of the points the author touches is documentation. I just couldn't get why then he gave advantage to Haskell, since the documentation of Haskell libraries famously consists of a few definitions of types. So, you know that there is an abstractly named monadic function, you know it takes a foo and returns monad foo. What more guidance would you ever need?

But when it comes to CL, he has expectations:

>I've opened an issue on GitHub of one quite popular library, asking the maintainer to write documentation, but after 6 months it's still not written (strange, right?).

<comment><USER21> I think that was indeed a bit biased.

That said, and not defending the author, I would add, that as an advanced beginner in Haskell, I find types to be sufficient documentation.

Very often if I look for something in Hoogle, I would be just skimming through type signatures looking for what I want. If I look for something specific I would just put the type I want into the search field.

On the contrary, f.x. with Java I tend to either google the operation I want to do using queries like "How to do blah" or read javadoc in advance to mentally index what a given library has. And there you really need to read into the text trying to figure out why a method is overloaded multiple times with some obscure extra boolean flags.

edit: grammar

<comment><USER4> I'm a Scala developer, using many libraries inspired by Haskell equivalents.

I have to disagree, types are not sufficient as documentation and this is what kept me from making the jump to Haskell actually.

But types are better than nothing, or better than outdated documentation. I can't imagine anything worse than code written in a dynamic language and without any documentation.

This is the same discussion as with types vs tests. Types give you certain proofs for free, freeing you from writing certain types of tests. And they make property based testing easier. But the ideal is to have types + tests, types + good documentation, etc.

</comment></comment></comment><comment><USER22> I enjoyed reading this article, fun read, even though I don't agree with much of it.

My problem with Haskell: I use a subset of Haskell and when using Emacs/Intero/etc. I feel like I am productive and I enjoy myself. But, reading and understanding/modifying other people's code is like running through mud. BTW, I wrote a Haskel book that just uses the small subset of the language that I use.

I very much enjoy working on my own projects in Haskel and using Emacs and a repl feels a lot like my 30 years experience using Lisp languages.

I also use Common Lisp, but now mostly just for paid projects, not as often for side projects. (I wrote a Common Lisp book for Springer Verlag in the 1980s, which is probably why I still get occasional CL consulting work).

</comment><comment><USER23> > _Speaking of tests, recently I discovered that Zach Beane AKA Xach, an über- > level Common Lisp hacker doesn't usually write tests. FYI, he is the author > of Quicklisp, that is something like (but not quite) Cabal or Stack. > Quicklisp is de-facto the only widely used library manager in Common Lisp > world, and so it's written in Common Lisp and doesn't have any tests. It's a > wonder for me how it's not breaking!_

Why is it "a wonder"? We could, and did, write robust code, for decades before testing and TDD became a thing.

<comment><USER24> But Quicklisp exists today. Are you suggesting testing is unnecessary or ineffective? If it is effective, why wouldn't Quicklisp use it?

<comment><USER23> > _But Quicklisp exists today._

So? Tons of the software of the 70s and 80s exists today too. In COBOL form, it powers some of the more critical banking, government, etc, systems. In C form, it powers just about everything else.

> _Are you suggesting testing is unnecessary or ineffective?_

Of course it's ineffective. It can only prove the present of errors, not their absence.

> _If it is effective, why wouldn 't Quicklisp use it?_

Because the need for testing also depends on how often you refactor and change your code, and how many bugs you're likely to put in it in the first place (based on the complexity of the domain, your skills, etc). I'd say both of those things are no issues for Quicklisp.

So, if having no tests works for Quicklist, and the program doesn't have many bugs people complain about, then that's it.

If a codebase works, is used, and doesn't seem to have bugs people complain about, we should also consult with reality when deciding if it's worth our time to write tests for it, not just some a priori ideology that they're necessary.

</comment></comment></comment><comment><USER25> The distinction between "hacking" and "protective" languages is a good one. If you want to be balanced as a programmer, you need to deeply understand at least one language in both categories. Protective languages are wonderful for large-scale projects (true "software engineering"), but they tend to lack the whimsy that drew so many of us to programming in the first place.

<comment><USER26> A similar distinction was made by Yegge before [1], which he (unfortunately) labeled as "liberal" and "conservative". It was quite controversial [2].

Another similar idea is Fowler's software development attitude [3]. He uses the terms "enabling" and "directing" instead.

[1] [https://plus.google.com/110981030061712822816/posts/KaSKeg4v...](https://plus.google.com/110981030061712822816/posts/KaSKeg4vQtz)

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

[3] [https://www.martinfowler.com/bliki/SoftwareDevelopmentAttitu...](https://www.martinfowler.com/bliki/SoftwareDevelopmentAttitude.html)

<comment><USER12> It's hard to describe, but the discourse on hn in 2012 just felt _different_ in some weird way.

<comment><USER27> The tone of the posts seems about the same as now to me, but the top level comments do seem to be longer and with more analysis than most top level comments lately.

</comment></comment></comment></comment><comment><USER28> The older I get, the more I realize that the ultimate factor in programming productivity is how readable the language is, or how readable the typical idioms and usage of that language are. There are a lot of really awesome languages, but they are tremendously difficult to read your own code, let alone someone else's. You can find languages that are very expressive while you're writing the code, but that code will be read much more often than the time you spent writing it, both by yourself and likely by other people.

For this reason alone, I can really see why python has been so enormously runaway successful.

</comment><comment><USER29> I'm not sure I understand his point. He wrote the function, and in under a second, he was able to easily run it to test it and got a type error.

The only difference in a static world would be the error would have showed up a few seconds earlier, before he needed to run it in the repl.

I mean, the error was definitly vague from CL, but is that really because it lacks static typing that the error is vague?

<comment><USER30> But he did get a _runtime_ failure. Imagine this wasn't about adding a function, but changing an existing function that is being called from 23 different locations in a 100kloc codebase, and that it contains some tricky condition logic so that a bug might only be triggered in 5% of the calls. Without exhaustive unit tests, a type error potentially would not show up until all those call sites had been executed with the specific arguments required to trigger the bug. His point was that in a statically typed language, this would all be detected at compile time.

<comment><USER31> This error would be detected at compile time without it (as another commenter shows), and if you are not using the more dynamic features of lisp you really should declare the types.

</comment></comment></comment><comment><USER32> > Quicklisp is de-facto the only widely used library manager in Common Lisp > world, and so it's written in Common Lisp and doesn't have any tests. It's a > wonder for me how it's not breaking!

Quicklisp also downloads and executes code over plain HTTP with no integrity checks whatsoever.

<comment><USER33> Yes, that is the default. But you could connect through an https proxy or check PGP signatures (see [http://blog.quicklisp.org/2017/09/something-to-try- out-quick...](http://blog.quicklisp.org/2017/09/something-to-try-out- quicklisp-with.html)).

</comment></comment><comment><USER34> Log of my last 3 minutes of activity:

      This is the TXR Lisp interactive listener of TXR 197.
      Quit with :quit or Ctrl-D on empty line. Ctrl-X ? for cheatsheet.
      1> (defun add-text-padding (str nspaces : newline-p)
           (let ((padding `\n@(mkstring nspaces)`))
             (when newline-p
               (set str `\n@str`))
             (regsub #/\n/ padding str)))
      add-text-padding
      2> (add-text-padding "hello\nworld")
      ** (expr-2:1) add-text-padding: too few arguments
      3> (add-text-padding "hello\nworld" 3)
      "hello\n   world"
      4> (add-text-padding "hello\nworld" 3 t)
      "\n   hello\n   world"

Note how (mkstring n) makes a string of n spaces by default; if you want a different character, specify it as a second argument.

I've never heard of trivial-update, but TXR has something like it built-in that I independently invented called _upd_ :

      1> (defvar a 0)
      a
      2> (upd a (+ 2) (* 3))
      6
      3> a
      6

_upd_ implicitly uses the syntax of the partial application operator _op_ to create a pipeline of partial applications. To get such a pipeline by itself as a function, _opip_ can be used; _upd_ is simply the result of wanting a place- mutating operator that takes a place's value through an _opip_ pipe and then writes the result back in.

TXR Lisp also has a well-featured command line option parsing library built- in:

[http://nongnu.org/txr/txr-manpage.html#N-02C70C38](http://nongnu.org/txr/txr- manpage.html#N-02C70C38)

</comment><comment><USER11> One other key difference between lisp and haskell... Common Lisp has a standard definition. My code from the last century still compiles and runs as does code from all of the books.

On the other hand, haskell seems to be a struggle. I recently downloaded the book "Write yourself a scheme in 48 hours" written in 2007. Page 18 tries to "import Monad", which fails. I tried surfing for that string and only see "Control.Monad". I tried installing the lastest Haskell and the workbench. Still no luck. So, 18 pages into a book written 11 years ago and the trivial examples don't work.

<comment><USER35> As of today, there are 2 versions of the Haskell specification; "Monad" is Haskell 98, but in Haskell 2010 it's "Control.Monad".

If you want to get legacy code to run with a current version of GHC, try "ghc -XHaskell98".

<comment><USER11> That also fails.

<comment><USER36> Certainly it does but given that Control.Monad is sufficient I do not see it as a larger issue. Haskell 2010 is a different language with libraries refactored. If you wish to use an older text (pre Haskell 2010) then it would probably be best to try either Hugs98 or one of the other haskell implementations as GHC is concerned with the current standard.

<comment><USER11> The problem is the phrase "the current standard". Is Haskell going to become the new C++? C++11, C++14, C++17, etc? Is it going to live up to the phrase "I love standards. There are so many to choose from."? Is it going to become a python 2.7 vs python 3 vs python 4 game?

I understand the benefit of using the same name as you can trade on the prior mindset. But if old code won't compile then it isn't the same language.

If you're going to change a language with a standard (e.g. Haskell98), change the name. Call it Peyton or something. Otherwise there will be a Haskell20 that is refactored for dependent types that won't compile under Haskell10. Then when people claim to "know haskell" the question becomes ... which language?

The "current standard" game leads into "library hell".

<comment><USER35> I think in theory you are correct: as soon as you have 2 different "versions" of a language, you can, with sufficient creativity, construct a program that will break with the newer version.

How likely this is going to bite you in practice, though, is a different question, and one where the specifics of the language are important.

C++ is a language without a module system; instead, the preprocessor resolves #include directives by textual substitution, which is of course extremely fragile wrt. compatibility, particularly considering idiomatic "header-only libraries" of the boost variety.

Haskell doesn't use #include but has a module system, which avoids a lot of the C++ standard incompatibility issues, because you can compile each module independently with its required language standard.

Also note that there is a pragma you can put into modules to specify the version directly inline, e.g., "{-# LANGUAGE Haskell2010 #-}" or "{-# LANGUAGE Haskell98 #-}" .

</comment></comment></comment></comment></comment></comment><comment><USER37> I have to say, this is a very bad blog post. There are things to critisize in Common Lisp. And of course there is a valid discussion about static vs. dynamic typing. But the author gets a lot wrong and that kills the validity of his criticism. What is left, is a very negative article, which might discourage people to check out Common Lisp, which would be a pity. Even if you do not end out as a permanent Lisp programmer, learning Lisp can teach you a lot about programming.

Before I comment about some aspects of the blog, about my background: I am a professional Lisp programmer, in the recent years I used Common Lisp less (working more with Scheme-style Lisps as they are provided by my work environment), but I have implemented (and sometimes still have to maintain) reasonably sized productive applications in Common Lisp.

The blog starts with the remark that coming back to his code after months took an hour - I consider this quite a reasonable time. You might be lucky and look at a function which can be modified without the consideration for its environment, but often you have to spend quite some time before you can do changes - this has very little to do with the language.

Then the example he basis his blog post on - I think it has several issues, some already pointed out by other posters. Padding should be a required unsigned integer, not a keyword param - if you omit it (it then becomes NIL), the function will error. While current SBCL compilers even warn about the map function is called, older ones don't give a good warning and not a great error message at run time. But the main issue here is: map is the wrong function to use in this context. Map, as he used it, builds up a string from the return results of the functions it calls in the iteration, but this string is not used by the algorithm, because it writes to the string output stream s instead. Directly looping over the characters in s with "loop" would have been the better way to do it here. Interestingly, I don't think I have ever used map in my Lisp programming career so far.

The rest of the post focusses on two things, that Common Lisp doesn't have enough libraries, and static vs. dynamic typing. Funny though, that he praises Python, where the availability of libraries certainly is great, without acknowledging, that Python is way more dynamically typed than Common Lisp. The side comment "Macros are missing, but you can live without macros after all." is hand-wavingly dismissing one of the strongest features of Common Lisp. They should be used with care, but macros are what puts Common Lisp ahead of most other languages - you can, inside your project, make careful adjustments and extensions to the language itself.

So, yes, the amount of libraries has some point, but attacking the one guy, who did most to give all Common Lispers easy access to lots of libraries, for "not writing tests" is not strengthening the argument. And while the Common Lisp community indeed could use more active contributers and more libraries, blog posts like this rather deter people. It would have been more productive to call for contributers. And from my own practical experience: yes libraries are very valueable and sometimes essential to start a project. But once you become a maintainer of production software, they can be also quite a liability, as you depend on a piece of software you don't maintain.

This leaves the critique of the lack of static typing in Common Lisp. First of all, yes, Common Lisp is not a statically typed language. If that is a blocker, use a static typed language, but then don't praise Python. There are many reasons which speak for static typing - and that is also a reason I have added Go to the programming languages I use. A proper static type checker can be quite a help developing. Interestingly in this context, Go uses a very limited type-inferencing, so that usually the type declaration of the function parameters is enough so that you don't have to explicitly type local variables. Which brings us back to what Common Lisp offers, especially SBCL: optional static typing. You can declare the type of any function parameter and the return results of functions. You can declare the type of any local variable. Depending on your "optimize" settings (speed/safety), SBCL will insert the necessary type checks and use the type information in its type inferencing engine, and create type errors, wherever it can detect them. With fully-typed code, SBCL can generate code which matches and occasionally even exceeds the output of gcc. So, Common Lisp has a lot to offer, which the author had not tapped into.

<comment><USER38> > what Common Lisp offers, especially SBCL: optional static typing

Common Lisp offers optionally unsound static typing.

(SBCL doesn't change that, that's why it inserts runtime checks.)

<comment><USER37> I am not sure what you mean by "unsound static typing", care to explain?

SBCL does offer optional static typing as it goes beyond Common Lisp and can perform static type checking across compilation units.

If you have a lisp file like:

      (defun foo (x) (declare (fixnum x)) (* x 2))
      (defun bar () (foo 3.5))

Where bar has a static type error by calling foo with a float value, compiling the file with SBCL will give you the expected static type warning:

      ; file: foo.lisp
      ; in: DEFUN BAR
      ;     (FOO 3.5)
      ;
      ; note: deleting unreachable code
      ;
      ; caught WARNING:
      ;   Asserted type FIXNUM conflicts with derived type
      ;   (VALUES (SINGLE-FLOAT 3.5 3.5) &OPTIONAL).
      ;   See also:
      ;     The SBCL Manual, Node "Handling of Types"

<comment><USER38> A sound type system would have guaranteed that no program execution ever calls your function _foo_ with the wrong type of argument. SBCL doesn't offer any such guarantee.

If some part of your program extracts values from a heterogeneous list and calls _foo_ on one of them, SBCL will not be able to statically guarantee that it is a FIXNUM at runtime. It can't reject the program either, that would require seriously subsetting the language.

<comment><USER37> SBCL will issue a compile warning, that it cannot guarantee that you call the functions only with FIXNUMS.

<comment><USER38> Whoa. Will SBCL emit false-positive warnings all the time when you dare to use lists in a Lisp, or does it at least try _hard_ to infer specialized list types, going above what's expressible using the standard LIST type?

<comment><USER37> No it doesn't emit false positive warnings when using lists. That is FUD. But if a function explicitly requires fixnums, and you pass something of type t, it might warn (depending on the optimize settings).

<comment><USER38> You didn't answer the question if SBCL infers specialized list types. I'll assume the answer is "no".

In that case, _everything_ extracted from a list is _T_ and you'd have to get that warning you mentioned above.

Such warnings would _very likely_ be false-positive, unless Common Lisp programs are buggy as hell most of the time—assuming _that_ would be the real FUD, no? Therefore, the non-FUD conclusion is to expect a high rate of false- positive warnings in typical list-using programs.

TBH, I suspect those false-positive warnings you mentioned aren't bona fide warnings, but some kind optimizer stream-of-consciousness log stream.

<comment><USER37> List elements are of type t, and of course acceptable to pass to all functions which take t as an argument, so no false-positive warnings.

<comment><USER38> Are you saying that the happy path of SBCL static typing—given you _also_ want to use lists, and _also_ not be inundated with spurious warnings—is to declare everything to be of type T?

<comment><USER37> No, I am not. Perhaps you read up a bit about Common Lisp and SBCL before we continue the discussion.

</comment></comment></comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER39> I was introduced to Lisp in my CS320 Programming Languages class and fell in love.

The sad thing is I've never really used it in any "productive" way. Never for a freelance gig, and absolutely never in my job as a web developer. That being said, I have learned to appreciate languages that I don't necessarily use to directly make money.

I've learned a lot of programming concepts from Lisp that will be with me forever. Thinking about problems in a functional way has been beneficial to a lot of my work.

<comment><USER40> You've probably heard of [http://lfe.io/](http://lfe.io/), I imagine

</comment></comment><comment><USER41> > The fact is difficult to argue with, nil is definitely not a character. But > why the heck do I get this? Can you tell?

Look at the stack trace first, what funtion signals that.

</comment><comment><USER42> I think that haskell is fine when your data structures are simple, for example tuples of length < 10\. When you need more general structures, like lists of lists of element of any type, then Lisp is a better fit. For example, I don't know any computer algebra system (cas) designed in Haskell, but have the free CAS Maxima programmed in Lisp.

<comment><USER43> When do you have lists of lists of elements of any type?

What can you even do given such a value?

<comment><USER42> You could use XML data structures in which some of the elements are programs that you can execute (program is data), other are graphic, other are links to more XML data and so on. And your program is able to process that information.

<comment><USER43> Then what you have is not "anything". You have an expression problem:

Either each element has some "handler" that does the right thing for that data type.

Or you have a set of cases that each data can be, and you handle them all.

Neither is just "any type". And static types are very suitable to describe either.

<comment><USER44> The handler being a typeclass in Haskell vs the enumerated cases being pattern matching?

<comment><USER43> A type-class or just a callback type, vs pattern-matching, yeah.

</comment></comment></comment></comment></comment></comment><comment><USER45> Are there anyone can compare Haskell vs Ocaml vs Sml vs Scala vs Nim vs Shen vs Rust?

<comment><USER46> All pretty different languages.

Haskell and OCaml are both functional programming languages (well OCaml has OO support as well) that have a REPL, interpreter, and native code compiler. They have decently sized communities considering that they are mainly academic languages although Haskell is starting to see industry use at some big name companies like Facebook. OCaml is maintained by the French national lab INRIA and is extremely popular at the fintech firm Jane Street. OCaml inspired much of the syntax of F# (.NET functional programming language). Haskell takes functional programming to the extreme and has a lot of academic jargon (Monads) that can turn off beginners. Scala is like OCaml in that it has support for both OO & FP, but it runs on the JVM and you can use Java libraries. I think both Haskell and Scala have excellent concurrency support. I forget which one uses STM. OCaml has been supposed to be getting multi-core functionality for a long time I think. These three languages are all pretty standard business languages that you could build a business out of. The fact that Scala can use the JVM is super super nice as a lot of Haskell and OCaml libraries are not something I would trust in production. FPComplete is a consultancy for helping firms use Haskell commercially.

Nim is a language with Python like syntax that transpiles (or compiles) its source code to C or JavaScript and then uses those compilers to get really fast code and an executable to distribute. It is still pre 1.0, but it has the option to use or not use garbage collection. A pretty cool language. It can be used for fairly high level projects where Python might normally be used, all the way to OS and video game work with some effort. Rust is mainly meant to replace C++ (closer to D than Nim, but they do overlap some). Rust uses the LLVM compiler and is being used at Mozilla. It currently has had a lot of hype for awhile. It is supposed to be a really safe language. The syntax is a mix of imperative, OO, and FP in my opinion. It is quite fast. Lastly Shen is a research language from Mark Tarver (wrote the bipolar lisp programmer essay). Last time I looked it focused on theorem proving and ran on top of another lisp (can't remember, but maybe Racket or Common Lisp). It used to have a pretty odd license, but I think it's been fixed for awhile. It has built in support for prolog functionality like some other lisps which is cool. He also has taken time to write some libraries which let you use Tk for GUI, which is also neat. I wish I had time to check it out.

Lisps are kind of like the ultimate dynamic languages, while Haskell is like the ultimate static language. Lisp has more flexibility, but the Haskell compiler will catch a lot of bugs.

<comment><USER45> Thanks for your detailed explain. I forgot the wonderful D language.

Can you give Some compare on their type system detail? Thanks.

<comment><USER47> D is more like an improved C++ with GC.

The type system is quite similar to C++'s one, just that the language has better support for meta-programming, modules, packages and explicit notion of unsafe code (system in D speak).

Code generation at compile time is done via compile time code execution, templates or plain replacement.

It has a GC, but like all GC enabled systems programming languages, has mechanisms to control its execution, forbid its use in performance critical sections (@nogc attribute) or just manually allocate memory via stack, globals or plain OS calls.

</comment></comment></comment></comment><comment><USER45> What about the Static Lisp : Shen language?

</comment><comment><USER48> _> Lisp and Haskell are arguably the most peculiar languages out there, at least they are from my experience._

Clearly the author has yet to encounter HOtMEfSPRIbNG!

</comment><comment><USER49> Greedily evaluating both Haskell and OCaml for systems development work rn. Haskell seems a lot cleaner, perhaps too purely clean, and OCaml seems to have some rough edges where it can't/doesn't infer types without awkward syntax. Lazy haskell has STM, monads, parallelism, concurrency and a huge community. Greedy OCaml can do impurity and pseudo-procedural code easier but lacks much of what Haskell has. Thoughts?

<comment><USER12> What does "systems development" work quite entail?</comment></comment>


Linux EBPF Off-CPU Flame Graph - <AUTHOR> http://www.brendangregg.com/blog/2016-01-20/ebpf-offcpu-flame-graph.html <comment><USER2> Off-cpu flame graphs are probably my favorite tool for discovering possible optimizations. They can also be created efficiently using SystemTap since you can do pretty much anything in-kernel. In fact, I was able to really narrow in by limiting my set of stack traces to only times when the process had been asleep for longer than some time. We had a network server where the p999 and p9999 latencies would spike up very occasionally (a few minutes out of an hour). Looking at the traces where the process was blocked for a long time pinpointed the exact issue and we were able to fix the problem.

<comment><USER3> Yes, I mentioned SystemTap in the post. SystemTap can not only can do this, but can currently do it better (user & kernel stacks, more than just x86_64, and more than 20 stack frames), and can also do it on older kernels (earlier than 4.1). So if anyone looks at this and wants it now on Linux, their best bet is likely SystemTap, as it can do the in kernel summarization. And it can include user-mode stacks too!

So why is eBPF important? One reason is that it's core kernel, so eventually everyone will have this in their Linux systems.</comment></comment>


Dozens of banks lose millions to cybercriminals' attacks - <AUTHOR> https://blog.kaspersky.com/metel-gcman-carbanak/11236/ <comment><USER2> All of the groups mentioned used spearphishing and 'browser vulnerabilities'. Shouldn't banks be more savvy of these attacks?

It's not a happy thought that the safety of a given bank depends on whether it's call centre staff are running old version of Flash.

</comment><comment><USER3> Dozens=29. Millions=?!

</comment><comment><USER4> Url changed from [http://arstechnica.com/security/2016/02/clever-bank-hack- all...](http://arstechnica.com/security/2016/02/clever-bank-hack-allowed- crooks-to-make-unlimited-atm-withdrawals/), which points to this.</comment>


Defending Against Hackers Took a Back Seat at Yahoo, Insiders Say - <AUTHOR> http://www.nytimes.com/2016/09/29/technology/yahoo-data-breach-hacking.html <comment><USER2> Utter negligence:

"Ms. Mayer also rejected the most basic security measure of all: an automatic reset of all user passwords, a step security experts consider standard after a breach. Employees say the move was rejected by Ms. Mayer's team for fear that even something as simple as a password change would drive Yahoo's shrinking email users to other services."</comment>


What's In Soylent - <AUTHOR> http://robrhinehart.com/?p=424

<comment><USER2> The ingredients list doesn't seem too far off from mass-gainers, especially when combined with milk. E.g.: [http://www.sportsnutritionmarket.com/assets/images/Optimum%2...](http://www.sportsnutritionmarket.com/assets/images/Optimum%20Nutrition/serious- mass-facts.jpg)

</comment><comment><USER3> The whole thing smells of Placebo...

<comment><USER4> So you're volunteering to just drink water for a month? I want to see what happens.

<comment><USER3> Drinking water != drinking a semi-nutricional mix with uncertain (and most possibly bad) long-term implications and fantasising I have superpowers, from super-concentration to curing dandruff and long-term eye diseases in 4/9 days of trying it (while feeling like the "million dollar man")...

I can get by on a power-mix like that for months. Maybe years. Heck, I can get of just Big Mac and Coke, or Beer and Tomatoes for months.

But the medium and long term health effects? I seriously doubt they would be any good, and wouldn't believe any random internet post without a proper study, from a reliable source, with at least 10 people and a control group.

The "cured dandruff, lost weight, increased mental capacity and cured eye- disease"? You can find similar and bolder claims in BS new-age groups touting Orgone, Pyramid Power, Spiruline and what have you. They are a dime-a-dozen.

That this takes the form of "science" (with basic vitamins, proteins and stuff taken into account) doesn't mean much. Much of the perpetual machine etc folklore also take the form of science.

(Not to mention these posts could be the first steps in a viral marketing effort to start selling the thing. Next step: the same mix on sale).

</comment></comment></comment><comment><USER5> Isn't the answer "people"?</comment>


Show HN: 3D shooter in your terminal using raycasting in Awk - <AUTHOR> https://github.com/TheMozg/awk-raycaster <comment><USER2> General greatness aside, I have to say that's the best quality awk code I've seen. Too many people treat writing awk like picking up after your dog - something to get done quickly, when you have to. Which leads to write-only line noise code, which leads to people treating awk like picking up...

<comment><USER3> I used to write a fair amount of AWK code back in the day. It was great for one-liners, but I wrote some more elaborate programs in it too. I treated it seriously, like a real programming language, and it served me well.

My favorite AWK program was probably my LaserJet II code listing program from 1991. I wrote this out of frustration with the terrible default listings I got when I printed source code. The AWK code did a "two-up" printout of source code: two pages of code per page of paper in landscape mode. It used a nice font and drew graphic boxes around the pages. I was in the habit of using separator lines like this in my code:

//\</comment></comment><comment></comment><comment></comment><comment></comment><comment></comment><comment></comment><comment>-

So the program found these and changed them to graphic line separators. It also avoided splitting a function onto two pages if it could - it would leave whitespace at the bottom of a page instead, filled in with a faint dot pattern.

Somewhere I have a printout I made with this program; I was hoping to find it and scan it in to show what it looked like. I know it's here somewhere, but in the meantime the source code will have to do:

[https://github.com/geary/awk/blob/master/LJPII.AWK](https://github.com/geary/awk/blob/master/LJPII.AWK)

Of course, these days I hardly ever print out any code. But back then we printed _everything_.

<comment> david-given Years ago I wrote a compiler (for bytecode) in awk. Ummm... [http://cowlark.com/mercat](http://cowlark.com/mercat), although you'll need to wade through zip files to get at the source. It was 1.6kloc for a fully typed algolish language producing stack-based bytecode.

awk's a lovely little language, and deserves to be better known than it is. Its two big failings are local variable syntax and absence of structured types... and the standard library's a bit mad in places (gsub, sigh). But it's expressive and concise _and_ still readable, and meets its core competency of doing easy text processing beautifully.

The most recent thing I wrote in it was this:

[https://github.com/EtchedPixels/FUZIX/blob/master/Applicatio...](https://github.com/EtchedPixels/FUZIX/blob/master/Applications/util/fforth.c)

That's a C file which is also an executable shell script which contains an embedded awk script. The whole thing's a Forth interpreter. Running the file uses the awk script to compile a Forth subset into bytecode and patch the source file with the new bytecode, which allows me to keep the whole thing in a single source file. It's not what I'd call good awk, but it's incredibly _effective_ awk...

<comment><USER3> That is brilliant!

So the embedded FORTH compiler written in AWK reads the FORTH code in a comment like this:

      //@C SPACES
      // \ n --
      //   BEGIN
      //     DUP 0>
      //   WHILE
      //     SPACE 1-
      //   REPEAT
      //   DROP

and compiles it into C code like this (reformatted here to help illustrate):

      COM(
          spaces_word, codeword, "SPACES", &space_word,
              (void*)&dup_word, (void*)&more0_word,
          (void*)&branch0_word, (void*)(&spaces_word.payload[0] + 8),
              (void*)&space_word, (void*)&sub_one_word,
          (void*)&branch_word, (void*)(&spaces_word.payload[0] + 0),
          (void*)&drop_word,
          (void*)&exit_word
      )

<comment> david-given Yup! COM() is a varargs macro that actually assembles the data in memory --- the actual word layout is not the traditional one Forth uses (to make it C friendly). But the end result is a linked list of Forth words in exactly the same format that user words have, which the user dictionary extends.

It all means that the C source can just be compiled in a single step --- gcc -o fforth fforth.c --- without needing a precompilation stage, which makes it vastly easier to manage.

It's even portable!

</comment></comment></comment></comment><comment><USER4> This could actually be used to build a file explorer, not sure for what, but it would be fun to explore directories this way.

<comment><USER5> "It's an AWK system. I know this."

</comment></comment><comment><USER6> Like a sculpture made out of snot,you can applaud the elegance of the sculpture, and the elegance of the construction, but you have to wonder about the building material...

<comment><USER7> Ah but awk is great! It's parsimony when processing structured text files is hard to beat. Such a pity the next step on from it is perl. Perl is snot certainly.

<comment><USER6> No, the next step from awk is ruby :-D.

Anyways, I was talking about how this thing totally misappropriated awk, not awk itself.

<comment><USER7> In all seriousness, Ruby is Awk's grandchild borne of a virtuous union between Perl and Python.

After looking at the code I'd agree that it's not really idiomatic Awk. But come on, snot? I would've said a humble yet more dignified medium, such as match-sticks.

<comment><USER6> But I'd say that ideologically, ruby is far closer to awk than perl is. And yeah, matchsticks would have been better. I do actually LIKE awk, and will defend it from anybody who says that it is useless or badly designed.

This is your father's awk. An elegant weapon for a more... civilized age. :-)

</comment></comment></comment></comment></comment><comment><USER8> Man, that AWK looks a helluva lot like Javascript.

<comment><USER9> As in Javascript, awk represents all numeric values using double precision floating point. I have always thought that was a strange (but not necessarily bad) choice for a language that is basically all about text processing. I guess it works out pretty well if you need to do 3D graphics math.

There is a bit of cheating going on here though. Awk doesn't support true multidimensional arrays. They are depending on a Gawk extension for that bit of functionality.

<comment><AUTHOR> Actually I tried to do without true multidimensional arrays, but deleting and sorting elements would be a pain.

</comment></comment></comment><comment><USER10> This is beautiful.

I'm reminded of an administration tool I wrote using AWK and ANSI command sequences. It was the most powerful programming language available on the machines available to me for that project. It worked great, but in the end meant that I had to fly back out to that site every time it needed maintenance or new features as nobody else there knew AWK.

<comment><USER11> Depending on whether the flights were stressful or a nice step away from home turf, that might be considered a feature, not a bug. It was a nice bit of job security, in any case.

I also hesitate to say that the site in question deserved to pay for the tickets, since AWK is reasonably easy to learn, even in the case of 4- or 5-digit-SLOC applications.

But if AWK was the most capable system available, that's saying a bit... :p

<comment><USER10> While the job security was nice, I considered it a personal failure as I had made a choice that resulted in less flexibility for personnel allocation for my organization.

The site in question was isolated from the Internet for security reasons. This was ~1994 and I would have had to submit significant paperwork to get permission to use one of the phone lines for a modem.

As I remember it, the site had a hodgepodge of SCO Unix, SunOS, IRIX, and Linux systems. SCO Unix was the least equipped of them. Configuration management had them all stuck at an old version. Perl wasn't even installed on all of the systems. I remember feeling that AWK was a good choice because, being interpreted, it allowed for fast development. Another obvious option would have been C with X for the GUI, but that would have taken much longer to implement.

<comment><USER11> > While the job security was nice, I considered it a personal failure as I had > made a choice that resulted in less flexibility for personnel allocation for > my organization.

Good way to put it, and point conceded (and filed away for future reference in my own life).

> The site in question was isolated from the Internet for security reasons. > This was ~1994 and I would have had to submit significant paperwork to get > permission to use one of the phone lines for a modem.

I figured as much. Usually flying someone out only happens when the core infrastructure is out (and the tiny DSL emergency modem failed _as well_ ), when something's being so annoying/intermittent it has to be poked onsite, or when something's airgapped.

> As I remember it, the site had a hodgepodge of SCO Unix, SunOS, IRIX, and > Linux systems. SCO Unix was the least equipped of them. Configuration > management had them all stuck at an old version. Perl wasn't even installed > on all of the systems.

Ouch, wow. (I'm not sure whether to be more impressed that Linux made an appearance at all only 3 years after entering existence, or that it was apparently stable enough at that point to not be laughed out of the building.)

> I remember feeling that AWK was a good choice because, being interpreted, it > allowed for fast development.

A problem that's still a toss-up for many people :) hah. I'm not even sure what to use half the time...

> Another obvious option would have been C with X for the GUI, but that would > have taken much longer to implement.

Ah, the joys of Xlib. I've poked it briefly but not too much, although I can resonate with the "much longer to implement" part... heh

<comment><USER10> > I'm not sure whether to be more impressed that Linux made an appearance at > all only 3 years after entering existence, or that it was apparently stable > enough at that point to not be laughed out of the building.

I was young and so was Linux. I was the only available Linux guy at that time in that organization. The site was running some experiments for military training simulators, so it wasn't uncommon to use technology that wasn't yet mainstream. If I remember correctly, it was just being used to translate some data from one system and inject it into another.

</comment></comment></comment></comment></comment><comment><USER12> It's amazing what you can do in so few lines of code. If you have the time you ought to do a tutorial on how to make this sort of game, it would be a great read.

<comment><AUTHOR> There is a great tutorial (it's actually a series of them) which I used: [http://lodev.org/cgtutor/raycasting.html](http://lodev.org/cgtutor/raycasting.html)

It's old and C++ but explains raycasting very well.

And there is also a similar project in just 265 JS lines: [http://www.playfuljs.com/a-first-person-engine- in-265-lines/](http://www.playfuljs.com/a-first-person-engine-in-265-lines/)

<comment><USER12> Thanks, I'll check it out.

</comment></comment></comment><comment><USER13> Whose idea was it to have the gun reload slower if you're running away? Deliciously evil.

Anyway, really cool project. Good work!

<comment><USER14> I think that's from the old original operation flashpoint. :-). It's a cool design idea anyway.

</comment></comment><comment><USER15> Needs bash and gawk, bash you can avoid by changing

cmd = "bash -c 'read -n 1 input; echo $input'"

to

cmd = "saved=$(stty -g); stty raw; var=$(dd bs=1 count=1 2>/dev/null); stty \"$saved\"; echo \"$var\""

all credit to izabera from #bash on freenode

<comment><AUTHOR> Finally merged that.

</comment></comment><comment><USER16> This is hilarious. Is there any technical reason it couldn't have been written twenty years ago?

<comment><AUTHOR> I guess 20 years ago CS students weren't told to "write a Doom-like game" as an awk homework =)

<comment><USER17> Well, there were those bored days with a TI-83... _shudders at TI-BASIC_

<comment><USER18> My son spends a ton of his class time programming games into his TI-83. He even built his own Final Fantasy type game (when he really should have been doing classwork). He built a battle system, and even a merchant/vendor for buying upgrades. I had a lot of fun playing his game, and offered him some ideas for improvement (which, again, were made during class time).

And yet, I can't get him to sit down and put any time into programming _on a computer_. Sigh.

<comment><USER6> TI-BASIC is a blessing and a curse. You can get the most non-technical people to write code in it, but if you've had experience in a REAL language, you can't bring yourself to.

</comment></comment></comment></comment></comment><comment><USER19> Having never looked at awk aside from its usage in shell one-liners, that code looks really nice. I might have to go learn awk for a bit.

</comment><comment><USER20> Very cool! And easily modifiable, thanks to readable code as bliti said. Seems well thought/laid out.

</comment><comment><USER21> This is very cool. The code is very readable. I honestly expected a bit of mess. It's easy to follow and managed to learn a bit about awk. Nice job!

</comment><comment><USER22> I was inspired to check out AWK after reading this sentence from the book Masterminds of Programming:

"If I had to choose a word to describe our centering forces in language design, I'd say Kernighan emphasized ease of learning; Weiberger, soundness of implementation; and I, utility. I think AWK has all three of these properties."

</comment><comment><USER23> My go-to-awk-guru-friend and I had fun playing with your game---if you couldn't tell by the PRs ;)

<comment><AUTHOR> Thanks to you and everyone for contribution. Seeing people care about this little project reminds me why I decided to do programming for a living.

As for the PRs, apparently I've slept through all the action =) I'll get back to them as soon as I can.

</comment></comment><comment><USER24> I was wondering how you'd read a key in raw mode in awk. The answer, I found with a mix of horror and admiration is 3 forks. Two stty and one bash (presuming read and echo are builtins)

<comment><USER11> Now it's been updated to use dd, and can run with /bin/sh.

It's sad that languages rise and fall by the feature base present in their standard libraries.

</comment></comment><comment><USER25> Awk is seriously awesome and too often forgotten or underrated.

Ill never forget the day I realized its true power was in shortness of code. I took a one page perl script I couldnt get to work and turned it into a one line awk script that worked.

</comment><comment><USER26> Now I have a new example to show AWK as a language. I usually get into arguments about AWK not being a program.

</comment><comment><USER27> Amazing!

</comment><comment><USER28> that is crazy awesome awk

</comment><comment><USER29> This is amazing.

</comment><comment><USER30> Great work!

PS: You need gawk to run this.

</comment><comment><USER31> Add more dragons</comment>


Show HN: Google BUILD files - <AUTHOR> https://github.com/chrisvana/repobuild

<comment><USER2> Why remake blaze when you could just go without the rules for common operation?</comment>


Defining your product:  Where do you draw the line? - <AUTHOR> http://contrast.ie/blog/where-to-draw-the-line/

<comment><USER2> I like the idea of writing out the steps a user takes to tackle a problem then pick the one or two steps that your product/service and improve upon (or remove altogether).

<comment><USER3> Agreed. I like that this approach forces you to consciously commit to capturing those (and only those) one or two steps in a product.

I also liked the fact that the author uses existing/established players to complement rather than compete with your product by drawing the end line there -- a solid MVP strategy.</comment></comment>


Rules for Dining Out – How a frugal economist finds the perfect lunch (2012) - <AUTHOR> https://www.theatlantic.com/magazine/archive/2012/05/six-rules-for-dining-out/308929/?single_page=true <comment><USER2> >I also start to worry if many women in a restaurant are beautiful in a trendy or stylish way. The point is not that beautiful women have bad taste in food. Instead, the problem is that they will attract a lot of men to the restaurant, whether or not the place serves excellent food. And that allows the restaurant to cut back on the quality of the food.

There are issues this writer has with eating out, that no amount of good food will solve.

<comment><USER3> Hooters isn't in business because of the quality of their food. They pioneered an entire genre of restaurants called "breastaurants" where this is the case - you pay premium prices not for the food but for the boobs.

<comment><USER2> Anything calling itself a 'breastaurant' is just a really crap strip club with a food fetish.

Besides, that isn't really what I was getting at. I don't think it is what the author was getting at either.

What I was trying to get at is that enjoyment of food is highly subjective and this writer says he gets himself worried if he sees pretty women enjoying themselves at the same restaurant he has just entered. He is basically setting himself up for a sequence of self-fulfilling prophecies that start from having an utterly ridiculous set of biases in the first place.

</comment></comment></comment><comment><USER4> This is an aside for European visitors to such sites. If you visit from a non- European country, don't worry. Everything is fine.

If you get a big GDPR "We Value Your Privacy" pop-up with a 'AGREE!' button, well, guess what? They don't value your privacy.

The officially sanctioned way of dealing with this is to re-open the link in a 'private' or 'incognito' tab and click AGREE! This hits two birds with one stone: from the perspective of the analysts of such sites,

a) one person has visited the site and 'bounced', that is to say, left the site, never to return. And: b) one person visited the site, 'agreed' and then never visited again.

I mean, unless you _like_ being tracked. Then, by all means, carry on.

</comment><comment><USER5> I was surprised that the author, given that he is an economist, didn't provide a single piece of data into the discussion.

<comment><USER6> To be fair, this is pretty clearly an opinion piece filled with anecdotes. I'm not sure how much the data would help.

</comment></comment><comment><USER7> It's weird he complains about Thai food being too sweet, because I honestly prefer American Thai over Thai food I had in Thailand because it's less sweet. When I was in Thailand all the Thai food was sweeter and less spicy than Thai food I found in the states. Heck 90% of the restaurants I went to in Thailand had a jar for sprinkling sugar over your food, like you would traditionally do with salt.

Also vietnamese food is sometimes too weird for my palate. I love pho, but can't stomach the congealed pork blood.

<comment><USER8> The sugar on the table is usually for tourists to dampen the spiciness (sugar neutralizes the burning flavor surprisingly well)

And there's a chance they didn't give you "real" Thai food because you're white (just assuming your ethnicity here)

<comment><USER9> That's pretty racist.

<comment><USER10> Why? It makes sense to adapt what you are giving to the ethnicity (= where they likely come from) of the guests.

When I was in Malaysia, I was warned all the time (I am white) and thanks God because the few me I did not listen I suffered.

<comment><USER9> Listen, dude, bro, amigo, compadre, chief, dude ... just because you can't stand spicy food, doesn't mean the rest of those that fall under the category of 'white' can't stand spicy food.

In the realm of formal logic, we call this "hasty generalization".

It's stupid. Don't do it. I mean, for fork's sake, one of the most popular show on YouTube right now is a white dude who eats spicy food with every guest they interview.

Maybe the times you were warned and didn't listen, they decided to fork with you and give you the extra hot ingredients.

<comment><USER10> I suggest you read again my message as apparently you are stuck on your idea of "white people eat spicy food".

I am saying that taking into account the possible differences because someone is from abroad and may have different tastes is a nice thing to do and I appreciate the gesture. But yeah, they probably do not teach this in youtube videos.

Have a good day.

</comment></comment></comment></comment></comment></comment><comment><USER11> So many rules, just to avoid a bad meal once in a while. The author should learn to live a little. Also, if I was ordering the least interesting sounding thing at fancy restaurants, I'd always be ordering a burger.

<comment><USER12> When he got to the bit about too attractive woman I couldn't read on. Seems really strange to me.

<comment><USER6> Seems pretty clear to me:

"When I'm out looking for food, and I come across a restaurant where the patrons are laughing and smiling and appear very sociable, I become wary. Don't get me wrong. Having fun is a fine ambition, but it's not the same thing as eating good food."

But really, it's an opinion. If you don't agree, move on.

</comment></comment></comment><comment><USER13> This article from 2012 reads like a person whose taste you don't trust giving you their 'best tips' on where to eat.

</comment><comment><USER14> >Instead, the problem is that they will attract a lot of men to the restaurant, whether or not the place serves excellent food

Interesting that we can casually stereotype male behavior now. I don't think this author is credible.

<comment><USER3> He didn't say it would attract all men, he said he would attract a lot of men. That's not stereotyping. Strip clubs attract a lot of men, but not all men like strip clubs.

<comment><USER14> Please. The clear implication is that men will be so busy coming to the restaurant and thinking with their dicks that they won't notice the shitty food.

You don't have to accuse an entire group to be guilty of stereotyping.</comment></comment></comment>


The 10 Mistakes I've made...so you don't have to - <AUTHOR> http://www.slideshare.net/missrogue/the-10-mistakes-ive-madeso-you-dont-have-to

<comment><USER2> Wow. Thanks for putting my presentation on Hacker News. I believe this is my first appearance here. :) If you have any questions, feel free to ask! (p.s. thanks Jerome for jumping in! that's why he's an amazing cofounder!)

And point taken re: stock photos, not putting all of the points up front (more for the audiences sake) and using Guy Kawasaki's stuff...

<comment><USER3> I m afraid there are uncountable number of possible mistakes, on top of the ten you have stressed. And all those mistakes usually occur due to sticking to rigid rules rather than trying to be flexible at different stages of business lives, but some occur due tho being flexible rather than having rigid principles.

</comment></comment><comment><USER4> Gems! I just went through this & felt compelled to thank - dropped a note to author.

Very nice presentation with plenty of pictures & amazingly good words of wisdom all through.

One thing that stood out for me is this: "just because your competitors have raised more $$ doesn't mean they will win. (we've watched 10 competitors raise oodles of dough and then shutter or pivot)". (paraphrased it).

</comment><comment><USER5> these are good slides. just realized that buyosphere is the same as pinterest.

one succeeded and one didn't (or maybe hasn't yet?). my first observation about buyosphere is that the name itself drives users away. to the user, it kind of sounds like spam, a site where they have to buy stuff.

and..."pinterest" is resonates better with the user.

so give a choice, i'd probably choose pinterest, even though the two sites you could say are similar.

<comment><USER6> For the record, I'm the CTO and co-founder of Buyosphere.

Yes, for the moment, Buyosphere may at a first glance look a lot like Pinterest. At the moment, the main visible difference is: we focus around products people want or have... and the site is much slower (that will be solved soon). The end goal is to help people discover products they want. Hence the name Buyosphere.

We're working on a nice twist that will be released at the end of the month. It will make our unique value proposition much clearer. Stay tuned!

</comment></comment><comment><USER7> I'd add "know when to quit". Determination by itself is great, but sometimes the right thing to do is to abandon your current startup and work on something else. How do you know when to quit? Unfortunately, there's no formula for that. (My tendency, if anything, is to quit too late.)

<comment><USER8> When is it better to quit then to pivot? Seems like with pivoting you are able to make better use of your experience then if you quit and start something completely new.

<comment><USER7> I can't say in general, but I can share my own experience. I did a YC startup, struggled, quit, and made the Rails Tutorial (which has gone _extremely_ well). There wasn't any way to pivot from the startup to the tutorial; they are completely different kinds of businesses. Among other things, my startup had a cofounder and investors (i.e., YC), whereas the Rails Tutorial is a solo enterprise. Developing an intuition for when to shut things down and move onto something new is an invaluable skill, one I'm only beginning to master.

<comment><USER9> How do you do marketing for Rails Tutorial? is it mostly search organic traffic? paid traffic? word of mouth?

<comment><USER7> Inbound links, organic search, and word-of-mouth are the main methods. I experimented with AdWords, but the conversion rate wasn't good enough, and I was too lazy to try to improve it.

</comment></comment></comment></comment></comment><comment><USER10> "Many of life's failures are people who did not realize how close they were to success when they gave up." - Thomas Edison. I've never seen that quote before but I love it. Great slideshow and thanks for sharing.

</comment><comment><USER11> Would be cool to have this presentation on <http://speakerdeck.com/>

<comment><USER12> Normally I would down-vote such a comment, being that it's all promotion and no contribution...

But I clicked the link and have to say that site is gorgeous. I signed up to give it a try.

<comment><USER11> I'm no where affiliated with the site, I like, like yourself, how clean their service is compared to slideshare.

</comment></comment></comment><comment><USER13> "Stop thinking about the big picture. Start thinking about creating value NOW."

Learned this one the hard way.

</comment><comment><USER12> 69 slides? How long was the presentation?

<comment><USER14> They're all brief. I imagine she flew through them.

</comment></comment><comment><USER15> Excellent presentation, I love the slide with the Gartner-esque magic quadrant!

</comment><comment><USER16> pdfs please.... i loved it.

<comment><USER17> There's a download link at the top of the presentation - though you'll need to log in to do so.

</comment></comment><comment><USER18> Awesome. Like the Venn diagram particularly ;-)

</comment><comment><USER19> I think there is a lot of refreshing stuff going on in this slide deck, thank you for sharing!

</comment><comment><USER20> She obviously didn't get the memo about the 10/20/30 rule of PowerPoint.

<http://blog.guykawasaki.com/2005/12/the_102030_rule.html>

If I had been in a room where she presented this live, I would've fallen asleep in about 5 minutes.

<comment><USER21> To quote from that article:

"this rule is applicable for any presentation to reach agreement"

And that's exactly it. This seemed like a talk people attended because it sounded interesting or insightful (and I found very interesting indeed) and not a pitch.

Especially technical talks (and let's be generous and file it as technical under entrepreneurship, but much more so about programming/etc topics) aren't bad just because of an abundance of slides. To the contrary, I very much appreciate elaborate slides on slideshare/etc so I can get something out of the talk without having attended.

</comment></comment><comment><USER22> I clicked the first 2 or 3 slides, and did not see all ten mistakes listed at once. I am NOT going to click through 60 odd slides to see if it might be worth my time to click through 60 odd slides.

Probably decent advice in here, the comment is more on attracting views. Let me know it's worth it.

<comment><USER23> I really enjoyed the presentation. It's designed more like a paper that's spread across 60 "pages" than a keynote speech, but there's quite a bit of good advice there.

</comment></comment><comment><USER24> Take guts to do that, thanks.

</comment><comment><USER11> Very nice presentation, loved the tables, very helpful

</comment><comment><USER25> Love it! Great words of wisdom.

</comment><comment><USER9> I like the point about how being in covers of tech blogs doesn't mean much. It's all mostly noise, and if one did a study, I bet they'd find the failure rate of startups covered by tech blogs to be around the same as the overall failure rate of the average business. E

<comment><USER26> Confirmation bias.

</comment></comment><comment><USER27> Cofounders need good conflict resolution skills. Sounds pretty obvious, but this is the first piece I've seen that says it outright.

</comment><comment><USER28> Bone - pick:

Please, if you are going to upload a presentation online after giving it, have a version tailored for Slideshare or Speakerdeck.

Please for the love of all that is holy in the world: stop with the meme's, stock photo + funny/ironic text. Getty Images et al have some funny stuff, and if you type "guy frustrated with the world with frizzy hair" you'll likely find something, but it's over-played.

For the most part, presentations work better online as a visual accompaniment to a really well thought out and concise blog post.

With no info graphics please.

<comment><USER29> I would rather speakers upload exactly what they presented, as soon as possible after a presentation, than spend time (and perhaps never actually complete) making a custom version 'tailored for online' or 'reduced to blog post'.

It's great if they want to make other versions, but it's no knock against them for sharing what they've got, in the form they've got it.

TL;DR: Commenters' peeves, in a totally different forum, are not the presenters' problem.</comment></comment>