Boeing acquires flight-planning app maker ForeFlight - <AUTHOR> https://www.houstonchronicle.com/business/article/Boeing-acquires-Houston-flight-planning-app-maker-13668642.php <comment><USER2> As a long time user and a big fan of Foreflight, this announcement chilled me to my very core. Jeppesen is the very definition of rent seeking, predatory, lock-in company. I deal with them because there is literally no other source for the data my airplane's avionics need to fly legally in our IFR airspace.

Foreflight offers everything Jeppesen offers (other than avionics data subscriptions) in a vastly cheaper and more usable manner.

Boeing also bought Jeppesen a few decades ago- I was a pre Boeing Jeppesen customer too. I feel a dreadful surety that new Foreflight will become predatory like Jeppesen. There were already signs that way, anyway, with each round of new features requiring a "higher level" of subscription with Foreflight.

Oh well, technology company startup costs being what they are (almost nil) I will excitedly await the next entrant if my fears are realized.

PS: Non professional use for me.

<comment><USER3> It's super scary, especially because ForeFlight has no realistic competition.

I've had this off-again, on-again plan (more like dream) to write an open- source ForeFlight clone, as I used to write aviation mapping software for a living and could probably throw something passable together. But the application's sheer quantity of high quality features makes the project super- daunting. It's unrealistic to believe that a group of amateurs without a budget could even come close to replicating it.

<comment><USER4> I've heard Garmin pilot stacks up reasonably well

</comment></comment></comment><comment><USER5> For the record, I think ForeFlight is honestly the best app I've ever used. In terms of depth, reliability, and ease of use it is really unmatched not just in aviation but in any app I use on a daily basis.

Giving all the information and capabilities a pilot needs is a hard problem.

<comment><USER6> What are the hard parts and what does ForeFlight get right?

<comment><USER7> There is just SO MUCH information. Airport diagrams, approach and departure plates (geo-referenced), all the different charts (sectionals, TACs, IFR hi and low, etc), checklists, radio frequencies, route planning, airspaces, weather, NOTAMs, TFRs, etc. I'm sure I'm leaving off tons of stuff. The flight planning features are fantastic.

<comment><USER8> Synthetic Vision, terrain avoidance.. also flight logs (including automatically determining currency.)

ForeFlight is amazingly good and fully leveraged the power of the new iPad pros as well. Literally the best app. They also didn't compromise by trying to do some kind of cross-platform attempt. It's supremely optimized for iOS hardware. An electronic flight bag app that can perform just as well as the G1000 glass cockpit. Combined with the Stratus receiver, it's even better because it gives you traffic and weather data in flight.

If there was ever a use case for not using some kind of pseudo-native framework in favor of real-native, this is it. Glass cockpit applications are the last place you want lowest common denominator code. It works great on even the iPad mini, but it really flies on the new iPad Pro.

Another cool feature is that you can use it with the X-Plane simulator. Amazing app and so inexpensive for what it does. The most expensive plan is $300 per year and the cheap plan is $99/year. I never fly without it.

<comment><USER9> I presume that it is meant for private pilots, i.e. commercial pilots would be required to use the airline supplied charts and checklists?

<comment><USER10> No, it can be and is used by pilots of all flavors. I have a commercial rating but not an ATP and use it every time I fly.

</comment></comment></comment></comment></comment></comment><comment><USER11> I literally bought the first iPad as a platform to run ForeFlight. Two years of charts and plates were costing me more than the iPad and two years of ForeFlight would so it was like getting a free iPad and much easier charting and cockpit management.

Was interesting to see the evolving attitude of instructors to it. Initially the curmudgeons were dead against it. Now, most of them to seem to use it.

<comment><USER9> No experience of aviation myself. But my uneducated reaction is what happens if the ipad falls and breaks or runs out of battery? A paper chart always works. Do you typically have a spare ipad on board?

<comment><USER11> At the time, I was flying an airplane that only had the iPad for charts and carried one set of expired paper sectional charts and had a handheld aviation GPS.

I have since upgraded to an airplane with glass avionics and onboard charts and plates. Now, I have the onboard materials plus my iPhone also has the charts on it.

For visual flight, it wouldn't be that hard to navigate by looking outside the window. For instrument flight (or visual flight if needed), it would be easy enough to ask ATC for the assistance you needed.

</comment></comment></comment><comment><USER12> Looking at comments, everyone has their personal jet or im missing something?

<comment><USER13> Probably that's because only people who are related somehow to planes / app / etc leave comments in here.

It's the same when people share only their bright moments in social media and you begin to think that you're missing something in your miserable daily routine. While in reality you just see exclusively bright moments and nothing behind the scenes.

<comment><USER12> Nice example of over-generalization, ty.

</comment></comment></comment><comment><USER14> Having worked at Boeing, it's strange to imagine such an acquisition. Boeing is the polar opposite of a software startup, and ForeFlight's about-page shows them to be founded by software entrepreneurs. I will be impressed if they can make this work. What does Boeing hope to get from this that they couldn't get from them as a partner or supplier?

