Grasswire - <AUTHOR> https://grasswire.com/

<comment><USER2> Oh wow, glad I saw the HN bots tweeeting that this was on the front page. (co- founder here).

I'm sure people will be frustrated that there's a login gate. We don't like it either, but we had some members of ISIS come in and try to wreak havoc, and it was hard to follow their IPs, so we started requiring accounts so we could hellban them. Hopefully that's a temporary measure.

We're learning there's lots we still need to fix and improve, but I'd love to hear your comments.

<comment><USER3> Sorry to hear that people have been trying to mess with your site, but why do you require an account just to view the page?

<comment><USER2> Eventually we'll build out multiple states; we didn't have time to do that, so we just threw a gate on the whole damn thing. It's a temporary measure, fixing 10 things at once right now. Had 2,500 unexpected signups today, so things are a little hectic.

<comment><USER3> Fair enough, best of luck getting it all sorted.

</comment></comment></comment></comment><comment><USER4> I swear I had an account on the old site. Or did I log in with Twitter? I forget. Anyway I'm glad I didn't have sit in a hype-building waiting list-- unlike everything else these days--which I was afraid of each time I checked back to see if the site was back in action.

Glad it's back though! Looking great I must say.

<comment><USER5> You probably did have an account :) We decided to deprecate the old accounts when we started rebuilding after our prototype. Hope it wasn't too much of an inconvenience.

</comment></comment><comment><USER6> would love to see some sort of info or demo before having to sign up.