<comment><USER8> Boeing is a lot more high tech than people give them credit for. In my opinion, Boeing could only serve to benefit ForeFlight as now the company has significant backing as well as deeper access into cutting edge flight systems tech.

<comment><USER15> >Boeing is a lot more high tech than people give them credit for

I'm sitting in a Boeing lab right now as a contractor, and I would disagree with this statement

</comment></comment></comment><comment><USER16> Big fan of ForeFlight, as are my favorite pilot YouTubers Matthew Guthmiller(N367HP) and Stevo1kinevo (N851TB). Hopefully Boeing keeps the wind in the sails of the ForeFlight team.

<comment><USER17> It's weird to read about Stevo1kinevo on HN... :)

<comment><USER10> I will throw in a flightchops and premier1driver to satisfy the entire query!

</comment></comment></comment><comment><USER18> This is the most reliable, highest utility app I have ever used. It's worth every penny.

</comment><comment><USER19> My son is a big fan of the Infinite Flight sim, which recently integrated with ForeFlight. He's really going to be bummed out if Boeing decides to stop supporting that link.

<comment><USER20> How does Infinite Flight compare to the mobile version of X-Plane 10?

I think it's pretty fun that X-Flight 10 mobile has, for example, the full version of their in-house Boeing 737. It pales in comparison to some of the 3rd party offerings for desktop X-Plane, but for a flight simulator on a mobile device it has very impressive system depth, with a working FMC and all: [https://www.youtube.com/watch?v=TaJuIfqYRPY](https://www.youtube.com/watch?v=TaJuIfqYRPY)

However, manipulating all those buttons on an iPad touchscreen is not the most comfortable and has some quirks (you kind of need to look at the button in the right angle, for example). Is that better in Infinite Flight?

</comment></comment><comment><USER21> Why have cookie banners become so insane? A misunderstanding of gdpr perhaps. So annoying

<comment><USER22> Here's my approach to this issue in Firefox:

1\. Right click - Inspect Element 2\. Right click on containing node in Inspector Panel - Delete Node 3\. Read article</comment></comment>


How to Write Unmaintainable Code (2017) - <AUTHOR> https://github.com/Droogans/unmaintainable-code <comment><USER2> I actually like using short variable names. Using "i" as an index variable has been widely accepted. It saves a lot of typing, the use case is clear and it is usually tied the a block which is visually identifiable.

I carry over the same principles to functions/methods. Functions are usually less than a screen which makes it rather easy to pick up the context and understand the program flow and the use of variables. I use "list" if there is there is a single list. The context usually defines what is in there. Maybe the function name, the type declarations or the fact that we are in a part of code handling lists of customers. How hard is it to guess what countCustomers(list) or incrementCustomersScore(list, n) is doing? Writing incrementCustomersScore(goodCustomerList, customerScoreDelta) is just redundant. Variable names just need to be descriptive enough to define their role within it's context. If the function is very small, the variable names can be very short.

Local variables are the smallest named things in our systems, whith a very small scope, there shouldn't be an excessive naming cult around it. Give advice how to properly name projects, packages, namespaces and classes and I start listening. We are really bad at this.

<comment><USER3> `i` vs `index` is whatever. `index` is better, but it's not like I'd bash someone for using `i`.

Using `list` is just bad. Your list (probably) holds a set of things that has a name. So name your list that. At the very least, name it after the type of things it's holding. Types are only declared once, but variable names are forever. Having to constantly look up the type of a variable because the programmer was too lazy to name the list of things as `things` instead of `list` is rather inconsiderate.