</comment><comment><USER7> [https://news.ycombinator.com/item?id=7954327](https://news.ycombinator.com/item?id=7954327)

<comment><USER2> That was a year ago; was completely different</comment></comment>


JPG Magazine Says Goodbye - <AUTHOR> http://jpgmag.com/blog/2009/01/jpg_magazine_says_goodbye.html <comment><USER2> "The Real Story of JPG Magazine"

<http://powazek.com/posts/534>

<comment><USER3> I guess we knew this day would come. I'm surprised they didn't just decide to sell it back. Perhaps Derek would want to keep running it? They were pioneers in identifying the Flickr/dSLR aesthetic, and there remains a void there in the coming HD dSLR video revolution...

</comment></comment><comment><USER4> I paste from <http://del.icio.us/kragen/jpg>. I'm as happy to see these guys fail as I am to see Bernie Madoff.

2007-06-03

[http://www.flickr.com/groups/jpgmag/discuss/7215760022357183...](http://www.flickr.com/groups/jpgmag/discuss/72157600223571831/)

Clarifications in The Unofficial JPG Magazine Group on Flickr, thread started by Paul Cloutier 2007-05-17

730 words from Paul Cloutier about what happened with the JPG blowup. Still doesn't explain why the first 6 issues are still missing from the issues page, why the official 8020 blog is still full of lies, etc.

tagged: paul-cloutier fraud jpg

2007-05-19

[http://www.flickr.com/groups/jpgmag/discuss/7215760022221027...](http://www.flickr.com/groups/jpgmag/discuss/72157600222210270/)

"context is everything", a discussion thread in The Unofficial JPG Magazine Group, started 2007-05-16

1200 words from Alana, the wife of Paul Cloutier, adding no new information to the scandal over Paul deleting the old JPG issues and rewriting history, but calling Derek Powazek a liar. Derek responds in 650 more words.

tagged fraud paul-cloutier 8020 jpg

2007-05-18

[http://www.8020publishing.com/blog/2007/05/dereks_departur.h...](http://www.8020publishing.com/blog/2007/05/dereks_departur.html)

Derek's Departure, from Paul Cloutier, via 8020 Publishing Blog

200 words subtly announcing his decision to back off on rewriting JPG Magazine's history, without acknowledging that it was his dishonesty that led to Derek's departure or providing an alternate explanation.

tagged decentralization-stories 8020 fraud paul-cloutier jpg

<http://powazek.com/posts/534>

The Real Story of JPG Magazine, from Derek Powazek, 2007-05-14

1500 words on JPG Magazine/8020/Paul Cloutier's new campaign of lying and rewriting history. "People are too smart and well-connected to believe a lie anymore." JPG published nice photos from Flickr etc. on paper.

tagged decentralization-stories communication 8020 fraud paul-cloutier jpg

</comment><comment><USER5> Newsweek feature asked: "Their magazines are full of user-generated content, but will people pay for it?"

<http://www.newsweek.com/id/120355>

I guess not?

I'm also kind of bummed out by this news. These guys were paying ZERO for their content and they still couldn't make it work.

Also, I agree that there's something odd about them not just going web-only + a pay fee for super users. How many people do you need to run that site? 3?

<comment><USER6> > These guys were paying ZERO for their content and they still couldn't make > it work.

Not true. They offered a bounty of $100 and a free subscription for photos and stories selected to be run in the print edition.

</comment></comment><comment><AUTHOR> I did not post this to celebrate another failure (as an entrepreneur, I would never do that). I'm mostly just sad that they're not able to break even and continue. And I wonder why they couldn't drop the print magazine and have their loyal members pay to be part of the community. I have to imagine they would if given the chance.

<comment><USER7> Pingmag ( <http://pingmag.jp/> ), a very popular Japanese design magazine (possibly only online, unsure, but it had a stagg), also stopped publishing just now under similar circumstances.

I think a lot of this is unnecessary. Publications, people, heck _everything_ needs to transition in times like these. Everyone needs to become more agile, more efficient and businesses need to cut things down to the bone. Unfortunately a lot of magazines, professional blogs, whatever, are still paying crazy rates and aren't cutting back.. so more will be going to the wall in 3.. 2.. 1..

<comment><USER7> Ooh, I just wanted to add to this that my last paragraph is _not_ directed at JPG Magazine. Their content sourcing was pretty innovative.

</comment></comment></comment><comment><USER8> This is really bad news for me.

I'm working on starting up a magazine, so I guess I'll be able to learn from everything that went down at JPG magazine. Maybe refine my business model a bit.

</comment><comment><USER9> I wonder what their costs are to keep the site running.</comment>


Profile Likelihood vs. Kriging Variance - <AUTHOR> http://blog.sigopt.com/post/134931028143/sigopt-in-depth-profile-likelihood-vs-kriging <comment><USER2> I am the author of these posts, and I am happy to answer questions if you have any.</comment>


Number 1 Economy in World is Norway's Social Welfare State - <AUTHOR> https://www.impartial-review.com/stories/norway-s-common-sense-welfare-state-versus-u-s-capitalism

<comment><USER2> The Economist doesn't think they are very socialist:

> The idea of lean Nordic government will come as a shock both to French > leftists who dream of socialist Scandinavia and to American conservatives > who fear that Barack Obama is bent on "Swedenisation" ...

> EDIT: (oops this graf was only about Sweden)

> So long as public services work, they do not mind who provides them. Denmark > and Norway allow private firms to run public hospitals. Sweden has a > universal system of school vouchers, with private for-profit schools > competing with public schools. Denmark also has vouchers—but ones that you > can top up. When it comes to choice, Milton Friedman would be more at home > in Stockholm than in Washington, DC.

There's more at [http://www.economist.com/news/leaders/21571136-politicians-b...](http://www.economist.com/news/leaders/21571136-politicians- both-right-and-left-could-learn-nordic-countries-next-supermodel)

</comment><comment><USER3> It probably wouldn't be without the oil. It's disingenuous to compare GDP of oil or mineral rich countries with those of others, because revenues from selling oil is conversion of capital rather than real income. If you measure GDP more accurately as change in assets + consumption, sale of resources adds nothing to the economy. It's like selling your furniture to bring in cash versus having a job.

<comment><USER4> Well, you have to take out resources from any other GDP you compare to.

Oh, and if you really want to be fair, you have to take a "world war 2 wasn't-destroyed" bias out of US and Swiss (and a few other) GDPs.

You can always find excuses, sorry, explanations, about why something is wrong. Just note that the US is resource rich as well - but it lets private hands take all the profits from e.g. oil, and just ignores e.g. rare earth elements.

<comment><USER3> I'm not saying Norway has an unfair advantage or whatever. I'm saying its mathematically wrong to treat oil sales as income the way we do for the GDP calculation. This applies to any country.

</comment></comment></comment><comment><USER5> Norway is a basically the country that won the lottery, wisely invested the winnings and now gets to enjoy early retirement in perpetuity. The UAE is similar: very few UAE citizens actually work in the private sector, and when they do, it's largely a token role.

The ideological arguments are largely moot anyway - you can't have a global economy populated by investor-nations. That would be like SF with all VC's and no startups. =D

<comment><USER6> The _huge_ difference between the UAE and Norway is that in Norway the prosperity is essentially shared by all, whereas in the UAE a tiny, super- privileged citizen elite (11%) and a small cadre of well-paid expats lord it over a vast class of disenfranchised foreign workers in menial jobs.

[http://www.independent.co.uk/voices/commentators/johann- hari...](http://www.independent.co.uk/voices/commentators/johann-hari/the- dark-side-of-dubai-1664368.html)

<comment><USER7> Who does the menial jobs in Norway?

<comment><USER8> Generally, Norwegians. They just get paid decently for them. It makes, for example, going out for dinner a little more costly than North Americans are accustomed to.

<comment><USER9> More than a little, from what I've read.</comment></comment></comment></comment></comment>


UK porn filter blocks League of Legends update - <AUTHOR> http://www.joystiq.com/2014/01/24/uk-porn-filter-blocks-league-of-legends-update-for-sex-in-file/ <comment><USER2> Obligatory link: [http://en.wikipedia.org/wiki/Scunthorpe_problem](http://en.wikipedia.org/wiki/Scunthorpe_problem)

"The Scunthorpe problem occurs when a spam filter or search engine blocks e-mails, forum posts or search results because their text contains a string of letters that are shared with an obscene word. While computers can easily identify strings of text within a document, broad blocking rules may result in false positives, causing innocent phrases to be blocked."

<comment><USER3> Even Google has this problem with some common words. If you type "Nudel", which is German for noodle, into the Google search box, you won't get auto- complete entries presumably because it contains the word "nude". This happens even on the German Google version (?hl=de).

Interestingly, it seems that Bing does a better job of separating "Nudel" and "nude" as it does offer appropriate auto-complete entries. I'm not sure how widespread this problem is and how Google and Bing compare on other search terms, though, since I only randomly stumbled upon this issue while searching for recipes.

<comment><USER4> Strange, did they fix it in 12h? For me "Nudel" autocompletes.

<comment><USER3> Indeed, I checked before posting my previous comment to verify that autocomplete for "Nudel" was still broken but it's fixed now, at least on the English version. If you go to google.com/?hl=de to force the German version then it's still broken.

Another autocomplete curiosity I found: "Mädchen", German for "girl", is blocked on the German version of Google while it autocompletes on the English version (not sure if this was just changed along with "Nudel" or not) even though the English equivalent is blocked on neither Google language version.

</comment></comment></comment></comment><comment><USER5> PCPro and Wired suggest otherwise.

[0] [http://www.pcpro.co.uk/news/security/386665/league-of- legend...](http://www.pcpro.co.uk/news/security/386665/league-of-legends-game- update-not-blocked-by-isp-filters) [1] [http://www.wired.co.uk/news/archive/2014-01/21/league-of- leg...](http://www.wired.co.uk/news/archive/2014-01/21/league-of-legends-porn- filter-block)

<comment><USER6> Sigh. I had to read half the page before I saw this. Can we get this to the top?

</comment></comment><comment><USER7> I love incompetent filtering like this, it irritates those who might not otherwise care. It would be nice to see it commonplace and socially acceptable to disable the filters purely because of how rubbish they are.

<comment><USER8> On the flipside, overfiltering that begets controversy like this tells the PTB what people care about. Better to ask forgiveness than permission, so sayeth the sociopath, and hey, any information on undesirables is gravy.

</comment></comment><comment><USER9> This reminds me of the early days of parental web control products like Net Nanny. I remember being frustrated that www.titanicmovie.com was blocked and asking my brother why. And then I learned what tits referred to :)

<comment><USER10> And then Kate Winslet showed you a pair!

<comment><USER11> Relevant username.

</comment></comment></comment><comment><USER12> Yeah, not so smart. A quick look at blekko's crawl data says that about 1/2 of the urls matching /sex/i are not objectionable, assuming you don't mind your kids seeing something labeled 'sexy'. A pretty crappy filter.

Here are 10 random urls that have /sex/i in them: 2 overblocks, 1 news article about sex offenders, 4 urls that mention "sexy", and 3 sex sites.

      https://www.arcadiapublishing.com/news/3322/essex-history-revealed-through-photographs
      http://trace.tv/en/urban/video/1345_top_sexy_boys_rihanna_s_special
      http://nutrius.tumblr.com/post/33689144704/sextafoil
      http://www.tribunetimes.com/article/20121016/NEWS/310160041/Treatment-being-sought-juvenile-sex-offenders
      http://sexypornocams.com/
      http://macys.tumblr.com/post/34356483165/spotted-and-sexy-a-leopard-eye-makes-for-the
      http://www.platinumsexpass.com/
      http://520sex.530video.info/
      http://bocadelrio.olx.com.mx/sexo-masculino-limpieza-para-restaurante-en-veracruz-iid-373475442
      http://www.waycoolgadgets.com/sexy-tron-costume/

</comment><comment><USER13> I assume all things Essex are likewise unreachable.

(The implication of my comment being that the filtering mechanism is not limited to being that dumb; the stupidity in the particular (as opposed to the general) may be laid at the feet of incompetent management.

In the general, the incompetence -- and maliciousness -- has already been rightly laid at the feet of governent as well as its subornation to vested and entrenched private interests.)

</comment><comment><USER14> Well, that's one way to encourage people to turn off an idiotic filter. Hopefully more game updates / media will add random "expertsexchange"-like URLs.

</comment><comment><USER15> This is complete incompetence. I am opposed to filtering at all, but if they are going to do it there are much more effective ways to do it that aren't very complicated, and if they don't want to do it themselves there are companies that do this.

Spam filtering has been extremely successful with just taking keywords that are commonly found or not found in spam and updating the probability that it is or is not spam. A single word isn't enough to indicate that something is porn, especially a common one like "sex", especially if it was found in a string of characters rather than an individual word.

</comment><comment><USER16> I like this. Companies should use filenames containing banned words in protest.

</comment><comment><USER17> From the perspective of the filter is it working like intended. The word sex is in there, if any character can be used as a whitespace. They limit the such characters, but then you would use dirty words with underscores or punctuators, which would get through. Therefore such filter for words in useless and impossible to make accurate enough.

</comment><comment><USER18> This is not the first time ISP deep package inspection cause trouble for League of Legends. A Swedish ISP identified league of legends game traffic as bittorrent and created an unplayable state for about 3 months.

Of course, world of warcraft has had no such issues. There are too many users and too much money, and so bugs get fixed on Saturday night if needed. Others have to just hope the bug gets fixed before the company losses too much money and too many customers.

I would like to see net neutrality laws could impose some liability for ISP who interfere with their customers traffic. It would self correct much of today problems, while still not outlaw filters, DPI and QoS as a technical solution.

<comment><USER19> I didn't hear about the Swedish ISP news, but League of Legends actually does have a bit torrent client installed with it (Pando Media Booster), and I believe League of Legends has much larger user base and similar if not larger profits than WoW.

I think that problem had more to do with Riot being based in North America.

</comment></comment><comment><USER20> There's no "UK Porn Filter". Please stop believing this.

<comment><USER21> We all know that there are various filters, different for each ISP, which exist because the government pressured them in to it. Generically and collectively we are all oh so terribly lazy and refer to them as a UK porn filter.

Please stop believing that we are stupid enough to take that short hand as literal.

<comment><USER22> I've read many posts from people who think that the government controls the filter and controls what is on the filter and that the filter is mandatory.

It's important to correct that misinterpretation.

</comment></comment></comment><comment><USER23> Computer game playing is inherently pornographic!!

Haven't folks cottoned on to the relationship between the term 'joystick' and the location of the male sex organ, as well as the attendant and persistently vigorous manipulations of said levers?

Both the PC industries, ie the Political Correctness and Personal Computer industries need to come up with a less offensive term, before the whole terminology degenerates into farce.

</comment><comment><USER24> This seems like bollocks because I'm on one of the "big four" ISPs and I can quite happily request anything I like other than a few sites listed here:

[http://help.sky.com/security/privacy/our-approach-to- protect...](http://help.sky.com/security/privacy/our-approach-to-protecting- copyright)

All of these can be trivially accessed by proxy sites.

<comment><USER25> Your filter is not enabled.

The sites listed in the URL you mention are blocked by CleanFeed, the censorship mechanism developed to block child porn and repurposed by the courts for commercial protection. CleanFeed can't be disabled with a phone call to your ISP.

<comment><USER24> Well I haven't disabled any filters, haven't been asked about filters and I'm a new customer as of last week.

</comment></comment></comment><comment><USER26> just one more reason to play DoTA 2 instead

</comment><comment><USER27> Well, now we do have a problem.

</comment><comment><USER28> I totally get all the snarky comments and dislike for the porn filter but as a father of a 11-year-old girl who surfs the web I am 100% behind the idea of regulating material that is not suitable for kids. The current filter may or may not work but the idea is sound and I'd like to think that the politicians who are putting the filter into place are doing so for the right reasons, i.e. to protect innocent eyes.

<comment><USER29> She's probably not as innocent as you'd like to believe, and she's probably tougher than you give her credit for. She also has a basic human right to access information.

Please try to see that restricting information when someone is young deforms their worldview for the rest of their life. We as parents hope that the deformation is a positive one, but this isn't necessarily so. We're biased into thinking we've made positive choices for our children regardless of any evidence to the contrary. The bias is hardwired, and unless we take conscious steps to evaluate whether our behavior makes sense then it's easy to get swept up in a "think of the children" argument.

<comment><USER28> Totally agree with you but I'm sure you'd agree that watching porn is not something that a 11-year-old should be doing? She is more or less free to browse what she wants, she reads Wikipedia articles, reads the news etc etc but I can't see how viewing porn would be good for her worldview?

<comment><USER30> If she is actively seeking it out, there really are no technical solutions that you can use to stop her (short of taking all electronics from her). She'll find a way around any filter. If that is the sort of situation that you're in, sitting down with her and having a talk is really the only workable solution.

If the concern is _accidentally_ viewing porn... well, I have a few thoughts on that:

1) How often does that actually happen? My office does not have content filters on the internet, yet I have never accidentally viewed porn at work. I can't actually remember the last time I accidentally viewed porn at work. I strongly suspect that 95% of the "accident" cases are excuses that people make when they get caught.

2) If the concern is popups and she won't stop going to shady sites that have porn popups, use adblock. Problem solved. Also, tell her not to go to those sites, before you get the UK equivalent of a DMCA notice from your ISP...

3) Accidentally viewing a few naked people in popups is probably not going to damage her worldview. Would it be _good_ for it? No. But I don't think it will cause any damage either.

<comment><USER31> It's the same logic as with DRM: it won't prevent anybody from doing what they want, but it will stop a significant part of them.

Right now websites have no way not to deliver inappropriate contents. The best they can do is to ask "are you 18+?" (see for instance Reddit), which a 3 years old could bypass.

A basic protection against accidental view and/or kids a bit too curious could be as simple as:

A) Have the adult sites to insert a HTTP header marking them as such. They have no reason from doing it, plus not delivering porn to kids is a legal requirement in most countries (or I guess so). This is a flexible solution for sites with mixed contents such as Reddit, because the mark is per-page.

B) Have browsers not to show these sites if the 'adult content' is not ticked in the user profile.

C) Make a tutorial that explains how to create restricted user profiles on their computers (so they can prevent their kids from using browsers that don't support this policy).

Alternatively, but it would impact too much websites I guess, is to use a "safe for kids" header and have browsers to only show such sites etc.</comment></comment></comment></comment></comment>


Is it useful to have a college degree? - <AUTHOR> http://www.smashcompany.com/business/is-it-useful-to-have-a-college-degree <comment><USER2> no</comment>


Mocl – a Common Lisp implementation for mobile platforms - <AUTHOR> http://wukix.com/mocl?hn <comment><USER2> At 200 bucks a license there isn't going to be more than a couple people who are ready to answer stack overflow questions about this, there isn't going to be a good plugin to most IDEs, the tooling support is going to be poor in general and there is going to be libraries for approximately nothing (yes I know, it takes a lot less time to write them in Lisp, but it still means you need to dive into the Oauth spec to work with Twitter, whereas I can just download a library for Java that _works_ ).

I say this as a huge fan of Lisp and there was a time where it made sense to buy a commercial compiler - that time has passed, because when you buy a compiler and a new language you are also buying into an ecosystem, and the more people that are in that ecosystem the better for you.

I can see maybe using Lisp to do some special parts of the program, but even then there is Chicken Scheme which is free and already have a bunch of eggs (extensions), oh and it compiles to C too.

<comment><USER3> It's funny to me that people will happily spend $40 for a t-shirt, $100+ for a pair of shoes, $300 for an ounce of weed -- but ask them for $200 for a professional development tool and they won't budge.

I for one, think the price tag is reasonable.

<comment><USER4> The thing is that it's easier to predict the personal value of a real-world item. You don't know in advance whether you're going to get $200 of value out of a particular development product, because there's no reasonable standard of comparison.

You would pay $40 for a T-shirt if it were some sort of collector's item you could resell. You would pay $100 for running shoes because that's less than $15000 for knee surgery, and you like having comfy feet. You would pay $150–300 for an ounce of weed because you know what weed is like, and you like it, and the price is driven up by legal issues. But what justification can you come up with for spending $200 on what is essentially a productivity tool, if it won't necessarily make _you_ more productive?

<comment><USER3> The same justification I use for buying books on programming: I am trying to make myself a better programmer and I'm willing to take a gamble on myself.

But book stores, unlike the company that produces mocl, won't give my money back if I find that the book didn't help me within the first 30 days.

So in this case, it's even a relatively safe gamble (assuming of course, that the company does in fact, honor the 30-day money-back thing).

<comment><USER5> Well it depends on the book store really. For example Barnes and Noble lets you return books up to 2 weeks after purchase. Amazon allows you to return kindle ebooks, but I'm not sure of their policy on physical books. And of course you could always go to your local library and see if the book is available there.

</comment></comment></comment></comment></comment><comment><USER6> Sounds like a cool project. But really, no documentation, no sample code, not even a whitepaper? Just a Buy Now button?

It probably isn't, but it sounds like a scam. Better put out some actual code to show that this is for real.

<comment><USER7> Hey, mocl creator here. I apologize for the minimal website. We are building it out as quickly as we can. Bit hectic with a fixed release date we were trying to meet (and did meet).

It is real, though. I gave a talk about it at ECLM 2013 [http://weitz.de/eclm2013/](http://weitz.de/eclm2013/).

<comment><USER8> Then why even release it? You're releasing a new "coding method" for mobile platforms with no documentation, no sample code, no example applications, no benchmark backups.

Nobody is going to hand over $200 without at least some of those items listed above. So it just seems a bit strange to even want to release it.

I'm just saying you should slow down a little bit, take a look at [http://www.rubymotion.com/](http://www.rubymotion.com/) for example. It's the same sort of thing, Ruby for iOS. They provide both examples, publicly available documentation, they even have a way to try it out yourself and see what it looks like.

<comment><USER7> For what it's worth I just put up some code so you can see better how it works.

<comment><USER9> So, you write the UI code in Java for Android and Objective-C for iOS, then there is some build process for both platforms?

This seems a little awkward. A sample project setup to build for both platforms would be useful to see.

For some types of applications, the native UI boilerplate would probably be minimal, but for apps with complex UIs, this might add a lot of dev overhead.

Don't get me wrong though, this looks cool!!

</comment></comment></comment></comment></comment><comment><USER10> This is exactly what I am looking for and I would probably buy it if I had some reassurance that it would actually work. Where is the docs? The sample code? Proof of concept apps that can be downloaded from app stores? Fine print for what is allowed in the different licenses?

<comment><USER7> Documentation, and a little bit of sample code is included in the download. The license agreement is viewable at [http://wukix.com/mocl-license- agreement](http://wukix.com/mocl-license-agreement).

<comment><USER10> With fine print I meant answer to questions like "what do I get in a commercial license that I do not get in a personal license?" as it is written it could mean that with a personal license you are not allowed to earn money from apps, or it could mean that it would only cover a single developer (then how many developers do I get for the commercial license?)

Also by actually reading that license it seems to contradict what you promise elsewhere, it says: "All fees shall be non-refundable".

<comment><USER7> Personal just means you are buying it with your own funds and not being reimbursed by a company. You are free to make paid apps with it. I'll work on language to clarify.

Thanks for pointing out the contradiction there. We may be going above and beyond what is required of us by the license, in the case of refunds. But we'll still do so.

</comment></comment></comment></comment><comment><USER11> Seems to me like LISP might defend itself as a mobile language through relative ease of GPU integration, given the parallelization possible through OpenCL/CUDA, the difficulties of using them with traditional languages, the mobile platforms' challenge of electrical power consumption, and the limits of CPU-based processing.

</comment><comment><USER12> A little bit expensive and with no trial (no, I don't want to buy something to return it later).

<comment><AUTHOR> It's actually cheap for a production ready(if it is) commercial cl implementation, but I agree, a trial version is essential.

<comment><USER5> However, note that most commercial lisp implementations, such as LispWorks, Allegro CL each have a free (gratis, not libre), albeit limited, personal/noncommercial edition as well as evaluation and trial licenses for their other versions.

</comment></comment></comment><comment><USER13> Nice, and congrats to the wukix Team for their effort. However, will Apple accept those apps in it's store? There was this guy who wrote a game in Gambit Scheme (iirc) and was rejected back then. This seems to be the same process here (generate C code from Lisp and glue it toether with GUI code), just with CL.

<comment><USER14> Apple no longer cares what language you use, as long as new code isn't downloaded to distributed apps after installation. So it's okay to use CL as long as there is no facility for interpretation of CL downloaded from the net.

</comment></comment><comment><USER15> I'm very happy about mocl's release. Great work, and congratulations!

</comment><comment><USER16> Clojure on Android: [https://www.youtube.com/watch?v=1NptqU3bqZE](https://www.youtube.com/watch?v=1NptqU3bqZE)

<comment><USER17> You do realize that Clojure is not Common Lisp ?

That being said, the linked video is from 2011 (published in 2013, but from 2011).

<comment><USER18> Clojure isn't Common Lisp, but it's A Lisp, and a pretty decent one...

<comment><USER19> Clojure is incompatible with any other Lisp...

<comment><USER18> So? Is Scheme compatible with Common Lisp?

Clojure can run on any platform the JVM can (so basically anywhere except iOS). Clojurescript can run anywhere Javascript does (so everywhere). It's a practical, immediately useful language, that's seen significant uptake and activity.

I like Common Lisp, but it's much easier to build useful apps in Clojure.

<comment><USER19> > I like Common Lisp, but it's much easier to build useful apps in Clojure.

Unlikely.

</comment></comment></comment></comment></comment></comment><comment><USER20> From language implementer perspective your ECLM slides are lame.

Is this ECL re-packaged you charge > $ 200 for without even giving a trial whatever? :-)

</comment><comment><USER21> could you only put a gist with the code of a hello world application ?

Like AppDelegate and a label with hello world in it ?

</comment><comment><USER9> Looks very interesting!

Some blog articles showing development of sample applications would also be nice :-)

</comment><comment><USER22> So is this based on an existing CL implementation, or a totally greenfield project?

<comment><USER23> It compiles to C; there is no JIT/bytecode/interpreter. It may be created from scratch.

[http://wukix.com/dist/mocl_eclm2013.pdf](http://wukix.com/dist/mocl_eclm2013.pdf)

</comment></comment><comment><USER24> Is this same as Gambit-c or Chicken scheme, but for CL?

<comment><USER17> If what you ask is if mocl compiles to C first (like Chicken and Gambit), than yes. It is the same.

</comment></comment><comment><USER25> interesting

</comment><comment><USER26> I'm going to assume a few things here...

\- No one has ever used this. \- It is filled with bugs and has no full time developers supporting it. \- It is extremely limited. \- The benchmarks are completely false.

I'd buy something like this if it didn't look like a good rich scheme.</comment>


What we didn't get: Science fiction and science history - <AUTHOR> http://noahpinionblog.blogspot.com/2017/09/what-we-didnt-get.html <comment><USER2> Seems to hype 1990s SF while dissing 1950s SF more than I think is appropriate.

"Artificial intelligences trade stocks"

That use in SF dates from at least Cordwainer Smith's "Norstrilia" (1975), and likely "The Planet Buyer" (1964). In Norstrilia, the AI in a war computer - economics is a part of warfare - makes the main character the richest person in history. Overnight. By leveraging the futures market.

"A meme virus almost as crazy as the one in Snow Crash swept an insane man to the presidency of the United State"

How about this earlier meme virus: Heinlein's "If This Goes On—" (1940) concerns a televangelist named Nehemiah Scudder who rides a populist, racist wave of support to the Presidency in 2012, then becomes dictator.

(I'm pretty certain the idea comes from Sinclair Lewis' "It Can't Happen Here", which Wikipedia summarizes as "Berzelius "Buzz" Windrip, a politician who defeats Franklin Delano Roosevelt (FDR) and is elected President of the United States, after fomenting fear and promising drastic economic and social reforms while promoting a return to patriotism and "traditional" values. After his election, Windrip takes complete control of the government and imposes a plutocratic/totalitarian rule ..")

"artificial pop stars"

Like the Monkees?

"The early industrial age saw sci-fi writers predict many inventions that would eventually become reality from air and space travel to submarines, tanks, television, helicopters, videoconferencing, X-rays, radar, robots, and even the atom bomb"

Okay, that's overly generous. A submarine was used in the US war for independence, and the word "helicopter" was coined in 1861, while the first working steam-powered helicopter was in 1878. What, by the way, is a robot? Are clock tower automatons "robots"?

[https://en.wikipedia.org/wiki/History_of_videotelephony](https://en.wikipedia.org/wiki/History_of_videotelephony) says "The concept of videotelephony was first popularized in the late 1870s in both the United States and Europe."

"And their social predictions were pretty accurate, too"

Oh? To really judge this I'll need to know what counts as early industrial age SF. Verne didn't really make predictions.

"they anticipated consumer societies and high-tech large-scale warfare."

What is the prediction? They lived in a consumer society with high-tech large- scale warfare. Look at the US Civil War for an example. Overnight wooden warships became worthless.

"Most famously, the mid-20th century was full of visions of starships, interplanetary exploration and colonization, android servitors and flying cars, planet-busting laser cannons, energy too cheap to meter."

Yes, they were. So was the pre-war SF. Starships and interplanetary exploration? "The Skylark of Space" (1928). Also in the same publication of Amazing Stories? Armageddon 2419 A.D., with the character who became Buck Rogers.

Interplanetary colonization? "Last and First Men" (1930) The Fifth Men colonize Venus and the Eighth Men Neptune. And the android in Metropolis (1927).

"Why didn't we get the Star Trek future, or the Jetsons future, or the Asimov future?"

Or the Buck Rogers future? Or the Flash Gordon future?

I'm hard pressed to think of a pre-pulp author who really set stories in a near-term future.

"uranium is a horrible deadly poison"

Umm, not true. Quoting [http://web.ead.anl.gov/uranium/guide/ucompound/health/index....](http://web.ead.anl.gov/uranium/guide/ucompound/health/index.cfm) : "Once in the bloodstream, the uranium compounds are filtered by the kidneys, where they can cause damage to the kidney cells. Very high uranium intakes (ranging from about 50 to 150 mg depending on the individual) can cause acute kidney failure and death. At lower intake levels (around 25 to 40 mg), damage can be detected by the presence of protein and dead cells in the urine, but there are no other symptoms. Also, at lower intake levels, the kidney repairs itself over a period of several weeks after the uranium exposure has stopped. "

"pocket laser cannon"

Buck Rogers called it a raygun, back in the 1930s.

"Starting in the mid to late 1990s, until maybe around 2010, sci-fi once again embraced some very far-out future stuff ..."

I think there's a bias error. The far-out future stuff of the 1970s, like "The Shockwave Rider", no longer seems that far-out. ("The hero is a survivor in a hypothetical world of quickly changing identities, fashions and lifestyles, where individuals are still controlled and oppressed by a powerful and secretive state apparatus. His highly developed computer skills enable him to use any public telephone to punch in a new identity, thus reinventing himself, within hours.")

As for pre-cyberpunk examples of "Strong (self-improving) AI, artificial general intelligence" \- Heinlein's "The Moon Is a Harsh Mistress" (1966) and D. F. Jones' "Colossus" (1966).

I think the argument is reasonable. We no longer have amazing stories about exploring the jungles of Venus because we know what Venus is like. But I really don't like the examples.</comment>


Open source template for building static web sites with Prismic.io and AWS S3 - <AUTHOR> http://futurice.com/blog/cms-done-right-vol-3 <comment><USER2> Thinking of moving a static site to S3 + CloudFront + AWS Certificate Manager with the purpose of enabling HTTPS for the site. Seems like CloudFront does not support index document even if you've enabled it on S3 ([https://tiffanybbrown.com/2016/01/aws-certificate- manager-s3...](https://tiffanybbrown.com/2016/01/aws-certificate- manager-s3-cloudfront-urls/index.html)). You can't have URL such as [https://example.com/about/](https://example.com/about/). Instead need to specifically use URL [https://example.com/about/index.html](https://example.com/about/index.html).

Will look into Netlify and Aerobatic next. Are there other PaaS/SaaS that makes it easy to host HTTPS static site generated from Jekyll/Hugo?

<comment><USER3> I'm using index document paths on S3 + CloudFront right now, it's definitely possible. Unfortunately, I don't remember exactly what I did to make it work. Some more Googling might give you the answer.

Edit: the setting is called "Default Root Object" when setting up a CloudFront distribution with an S3 origin.

<comment><USER4> Does that setting apply to any subdirectory? The article linked in a comment above states otherwise.

<comment><USER5> > Does that setting apply to any subdirectory? The article linked in a comment > above states otherwise.

No, unfortunately it doesn't.

One workaround that I use is to upload files without an extension and explicitly set their content type as `text/html` in S3. So a request to `/about` just serves a file in your S3 bucket called `about`. This works with both CloudFront and S3.

I wrote about a few more details of the process here: [https://brandur.org/fragments/aws-static-hosting- workaround](https://brandur.org/fragments/aws-static-hosting-workaround)

</comment></comment></comment></comment><comment><USER6> What we do is create a static site using Jekyll (or any other SSG) and then add teletext.io on top for content management. Then host it in S3 or GitHub pages.

See: [https://medium.com/teletext-io-blog/empower-your-static- gene...](https://medium.com/teletext-io-blog/empower-your-static-generated- jekyll-site-with-instant-content-management- capabilities-82ce5569d7fb#.pod52hcoo)

<comment><USER7> I like the simplicity of just using a static site setup with a SSG, nice!

</comment></comment><comment><USER8> Seems pretty cool. I host several static web sites on S3 and am pretty happy with the results. I am presuming that this toolset will make collaboration and organisation of said sites much better.

Question - How well does it work if the S3 website is linked to a CloudFront CDN? Does it take care of asset versioning or URL invalidations when updates are done? That is by far the most tedious part of S3 Web + CloudFront for me. I just invalidate the whole site from top down whenever I make changes just to make sure I don't miss anything, but a more automated, granular approach would be better, and I am hoping that Prismic can assist?

</comment><comment><USER9> Here is a _very_ quickstart tutorial to test prismic.io [https://prismic.io/quickstart](https://prismic.io/quickstart)

Don't hesitate to ask questions!

<comment><USER10> ^ co-creator of the Play! Framework

disclaimer: no affiliation with Prismic.io

...and Play is really quite awesome, thanks Guillaume and Sadache! Thanks for the open bar you guys sponsored after Scala.io Paris conference as well ;-)

</comment></comment><comment><USER11> This is a pretty nice setup for those who aren't technical or couldn't be expected to setup a local environment to test in.

I used to work in IT at a place with used this GOD-AWFUL CMS that did this similarly but was written in apparently jQuery-plugin-hell and ASP.NET Forms. The website to edit was slow (many seconds per page. In page JS actions took many seconds) and required manual deploys.

Code could not be edited outside the browser editors (PHP, JS, etc.)

So a system that publishes a static site on S3 fairly easily seems like a win to me.

</comment><comment><USER12> Oh man, this is clever. Out of curiosity, can Prismic's content editor be made to work with a secondary CMS like WordPress or Drupal without a lot of trouble?

One of the problems I've run into as a writer is that … well, nearly every copy editing tool out there sucks, and the ones that didn't (Poetica, Editorially) inevitably don't have a business model and get bought out.

</comment><comment><USER13> What's the advantage of S3+CDN over plain GitHub Pages?

<comment><USER14> HTTPS for custom domains is why I didn't go with GitHub Pages.</comment></comment>


In Search of the Perfect JavaScript Framework - <AUTHOR> https://dev.opera.com/articles/perfect-javascript-framework

<comment><USER2> Disclaimer: I'm the author of Mithril.js (one of said Javascript frameworks)

Honestly I didn't find this article very good. For example, it says things like "RequireJS is one of the popular instruments for resolving dependencies... AngularJS goes a little bit further by giving us something called factory", which show some bias towards Angular, when in reality RequireJS is quite a bit more sophisticated (it allows you to bundle things offline and have async modules, for example), whereas Angular is just an IoCC (and the magic shorthand syntax is actually not recommended for production).

Also disagree with this to a certain extent: "I like the idea of turning features off and on." Being able to turn things _off_ is a bad default. Imagine joining a new team, and you write some code and it blows up because their underscore is actually not underscore but a shim missing half of the functionality.

Also disagree with "The popular two-way data binding should not be a feature, but a must-have core functionality." Two-way data binding is expensive (and can get prohibitively so in a sufficiently complex page). There's a reason Angular people recommend not going over 2000 bindings on a page, and ironically out-of-the-box data binding solutions tend to completely ignore things like the event delegation model, which is a powerful performance tool (I wrote about it here [http://lhorie.github.io/mithril-blog/asymmetrical- data-bindi...](http://lhorie.github.io/mithril-blog/asymmetrical-data- bindings.html) ).

In general, I feel his experience with templating engines comes across as a bit shallow. For example, "The framework of the future should make us think only about the data and only about the markup. Nothing in between." This is idealistic. In reality people have deadlines and there's a large ecosystem of libraries that you simply can't ignore.</comment>


Hacker News London Meetup Videos - September 2011 - <AUTHOR> http://vimeo.com/album/1724096

<comment><USER2> Great work Chris. It's cool to be able to watch it all back. It was a well produced event.

</comment><comment><USER3> Awesome, thanks Chris

Are there videos of the other presenters anywhere?

</comment><comment><USER4> Thanks for putting these together, Chris. This was a lot of fun.

<comment><AUTHOR> Not a problem! Sorry it took so damn long. Next time we aim to have them shot in HD and a faster pull through. A budget would be a nice incentive ;)

</comment></comment><comment><USER5> Great stuff - thanks Chris!</comment>


Inheritance Often Doesn't Make Sense - <AUTHOR> https://www.sicpers.info/2018/03/why-inheritance-never-made-any-sense/ <comment><USER2> A couple of other comments have argued that "ontological inheritance" and "abstract data type inheritance" are actually the same thing:

 _> This is because Squares are Liskov substitutable for Rectangles... which is because Squares are, platonically, a kind of Rectangle._

 _> If the type system is sound and expressive enough, ontological inheritance ( this thing is a specific variety of that thing) and abstract data type inheritance (this thing behaves in all the ways that thing does and has this behaviour) should be essentially the same thing._

The difference is that ontology exists in the mind of the programmer, but Liskov substitutability is a property of the program itself. No matter how you model it, a Square is "platonically a kind of" Rectangle. But in order for them to be Liskov substitutable, you have to model them in compatible ways. If my Square class only has a sideLength method, I can't substitute it for a Rectangle.

This simple example may seem silly, but as models get more complex, it becomes harder to make them compatible, even if one modeled class of objects seems like "platonically a kind of" another class. You see this kind of thing all the time in real-world systems. For example, in a UI system, an "OpenGL View" is conceptually a kind of "View", and this relationship is modeled by making OpenGLView a subclass of View. Normal 2D drawing doesn't work in this kind of view, however, so it's not Liskov substitutable.

<comment><USER3> Yes! The thing that ends up breaking in the squares and rectangles examples is mutability. Remember that math things are immutable by default. This thing is a square, and by definition also a rectangle, and since its properties and identity are immutable, that will always be true.

However, programming takes those immutable concepts and tends to make them mutable. So now we have a rectangle, and we can change its identity by, say, scaling its width. And it's obvious that scaling just the width of a square will make it no longer a square. So now a square cannot support the same operations that a rectangle can. So now a square is no longer Liskov- substitutable for a rectangle.

<comment><USER4> Perfect! This is the covariant/contravariant/invariant distinction, right?

"Read-only data types (sources) can be covariant; write-only data types (sinks) can be contravariant. Mutable data types which act as both sources and sinks should be invariant." from [https://en.wikipedia.org/wiki/Covariance_and_contravariance_...](https://en.wikipedia.org/wiki/Covariance_and_contravariance_\(computer_science\))

<comment><USER3> Absolutely, and that's another excellent way to explain the problem and come to the same conclusion. The mathematical relationship between rectangles and squares is covariant, because squares have _more specific_ constraints than rectangles. But when you make rectangles mutable, those mutations are contravariant, because they only guarantee to preserve _less specific_ constraints. So you can't make squares from mutable rectangles!

</comment></comment></comment></comment><comment><USER5> If you ever open the hood of a modern car and look around a bit you'll discover that at the front there's a half dozen pullies connected to one or more belts. Each of these pullies is connected to some diffeerent system each able to turn rotational acceleration into a useful service. The alternator converts that rotational energy into electricity. The AC unit uses it to operate a heat pump. The coolant and oil pumps use it to circulate fluid. In the past, these parts were sometimes driven by another system or integrated directly into another part. But over time, as a convenience to many different parties it was decided they should all implement a pully and connect dirctly to one of the main belts that connect directly to the motor. Not a single one of these parts has anything you'd call a taxonomical relationship. They do have an invented one. And it is as much about conveniencing the overall system design as much as conveniencing the individual part design. They are all "pully implementers" subscribed to the "belt druve" system.

This is the inheritence I find most powerful in software. These things aren't the same but if we treat them the same, the downstream and upstream code are simpler, easier to replace and consistent. I don't worry too much about the philisophical relationship between the objects.

<comment><USER6> You've described interfaces, not so much inheritance.

<comment><USER7> In the language of the article, this is subtyping without subclassing. Sure Java/C# implement this as interfaces, but in C++ this would be a case of multiple inheritance. This is a good example of the article's main point that people mean a lot of different things by inheritance and get different value from the different applications of the concept.

<comment><USER8> There are at least a few ways to define and implement interfaces in C++ without touching inheritance.

<comment><USER9> Structures of function pointers and, what, string method names? My C++ is rusty, but that's all I can think of. I guess there's a lot of variations on structures of pointers...

<comment><USER10> In Sean Parent's 'Inheritance is the base class of evil' talk Sean outlines an interesting way to achieve runtime polymorphism without inheriting interfaces in C++.

[https://www.youtube.com/watch?v=bIhUE5uUFOA](https://www.youtube.com/watch?v=bIhUE5uUFOA)

<comment><USER11> But he uses interface inheritance.

You see it at 9:44. Where he creates the concept_t and int_model_t inherits from it.

<comment><USER10> Indeed. But the original type isn't 'burdened' with the interface. I've used the technique for a simple audio signal processing chain.

</comment></comment></comment></comment></comment></comment></comment></comment><comment><USER12> > you cannot use a square everywhere you can use a rectangle (for example, you > can't give it a different width and height)

Can someone come up with a better example here? Intuitively, I would say, "Yes, if you ask me for any rectangle, and you reject a square, you are wrong." If you say you can use _any_ rectangle to do your thing, you should absolutely be able to also use a square.

Why am I not convinced with the given example? Because fundamentally, I don't think "set the width and height" counts as something you can do with a rectangle. A rectangle has a width and height, and you can't just _will_ it to have a different width and height and expect it to obey you through some force of nature. What you can do is construct a new rectangle and destroy the old one in the process.

In other words, if you expect to change the shape of the item, you should not permanently identify the item by its shape. The given example is a bit like saying "The superclass Animal has a method becomeCat which turns any animal into a cat." and then feigning surprise when your code breaks for any non- feline animal.

<comment><USER13> > and you can't just will it to have a different width and height and expect > it to obey you through some force of nature

I think you have let functional programming and immutable data-structures bias your world view.

The real world is mutable and the wonder of the digital mutable world is that it is pretty much just will-alone that can set attributes as you describe. It is immutability that is a trendy but artificial layer on top of this reality.

<comment><USER14> > The real world is mutable

Only if you ignore time. It's not possible to change the state of the world at some previous instant (as far as our understanding of physics is concerned). The mutable world model is an artificial construction that aligns with our human perception.

<comment><USER15> Something that changes over time is mutable. Time exists and we can't escape it, even with time-indexed immutable data structures that implement explicit mutability. The only question is does the thing change internally (an object) or is it replaced with a new one (a value).

<comment><USER16> I think it's not at all evident that reality is not a value replaced with a new one all the time.

<comment><USER15> Even if that were the case, it wouldn't be useful since we experience time with continuity anyways. Bob at time t is still Bob at t+1 even if his state (like position) has changed. If Bob were a value, then he would be another person, we would have to add a persistent ID to the bob values so we could see them as the same object.

<comment><USER14> > Bob at time t is still Bob at t+1

I guess we're getting more into philosophical issues now. If I leave an ice cube on my counter, at exactly what time is it no longer an ice cube.

<comment><USER15> Mutability is mutability, it also applies to ontology even if most OO languages don't model dynamic ontology with inheritance (unlike say Self or Cecil).

Your ice cube was never just an ice cube in the first place, it was just some water that happened to be frozen as a cube...once heat was applied to the water, it's state changed so that it eventually could no longer be classified as an ice cube.

<comment><USER14> > Your ice cube was never just an ice cube in the first place

That's my point. This idea that there are objects with mutable state is a myth. Even at the smallest scale, what we call elementary particles, are abstractions. There is nothing except the state of the universe at a given instant in time.

<comment><USER15> Again, we are unable to work or perceive at that level. So the abstraction of state is incredibly useful to us non-sub-atomic beings.

<comment><USER16> Agreed, but if we're accepting an abstraction instead of reality, than arguing for mutability because you think it's reality doesn't make much sense now does it? You're saying it's okay to abstract things away from molecules, but it's not okay to abstract things away from mutation. Why?

(Note that I'm not even persuaded yet that mutation _is_ reality. I'm just saying that even _if_ mutation _were_ reality, it doesn't follow that mutation is the best abstraction with which to model reality.)

</comment></comment></comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER17> I took over the maintenance and enhancement of a customer's eCommerce site.

It's written in Python, using an ancient framework - Pylons.

The person who originally designed and wrote it, coded large super classes and then subclassed off those.

And then somtimes subclassed off those subclasses.

So now I'm lost in a maze of twisty classes/subclasses, which makes maintaining and enhancing this eCommerce site much, much more of a challenge than it should have been.

In a few particular cases, I've found myself having to move functions out from one subclass and into the superclass, in order for related subclasses which needed access to it, for me to be able to add more functionality to the site.

I think what I'm trying to say is - from my experience, you can use Inheritance in many, many ways which can make life very difficult - nay, miserable - for your future self and especially for anyone 'inheriting' your project.

In my own home-grown Python projects, I have actually yet to use Inheritance (in classes I write myself - there's no escaping it when you're using other libraries of course), even after years of Python coding, because when I'm coding a new class DoSomething(), it's for that particular task and to date I've not ever had to subclass any of my classes.

<comment><USER18> Inheritance was probably was a good idea for a small thing and quickly achieve certain goals until features ballooned and he keep promising to deliver more features on top promptly

<comment><USER19> There's a rule from XP that people still ignore at their own peril. The rule of Three is, for those who tend to overengineer, a plea to wait a little longer. But for everyone else it's a call to action.

When you hit three copies of a pattern is when you should reconsider your choices. Just because a pattern was fine ten minutes ago doesn't mean you should keep doing it _now_. At some point it has become "too much and as part of the campsite rule you have to ask if the block of code is ridiculous. It may have already been ridiculous, or you might be the one who took it there, but that doesn't matter because you're here now and what are you gonna do about it?

</comment></comment></comment><comment><USER20> Oh, come on. The title submitted to HN is "Inheritance often doesn't make sense"; the actual title of the article is "Why inheritance never made any sense". Are you kidding me?

Do we really need, in 2018, another article continuing this particular religious war? Inheritance is just another tool in the software engineer's toolkit. When you need that tool, use it; when you don't, don't. But taking a position where you say it's never the right tool or, conversely, always the right tool makes you sound ignorant and inexperienced.

<comment><USER2> I didn't get that from the article at all. I actually like what the article is doing a lot, and I wish people would take the same approach more often. When arguments about high-level concepts like inheritance go poorly, it's usually because everyone involved is talking about something slightly different. Maybe a supporter of inheritance likes the way it lets them think about their program (ontological inheritance) while a detractor doesn't like how it forces each subclass to carry along the baggage of its superclass (implementation inheritance). These people are not going to have a fruitful discussion without understanding that they're talking about different things.

The concept of "types" in programming languages is another great example -- there are syntactic type declarations, memory-level types to specify which bytes mean what, things like typeclasses or interfaces which give you runtime polymorphism, the "type" you have in your head when you're thinking about what kind of data your code needs to handle... before you even start to have a discussion, you need some idea of what you're talking about.

<comment><USER21> The problem balancing implementation vs ontological inheritance while providing strong type safety is that your language needs to either support defining contravariant types (and you still likely end in a mess, see Scala's eternal discussion about "total" type safety), or you disallow ontological inheritance completely (like Golang, and therefore cannot support many modern programming features, for the better or worse, doesn't matter). Not sure if there is a language that truly does the opposite _by design_ , though (being strongly typed and disallowing implementation inheritance, while providing ontological inheritance). Such a language might be the DDD modeller's heaven? :-)

<comment><USER22> > or you disallow ontological inheritance completely (like Golang, and > therefore cannot support many modern programming features

Sincerely, what features does this preclude. I pretty much ignore ontological inheritance in any programming language because it never seems useful. Am I missing something?

<comment><USER23> Same here. The whole "is a square a type of rectangle, or is a rectangle a type of square" question seems like an unnecessary debate.

</comment></comment></comment></comment></comment><comment><USER24> > A common counterexample to OO inheritance is the relationship between a > square and a rectangle. Geometrically, a square is a specialisation of a > rectangle: every square is a rectangle, not every rectangle is a square.

Alternatively, you can argue that a rectangle is just a square with the additional freedom to vary the width and height independently. So in C++ syntax you would have:

        class Square {
        protected:
          size_t width;
          // No need to have "height" field because Square guarantees that height ==
          // width.
        public:
          virtual size_t getWidth() const { return width; }
          virtual size_t getHeight() const { return width; }
        };

        class Rectangle : public Square {
          size_t height;
          // A rectangle allows height to be different from width.
        public:
          virtual size_t getHeight() const override { return height; }
        };

See? This makes OO hard because it's hard to decide which should be the subtype of which intuitively, and people get even more confused since the arrow is contravariant in its left argument and the relationship would sometimes appear reversed. There in fact _is_ one correct answer but people often get it wrong. You need some serious appreciation of OO to know which.

Here are some more examples that can cause confusion. Suppose we have Reference (which can be read or written), ReadableReference (read-only) and WritableReference (write-only). From a purity perspective, should we have Reference inherit from both ReadableReference and WritableReference (ignoring OO languages that don't allow multiple inheritance), or should we have ReadableReference and WritableReference inherit from a single base class Reference? This kind of question frequently trips people up.

<comment><USER25> > There in fact is one correct answer but people often get it wrong. You need > some serious appreciation of OO to know which.

Please enlighten me which one is _correct_ , and I'll happily argue that the other is in fact correct!

(I _think_ you're going to say Square extending Rectangle is correct lest Rectangle break Square's invariants, but I'm not certain. What language you're operating in may influence the matter; for there can be very important differences in how different languages handle variance which can invert the answer. I'm a little rusty on this, though, because I haven't had to actually worry about it for a few years since I last wrote Rust code where the variance of a type with respect to a generic parameter actually mattered, and for work I'm mostly writing JavaScript where it's all fuzzy enough that you pretty much get to decide what is right and what is wrong!)

<comment><USER26> If you want to argue about OO you should use Smalltalk. Many other languages use some shortcuts (often for performance reasons) which ignore central concepts of OO (e.g. 'everything is an object').

</comment></comment></comment><comment><USER27> This article seems to be confused about what abstract data type inheritance is, as exemplified by "As a type, this relationship is reversed: you can use a rectangle everywhere you can use a square (by having a rectangle with the same width and height), but you cannot use a square everywhere you can use a rectangle (for example, you can't give it a different width and height)."

If an abstract data type X inherits from Y, that means that _every_ X can be used where you can use a Y. You can only use a rectangle where a square is expected if that rectangle happens to be a square. Inversely, you _can_ use a square everywhere you can use a rectangle: if you change the width and height of a rectangle, you turn it into a rectangle with different width and heigth; if you change the width and height of a square, you _also_ turn it into a rectangle with different width and height.

That also means that you can't have mutable values, static types and subtyping in the same language: if you apply a mutating function defined for a supertype on a subtype, you might end up also mutating the type of the mutated value by invalidating invariants of the subtype. It's the same problem that made covariant arrays in Java unsound.

If the type system is sound and expressive enough, ontological inheritance ( this thing is a specific variety of that thing) and abstract data type inheritance (this thing behaves in all the ways that thing does and has this behaviour) should be essentially the same thing.

<comment><USER24> > That also means that you can't have mutable values, static types and > subtyping in the same language

Yes you can. You just need to make a clean separation between mutable variables and immutable variables. Then mutable variables must be invariant, and immutable variables can enjoy subtyping.

Alternatively, classify mutable variables further and make references carry information about whether only reading/writing is allowed through this reference. Then read-references enjoy the usual covariant subtyping, and write-references enjoy contravariant subtyping.

<comment><USER28> Agreed, although I'd go a step further. A mutable variable has a type of reads and a type of writes. They vary in opposite directions. If you constrain them to be the same then they must therefore not vary at all.

</comment></comment></comment><comment><USER29> Unless your program's goal is to ontologically categorize objects, #1 is a trap that will just bite you in the ass.

In the physical world, if I have a rectangle shaped box I want to cover, I don't want a square, no matter how much "squares are rectangles". It's no different in a program. What really matters is the behavior and goals of your program. It's cute to say squares are rectangles but if your program needs to let your user independently set width and height then a square is completely useless.

<comment><USER22> > Unless your program's goal is to ontologically categorize objects, #1 is a > trap that will just bite you in the ass.

Strangely, ontological inheritance isn't even useful for that purpose. If you're organizing things ontologically, you certainly want to have runtime access to the relationships in your ontology, which means you should model things as data, not static class relationships (although reflection can turn static class relationships into data, it's a pretty hokey, indirect solution).

<comment><USER15> Most languages that have classes expose inheritance relationships in someway without reflection. Even JavaScript provides a non-reflective instanceof now. You can also reify inheritance relationships more directly by hand of needed.

</comment></comment></comment><comment><USER30> I feel as though the rectangle/square example falls down mostly because of a linguistic trick.

Rect->Square could be a perfectly reasonable type hierarchy, as long as you don't allow self-mutation of the very attribute that defines this specialization. But then, mutation tends to wreak havoc on inheritance anyway (e.g., covariance/contravariance) -- and almost everything else. When I take the needle out of my record player, it can't play records any more, so is it really still a "record player"?

This isn't special to any particular type of inheritance, either. If you let all the air out of your ball, it's no longer a sphere, so even with purely ontological types, you're already in trouble. Inheritance isn't the problem. Mutation is.

<comment><USER31> This would be overengineering, but the following six types would solve the problem:

* ImmutableSquare

* ImmutableRectangle

* MutableSquare

* MutableRectangle

* Square

* Rectangle

The "Mutable..." classes are mutable, the "Immutable..." classes are immutable, and the "Square" and "Rectangle" classes mean that you can read the values, but there is no guarantee about either mutability or immutability.

In this system, "ImmutableSquare" and "MutableSquare" are subtypes of "Square"; "ImmutableRectangle" and "MutableRectangle" are subtypes of "Rectangle"; and also "ImmutableSquare" is a subtype of "ImmutableRectangle" (and therefore "Rectangle").

But if you go this way, don't be surprised when you end up with millions of classes.

<comment><USER30> In some languages, there are also (non/)threadsafe variants of mutable classes. As you say, this approach blows up quickly.

If I saw that, I would ask what 'problem' it's trying to solve. Is mutation actually the goal, or simply the means? In languages which don't support general mutation (I'm writing Clojure right now), I really don't miss it at all.

</comment></comment></comment><comment><USER32> The reason implementation inheritance with substitution (aka "virtual methods") is bad is that it results in classes having two APIs: the normal public API and one for inheritors, the latter of which is usually undocumented, and even worse the APIs are conflated.

To see the issue, imagine you have a class representing a thermometer, with two virtual methods: get_c() and get_f() returning the temperature in Celsius and Fahrenheit degrees respectively.

Now it turns out that a specific model of that thermometer was miscalibrated and always returns 10 C more, so you decide to make subclass that corrects the behavior.

Unfortunately, that's impossible (without composition or mutable state).

A first attempt could be to override get_c() to call the parent and subtract 10. However, get_f() will still be wrong unless it happened to be implemented by calling get_c() and converting.

A second attempt could be to override both and apply the correction to both. Except now if get_f() is implemented by calling get_c() and converting, the correction will happen twice!

The issue here is that how the class uses its internal API is undocumented, and also that the internal and public APIs are conflated, making it impossible to change only one.

This can be solved by never having a class call overridden functions on itself, but that just results in a system that is equivalent to composition with delegation.

If such overriding is really required, it can be accomplished by adding a "callback interface" parameter to the constructor and documenting how it is called and how it's expected to behave.

</comment><comment><USER33> We don't use inheritance anymore. If something needs to be shared it gets its own service class.

Every time we've used inheritance it's ended up being more of a hassle to keep track of as functionality changed. I know we could utilize it better than we have, but that's part of development management as I see it, if I know my crew won't utilize something to good effect, then it's often better to adapt our practices rather than fail at change management after a long period of trying. Especially because a lot of new hires are really bad at OO principles beyond the fundamentals.

</comment><comment><USER34> I don't understand why some functional programmers have so much difficulty with the concept of inheritance. Discriminated Unions and pattern matching is just inheritance and virtual dispatch turned inside out. Yet no one is naval gazing about whether their algebraic datatypes are 'ontological' or not.

I also really wish people wouldn't try and dismiss concepts they're ignorant of:

 _because multiple inheritance is incompatible with the goal of implementation inheritance due to the diamond problem_

I have no idea what that sentence is supposed to mean. It doesn't make sense even given their own definition of implementation inheritance.

<comment><USER24> Yes it's true that discriminated unions and pattern matching is just inheritance and virtual dispatch turned inside out. But discriminated unions and pattern matching are easier to use, easier to understand than inheritance and virtual dispatch.

And you don't need to struggle with principles like "is-a relationship" which can be confusing.

<comment><USER34> _But discriminated unions and pattern matching are easier to use, easier to understand than inheritance and virtual dispatch._

That seems incredibly subjective. It's 50/50 for me, I just go with the grain with the language I'm using. I'll admit that in practice pattern matching wins due to the depressing lack of multiple dispatch in OO and pseudo-OO languages.

 _And you don 't need to struggle with principles like "is-a relationship" which can be confusing._

Why would you struggle with that question with inheritance and not DUs? what is it about DUs that make it not an issue?

</comment></comment></comment><comment><USER35> Nice article.

Worst thing I've ever seen was a class which inherited another just to keep the lines of code short (<2500). That said it wasn't just one time inheritance... It was up to four times. There was no logical split of the inheritance. It looked like someone simply split one huge file into some smaller ones.

We called that kind of inheritance "code sharding" and we had a lot of headache at that time.

</comment><comment><USER36> The programmer's perspective:

 _The phrase 'object-oriented' means a lot of things. Half are obvious, and the other half are mistakes._ \- Paul Graham.

 _Implementation inheritance causes the same intertwining and brittleness that have been observed when goto statements are overused. As a result, OO systems often suffer from complexity and lack of reuse._ \- John Ousterhout Scripting, IEEE Computer, March 1998.

 _The problem with object-oriented languages is they 've got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle._ \- Joe Armstrong

The artiste's perspective:

 _Everything tends to make one think that there is little relation between an object and that which represents it._ \- René Magritte, surrealist

The conceptual purist perspective:

 _The notion of object oriented programming is completely misunderstood. It 's not about objects and classes, it's all about messages._ \- Alan Kay

The pedagogical perspective:

 _CSCI 2100: Unlearning Object-Oriented Programming - Discover how to create and use variables that aren 't inside of an object hierarchy. Learn about 'functions,' which are like methods but more generally useful. Prerequisite: Any course that used the term 'abstract base class.'_ \- James Hague

Quotes via [http://github.com/globalcitizen/taoup](http://github.com/globalcitizen/taoup)

<comment><USER37> I think the problem is more that OOP and FP teach that the solution is in the language constructs, when in fact the solution is in the developer.

OOP and FP are typically taught as outputs. You take a problem, you apply FP or OOP magic, and you get a solution squeezed into an FP or OOP shape. The implication is that the language somehow half-solves your problem just by being how it is, and all you have to do is apply it.

IMO this is the wrong way to do things. Developers should be taught abstract domain modelling skills in a language-independent way, then taught how solutions can be implemented in different paradigms. _Then_ they can start coding.

The solution is in the design of the relationships, not in the language syntax. And there's no such thing as a off-the-shelf one-size-fits all set of relationships.

There are domains where it makes total sense to subclass polygon through rectangle to square, and domains where that's a very bad idea and will cause endless pain. So it's not enough to say "This thing is like this other thing, so they both belong on the same inheritance tree." Sometimes the resemblance is superficial and irrelevant in terms of the domain - even though to you as a human programmer the similarities are "obvious."

Neither OOP nor FP can help you if your ability to design minimal but powerful abstractions that fit specific problems is poor. OOP and FP will expose you to new ways of thinking about problems, but neither is general enough to "just work" or keep you out of trouble if you don't truly understand what you're trying to do.

<comment><USER38> I think the problem is more that Roman and Indo-Arabic numerals teach that the solution is in the notation, when in fact the solution is in the mathematician. . .

<comment><USER39> I'm confused about your analogy. Indo-Arabic number representation enables one to mentally carry out computations that would be much more complex in Roman notation. The notation might not be the solution, but the notation certainly enables solutions not really conceivable in other notations.

<comment><USER38> I believe functions + immutable data enable me to mentally figure out solutions to complex problems that would be much more complex if solved with objects and inheritence and mutable state.

<comment><USER40> The analogy breaks down (at least for me) as there are some trade-offs being glossed over that don't really exist with the different systems of numerals. What's being lost for the conceptual simplicity you've gained?

</comment></comment></comment></comment></comment></comment><comment><USER41> > Abstract data type inheritance is about substitution: this thing behaves in > all the ways that thing does and has this behaviour (this is the Liskov > substitution principle)

There is no such thing as "inheritance" for abstract data types, because inheritance is a _syntactic_ relation between two definitions (which needn't be type defintions, by the way!). Abstract data types may be related by subtyping, although IMO this is hardly ever useful. What you actually want to refine is _abstractions_ (of which abstract types are merely constituent parts).

> As a type, this relationship is reversed: you can use a rectangle everywhere > you can use a square (by having a rectangle with the same width and height), > but you cannot use a square everywhere you can use a rectangle (for example, > you can't give it a different width and height). Notice that this is > incompatibility between the inheritance directions of the geometric > properties and the abstract data type properties of squares and rectangles; > two dimensions which are completely unrelated to each other and indeed to > any form of software implementation.

There are valid arguments against inheritance, but this is not one. In fact, this argument has nothing to do with inheritance at all! All that this says is "if the type variable T only appears in contravariant position in F(T), and A is a subtype of B, then F(B) is a subtype of F(A)". Moreover, this is not an argument against subtyping either. It's just the description of how to handle it correctly. It appears in any standard PL semantics or type theory textbook.

Here is a real argument against inheritance: "Try formalizing the semantics of a toy language with inheritance. Try proving things about a couple toy programs using this semantics. Note how the proofs about what your superclasses do often make a lot of unwarranted assumptions about how subclasses will use or override inherited functionality. These assumptions couple not only the interfaces (which is okay), but also the implementations (which is not okay) of superclasses and subclasses. This is the antithesis of modularity."

</comment><comment><USER42> In practical terms, away from the nebulous confusion, object orientation means that the actual function to call must first be looked up in the first argument of the function to execute:

x.f(y,z);

<==>

F=ooLookup(x,f); F(x,y,z);

This scheme does indeed allow for polymorphism, but I wonder why we would shoehorn polymorphism into a situation, unless it naturally emerges throughout the programming effort as really needed?

In my opinion, functions should not be polymorphic by default, simply, because there is no reason to complicate things unless these complications truly solve a problem.

Inheritance is then a next complication in which F=ooLookup(x,f) recursively tries to resolve the function from a hierarchical class data structure:

x->class->functions

x->class->class->functions

...

This is even a worse complication, which is even more unlikely to be useful.

</comment><comment><USER43> I think inheritance make code more coupled, which make it hard to delete or refactor. Most of the cases it's better to just copy and paste. You can still share methods. But the moment you need to modify a shared method just so it can be reused: Make a new function instead. One popular solution is to only let functions do _one thing_ but that leads to even more coupling and less reuse. There's a fine balance between reuse and coupling. Where reuse is good and coupling is bad. A general rule for when to reuse/share/modularize is when the method/function can be reused in _other_ code base. eg. when it can be/is decoupled.

</comment><comment><USER44> If we are doing OO programming, and we have rectangles, IsSquare would be a good method for a Rectangle whose dimensions are mutable rather than Square being a subclass of Rectangle.

<comment><USER45> Now you have to remember to check (and repeatedly check) IsSquare at runtime to somehow deal with rectangles that aren't squares, which probably means throwing an exception that someone else has to remember to catch or face runtime errors. But if the dimensions are mutable, no alternative is very satisfactory.

</comment></comment><comment><USER46> The conclusion 'separate out implementation inheritance' rather weakens the claim 'multiple inheritance of implementation isn't useful'. Because then pragmatics can be allowed to dominate.

We do need more powerful vocabulary for composing implementation (eg, to specify object layout spread non-locally in memory). But multiple inheritance can be valuable, and gets a lot of low-quality criticism.

</comment><comment><USER47> Yeah. Even though I mainly code in C#. The more years I've been at it the less I've used inheritance. Its become something I try to never do.

</comment><comment><USER48> I'm not convinced the sqr rect example is the best one, at least to say inheritance is wrong. I think this is an example of how not to use inheritance. In my mind the base class should be shape (not rect) or four- sided shape, or whatever the name is for shapes with non-curved sides.

Just me?

</comment><comment><USER49> Here are some harder examples-

abs(x) + abs(y) = 1 is a square of side 1.

x^2 + y^2 = 1 is a circle of radius 1.

But abs(x) = positive sqrt(x^2)

so squares and circles ought to have the same 2D parent, since given the x & y, its just a matter of applying the right transform.

y = ax^2 + bx is a parabola through the origin.

y = bx is a line through the origin.

so lines and parabolas ought to have a common 1D curve as a parent, because a parabola reduces to a line when a=0.

clearly a line shifted by a constant is still a line.

so also, a line rotated clockwise or anti clockwise through say 90 degree is still a line.

so then i take a horizontal line, shift it once and rotate it twice, join these 4 lines and get a square.

so squares ought to be a container type with 4 lines ? or wait, if i collapse the two verticals ie. set the height to 0, then a square is just a straight line with no height, which is absolutely true geometrically, but think about the damage you'd do to your type-theory.

but didn't we just say lines are just degenerate parabolas. so then we ought to be able to take a square, grab its 4 sides which are lines, transformed each line into a parabola, and tell me what that gives you.

and you haven't even gotten me started on activation functions. since all logistics are richards curves, a gompertz is just a particular richards. so then a relu should inherit from a gompertz and a swish should be a child of relu and somewhere in here we need the hyperbolic tangent, either as a parent or a child or a sibling or the notorious c++ friend function.

now go ask your friendly neighborhood tensorflow colleague why the activations don't share a common parent, why lines aren't parabolas and squares aren't lines and so in and do forth.

</comment><comment><USER50> IMO this is one of the primary reasons many modern languages not not strictly Object Oriented. They usually support objects to a limited extent, but a certainly not OO like the 90s languages.

</comment><comment><USER26> > Inheritance was never a problem: trying to use the same tree for three > different concepts was the problem.

I wonder why the author describes Polymorphism[1], but doesn't mention the term in any way. At the same time he uses the word 'abstract', but in a different way than any OO/Smalltalk programmer would do. While he mentions the 'Smalltalk blue book', I somehow do not trust his expertise in the field.

[1]: [https://en.wikipedia.org/wiki/Polymorphism_(computer_science...](https://en.wikipedia.org/wiki/Polymorphism_\(computer_science\))

<comment><USER51> > At the same time he uses the word 'abstract', but in a different way than > any OO/Smalltalk programmer would do.

I doubt most people who define themselves as OO programmers, eg. working in C#/Java/C++/Python/etc... consider themselves on the Smalltalk side (eg message-passing) of the OO debate. 95% of actual programming experience in object-oriented languages is in languages of SIMULA descent.

</comment></comment><comment><USER16> People in this thread are trying to separate the concept of mutation from the concept of inheritance, but the problem with this is that you can't separate the two. Consider the following pseudocode:

        Rectangle r = new Rectangle(height = 3, width = 5);
        Square s_as_s = new Square(side = 4);
        Rectangle s_as_r = s_as_s;

        print(r.height); // prints 3
        print(r.width);  // prints 5
        print(s_as_s.height); // prints 4
        print(s_as_s.width);  // prints 4
        print(s_as_r.height); // prints 4
        print(s_as_r.width);  // prints 4
        print(r is_a? Square); // prints false
        print(s_as_s is_a? Square); // prints true
        print(s_as_r is_a? Square); // prints true

Okay, so the question comes up when you mutate these results:

        r.height = 2;
        s_as_r.height = 2;

Keep in mind, this is a perfectly reasonable thing to do in both cases: you're just making two rectangles a little shorter. But no matter how you handle this situation, the results are surprising:

One way:

        print(r.height); // prints 2
        print(r.width);  // prints 5
        print(s_as_s.height); // prints 2
        print(s_as_s.width);  // prints 2
        print(s_as_r.height); // prints 2
        print(s_as_r.width);  // prints 2
        print(r is_a? Square); // prints false
        print(s_as_s is_a? Square); // prints true
        print(s_as_r is_a? Square); // prints true

This is the simplest to implement, but only because there's a part of the contract of Rectangle which is _implied_ and not enforced by the compiler. When we change the height of a rectangle, we don't expect the width to change. This is the sort of gotcha that needs to be put in the documentation in big red letters: "WARNING: CHANGING THE HEIGHT MAY CHANGE THE WIDTH IN SOME SITUATIONS."

Another way:

        print(r.height); // prints 2
        print(r.width);  // prints 5
        print(s_as_s.height); // prints 2
        print(s_as_s.width);  // prints 4
        print(s_as_r.height); // prints 2
        print(s_as_r.width);  // prints 4
        print(r is_a? Square); // prints false
        print(s_as_s is_a? Square); // prints true
        print(s_as_r is_a? Square); // prints true

But now you've broken the contract of Square: the user is going to be very surprised when changing the side of one side of a Square means that the Square instance no longer represents a square.

Okay, what about this:

        print(r.height); // prints 2
        print(r.width);  // prints 5
        print(s_as_s.height); // prints 2
        print(s_as_s.width);  // prints 4
        print(s_as_r.height); // prints 2
        print(s_as_r.width);  // prints 4
        print(r is_a? Square); // prints false
        print(s_as_s is_a? Square); // prints false
        print(s_as_r is_a? Square); // prints false

This might be possible with some horrible hack in a language that does dynamic typing. This maintains the contracts of all the types, but I'd argue that it breaks the contract of the language itself: it's deeply confusing to have the type of the s_as_s variable change out from under you.

Perhaps you could do this:

        print(r.height); // prints 2
        print(r.width);  // prints 5
        print(s_as_s.height); // prints 2
        print(s_as_s.width);  // prints 2
        print(s_as_r.height); // prints 2
        print(s_as_r.width);  // prints 4
        print(r is_a? Square); // prints false
        print(s_as_s is_a? Square); // prints true
        print(s_as_r is_a? Square); // prints false

Setting aside how one might even implement this, we've now got the surprising result that s_as_s and s_as_r seem to be different instances now.

Maybe we should have prevent this in the first place:

        r.height = 2; // works
        s_as_s.height = 2; // throws CannotSetSideViaHeightException
        s_as_r.height = 2; // throws CannotSetSideViaHeightException

s_as_s.height = 2 throwing an exception sort of makes sense, but now s_as_r isn't behaving like a rectangle--we're breaking the Rectangle contract again.

Another way to prevent it:

        r.height = 2; // works
        s_as_s.height = 2; // works
        s_as_r.height = 2; // throws ThisWouldBeConfusingException

Again you're breaking the contract of the language, that s_as_s and s_as_r seem to be different objects.

There's only one way left I can think of to make Rectangle maintain its contract, Square maintain its contract, and keep s_as_s and s_as_r behaving the same way:

        r.height = 2; // throws MutationException
        s_as_s.height = 2; // throws MutationException
        s_as_r.height = 2; // throws MutationException

Does this look familiar? It should: it's basically immutability implemented as checks at run time, which is not a good way to implement it. At this point we should just implement these as immutable objects.

I'm not necessarily saying that immutability is the only way. You could also give up inheritance:

        Rectangle makeSquare(int side) {
          return new Rectangle(side, side);
        }

        Rectangle r = new Rectangle(3, 5);
        Rectangle s_as_r = makeSquare(4);

        print(r.isSquare); // prints false
        print(s_as_r.isSquare); // prints true

        r.height = 2;
        s_as_r.height = 2;

        print(r.height); // prints 2
        print(r.width); // prints 5
        print(s_as_r.height); // prints 2
        print(s_as_r.width); // prints 4

        print(r.isSquare); // prints false
        print(s_as_r.isSquare); // prints true

This also results in unsurprising behavior.

</comment><comment><USER52> I think there's no Silver Bullet. But there are bullets

</comment><comment><USER53> The Decorator pattern is your friend.

<comment><USER6> Until it isn't.

</comment></comment><comment><USER54> Some languages use polymorphic row types and eschew inheritance

[https://brianmckenna.org/blog/row_polymorphism_isnt_subtypin...](https://brianmckenna.org/blog/row_polymorphism_isnt_subtyping)

[https://www.reddit.com/r/types/comments/73lg05/comment/dnt7q...](https://www.reddit.com/r/types/comments/73lg05/comment/dnt7q5p)

[https://noamlewis.wordpress.com/2015/01/20/introducing- sjs-a...](https://noamlewis.wordpress.com/2015/01/20/introducing-sjs-a-type- inferer-and-checker-for-javascript/)

[https://github.com/purescript/documentation/blob/master/lang...](https://github.com/purescript/documentation/blob/master/language/Types.md)

</comment><comment><USER55> This gets off to a bad start:

> There are three different types of inheritance going on.

> 1\. _Ontological_ inheritance is about specialisation: this thing is a > specific variety of that thing (a [soccer ball] _is_ a sphere and it has > this radius)

> 2\. _Abstract data type_ inheritance is about substitution: this thing > behaves in all the ways that thing does and has this behaviour (this is the > Liskov substitution principle)

> A common counterexample to OO inheritance is the relationship between a > square and a rectangle. Geometrically, a square is a specialisation of a > rectangle: every square is a rectangle, not every rectangle is a square. For > all s in Squares, s is a Rectangle and width of s is equal to height of s. > As a type, this relationship is reversed: you can use a rectangle everywhere > you can use a square (by having a rectangle with the same width and height), > but you cannot use a square everywhere you can use a rectangle (for example, > you can't give it a different width and height).

> Notice that this is incompatibility between the inheritance directions of > the _geometric properties_ and the _abstract data type properties_ of > squares and rectangles; two dimensions which are completely unrelated to > each other

By the definitions given at the beginning, where the "abstract data type properties" of an object are its properties as considered by the Liskov substitution principle, this is nonsense.

Compare the definition stated in [https://en.wikipedia.org/wiki/Liskov_substitution_principle](https://en.wikipedia.org/wiki/Liskov_substitution_principle) . Type S is substitutable for type T when, if f( _x_ ) is true of all objects _x_ of type T, then f( _y_ ) is true of all objects _y_ of type S.

Obviously, according to this definition, any subtype S of type T which satisfies the article's definition 1 will also be Liskov substitutable for T and therefore satisfy the article's definition 2 as well. This is as far from being "unrelated concepts" as you can get; the one requires the other.

The example with Squares and Rectangles doesn't make sense either. If you have code that is set up to handle Rectangles, and you give that code a Square, then the code will handle the Square correctly. This is _because_ Squares are Liskov substitutable for Rectangles... which is _because_ Squares are, platonically, a kind of Rectangle.

It looks like the author wants to ask "if I encounter an interface that processes Rectangles, and I can only construct Squares, can I achieve everything, by using Squares, that someone else could have achieved by using Rectangles?" But that is not the Liskov substitution principle, or any sort of type theory principle. That would be a principle of computational equivalence.

<comment><USER56> > If you have code that is set up to handle Rectangles, and you give that code > a Square, then the code will handle the Square correctly.

Hmm...try setting different widths and heights on your square.

<comment><USER15> Many rectangle APIs, even in OO languages, are immutable, so setting width and length isn't allowed anyways, all you can do is operate on it to get a new one.

I've rarely seen a square subtyped as a rectangle, let alone a mutable one. But I guess it's possible if the mutable and immutable APIs are divided, so that squares are rectangles in its immutable sense but not in its mutable one.

<comment><USER57> This also pops up in modeling sets. You can define an immutable set by its explicit list of members (intrinsic) or by function that tests membership (extrinsic). If you want to have only one unified type Set that permits both methods of construction, it has to be invariant with respect to the type of its members. This is because the intrinsic approach is covariant (just as a list is) but the extrinsic approach is contravariant (just as a function is in its inputs).

I wish I had a really clear example of this, but it escapes me right now.

</comment></comment></comment></comment><comment><USER58> I used to feel like this before writing big and complex programs. But in term of practicality, it's a whole lot easier to just write the expansion of "rectangle" to "square" than re-writing "square" from scratch, essentially copying the majority of "rectangle" properties and functionality.

<comment><USER59> Factor out the commonality into a service class (as stated in another comment), where your common logic can be shared.</comment></comment>


How to become a Pure Mathematician  - <AUTHOR> http://hbpms.blogspot.com/2008/05/content-and-about.html

<comment><USER2> Thanks for the link, some good resources on a variety of topics, many of which are free. This is why I read HN!</comment>