(Of course, there are times when you would use `list`. For instance, if you're writing a list sorting function, and you actually have zero context more than "yep, this thing is a list".)

<comment><USER4> Index isn't going to be consistent when you need a second iterator in a generic algorithm; people just don't like the sound of jndex. Use "i" and "j" and "k", or "idx" and "jdx" and "kdx" if you must, but please don't use "index1" and "index2" and "index3."

As you say, list might be the best name for a variable if the use context is generic. The same with iterators and such. But you really have to think ahead to keep the names consistent, complicated names work against consistency.

<comment><USER3> Well, if you combine the two together...

        List<Foo> foos;
        for (fooIndex = 0; fooIndex < foos.length; ++fooIndex) {
            Foo foo = foos[fooIndex];
            List<Bar> bars = foo.bars;
            for (barIndex = 0; barIndex < bars.length; ++barIndex) {
                Bar bar = bars[barIndex];
            }
        }

It would be immediately, visibly obvious if you accidently use `fooIndex` in the `bars` list. Good luck getting that with `i` and `j`.

That, of course, is assuming you even need the indexes. Otherwise you get this:

        foreach (Foo foo in foos) {
            foreach (Bar bar in foo.bars) {
            }
        }

<comment><USER5> You have more context (in that first example) and so the foo and bar indexes make great sense.

i and j really make more sense (as i and j) when used in their more mathematical connotation: indexes into a multidimensional array/object.

      for (i = 0; i < thing.length; i++) {
        for (j = 0; j < thing[i].length; j++) {
          thing[i][j]; // this is very close to the mathematical use of indexes
        }
      }

Makes perfect sense because i and j are being used to index into the same thing.

i and j would be poor fits for your first example because they don't index into the same thing anymore. You've introduced additional levels of indirection, to rewrite your first example using i and j (and illustrate why this is an awkward construct):

      for (i = 0; i < foos.length; i++) {
        for(j = 0; j < foos[i].bars.length; j++) {
          foos[i].bars[j];
        }
      }

It's not _wrong_ , but it is awkward and unclear as the code grows larger it becomes easier to misuse i, j, and subsequent index variables.

=====

And of course, you're absolutely correct: foreach or equivalent is a better construct. It states the intent of the code, rather than the how of the code. This keeps your code closer to the semantics of your problem specification.

<comment><USER6> however I would skip j as it is too similar to i. Use k instead.

</comment></comment></comment></comment></comment></comment><comment><USER7> Any time I read C/C++ code, I am under the impression it was written to be illegible.

I realize that with time, functions like `malloc` become second nature, but why not call it `allocate_memory`? (bash suffers from this too) It's even worse when reading the source code of old video games due to the abstract nature of the operations being performed on virtual representations of visual elements.

The argument of time constraints when authoring doesn't hold much value. Java is verbose AF but it's also one of the most used languages. Second, most code is read, not written and should be written to be read by others, not just the author.

There may be a reason to be terse due to time constraints and lack of IDEs/autocomplete or memory constraints or w/e, but the need to shorten variables names and functions today only serves the whims of the author, not the 10+ future readers. _tinyrant_ :D

<comment><USER8> There _was_ a time where visual and actual compactness was important. So for instance things like `malloc` date to that era. I'd argue that changing it to `allocate_memory` now would be even more confusing than leaving it as `malloc`

<comment><USER7> I fully agree. This reminds me of how some text books will teach people to write `a = 10` rather than `age = 10` for the sake of brevity. From that moment on, it becomes a habit to write code in a terse manner. It took me a few years and some good IDEs to no longer be afraid of names like `ageOfUser`/`age_of_user`.

<comment><USER9> > `ageOfUser`/`age_of_user`.

I'd be going with `userAge` or `user_age` either way. :-P

<comment><USER7> We can't be friends :P

</comment></comment></comment></comment></comment><comment><USER10> _> The design doc should break the algorithm down into a hierarchy of structured steps, described in a hierarchy of auto-numbered individual paragraphs in the document._

 _> then... (and this is the kicker) when you write the code, for each of these paragraphs you write a corresponding global function named:_

 _> Act1_2_4_6_3_13()_

 _> Do not document these functions. After all, that's what the design document is for!_

Ideally, your company will also have several file shares into which old and unidentifiable documents are filed, in nested layers of folders named things like "Old documents", "John's Code", "Please Clean Up", and "Maybe Delete". However, for maximum effectiveness do not file your design documents here! Instead, put various old drafts (not identified as such, of course) in a folder on the server where your code _used_ to run, somewhere like C:\backups\aurdbcl1\C\Documents and Settings\users\jdoe\Desktop\ (where aurdbcl1 is the name of the server where your program ran 20 years ago). This will ensure that they will spend as long of a time as possible hunting for something that could be useful. If possible, also ensure that there are some multi-Gigabyte zip files scattered about which have to be unpacked just in case there's something useful inside.

A related technique for compiled languages is to arrange for various copies of the source code to be copied into similarly diverse locations. Do not use version control under any circumstances; if you must, check in at most once a month with the comment "changed code". This works best for a program which is maintained very rarely. Anyone attempting to fix it will first have to identify which copy of the source code is the right one. Make sure you also have some copies that never made it to production, where you started changing things and never finished. If possible, the production version should also be subtly different from _all_ copies of the source code that can be found.

(The above is, unfortunately, from experience. I have many other rants which similarly belong in this document, particularly around exception handling and copy-pating, but I feel that this comment is becoming too long already.)

<comment><USER11> An approach from one of my early employment experiences (1980s):

1\. Write a CAD system. User-facing code in BASIC. Rendering engine written in assembly.

2\. Run the interpreted BASIC code through an optimizer, which condensed all variable and function names to be as short as possible (one or two characters) and moved frequently-used routines to the top of the module before compiling it all into one executable chunk (no more interpreter). This optimized code is almost unreadable but executes a lot faster (25%-50%) than the human-readable interpreted code. Hurray!

3\. Lose the original source code.

Build machine's hard drive died. The backups weren't. No version control -- only occasional snapshots. Source code that was on various floppy disks lying around the office was incomplete and badly outdated (like the "Old Documents/John's Code example, above).

4\. Team panics and spends a month trying to piece "Humpty Dumpty" (the software) back together again. No luck.

5\. Spend the next year trying to reconstruct function and variable names from "AA423()" and "aa_237" to such gems as "customerListIThink", "doesSomethingToInventory()", "NoIdea()", "BreaksWhenIChangeIt()" while struggling to add new features at 1/10th the rate before the loss.

6\. Try to rewrite the whole thing in C.

7\. Go out of business.

True story.

</comment></comment><comment><USER12> Disclaimer: This comment is mostly in jest.

For a second there I thought i was reading about golang[1].

* Single letter var names[2] / [3]

* Underscores [4] / [5]

* extended ascii code [6] / [7]

[1][https://golang.org/doc/effective_go.html](https://golang.org/doc/effective_go.html)

[2] [https://github.com/Droogans/unmaintainable-code#single- lette...](https://github.com/Droogans/unmaintainable-code#single-letter- variable-names) [3] [https://github.com/golang/go/wiki/CodeReviewComments#variabl...](https://github.com/golang/go/wiki/CodeReviewComments#variable- names)

[4] [https://github.com/Droogans/unmaintainable- code#underscore-a...](https://github.com/Droogans/unmaintainable- code#underscore-a-friend-indeed)

[5] [https://golang.org/doc/effective_go.html#blank](https://golang.org/doc/effective_go.html#blank)

[6] [https://github.com/Droogans/unmaintainable-code#extended- asc...](https://github.com/Droogans/unmaintainable-code#extended-ascii)

[7] [https://golang.org/ref/spec#Source_code_representation](https://golang.org/ref/spec#Source_code_representation)

<comment><USER13> > Single letter var names

They are also a Haskellers favorite.

There's a non-sarcastic paper running on the internet named something like "descriptive variable names considered harmful". Most of the community agrees with it, including me.

<comment><USER14> Why are they harmful?

</comment></comment></comment><comment><USER15> > Consider this real world example: a_crszkvc30LastNameCol.

> It took a team of maintenance engineers nearly 3 days to figure out that > this whopper variable name described a const, reference, function argument > that was holding information from a database column of type Varchar[30] > named "LastName" which was part of the table's primary key.

<comment><USER16> That's insane, what could those 3 engineers possibly be doing for 3 days?

\- const, reference and function argument should be pretty obvious from the code context

\- LastNameCol seems like self-describing... of course you would have to know that you're debugging an application that talks to databases, but eh

<comment><USER17> Most likely tracking down what originally populated the variable and how it's used. I'm assuming the code base was large and spaghetti like.

I'd say it's somewhat akin to proving a negative. Sure you get that it's a const, reference and function argument which likely refers to the Last Name Column. However is that all it is? Or is there more meaning in the name? Meaning that could be crucial to understanding how the application functions? Does one of the characters mean function reference or does it refer to something else? Apparently not in this case but how can you know without investigating?

<comment><USER18> Spending time to understand the author's intent of some code is one of the hardest parts of reading code.

It's like when you find a nil-guard in a function. You can't truly refactor it until you know whether it was added defensively just-in-case or whether nils can still exist in the system at the function's callsite, calling for further upstream examination.

There's a certain hell in trying to follow a code base where every function is infected with 'if (!arg) return'.

<comment><USER19> After dealing with code absolutely plagued with that pattern, languages with non-nullable types are amazing (Flow, Typescript in strict mode, Kotlin, Rust, ...) and I don't think I'm ever going to voluntarily switch away from them now.

</comment></comment></comment></comment></comment><comment><USER20> I had a colleague who used to use variable names from his local language in India (we were working in Europe at the time). So hwndParent would become hwndBaap. This combines both the hungarian and the local language strategies for job security.

Fortunately, he stopped programming and became very successful in agriculture. Good outcome for both fields.

<comment><USER21> > Good outcome for both fields.

Well that is what agriculture is all about.

</comment></comment><comment><USER22> This is much older than 2017; the version at [http://mindprod.com/jgloss/unmain.html](http://mindprod.com/jgloss/unmain.html) dates back to 2000.

</comment><comment><USER23> As a side note, the "opening" quote attributed to Napoleon, seemingly isn't:

[https://quoteinvestigator.com/2016/12/30/not- malice/](https://quoteinvestigator.com/2016/12/30/not-malice/)

I can offer as corollary to the article a couple of unmaintainable simple batches:

[http://reboot.pro/topic/2986-yacbfc-dec2hexcmd-and- hex2deccm...](http://reboot.pro/topic/2986-yacbfc-dec2hexcmd-and- hex2deccmd/?p=204425)

<comment><USER24> > Quidquid latine dictum sit, altum sonatur. - Whatever is said in Latin > sounds profound.

This one is good and there's no attribution problem.

</comment></comment><comment><USER25> I have an addition to writing unmaintainable code.

Only have one struct with a member of every type. That one struct will be the type of every variable you have.

If the language you use support implicit operator overload abuse them to make sure all types can be implicitly converted to each other.

Ex.

struct Variable { byte a; short c; int d; long e;

        ...

}

This will make it impossible to know what type a variable is until you find its assignment, which of course isn't on the same line as the declaration and even better reuse the same variable for multiple values.

<comment><USER26> If you want to be more efficient, you can also use a union for this.

typedef union { int i; float f; double d; long l; char c; void *p; ... } var;

Now you might also get some nice float-interpreted-as-int bugs if you forget the type!

You can also kind of pretend that you have C#-style type inference:

var x = { .i = 10 }; var y = { .f = 2.0f };

<comment><USER25> But you don't want to be efficient lmfao

</comment></comment></comment><comment><USER27> I had a funny now/frustrating then story where I worked with his guy who named five variables in a class a, aa, aaa, aaaa, aaaaa. I was trying to refactor his code and I had no idea what anything did. The company is out of business now, but it was definitely unmaintainable.

</comment><comment><USER28> Recently I came across some code that checks quite a few boxes in this guide. Check it out: [https://github.com/KxSystems/kdb/blob/master/c/c/k.h](https://github.com/KxSystems/kdb/blob/master/c/c/k.h) [https://github.com/KxSystems/kdb/blob/master/c/c/odbc.c](https://github.com/KxSystems/kdb/blob/master/c/c/odbc.c)

<comment><USER29> It's written like it's APL (I think? iirc k is an APL-style language), so it actually makes some sense. To the way that the authors actually write code, I think it's perfectly legible, just not to outsiders.

<comment><USER28> Isn't making code ineligible to outsiders an essential requirement for job security? And how much sense does it make to you? What can you tell about this code except for "it's written like APL?" Can you tell what it does? How it does that? What all those one letter functions/macros mean? No, you can't tell shit.

</comment></comment></comment><comment><USER30> Along a similar line, I love Stuart Halloway's talk on Narcissistic Design - [https://www.youtube.com/watch?v=LEZv- kQUSi4](https://www.youtube.com/watch?v=LEZv-kQUSi4)

Prefer APIs over data.

Start with DSLs.

Always connect (and never enqueue).

Create abstractions for information.

Use static typing across subsystem boundaries.

Put language semantics on the wire.

Write lots of unit tests.

Leverage context.

Update information in place.

</comment><comment><USER31> > a naming convention from the world of C++ is the use of m_ in front of > members. This is supposed to help you tell them apart from methods, so long > as you forget that "method" also starts with the letter "m".

C++ has member variables (which this refers to) and member functions.

"Method" is not part of the vernacular.

</comment><comment><USER32> What incenses me is this recent notion that because programmers fail to change comment with the code change, they shouldn't even write comments. They should instead write the self-documenting code.

This doesn't make sense on so many levels. Only a recluse sitting in some dungeon who never dealt with people can come up with something so inane.

Edit:

I understand that that every developer should aspire to become someone who writes code that reads like a children's book, and they should. However, actively discouraging writing comments is so wrong on so many levels.

At the last place I worked, we used to have a small at-home coding test before interview and none of the young developers who successfully completed the test did any sort of code documentation or commenting. When I asked why, they would tell me that their code is self-documenting, which was utter nonsense.

<comment><USER33> I found this technique to work quite well, but this idea does not mean imply that one should simply "quit writing comments", but rather that comments can most often be replaced with actual structures that improve the code (e.g., extracting long boolean expressions into a function with the same name as the actual comment), but that also depends on the language and aptitude of the developer.

Would you really argue in favor of something like this?

``` class Account { ... /// returns the accountId public int d_nr() { ... } } ```

``` class Account { ... /// returns the accountId public int getAccountId () { ... } } ```

The first comment is obsolete when using a proper method name, the second does that and so the comment is redundant.

May I ask: What did you experience in the wild?

<comment><USER34> Or even better don't return an int return an "accountId" type.

<comment><USER35> Please don't do this!

All you have accomplished really is to move the descriptive name from the variable's name to the variable's type, and at what cost? You now have to create a whole new datatype. The programmer must look up that datatype and see oh, it's just an int. And now you need conversion routines or worse yet casting to convert that type to a simple int for interop reasons (database, UI).

Experience has shown that it is very productive to have a _small number of generally useful datatypes_ which are augmented by custom datatypes.

Creating a new datatype for something as simple as an int or String defeats that and makes it more cumbersome to work with. (It's especially unwarranted for a variable that is an immutable variable serving as a simple id.)

<comment><USER34> You haven't just moved the descriptive name from the variable name to the type.

If you are using a strongly typed language, you can just right click on the accountId type and find everywhere in your codebase where the "accountId" is being used.

The "accountId" is not "just an int". An accountId has semantics that would be different than an int. An accountId is not the same as a "customerId" that may also be represented as an int. The accountId also has different uses than an int. You're not going to take the sum, average, etc of an accountId.

An accountId that happens to have a value of 1 is semantically not equivalent of a customerId of 1. A method that expects a list of accountIds that are just ints will just as happily take a list of customerIds.

But a method that takes as a parameter List<AccountId> will cause a compile time error if you pass in a List<CustomerId>.

Why use a strongly typed language and then ruin one of the benefits of it if you don't use domain specific types?

<comment><USER33> I agree with @scarface74 and would go even further in that I would probably create a custom type for List<AccountId> to convey the purpose of what that thing is now.

And as for the "type shyness":

> Creating a new datatype for something as simple as an int or String defeats > that and makes it more cumbersome to work with.

It is never "just an int". Soon you will ask questions about the int, and in a sufficiently large application you will forget the answers to the quesions easily, and scatter the same question (i.e., the same boolean logic) all over the place. Consider an application where you need to filter something by year. A year, you know? As in 1974, 2018, etc. An int is bad, because an int could be -5, which does not make sense. Ok, a uint then? Still bad, because then there is a year 0 and - if your application deals with birthdays of real people, 1800 would be an invalid birthday. The semantics (or pragmatics, linguistically speaking) emerge from how you interpret the integer, and this interpretation can happily live in that one file with that one class that encapsulates "just" that integer.

The AccountId probably shouldn't be < 0, and a specific type could be the one place where you make sure that this is always the case.

What if you start with a 32bit integer and suddenly you realize that your weird Internet-Of-Things-Sensor reading database has grown and the 32bit integer is getting too small? You could just use 64bits. With "just an int", you now get to change every single function that expects an int for the purpose of a SensorReadingId (or an account id or whatever) and change it to size_t, uint, int64 or whatever. OR, you just tell the object that its internal representation uses 64bits now, because the AccountId class is the one single place that deals with account ids. The type provides a consistent interface that allows you to infer the semantics of its use. An int doesn't do that.

This idea predates java by some ~20 years [1]. An int is not an account id. An int is not a year. An email is not a string. The result of working like that is considered a code smell [2].

Still, coming back to the example I made: It was primarily about commenting. I was taught to always comment, and StyleCop enforced comments on each and every field of a class, leading to noisy, superfluous comments.

        /// Gets or Sets the Name
        string Name { get; set; }

does not add anything.

As for returning an AccountID: I'd like to point out that the Account is a strong and independent object, who can make his own decisions and does not need to return anything. Returning its id like that is actually breaking encapsulation. Still if you do it, it probably shouldn't be an integer.

Why are people scared of creating types and objects?

[1] [https://link.springer.com/chapter/10.1007%2F978-1-4612-6315-...](https://link.springer.com/chapter/10.1007%2F978-1-4612-6315-9_22)

[2] [https://sourcemaking.com/refactoring/smells/primitive- obsess...](https://sourcemaking.com/refactoring/smells/primitive-obsession)

<comment><USER35> Your example of needing to define a type because "int" is not good enough is very C/C++ centric.

Most languages don't have the plethora of integer types that C has. Java, for example, has just has 2 in general use: int (signed 32 bit) and long (signed 64 bit). (Nobody considers byte a general integer type.)

In C/C++, you have to define so many things about the types you use because so much is "implementation dependent." So for C/C++, you may be correct. Most other languages define their types more stringently and include a smaller number of general purpose types.

<comment><USER34> C# has nine integral types.

[https://docs.microsoft.com/en-us/dotnet/csharp/language- refe...](https://docs.microsoft.com/en-us/dotnet/csharp/language- reference/keywords/integral-types-table)

But even then, a year is an int, but it would have certain semantics you would want to enforce outside of integers.

</comment></comment></comment></comment></comment></comment></comment></comment><comment> pure-awesome > Since global variables are "evil", define a structure to hold all the things > you'd put in globals. Call it something clever like EverythingYoullEverNeed. > Make all functions take a pointer to this structure (call it handle to > confuse things more). This gives the impression that you're not using global > variables, you're accessing everything through a "handle". Then declare one > statically so that all the code is using the same copy anyway.

I see this in practice WAY too often... Heck, I've been somewhat guilty of it myself before.

(Bonus points if it's in a functional language :P )

<comment><USER36> And it's perfectly valid on constrained systems where you don't have or want to make heavy use of malloc() and don't have namespaces. Provided the structs stay reasonably focused on one domain.

<comment> pure-awesome Emphasis on the "reasonably focused on one domain" part - it's when you're passing through your entire program state in one gigantic state object that things get messy.

Also, I've been led to believe that design of constrained / embedded systems follow different rules. Your code can be unreadably complex if you _have_ to squeeze out that extra performance (however, even then, it should probably be well-commented or well-documented), and generally (though not alway) such programs will be smaller and made by smaller teams.

It's when these kind of practices are applied in enterprise software with large number of programmers, where maintainability is more important than performance, that this is an issue.

</comment></comment></comment><comment><USER37> > In C, functions are supposed to be idempotent, (without side effects).

What is meant by that statement? Is "idempotent" a mistype/mistakenly selected word? If the author meant "pure" instead, should I file a PR, or consider this some sort of meta-meta-obfuscation? If the author meant "pure", is that actually true of C specifically, or just generally good programming advice (localize side effects to known locations, the fewer the better, don't sprinkle them all over and document where they occur)?

<comment><USER38> C functions shouldn't change behavior based on state, they do the same thing every time. Instead of changing a particular global variable, any variable of that type should be passed in and changed, then returned. It's good programming advice for functional languages. In OO it makes sense to make state changes in object methods, but not _usually_ the best functional approach.

</comment></comment><comment><USER39> Well, since the repo more or less took the contents verbatim from the original author (unless they are the same), and here presents it _more_ clearly than the original, I'd say the repo owner failed.

At the very least it should be presented in a more unmaintainable way.

Edit, apparently repo owner already checked with author: [https://github.com/Droogans/unmaintainable- code/issues/3](https://github.com/Droogans/unmaintainable-code/issues/3) :+1:

<comment><USER40> Interesting, I find the one long document less clear then the original that's categorized in subpages.

</comment></comment><comment><USER41> As a creative process, and in the interest of compassion, I tend to name everything as humanly readable as possible, and provide voluminous documentation in production systems. Even quick-and-dirty things tend to get moved to production if they work, so I increasingly apply the same approach to them, as the "this will be tossed after x" sentiment has bitten me on the ass more than once.

<comment><USER33> Could you elaborate what criteria you apply to decide whether something is "as humanly readable as possible"? I am asking out of genuine interest, I am researching readability and I am interested in how you make decisions and what criteria you apply. What means "readable" to you?

</comment></comment><comment><USER42> Ok so sometimes I have no concept of what american and british variants of a word are because I'm from mainland europe and so I will just use whatever. Sorry maintainers!

Grey/Gray gets me every time.

<comment><USER43> > Grey/Gray gets me every time.

GrEy for England, grAy for America.

<comment><USER42> Oh! That's a nice way to memorize it, thanks!

</comment></comment></comment><comment><USER9> I'd add something about breaking common conventions like moving the verb to the end of the function name. For example, I'd change GetPageFromServer() to PageFromServerGet()

Also, use synonyms for common function verbs. Like Grab instead of Get. GrabPageFromServer()

In a code base I dealt with, a developer did exactly those. Most "get" functions had "get" at the end of the function name. Some functions had it at the beginning, but replaced with "grab".

Also, he misspelled a class name and just went with it.

</comment><comment><USER25> "Hungarian Notation is the tactical nuclear weapon of source code obfuscation techniques; use it!" \- I'm laughing so hard. This whole article is genius.

<comment><USER25> Also "Be polite, Never Assert Avoid the assert() mechanism, because it could turn a three-day debug fest into a ten minute one."

</comment></comment><comment><USER44> A much novel way - use functional programming and create higher order functions and purely mathematical combinatoric functions and compose them in a complex way. A normal day developer must go to college again to even getting closer to understand it. This way the code is highly functional and there won't be a compromise in the quality of the output!

<comment><USER45> Thats what i actually use with C macros, except its intentional and saves lots of typing: however you must know some macro trickery to understand how it even works.

</comment></comment><comment><USER46> I inherited some code with m_ prefixes on parameters to a function. eg theFunction(int m_param1) That should be a lint error.

</comment><comment><USER47> How is this any "easier to share"?

<comment><USER48> This version is certainly much more readable for me than the older intrusive ad ridden, click farming version.

</comment></comment><comment><USER49> There are 2 hard problems in computer science: cache invalidation, naming things, and off-by-1 errors.

</comment><comment><USER50> Don't bother with all that documentation, get straight into the Stackoverflow example:

[https://github.com/Droogans/unmaintainable-code#a-real- life-...](https://github.com/Droogans/unmaintainable-code#a-real-life-example)

</comment><comment><USER51> For embedded C work I do like to mark global variables with a Hungarian g_, all other prefixes are generally handled pretty well by the IDE's type hinting. Other than that I agree Hungarian can go!

</comment><comment><USER52> Surprisingly light on multithreading and version control best practices.

</comment><comment><USER53> The comment section is particularly trenchant because I recently worked on a project that had hundreds of instances of the comment "// do this here"

</comment><comment> S-E-P My personal trick: Write a basic (not turing complete) brainf __k compiler into your application and feed your business logic through that.

<comment><USER25> The brainfk compiler should have reversed symbols. Ex. > will decrement the pointer, < will increment the pointer, + will subtract, - will add, . will read, , will read, ] start loop, [ end loop

<comment> S-E-P you are an absolute madman you know that haha!

<comment><USER25> I'm awawre of that!

Also I noticed a mistake in my comment.

I wrote ", should read" it should of course have been ", should write"

</comment></comment></comment></comment><comment><USER54> One of the longest jokes I've seen.

</comment><comment><USER55> Now whenever someone criticizes my old code I can point them to this and say it could be worse.

</comment><comment><USER56> hahah so glad Hungarian notation was included.

</comment><comment><USER57> Just use perl.

<comment><USER58> Do you have any data to back up that claim? Or are you just propagating prejudice?

<comment><USER57> It was a joke, take it easy. With that said, perl has a multitude of ways to shoot yourself in the foot and future maintainers in the face. Notably, the obscure tricks perl allows you to write that are difficult to read in the future but seem clever when you write them. I've written enough perl to know they exist but thankfully forgotten all of them so I can't give a good example. I just remember something about $_ being interesting at times.

<comment><USER59> Then you don't know enough about it.. now you are the joke.

</comment></comment></comment></comment><comment><USER33> Many people are pointing out that short identifier names are ok, and that i is perfectly fine as an identifier name. It likely is, and I believe the rule to be true that short identifier names are ok for short scope / context. However, there are several issues:

i for an index is ok, but this is a red herring: You only ever need an i for imperative iteration and in a sufficiently high level language you are better of with selection and projection, (iteration for that matter), where you just foreach over each element and don't actually need to ask for things by index. Sure, y'all be hacking C, nothing wrong with that, it depends on what you str doing, but for comprehension, the mere existence of i is a red flag, because most of the time you want something to happen to a collection if things and foreach is perfect for that (or map, fold, filter, pick your poison).

Still, a better example than `i` for short identifier names would be x,y,z, or r,g,b These are so common and conventional that I would expect them to have semantics of their own, still they could be chunked to types such as Coordniate, Location, or Point, or Paint, or Color, respectively. But comming up for better names than x,y,z is really difficult, will bloat your code and make it hard to understand what is going on.

I am pointing this all out, because many of you seem to favor such very short identifier names - and I am with you: sometimes they make sense, see above - but empirical evidence suggests that very short identifier names, and single- letter identifier names in particular significantly worsen comprehension of code. The same is true for abbreviations (depending on how strongly you abbreviate).

[1] [https://ieeexplore.ieee.org/document/7884623/](https://ieeexplore.ieee.org/document/7884623/) (disclosure: author)

[2] [https://doi.org/10.1007/s11334-007-0031-2](https://doi.org/10.1007/s11334-007-0031-2)

[3] [http://compscinet.dcs.kcl.ac.uk/JP/jp040302.abs.html](http://compscinet.dcs.kcl.ac.uk/JP/jp040302.abs.html)

[4] [https://dl.acm.org/citation.cfm?doid=382080.382628](https://dl.acm.org/citation.cfm?doid=382080.382628)

[5] [https://link.springer.com/article/10.1007%2Fs10664-018-9621-...](https://link.springer.com/article/10.1007%2Fs10664-018-9621-x)

Preprint for [1] here: [https://brains-on-code.github.io/shorter-identifier- names.pd...](https://brains-on-code.github.io/shorter-identifier-names.pdf)

[5] is the extended Version of [1] including discussion of how attention is shifted during the experiment. It turns out that, when code uses words as identifier names people don't need to read the comments as much.

</comment><comment><USER60> "Hungarian Notation is the tactical flesh light of source code obfuscation offering max pleasure; use it!"

</comment><comment><USER61> This is suppose to be funny , unfortunately this is the sad reality of what you'll find in 90% of Enterprise / Startups environment as well as THE majority of open source repositories of popular open source projects.

I've noticed this especially true for JavaScript and Go.

In JavaScript , because the language is still evolving and there is no real standard about how to architect code with this language unless you are using a entire "platform" like Angular / Vue / React witch will highly influence your coding style.

In Go because Go developers are performances obsessed , coming from C/C++ background and do believe that naming their variable with one letter will save 1GB of memory allocation , 1000 CPU Cycles and make their code "Clear and Concise"

Ultimately , because there is very little standard in this industry in terms of code governance and a large percentage of projects are outsourced to other companies , we end up with what is described in this repository.

<comment><USER62> In Go single letter variables are used when they are short lived (3 or 4 lines) and in this cases I find it way more readable than long names.

<comment><USER63> It's also perfectly acceptable (and preferred) if the code maps cleanly onto some existing mathematical terminology. 'v' is more readable than 'velocity' in the correct context.

<comment><USER64> ... until it isn't.

The problem is that you get too close to the code you write, and make assumptions about its obviousness that simply aren't true. Far better to be explicit at the cost of a few extra keystrokes.</comment></comment></comment></comment>


RCS, Not Hangouts, Is Google's Play in Conversational Commerce - <AUTHOR> http://servo.ai/rcs-not-hangouts-is-googles-play-in-conversational-commerce/ <comment><USER2> Apparently RCS is this: [https://en.wikipedia.org/wiki/Rich_Communication_Services](https://en.wikipedia.org/wiki/Rich_Communication_Services)</comment>


Google reportedly removing SMS texting from Hangouts on May 22 - <AUTHOR> https://arstechnica.com/business/2017/03/google-reportedly-removing-sms-texting-from-hangouts-on-may-22/ <comment><USER2> More disappointing news of Google removing a useful feature...</comment>