[HN Gopher] Software development topics I've changed my mind on
       ___________________________________________________________________
        
       Software development topics I've changed my mind on
        
       Author : belter
       Score  : 570 points
       Date   : 2025-02-05 09:50 UTC (13 hours ago)
        
 (HTM) web link (chriskiehl.com)
 (TXT) w3m dump (chriskiehl.com)
        
       | Terr_ wrote:
       | > Java is a great language because it's boring [...] Types are
       | assertions we make about the world
       | 
       | This is less of a mind-was-changed case and more just
       | controversial, but... Checked Exceptions were a fundamentally
       | good idea. They just needed some syntactic sugar to help redirect
       | certain developers into less self-destructive ways of
       | procrastinating on proper error handling.
       | 
       | In brief for non-Java folks: Checked Exceptions are a subset of
       | all Exceptions. To throw them, they must be part of the
       | function's type signature. To call that function, the caller code
       | must make _some_ kind of decision about what to do when that
       | Checked Exception arrives. [0] It 's basically another return
       | type for the method, married with the conventions and flow-
       | control features of Exceptions.
       | 
       | [0] Ex: Let it bubble up unimpeded, adding it to your own
       | function signature; catch it and wrap it in your own exception
       | with a type more appropriate to the layer of abstraction; catch
       | it and log it; catch it and ignore it... Alas, many caught it and
       | wrapped it in a generic RuntimeException.
        
         | dustingetz wrote:
         | remind me why they don't work? because "throws Exception"
         | propagates virally to every method in the codebase?
        
           | rad_gruchalski wrote:
           | Well, if you don't handle them then... yes? What else can be
           | done?
        
             | karatinversion wrote:
             | There's also the fact that common methods threw exception
             | types that were not final, and in fact overly generic. If I
             | call a method that declares itself to throw
             | NoSuchFileException or DirectoryNotEmptyException, I can
             | have a pretty good idea what I might do about it. If it
             | throws IOException without elaboration, on the other
             | hand...
        
               | jkrejcha wrote:
               | With regards to I/O, there are generally any number of
               | weird errors you can run into, file not found, directory
               | exists, host unreachable, permission denied, file
               | corrupt, etc etc. Like anything file related will be able
               | to throw _any_ of those exceptions at almost any point in
               | time.
               | 
               | I think IOException (or maybe FileSystemException) is
               | probably the best you can do in a lot of I/O cases unless
               | you can dedicate time to handling each of those specially
               | (and there's often not a lot much more you can do except
               | for saying "Access is denied" or "File not found" to the
               | user or by logging it somewhere).
        
               | bluGill wrote:
               | There are fatal IO errors and non-fatal. Most of us don't
               | care about the non-fatal case, but mainframes have the
               | concept of "file isn't available now, load tape 12345",
               | "file is being restored from backup, try again tomorrow"
               | - things that your code could handle (if nothing else you
               | should inform the user that this will take a while).
               | There is also the "read off the end of the file"
               | exception which in some languages is the idiomatic way to
               | tell when you have read the whole file.
               | 
               | But most IO errors are fatal. It doesn't matter if the
               | filename is not found, or the controller had too many
               | errors talking to the drive and gave up - either way your
               | code can do nothing.
        
           | lmm wrote:
           | Because you can't capture the evaluation of a function as a
           | value, or write the type of it. E.g. try to write a generic
           | function that takes a list and a callback, and applies the
           | callback to every element of the list. Now what happens if
           | your callback throws a checked exception? It doesn't work and
           | there's no way to make it work, you just have to write
           | another overload of your function and copy/paste your code.
           | Now what happens if your callback throws two checked
           | exceptions? It doesn't work and there's no way to make it
           | work, you just have to write another overload of your
           | function and copy/paste your code. And you'll never guess
           | what happens if your callback throws three checked
           | exceptions!
        
             | dustingetz wrote:
             | what is "it doesn't work" ? The exception is part of the
             | type, so it doesn't typecheck unless all callbacks are of
             | type "... throws Exception"? What's the problem with that?
             | It's not generic enough, i.e. the problem is Java generics
             | are too weak to write something like "throws <T extends
             | Exception>"? (Forgive me, it's been 13 years since I wrote
             | java and only briefly, the questions are earnest)
             | 
             | edit, so like `@throws[T <: Exception] def effect[T]():
             | Unit` or something, how is it supposed to work?
        
               | lmm wrote:
               | You can't be polymorphic between not throwing and
               | throwing, or between throwing different numbers of
               | exceptions. You have to write something like:
               | <R> List<R> map(Function<? super T,? extends R> mapper) {
               | ... }         <R, E1 extends Throwable> List<R>
               | map(FunctionThrows1<? super T,? extends R, E1> mapper)
               | throws E1 { ... }         <R, E1 extends Throwable, E2
               | extends Throwable> List<R> map(FunctionThrows2<? super
               | T,? extends R, E1, E2> mapper) throws E1, E2 { ... }
               | 
               | and so on until you get bored.
        
               | catlifeonmars wrote:
               | Ah because there is no way to express E1 | E2 as a type
               | parameter?
        
               | dustingetz wrote:
               | ah!
        
             | AnimalMuppet wrote:
             | Make the signature of your generic callback "throws
             | Throwable". It's generic; it should never care about the
             | specific types that the callback can throw.
             | 
             | (Except that then you have to decide what your generic
             | function is going to _do_ if the callback throws an
             | exception...)
        
               | lmm wrote:
               | > Make the signature of your generic callback "throws
               | Throwable". It's generic; it should never care about the
               | specific types that the callback can throw.
               | 
               | > (Except that then you have to decide what your generic
               | function is going to do if the callback throws an
               | exception...)
               | 
               | Exactly. Presumably you don't want to handle them and
               | want to throw them up to the caller. But now your
               | function has to be "throws Throwable" rather than
               | throwing the specific exception types that the callback
               | throws.
        
               | bluGill wrote:
               | By doing that you lose all the benefits of checked
               | exceptions. If you have checked exceptions everywhere the
               | compiler will tell you when an exception is not handled
               | and in turn you can ensure you handle it.
               | 
               | Of course in general the manual effort to do that in a
               | large code base ends up too hard and so in the real world
               | nobody does that. Still the ideal is good, just the
               | implementation is flawed.
        
               | throwaway-9111 wrote:
               | In that case you can use the lombok @SneakyThrows
               | annotation that converts a checked exception to a runtime
               | exception
        
           | bluGill wrote:
           | Because eventually someone will want to add another exception
           | to a new leaf class and the proper place to handle it is 20
           | functions down the call tree and every single one of those 20
           | functions needs to now add that new exception to their
           | signature even though only the handler function cares and you
           | adjusted it.
           | 
           | I haven't done java in decades, but I imagine this would get
           | really nasty if you are passing a callback to a third party
           | library and now your callback throws the new exception.
           | 
           | Checked exceptions seem like a great idea, but what java did
           | is wrong. I'm not sure if other implementations are better.
        
             | zaphar wrote:
             | The counter point here is that at least with Checked
             | Exceptions you know only those 20 functions are part of the
             | code path that can throw that exception. In the runtime
             | exception case you are unaware about that 21'st function
             | elsewhere that now throws it and it's not in the correct
             | handling path anymore.
             | 
             | You have no way to assert that the error is always
             | correctly handled in the codebase. You are basically
             | crossing your fingers and hoping that over the life of the
             | codebase you don't break the invariant.
             | 
             | What was missing was a good way to convert checked
             | exceptions from code you don't own into your own error
             | domain. So instead java devs just avoided them because it
             | was more work to do the proper error domain modeling.
        
               | bluGill wrote:
               | Like I said, the implementation is wrong. Adding an
               | exception to that 21st function, and then that whole call
               | chain as well ends up being a lot of work. Sure you
               | eventually find the place to handle it, but it was a lot
               | of effort in the mean time.
               | 
               | It gets worse. Sometimes we can prove that the 21st
               | function because of the way it is calling your function
               | can never trigger that exception, but still it will need
               | code to handle it. If that handler code if the 21st
               | function changes to trigger the exception now should be
               | propagated back down but since you handled the exception
               | before checked exceptions won't tell you that you handled
               | it in the wrong place.
               | 
               | I don't know how to implement checked exceptions right.
               | On paper they have a lot of great arguments for them.
               | However in practice they don't work well in large
               | projects (at least for java)
        
               | zaphar wrote:
               | The Rust Result type with accompanying `?` operator and
               | the `Try*` traits are how you implement exceptions
               | correctly. It makes it easy to model the error domain
               | once in your trait implementations and then the `?` does
               | the rest of the work.
               | 
               | You could imagine something similar with Exceptions where
               | there is simple and ergonomic way to rethrow the
               | exception into your own error domain with little to no
               | extra work on the part of the developer.
        
         | pjc50 wrote:
         | It was botched from the start because there's so many
         | opportunities for _unchecked_ exceptions as well. Without a
         | more sophisticated type system that represented nullability,
         | you can get NullPointerException anywhere. Divide by zero. And
         | so on.
         | 
         | You also have a problem similar to "monads and logging": if you
         | want to log from anywhere in your program, your logging
         | function needs to be exception-tight and deal with all the
         | possible problems such as running out of disk space, otherwise
         | you have to add those everywhere.
        
           | jeroenhd wrote:
           | Unchecked exceptions are just Java's weird way of what
           | languages call panicking these days. They suck, but as long
           | as you don't throw them yourself and catch them in a logical
           | place (i.e. at request level so your web server doesn't die,
           | at queue level so your data processing management doesn't
           | lock up, etc.) you can usually pretty much ignore them.
           | 
           | The worst part about them is that for some reason even
           | standard library methods will throw them. Like when you try
           | `list.Add(1)` on a list without checking if said list is
           | read-only. The overhead of having to read every single bit of
           | documentation in the standard library just to be ahead of
           | panicking standard methods is infuriating.
           | 
           | That's got nothing to do with the concept of
           | checked/unchecked exceptions, though, that's just Java's
           | mediocre standard library.
        
           | corytheboyd wrote:
           | > Without a more sophisticated type system that represented
           | nullability, you can get NullPointerException anywhere.
           | 
           | I started working in Java a few months ago and holy shit does
           | this stick out like a sore thumb. Null checks cascade down
           | from gods domain all the way to hell. But oop we missed one
           | here and caused an outage lol add one more! So much wasted
           | human effort around NPE, and yet, we sit around in a weekly
           | meeting getting yelled at about how stability needs to be
           | taken more seriously. Hrm.
        
             | pjc50 wrote:
             | C# half-fixes this with its nullable annotations. I say
             | half-fixes, because the boundary between code that supports
             | them and code that does not is leaky, so you can make a
             | mistake that leaks a null into a non-nullable variable.
             | 
             | If you build an entire program with nullability checking on
             | it's pretty great, though.
        
               | corytheboyd wrote:
               | Java, or at least Lombok, seems to have a @NonNull
               | annotation that does what I want-- cause code not to
               | build that fails the check, and forces propagation of the
               | annotation.
               | 
               | Reality does indeed feel exactly like what you mentioned
               | with C#, though. The annotation is going to be missing
               | where it's needed most unless something forces the whole
               | project to use it.
        
               | mands wrote:
               | check JSpecify (https://jspecify.dev) - it's the
               | standardised null annotation package for Java. Intellij
               | understands the annotations so you generally get decent
               | null-checking across your codebase.
               | 
               | Even better, apply at the package level via `package-
               | info.java` (unfortunately sub-packages need to be
               | individually marked as well)                 @NullMarked
               | package com.foo;            import
               | org.jspecify.annotations.NullMarked;
        
               | YoshiRulz wrote:
               | Kotlin fixes the null handling problem too, and with the
               | added benefit of being able to gradually migrate Java
               | code.
        
         | flir wrote:
         | > Alas, many caught it and wrapped it in a generic
         | RuntimeException.
         | 
         | Actually sounded great right up until this point. Deal with it,
         | or explicitly acknowledge that you do not. It's honest.
         | 
         | Apparently other developers are why we can't have nice things.
        
           | mrkeen wrote:
           | It's already very unlikely that you can 'recover-and-proceed'
           | in the context of any business app exception (Security
           | violation, customer not found, no such payment, etc.).
           | 
           | So what's left in exception handling is logging and/or
           | rethrowing. And the 'nasty hackish way' of doing it
           | (RuntimeException) already passes a complete stack trace up
           | to the caller.
        
             | wavemode wrote:
             | "recover and proceed" generally means "log the error and
             | then continue processing on other data, rather than exiting
             | entirely"
             | 
             | Lots of different kinds of software tends to follow this
             | pattern - web servers, data pipelines, compilers/build
             | tools, etc.
        
         | pjmlp wrote:
         | I agree, although I would like to point out Java usually gets
         | the blame for what was actually an idea being done in CLU,
         | Mesa, Modula-3 and C++, before Oak came to be and turned into
         | Java.
         | 
         | Additionally, the way result types work, isn't much different,
         | from type system theory point of view.
         | 
         | I really miss them in .NET projects, because no one reads
         | method documentation, or bothers to have catch all clauses, and
         | then little fellow crashes in production.
        
         | girvo wrote:
         | Checked exceptions as an idea are great (Nim's usage of
         | something similar is excellent) but yeah Javas particular
         | implementation was annoying and easy to avoid, so most did.
        
         | baq wrote:
         | > adding it to your own function signature
         | 
         | This is precisely why they are so bad: checked exceptions must
         | not be allowed to be used outside the package (or jar, or
         | whatever, just limit it) otherwise they cause non-local build
         | failures in all dependencies. They're fine if you are
         | developing the artifact that's going to be deployed.
        
           | catlifeonmars wrote:
           | I think that's more of a problem of changing the function
           | signature. Not specific to checked exceptions.
        
             | baq wrote:
             | What's specific in checked exceptions is that if you don't
             | handle or silently ignore the new exception, you must
             | change the signature. Then your callers must do the same
             | thing. Then their callers etc. sometimes right down to your
             | public static void main.
        
               | catlifeonmars wrote:
               | Yep, don't change the function signature of depended on
               | code. That's the problem :)
               | 
               | It would be equally problematic to change the method
               | name, or the argument arity or types (ignoring
               | overloading for the moment).
               | 
               | It would be even more problematic if I kept the same
               | function signature, but changed the meaning of the
               | parameters. Then your breakage is silent.
        
               | baq wrote:
               | yes exactly, hence unchecked exceptions are the sane
               | option.
        
               | catlifeonmars wrote:
               | Doesn't that just introduce a silent breaking change to
               | your downstream consumers? That sounds worse.
               | 
               | It sounds ok from a library authors perspective but
               | definitely not from a library consumer perspective.
               | 
               | A sane thing to do would be to do a version bump.
        
               | baq wrote:
               | consider the standard library case - e.g. there's a new
               | kind of exception because new storage or network
               | technology demands it. you can't add it without breaking
               | the build of everything everywhere effectively freezing
               | the standard library version for people who don't have
               | the means to fix their build. that's super duper bad.
        
               | Terr_ wrote:
               | 1. The standard library is special in many ways,
               | particularly because it often isn't shipped along with
               | your product and you can't always control what version is
               | used. Just because something is problematic for _those_
               | libraries doesn 't mean it it's a bad idea everywhere
               | else.
               | 
               | 2. The difference between altering your un/checked
               | exceptions is not _whether_ consumers will have to react,
               | but _how_ it shows up and _how badly_ you will ruin their
               | day. A checked exception is unambiguously better. It will
               | immediately break their build at the same time they
               | _ought_ to be expecting build-breaks, and the compiler
               | will give them a clear and comprehensive list of cases to
               | address. In contrast, an unchecked exception may let them
               | compile but it will break their business _in production_
               | , unpredictably.
        
               | baq wrote:
               | Re 1) when the standard library becomes a major blocker
               | for the runtime version upgrade many people are seriously
               | angry, or depressed.
               | 
               | Re 2) that's what it must've sounded like in theory in
               | the conference room when they were designing that part of
               | the language. In practice, the upgrade of the library
               | will never happen if it breaks the build. Production
               | should catch all runtime exceptions and be able to
               | restart itself gracefully anyway because cosmic rays
               | don't make sense as checked exceptions.
        
               | Terr_ wrote:
               | And that is _extremely good_ compared to the same
               | function-writer adding or changing their non-checked
               | exception, for which an 1+ levels removed consumer gets
               | _no warning at all_ until the pager goes off because the
               | system broke in production.
        
               | baq wrote:
               | Unless the library upgrade is also fixing a 9.9 CVE.
        
               | Terr_ wrote:
               | That same scenario (an emergency version-change to a
               | direct dependency) could also _remove a function_ that
               | your code calls! Yet that does not mean mean compiler-
               | checks are bad, or that the solution is to make a system
               | that lets you yeet it into production anyway.
               | 
               | Look, I get it: Sometimes a Checked Exception defined in
               | a niche spot "infects" higher-level code which adds it to
               | their signatures, because nobody takes the time to
               | convert it into something more layer-appropriate.
               | 
               | But that is the _exact same kind of problem_ you 'd also
               | get when library's NicheCalculationResult class is
               | trickling upwards without conversion too! However nobody
               | freaks out over _that_ one. Not because it 's
               | mechanically different, but because it's _familiar._
        
               | baq wrote:
               | > That same scenario (an emergency version-change to a
               | direct dependency) could also remove a function that your
               | code calls!
               | 
               | absolutely, but the catch is it doesn't affect me
               | _transitively_. the immediate caller must deal with the
               | issue somehow. with exceptions, it is _expected_ to not
               | handle the ones you have no business handling, so you
               | _should_ change your signature. this propagates upwards
               | and there is no layer of abstraction that can handle this
               | problem without breaking the world. the only somewhat
               | sane way is wrapping the new exception is something that
               | you already handle - if that makes logical sense, which
               | it very well might not.
               | 
               | > NicheCalculationResult class is trickling upwards
               | 
               | yes, and yes people do freak out, not sure why you think
               | they aren't :)
        
         | kaapipo wrote:
         | Nah, I think having a monadic Maybe/Option type and first-class
         | support for it is the correct solution. Exceptions are
         | fundamentally flawed.
        
           | rixed wrote:
           | "None" to represent any type of failure sounds similarly
           | fundamentally flawed too.
        
             | lmm wrote:
             | That's why you need not just an Either/Result type, but
             | proper monads so that you can use the same functions with
             | both.
        
               | rixed wrote:
               | Yes, but then you have to handle every possible errors at
               | every call point, and wrap all those you can't handle at
               | the calling site into your own return type... This is
               | well documented.
               | 
               | One should be cautious every time it feels like there is
               | an obviously right way to do something that everybody
               | fails to see :)
        
               | valcron1000 wrote:
               | As someone who worked with Haskell and Rust in production
               | this is a nightmare: - All functions end up returnig
               | `Either/Result` - Stack traces are gone - Exceptions and
               | panics can still creep so it's not even "safer" - There
               | is no composability of different result types, you need
               | something like `Either<FooError | BarError | ..., A>
               | which is not supported in most languages (I think Scala 3
               | and Ocaml have this feature), or you create a "general
               | wrapper" like `SomeException` (Haskell) or use `anyhow`
               | (Rust).
               | 
               | Today I write C# at my job and I could not be happier
               | with the usage of exceptions.
        
         | The_Colonel wrote:
         | > They just needed some syntactic sugar to help redirect
         | certain developers into less self-destructive ways of
         | procrastinating on proper error handling.
         | 
         | Syntactic sugar it needs is an easy way (like ! prefix) to turn
         | it to a runtime exception.
         | 
         | Procrastinating on exceptions is usually the correct thing to
         | do in your typical business application - crash the current
         | business transaction, log the error, return error response. Not
         | much else to do.
         | 
         | Instead the applications are now littered with layers of try-
         | catch-rethrow (optionally with redundant logging and wrapping
         | into other useless exceptions) which add no benefit.
        
           | jeroenhd wrote:
           | The try/catch/rethrow model can easily be substituted by just
           | adding a `throws` to the method. If you truly don't care,
           | just make your method `throws Exception` or even `throws
           | Throwable` and let the automatic bubbling take care of making
           | you handle exceptions at top level.
        
             | The_Colonel wrote:
             | That (or rather checked exceptions in general) doesn't play
             | well with lambdas / streams.
        
           | pinoy420 wrote:
           | How many errors are actually recoverable. I bet most thrown
           | exceptions could be replaced with a printf("it went wrong
           | here") for all their utility.
        
             | The_Colonel wrote:
             | Well, usually you want to handle it at some level - e.g. a
             | common REST exception handler returning a standard 500
             | response with some details about what went wrong. Or retry
             | the process (sometimes the errors may be intermittent)
        
             | bluGill wrote:
             | I disagree. The real value of exceptions is you can skip 6
             | levels of functions that have lines like
             | 
             | status = DoThing(); if(status != allIsWell) {return
             | status;}
             | 
             | C++ embedded for a long time has said don't use exceptions
             | they are slow. However recent thinking has changed - turns
             | out in trivial code exceptions are slow but in more real
             | world code exceptions are faster than all those layers if
             | checks - and better yet you won't give up on writing all
             | the if checks. Thus embedded projects are starting turn
             | exceptions on (often optimized exceptions with static pre
             | allocated buffers)
             | 
             | The final "print something when wrong" is of little value,
             | but the unwinding is very valuable.
        
               | hasley wrote:
               | Do you have any references for that? I used to avoid
               | exceptions on small Cortex M0/M3 devices as well.
        
               | bluGill wrote:
               | Khalil Estell has some great work on that.
               | https://www.youtube.com/watch?v=bY2FlayomlE is one link -
               | very low level technical of what is really happening. He
               | has other talks and papers if you search his name.
        
               | hasley wrote:
               | Nice, thank you!
        
               | ackfoobar wrote:
               | > The real value of exceptions is you can skip 6 levels
               | of functions that have lines like
               | 
               | For some reason some Go programmers think those lines are
               | the best thing since sliced bread.
        
         | Cthulhu_ wrote:
         | I mean on paper they're a good idea and well implemented etc.
         | However, the main two flaws with exceptions are that one, most
         | exceptions are not exceptional situations, and two, exceptions
         | are too expensive for dealing with issues that aren't
         | exceptional like that.
        
         | taeric wrote:
         | The problem with checked exceptions is they are best explained
         | and utilized in a single threaded execution model where the
         | exceptions can be bubbled up to the operator.
         | 
         | This is not, of course, the only way that checked exceptions
         | can be utilized. But, all too often, that is by far the easiest
         | way to reason on them. They represent a decision that needs to
         | be bubbled up to the operator of the overall system.
         | 
         | Worse, the easy way to explain how the system should resume, is
         | to go back to where the exception happened and to restart with
         | some change in place. Disk was full, continue, but write to a
         | new location. That is, having the entire stack unrolled means
         | you wind up wanting the entire process reentrant. But that is
         | an actively hostile way to work for most workflows. Imagine if,
         | on finding a road was closed, a cab driver took you back to
         | pick up location to ask what you want to do about it.
         | 
         | If it is not something that you want to unwind the stack, or
         | bubble up to the users, then you go through effort to wrap it
         | so that it is another value that is being processed.
        
           | kflgkans wrote:
           | The most common pattern in languages with explicit error
           | handling, is to simply return the error (possibly with some
           | context added) in every function up to the point where the
           | process was started (e.g. an HTTP endpoint handler, or the
           | CLI's main function) to deal with it.
           | 
           | I'm not saying exceptions are good, but I am saying that they
           | do represent the most common error handling pattern.
        
             | taeric wrote:
             | Right, this is largely the same idea. For things that have
             | to be bubbled up, you wind up in the simplistic "single
             | thread of execution by an operator" pattern. And, in that
             | scenario, exceptions work exactly the same as just
             | returning it all the way up. It is literally just making it
             | easier to unwind the stack.
             | 
             | My assertion is that actual error handling in workflows
             | doesn't work in that manner. Automated workflows have to
             | either be able to work with the value where it was broken,
             | or generally just mark the entire workflow as busted. In
             | that scenario, you don't bubble up the exception, you
             | instead bubble up an error code stating why it failed so
             | that that can be recorded for later consideration. Along
             | the way of bubbling up, you may take alternative actions.
        
               | kflgkans wrote:
               | Thanks for the additional clarification!
        
               | taeric wrote:
               | Certainly! And please let me know if I'm off or otherwise
               | confused here. I can guarantee I'm not the brightest bulb
               | around here! :D
        
         | mightyham wrote:
         | I'm not a fan of checked exceptions because they force you to
         | use a verbose control structure (try-catch) that distracts from
         | the actual logic being expressed. Typically, checked exceptions
         | are also not exceptional, so I prefer working with monadic
         | exceptions, like Rust's Option/Result, because they encourage
         | error recovery code to use normal control flow, keeping it
         | consistent with the rest of the application.
         | 
         | I also find that generally exceptions can't be meaningfully
         | caught until much higher in the call-stack. In which case, a
         | lot of intermediary methods need to be annotated with a checked
         | exception even though it's not something that matters to that
         | particular method. For this reason, I've really come around on
         | the Erlang way of doing things: throwing runtime exceptions in
         | truly exceptional situations and designing top level code so
         | that processes can simply fail then restart if necessary.
        
         | ben7799 wrote:
         | I've pretty much been stuck on java since 1995, I started right
         | around 1.0. There have been some stints of Python or we have
         | some glue code in C/C++ or whatever but we're talking 95% java.
         | 
         | Some of these things are mildly annoying when you think about
         | them in theoretical terms.
         | 
         | But all the professional teams I've been on a (a lot) have
         | successfully dealt with exceptions without issue. The teams
         | settled on an exception and error handling process early in the
         | design phase and it rarely has caused a major issue.
         | 
         | Yet it seems out on the internet in any place where programming
         | languages are discussed it is an insurmountable problem that
         | has caused all projects in Java to fail and the language died
         | an early and unpopular death. It seems if it caused anyone huge
         | problems it was not Java's issue but that team's issue.
         | 
         | There are/were other much bigger issues over the years. Memory
         | leaks have been issues. Spring was hard for many people to deal
         | with back around 2005 or so. The first iterations were quite
         | bad with XML. XML in general caused a lot of issues. J2EE
         | caused a lot of issues just because it was so badly designed
         | early on. (Some of this was because it was birthed out of
         | CORBA, which was itself pretty horrible.) Plenty of issues were
         | caused by using Collections with mixed objects in them early on
         | before Generics were introduced. Visual J++ caused havoc.
         | Different models of web application caused a lot of havoc
         | before we got to Javascript UIs in the browser driven by Web
         | API back ends. JPA was a big mistake IMO. But exceptions were
         | never really a huge problem anywhere.
         | 
         | So many have blamed a problem on Java when it was actually a
         | problem with a library, component, or framework written in Java
         | that became way more popular than it should have been. And
         | along the way there were a lot of "developer influencer
         | celebrities" who were listened too far far more than they
         | should have been. Many of these guys (I can't remember one ever
         | being a woman) sold everyone on ultra complex designs and ways
         | of doing things and the community almost always bought in to a
         | ridiculous degree.
        
       | cies wrote:
       | > ORMs are the devil in all languages and all implementations.
       | Just write the damn SQL
       | 
       | This week wrote an article on this, since I found there's a lot
       | to explain wrt this topic:
       | 
       | https://dev.to/cies/the-case-against-orms-5bh4
       | 
       | On HN:
       | 
       | https://news.ycombinator.com/item?id=42922014
        
         | MisterKent wrote:
         | I've been loving edgedb in my typescript side projects for a
         | number of years now. I have always hated ORMs, mostly for
         | performance and a little bit for elegance / ergonomics. Curious
         | if you have thoughts on a solution like that?
        
           | cies wrote:
           | I like EdgeDB. The only downside I see is the lock-in, that
           | is less of an issue with SQL.
           | 
           | While I have not used EdgeDB, I have used Hasura, which I
           | really liked.
           | 
           | Wrt the syntax of queries, I know of https://prql-lang.org
           | which is kind of similar of EdgeQL.
           | 
           | Funny that EdgeDB says on its page it tries to solve the ORM
           | problem: I strongly believe ORMs do not solve any problem,
           | they merely create problems (as I argue in the linked
           | article).
           | 
           | Wrt my thoughts: the EdgeQL queries are usually still strings
           | (no compile time type checking, not IDE tooling). With Hasura
           | the GraphQL interface (that EdgeDB also supports) allows one
           | to generate a client library _based on the GraphQL schema_ :
           | this allows one to have compile time checks on the queries,
           | which is really neat.
        
             | cluckindan wrote:
             | If you like GraphQL and are looking at databases, try
             | Dgraph community edition some day.
        
       | greener_grass wrote:
       | The author learns that Java is not a Functional Programming
       | language; lambdas ain't enough!
        
       | cies wrote:
       | > Gradual, dependently typed languages are the future
       | 
       | I really interested why the author thinks this.
       | 
       | I've seen the general sentiment wrt "the future" go from C to C++
       | to Java to Ruby to JS (also server-side) and Python.
       | 
       | My own sentiment went from Ruby to Haskell to, well, Kotlin I
       | guess...
       | 
       | I looked into Idris (dependently typed), but did not think it
       | would fit the Overton window[1], to be a reasonable expectation
       | for the future.
       | 
       | 1: https://en.wikipedia.org/wiki/Overton_window
        
         | samsartor wrote:
         | Dependent typing is mainly just that feature of Typescript that
         | `x: number | null` becomes just `x: number` inside an `if (x !=
         | null) { ... }` statement.
         | 
         | If you dig deeper into the type theory, it gets really
         | interesting and complicated because types themselves can start
         | to include any arbitrary code. And that's where Idris comes in!
         | But after doing a whole project on Idris in college, I agree it
         | is way outside the overturn window. Python and typescript
         | rightfully keep it simple.
        
           | wk_end wrote:
           | Narrowing, as TypeScript calls it, isn't dependant typing -
           | it's basically just a form of pattern-matching over a sum
           | type.
        
         | lucasoshiro wrote:
         | > to C++ to Java to Ruby to JS (also server-side) and Python
         | 
         | I feel that languages are going back to static typing. Newer
         | languages such as Go, Rust, Kotlin, Swift, Dart, Nim etc are
         | all statically typed (I can't remember a language from the last
         | decade that is dynamically typed).
         | 
         | Even some dynamically typed languages are moving towards a more
         | static typed system: for JS we have TS, and for Python we have
         | type hints
        
       | physicsguy wrote:
       | > People who stress over code style, linting rules, or other
       | minutia remain insane weirdos to me. Focus on more important
       | things.
       | 
       | I just want to set up a linter that's standard for the language
       | and let CI deal with it. Anything other than that is mental to
       | me.
        
         | pgsandstrom wrote:
         | Agree. People who join a project and insist on changing the
         | default styling configs are insane weirdos. But people who dont
         | want to use any styling solution on a project with several
         | developers are EVEN MORE insane weirdos.
        
       | oniony wrote:
       | >People who stress over code style, linting rules, or other
       | minutia remain insane weirdos to me.
       | 
       | Um, "minutiae", erm, uh.
        
       | pjc50 wrote:
       | > Good management is invaluable. (I went most of my career before
       | seeing it done well)
       | 
       | Yes, and: it's difficult to describe, must be led from the top,
       | and _extremely_ difficult to evaluate from above.
        
         | bayindirh wrote:
         | If the person at the top can come down for a coffee with people
         | who endured some bad management, and ask honest, non-loaded
         | three questions, it can be measured qualitatively but with very
         | high accuracy.
         | 
         | The three questions are:                   - What should we
         | start doing?         - What should we continue doing?         -
         | What should we stop doing?
         | 
         | This is an immensely powerful tool. Thanks to the awesome
         | person who introduced me this.
         | 
         | Addenda: "Theory X" is something really bad. If you're working
         | with a team which responds positively to Theory X, you have
         | much bigger problems IMHO.
        
           | floydnoel wrote:
           | sounds just like the advice in the book "The Coaching Habit"
           | which i thought was great
        
           | franktankbank wrote:
           | What insight does an IC have on what the person at the top
           | even does? I can basically only comment on my interactions
           | with direct management and I otherwise don't know how they
           | spend their day.
        
             | pjc50 wrote:
             | That's not important - you're not discussing how to do
             | their job, but what your own view is of your part of the
             | work and those around you. The leader can then synthesize
             | all these views and see if there are any surprises.
             | 
             | (another case similar to "you should listen to a customer
             | when they say there's something wrong with the design of
             | your product, but you should absolutely not pay attention
             | to what they think the solution should be")
        
             | cosmosgenius wrote:
             | By having a 5 min group meeting where only the manager
             | speaks. Manager is not allowed to talk about what direction
             | the team should go and what the team should do. Anything
             | else will give instant insights on whats going on at the
             | isolated top.
        
       | Kototama wrote:
       | > Typed languages are essential on teams with mixed experience
       | levels
       | 
       | I like this one because it puts this endless dilemma in a human
       | context. Most discussions are technical (static typing ease
       | refactoring and safety, dynamic typing is easier to learn and
       | better for interactive programming etc.) and ignore the users,
       | the programmers.
        
         | flir wrote:
         | UX really is everywhere, once your eyes are opened to it.
        
           | bbatha wrote:
           | Ill plug the "Design of Everyday Things" by Don Norman in
           | case anyone in the thread hasn't read it. Its the classic
           | text on design. You will never think about doors the same
           | again.
        
         | cies wrote:
         | I think the size of the code base also matters: bigger size =
         | having types is more important.
         | 
         | There is a contradiction here as: bigger size = compile speed
         | more important AND types slow down compilation. More advanced
         | typing features slow down compilation even more.
        
           | pjc50 wrote:
           | > More advanced typing features slow down compilation even
           | more.
           | 
           | C++ is a bit of an outlier here. But really people should
           | think of typechecking as shifting fault detection earlier in
           | the process than runtime. It doesn't matter if your test
           | suite starts slightly quicker if you have to wait for the
           | whole thing to run to find something you could otherwise have
           | found with types.
        
             | cies wrote:
             | I agree. But the nice thing about types is that they are
             | not an afterthought, but more a "pre thought". TDD tries to
             | make testing a pre thought...
        
         | wesselbindt wrote:
         | I'm kind of wondering where the "mixed experience levels" part
         | comes from. What is it about more homogeneously skilled teams
         | that makes them less susceptible to the productivity boost that
         | statically typed languages give in large code bases?
        
           | Cthulhu_ wrote:
           | I'm reading in it that experienced developers (be it overall
           | or in a specific codebase) "know" all the ins and outs,
           | types, conventions etc, whereas less experienced people
           | cannot yet know all of that; being able to lean on good types
           | and / or other types of automated checks helps them make more
           | confident changes.
        
             | naasking wrote:
             | Less experienced devs iterate on something until it looks
             | like it works, not realizing the footguns they may have
             | embedded. Static typing removes some footguns and provides
             | documentation for the next unfortunate soul to look at this
             | code.
        
           | bluGill wrote:
           | > What is it about more homogeneously skilled teams
           | 
           | They are a strawman example that doesn't exist in the real
           | world.
           | 
           | Companies will be in big trouble in a few years when the team
           | retires, people find new jobs, someone dies... All of them
           | mean that a homogeneously skilled team will exist for at most
           | a few years if you have one. As a company you need to ensure
           | you have a program to train in new people.
           | 
           | I have long believed that when someone retires you should
           | replace them with someone fresh out of school, promoting
           | people all the way down to fill the opening. If someone finds
           | a new job you can replace them with someone else with similar
           | experience, but when someone retires they should be replaced
           | by someone you already have groomed for the job.
        
           | whstl wrote:
           | IMO it's like scrum: if your team is good and homogeneous, it
           | doesn't really matter much what you do: it just works. Scrum
           | and no scrum, types and no types. It's not about having
           | rockstars or 10x engineers, it's just about having
           | shorthands, shared knowledge, etc.
           | 
           | If your team is varied or too large, you need things to help
           | you out with organisation and communication.
           | 
           | (Whether my examples of Scrum and Types are the answer:
           | depends on the team unfortunately)
        
             | bluGill wrote:
             | In my experience: Too large is any team larger than 10
             | people or any code base with more than 10,000 lines of
             | code. Both of those would be considered tiny by most in the
             | industry.
        
               | whstl wrote:
               | Oh, you are definitely correct about 10 people being too
               | many. For me I think the magic number was 4 or 5.
               | 
               | About 10k lines, I really never stopped to think but I'm
               | gonna guess you're correct on that too.
        
               | bluGill wrote:
               | The numbers I gave are not exact. Depending on details
               | that I don't think anyone entirely knows. Sometime 1
               | person is too many (generally implying a bad programmer),
               | while other times you can get a bit over 10 if you have
               | strong discipline. Likewise strong discipline can get you
               | to 100k lines. Really what this is about is how much pain
               | you are willing to put up with. 10 people and 10k lines
               | of code are good round numbers to work with.
        
           | nucleardog wrote:
           | I would tend to agree with the author's statement there.
           | Though less "necessary for heterogeneous teams" and more
           | "unless your team is entirely senior/skilled".
           | 
           | To sum up some thoughts that have evolved over decades into
           | something more reasonable for a comment--more junior
           | developers are less able to develop a robus mental model of
           | the codebase they're working in. A senior developer can often
           | see further out into fog of war, while the more junior
           | developer is working in a more local context. Enforcing
           | typing brings the context closer into view and reduces the
           | scope necessary for the developer to make sensible changes to
           | something manageable.
           | 
           | It also makes it much easier to keep contracts in the
           | codebase sane and able to be relied on. With no declared
           | return type on some method, even with checks and code reviews
           | it's possible there's some non-obvious branch or set of
           | conditions where it fails to return something. Somebody might
           | try and take a "shortcut" and return some totally different
           | type of object in some case. In every case, it puts these
           | things front and center and reduces the ability to "throw
           | shit at the wall until it sort of works on the happy path"
           | without making that much more obvious.
           | 
           | And once those types are declared, it saves everyone else
           | time when stupid shit does slip through. You probably have
           | some idea what `getProductAvailability(products)` might do in
           | some eCommerce system. But when the actual function is
           | implemented as `getProductAvailability(InvoiceItem[]
           | products): void`, the foot gun for the rest of the team is...
           | less. (Your guess as to how I know this is correct.)
           | 
           | In teams with good, experienced people the types are still
           | helpful and I'd still question anyone choosing _not_ to be
           | explicit about these sorts of things regardless of team
           | composition. But they're much less _necessary_ in a skilled
           | team in my experience.
        
         | loxs wrote:
         | Even when I am alone, I have "mixed experience levels", for
         | example I can learn something niche, write some algorithm that
         | works in that, then 2 years later I may have forgotten it.
         | Types are essential for me.
        
       | FrankWilhoit wrote:
       | The comment about project managers is interesting. At my last
       | workplace, the PMs -- all consultants -- were the only reason
       | anything ever got done.
        
         | qaq wrote:
         | Depends on team's experience level
        
       | pgsandstrom wrote:
       | > Most programming should be done long before a single line of
       | code is written
       | 
       | I'd rephrase this to something like: Most programming should be
       | done before 5% of the code is written. Because "no plan survives
       | contact with the enemy". I often develop a plan, work for just a
       | tiny bit, and realize some new constraints. It's after that point
       | that you should construct your grand battle plan.
        
         | latexr wrote:
         | From "The Cathedral and the Bazaar":
         | 
         | > # 3 "Plan to throw one away; you will, anyhow." (Fred Brooks,
         | "The Mythical Man-Month", Chapter 11)
         | 
         | > Or, to put it another way, you often don't really understand
         | the problem until after the first time you implement a
         | solution. The second time, maybe you know enough to do it
         | right. So if you want to get it right, be ready to start over
         | at least once.
         | 
         | https://en.m.wikipedia.org/wiki/The_Cathedral_and_the_Bazaar
        
         | v3ss0n wrote:
         | Its wrong in those day , exploratory coding is better for
         | dynamic languges like python using jupyter notebook , and then
         | do proper coding after exploratory step..
        
         | The_Colonel wrote:
         | I've made an opposite progression from the op. I was a strong
         | believer of upfront design, but now value iterative approach as
         | you do.
         | 
         | For the first try, hack together something working, you'll
         | learn things along the way, validate/disprove your assumptions.
         | Iterating on this will often bring you to a good solution.
         | Sometimes you find out that your current approach is untenable,
         | go back to the whiteboard and figure out something different.
        
       | bayindirh wrote:
       | It felt good to read someone who thinks like me, honestly.
       | 
       | Also the observation of "The trouble with functional programming
       | is functional programmers" is _absolutely correct_.
       | 
       | This needs to be said more. Way more.
       | 
       | P.S.: You can ask why, and I can answer honestly, without
       | hostility.
        
         | lbj wrote:
         | Maybe say it less but it explain it more. I don't get it at
         | all.
        
           | bayindirh wrote:
           | Let me try to explain it a bit more.
           | 
           | From my experience, functional programmers come in two
           | flavors. The ones who constantly nag others by telling them
           | "everything you do is wrong", and "hey, come here, I want to
           | show you something!". Unfortunately, the first camp is way
           | more dominant than others.
           | 
           | Again, from the same article, there's observation "People who
           | care about the craft are rare. Cherish the who cares, meet
           | the rest at where they are". This is very true. The problem
           | is, the people in the first camp can't cater to either group.
           | First group has strong opinions and want a solid (not
           | hostile, solid) discussion about how they can improve and how
           | that tool works, and the second group doesn't care.
           | 
           | Also, every programmer has an understanding of the machine,
           | and they program on top of that abstraction. For me, "C
           | virtual machine", or the modern hardware is very easy to
           | grasp. For every line of code, I can have an educated guess
           | about how my code will run (e.g. how will the branch
           | predictor will behave or got inadvertently poisoned), hence
           | imperative languages and the primitive memory management is
           | easy for me. For others who think more meta, functional
           | paradigm is a natural think to construct in their brains. Not
           | meeting them at where they are is again off-putting.
           | 
           | All in all, nobody wants to be constantly nagged to feel
           | "stupid" about not understanding functional programming or
           | how unelegant imperative is, and most of the functional
           | programmers are doing this, even without knowing it.
           | 
           | Some of my friends who do functional programming are more
           | reasonable people. Who sit down and look at some code or
           | problem say "oh, this looks an interesting problem and
           | interesting solution, can I show you how it's done in
           | functional way", and we can go from there, and go a very long
           | way from there.
           | 
           | I have never picked up Common LISP because of an academic who
           | praised functional programming like it's the second coming of
           | Christ. I still have the first chapter of the LISP book
           | printed on my desk. I'll start it after 15 years, but now I
           | don't have the time I want to spend on it.
           | 
           | Lastly, from an architecture/elegance perspective, I believe
           | a good imperative program in C/C++/Go is somewhere between
           | Bauhaus and Brutalist architecture depending on what domain
           | you're targeting (lower the level, more Brutalism), and I
           | find that naked nature of imperative code directly tapping
           | into the hardware or the kernel efficiently very elegant and
           | well-designed. For the same majority of functional
           | programmers this is ugly and shall be got ridden with a
           | flamethrower. Also, an imperative programming language is no
           | lighter on PLT and mathematics which the same majority finds
           | mouth wateringly elegant.
           | 
           | TL;DR: If the majority of functional programmers can be a bit
           | less arrogant, meet in the middle and learn why we love what
           | we love, we can build better languages, ecosystems, and a
           | better world to live in, but no, functional elegant,
           | imperative bad.
           | 
           | Robert Martin's Talk: "What Killed Smalltalk can Kill Ruby,
           | Too": https://youtu.be/YX3iRjKj7C0 which notes a similar
           | mechanic about Smalltalk.
        
             | yakshaving_jgt wrote:
             | Really? You think most functional programmers are arrogant?
             | 
             | Have you considered that your position is lazy, and that
             | actually _you_ have the problem?
        
               | bayindirh wrote:
               | How my position is lazy? By not learning Functional
               | Programming? I openly said that I was _driven away_ by
               | these very people, because I don 't want to be part of a
               | community who belittles the outsiders the moment they
               | talked.
               | 
               | I mean, most (not all) functional programmers I met (for
               | the last 20 years, no less!) started to praise functional
               | programming by bashing imperative programming languages
               | and never asked me about what I like about programming,
               | and why I was so adamant to stay away from functional
               | paradigm.
               | 
               | When you start selling what you like as an omnipotent
               | silver bullet without listening to what the other party
               | is saying, or by calling the other party lazy and the
               | root of the problem you drive away people from the thing
               | you are selling,
               | 
               | like you're doing right now.
               | 
               | Extra points for you for doing this, even after I have
               | politely said that I have left that beef behind and
               | trying to find the time to learn functional programming,
               | and PLT in depth. Chef's kiss, actually.
        
               | yakshaving_jgt wrote:
               | > How my position is lazy? By not learning Functional
               | Programming?
               | 
               | No, your position is lazy by asserting that most people
               | who do functional programming are arrogant. This is a
               | nonsensical value judgement. You don't know most
               | functional programmers.
               | 
               | I don't know whether or not you're skilled FP. I don't
               | know you. But as is appropriate, I assumed that you do
               | actually know what you're talking about.
        
               | AnimalMuppet wrote:
               | No, I've seen it too. Here on HN. Not just once.
               | 
               | Maybe not "most functional programmers", though. Maybe
               | "the functional programmers who post the most" or "post
               | the most stridently" and therefore "the functional
               | programmers that I encounter the most often in ways that
               | let me know that they are functional programmers".
               | 
               | And "Have you considered that your position is lazy"
               | isn't a reply likely to change hearts and minds. (It is
               | also, itself, a pretty lazy reply, compared to the effort
               | the GP put into their answer.)
        
             | lbj wrote:
             | My experience is the opposite, I've only met incredibly
             | friendly and helpful people within the functional world.
             | 
             | Your description of a person who has to put down everyone
             | else in other to raise himself up, is just person with such
             | low self-esteem that it's become toxic. You'll find these
             | people everywhere, it's not exclusive to FP.
             | 
             | I'm personally fairly rigid about implementing business
             | logic as functionally as possible, but I also enjoy game
             | development which is inherently stateful and never without
             | some imperative parts. I do think FP has some advantages
             | over Imperative programming in many instances, but the
             | opposite is also true, and I'd never pretend to be smarter
             | or better than someone like John Carmack, who's made his
             | career almost exclusively in Imperative languages.
        
         | nickpeterson wrote:
         | I think trying to fit everything into the same lens is usually
         | the real problem. Functional programming is a great methodology
         | for a lot of things, but there are many ways to design things.
         | Chances are really good that something elegantly written in
         | prolog won't be as elegant in scheme or java, and vice versa.
        
           | bayindirh wrote:
           | Yes, this is one of the bigger (if not the biggest) problems.
           | I don't think that imperative programming is the only or the
           | best way, either.
           | 
           | The different approaches can and do transform some really
           | ugly things in one paradigm to something really neat and
           | joyful things in another.
           | 
           | But reaching that level of maturity or flexibility is rather
           | hard as far as I can see, and it's honestly sad.
        
         | mrkeen wrote:
         | > The trouble with functional programming is functional
         | programmers
         | 
         | > This needs to be said more. Way more.
         | 
         | In other words, why stop with an ad-hominem when you can do an
         | ad-nauseam too.
        
           | bayindirh wrote:
           | There's a comment down there which I explain why I support
           | this claim, without any attacks, but with citations from
           | experience.
           | 
           | Why not give that one a read, then come again?
           | 
           | Maybe we can discuss, and we can both learn something from
           | it?
        
       | ertucetin wrote:
       | > REPLs are not useful design tools (though, they are useful
       | exploratory tools)
       | 
       | I disagree with this. I'm a Clojure dev, and most of the time, I
       | use the REPL to iterate on features, fix bugs, and refactor,
       | thanks to the fast feedback loop.
       | 
       | I used to be a Java dev--oh god, restarting the whole app after
       | every change made me want to shoot myself in the head. Now, I use
       | the REPL to build what I want and then move on. This brings joy
       | back to programming.
       | 
       | I'm not saying other languages are bad, but working with Clojure
       | is more enjoyable for me. I'm at least 2-3 times faster than I
       | was with Java. Of course, there are techniques you need to know
       | to write efficient and idiomatic functional code.
        
         | nickpeterson wrote:
         | I could definitely see how if you work in Java or C# all day,
         | repls feel like a neat curiosity. Picture telling someone who
         | writes scheme in emacs that repls aren't a good design tool.
         | 
         | If you want to argue the point with non lisp people, I'd go to
         | javascript or SQL as great examples where you really use repl's
         | quite a bit.
        
         | cess11 wrote:
         | I'm a heavy REPL/interactive shell user so when I do Java I
         | abuse the testing framework, basically I put my sketches in
         | unit tests and run those. The feedback loop is pretty tight,
         | close to what I get in some other languages, whatever happens
         | behind the scenes in IntelliJ it's much shorter than a full
         | recompile and boot.
         | 
         | Supposedly there are some Java shells around but I haven't
         | tried them out.
        
           | skydhash wrote:
           | You either REPL or do TDD.
        
         | smallerfish wrote:
         | Apparently Graal lets you hotswap. I tried getting it working
         | about a year ago, but couldn't figure out how to install it
         | with Gradle toolchains, so gave up at that point. I should
         | probably look at it again. Anybody using this?
         | 
         | https://www.graalvm.org/latest/reference-manual/espresso/hot...
        
         | iLemming wrote:
         | Well, because Clojure actually has a "proper" REPL. Non-lispy
         | languages don't have such REPLs, at best - they are interactive
         | shells. The blogpost author doesn't seem to have experience
         | with homoiconic languages, otherwise, I'm sure, that sentence
         | would be different.
        
       | latexr wrote:
       | > Most won't care about the craft. Cherish the ones that do, meet
       | the rest where they are
       | 
       | > (...)
       | 
       | > People who stress over code style, linting rules, or other
       | minutia remain insane weirdos to me. Focus on more important
       | things.
       | 
       | What you call "stressing over minutiae" others might call "caring
       | for the craft". Revered artisans are precisely the ones who care
       | for the details. "Stressing" is your value judgement, not
       | necessarily the ground truth.
       | 
       | What you're essentially saying is "cherish the people who care up
       | to the level I personally and subjectively think is right, and
       | dismiss everyone who cares more as insane weirdos who cannot
       | prioritise".
        
         | hkwerf wrote:
         | There is more than one type of people who stress over code
         | style. There's the group who wants to discuss about how to
         | style your code and then there's the group who wants to just
         | use a common code formatter and be done with that.
         | 
         | For example, I have objections to rustfmt's default style. I
         | would never start discussions on rust projects about changing
         | that to another formatter or changing its configuration. I
         | definitely would carefully ask that people should really use
         | rustfmt, though, if they don't do so yet.
        
           | xnorswap wrote:
           | Edit: This comment was based on misreading the parent
           | comment. I've left it up, but I should have been more
           | careful.
           | 
           | You've set yourself up to always be the outlier. To always
           | need to have that discussion or tweak the rules on every
           | project you work with.
           | 
           | You've increased the overhead of onboarding anyone used to
           | the default style. You've increased the overhead of you
           | working on anyone else's projects that is more likely to have
           | the default style.
           | 
           | All of that is friction introduced because you haven't
           | learned to live with the default style.
           | 
           | Do I love that the default C# rules put a new line before the
           | else block? No, but I've learned to live with it so that I
           | can work on all manner of projects without fussing over that
           | style option every time.
           | 
           | By adhering to default rules, you never have to have the
           | endless arguments such as tabs vs spaces again. ( Spaces won,
           | and the tabbers got over it fairly quickly once it was the
           | default in almost all formatters. )
        
             | hkwerf wrote:
             | I believe you may have misunderstood my comment, as I
             | agree.
        
               | xnorswap wrote:
               | I apologise, I misread your statement as: "I would never
               | start discussions on rust projects *without* changing
               | that to another formatter" which changed the meaning
               | entirely. I should have taken a moment to re-read what
               | you wrote.
        
             | latexr wrote:
             | What I understood from your parent comment was the exact
             | opposite, i.e. that they're saying "I disagree with some of
             | the default choices of the formatter (and so would prefer
             | they were different) but I never voice those because it's
             | not worth it. However, I do think everyone should use
             | _something_ , whatever it is (even if the default style),
             | as opposed to nothing".
        
           | maleldil wrote:
           | > I definitely would carefully ask that people should really
           | use rustfmt, though, if they don't do so yet.
           | 
           | If you don't already, you should run `cargo fmt --check` in
           | CI and block PR merges until it passes. You can also run it
           | in a pre-commit hook, but you can't be sure everyone will set
           | that up.
           | 
           | Automating such types of decision is great but moot if others
           | have to opt into it.
        
         | OJFord wrote:
         | It's not even more or less, it's just about different aspects.
         | Consider a woodworker obsessing over sharp chisels - they don't
         | all care beyond 'sharpish', or about the tools used to do so -
         | but to some that's hugely important and how they are then able
         | to do their best work.
        
           | chasd00 wrote:
           | To take it further some woodworkers are really tool
           | hobbyists. They obsess over the tools and never really touch
           | the wood they're supposedly working. Same goes for software
           | devs, I think about this when reading threads obsessing over
           | AWS services, pipelines, build stacks, instead of writing
           | software.
        
         | xnorswap wrote:
         | The solution is to have computers enforce the code style. Pick
         | a linter, pick a set of rules, and then forget about them.
         | 
         | Things I beleive:
         | 
         | - If you're picking up on code-style in PRs then your toolchain
         | is backward.
         | 
         | - If you're changing linting rules every month then you're
         | focussed on the wrong things
         | 
         | - It's better to have a consistent style than a perfect style
        
           | secondcoming wrote:
           | This is what we did with clang-format on our code base.
           | 
           | The result is occasionally ugly code and nobody is 100% happy
           | but at least it's consistent.
        
             | maleldil wrote:
             | Gofmt's style is no one's favorite, yet gofmt is everyone's
             | favorite.[1]
             | 
             | [1] https://go-proverbs.github.io/
        
               | maxwell wrote:
               | While everyone has a favorite ES Lint ruleset but few
               | agree on which to use.
        
             | gpderetta wrote:
             | *cough*clang-format off*cough*
        
               | secondcoming wrote:
               | Ha, yes. I started doing that but then lost the will to
               | continue.
        
           | bayindirh wrote:
           | Yes. I love how gofmt has no settings, basically. Is this how
           | you envisioned? Great. Now I don't have to think about
           | optimizing it.
           | 
           | Coincidentally, the choices they made are the choices I'd
           | made, but it doesn't matter in the end.
        
             | maleldil wrote:
             | IMO, gofmt doesn't go far enough. It should sort imports
             | and break lines automatically, or you end up with different
             | people with slightly different preferences for breaking up
             | lines, leading to an inconsistent style.
             | 
             | Something like gofumpt + golines + goimports makes more
             | sense to me, but I'm used to ruff in Python (previous black
             | + isort) and rustfmt.
             | 
             | I'd say that if you're manually formatting stuff with line
             | breaks and spaces, that should have been automated by
             | tooling. And that tooling should run both as a pre-commit
             | hook and in CI.
        
               | bayindirh wrote:
               | gofmt sorts imports within the block they are in.
               | 
               | I have a habit of putting stdlib imports, a line break,
               | golang experimental (x) imports, a line break and
               | external imports.
               | 
               | I just tested, gofmt orders imports within these blocks.
               | If I won't use the line breaks, it'll consider it a
               | single block and will globally sort.
               | 
               | golang also aligns variable spacing and inline comments
               | to look them as unified blocks (or a table if you prefer
               | the term) and handles indents. The only thing it doesn't
               | do is breaking lines, which I think acceptable.
        
               | maleldil wrote:
               | I meant that you could do this with isort in Python or
               | rustfmt with `group_imports = StdExternalCrate` (sadly,
               | not the default), where the imports are automatically
               | separated into blocks, which is basically what you seem
               | to be doing manually.
               | 
               | My point is that many things we end up doing manually can
               | be automated, so I don't need to care about unsorted or
               | unused imports at all and can rely on them to be fixed
               | without my input, and I don't have to worry about a
               | colleague forgetting to it either.
        
               | Freak_NL wrote:
               | Be careful what you wish for. Sometimes leaving a line
               | stupidly long is better for readability than awkwardly
               | trying to break it up.
               | 
               | If you have five similar statements somewhere with only
               | one exceeding the linter's line length, breaking up that
               | one can lead to code that is harder to parse than just
               | leaving it jutting out by way of an exception to the
               | general rule; especially if it contains some predictable
               | bit of code.
        
               | maleldil wrote:
               | Those would be edge cases where formatting can be turned
               | off if needed. This would require justification during
               | code review. Otherwise, we'd keep the automatic format,
               | with a strong tendency towards the latter.
               | 
               | The general benefit of automated formatting outweighs
               | these edge cases.
        
           | bjourne wrote:
           | While Python has some great linters, I don't know of any in C
           | that can correctly and automatically enforce some coding
           | style. Most of them can only indent correctly, but they can't
           | break up long lines over multiple lines, format array
           | literals, or strings. Few or none knows how to deal with
           | names or preprocessor macros.
        
             | brandmeyer wrote:
             | clang-format and clang-tidy are both excellent for C and
             | C++ (and protobuf, if your group uses it). Since they are
             | based on the clang front-end, they naturally have full
             | support for both languages and all of their complexity.
        
           | xbar wrote:
           | Agreed.
           | 
           | A healthy toolchain lets a developer separate the Craft from
           | the minutiae.
        
           | petesergeant wrote:
           | 100%. Enforcing lint rules is very important. What those lint
           | rules should say is generally very unimportant because the
           | editor should be doing all the work, and most of the time
           | "that's just like, your opinion, man".
        
           | pugworthy wrote:
           | Agreed. I don't care what the indentation is or formatting
           | is, as long as it's consistent.
        
         | jajko wrote:
         | Not really. Obsessing over breaking lines after famous 80 chars
         | in Eclipse was, is and will be idiotic to be polite.
         | Surprisingly large amount of people were obsessed by this long
         | after we got much bigger screens, if that was ever an argument
         | (it wasn't for me). 2 spaces vs 4 spaces or tab. Cases like
         | these were not that rare, even though now it seems better.
         | That's not productive focus of one's (or team's) energy and a
         | proper waste of money for employer/customer, it brings 0 added
         | value to products apart form polishing ego of specific
         | individual.
         | 
         | Folks who care about the craft obsess (well within realm of
         | being realistic) more about architecture, good use of design
         | patterns, using good modern toolset (but not bleeding edge),
         | not building monolithic spaghetti monster that can't evolve
         | much further, avoiding quick hacks that end up being hard to
         | remove and work with over time and so on.
         | 
         | If you don't see a difference between those groups, I don't
         | think you understood author's points.
        
           | sfn42 wrote:
           | I'd say avoiding long lines is one of the most important
           | rules. I regularly have 2-3 files open side by side, I don't
           | want to have to scroll sideways to read the code.
           | 
           | 80 characters is a bit on the low end imo but I'd rather have
           | the code be too vertical than too horizontal. Maybe 120-150
           | is a more reasonable limit. It's not difficult to stay within
           | those bounds as long as you don't do deep nesting which I
           | don't really want to see anyway because it's hardly ever
           | necessary and it makes code more difficult to read.
        
             | CrimsonRain wrote:
             | Functional code is more chained and need more space often.
             | Descriptive names are better; tends to be longer. Buy
             | ultrawide.
             | 
             | 80 is for aholes who like to use small laptop and then
             | force it on everyone else. 120/150 is reasonable.
             | 
             | 200 is great.
        
               | sgarland wrote:
               | 200 is entirely too fucking long, and I code on a 43" 4K.
               | I try to stay under 90 in deference to others, and if it
               | looks better breaking at 80, so be it.
        
               | whstl wrote:
               | Yep.
               | 
               | And the laptop excuse is not even valid, I used a 11"
               | MacBook Air for 10 years and even back then 80 always
               | felt extremely limiting for me.
               | 
               | I just tested and: even when zooming +1 on VSCode and
               | leaving the minimap open I can fit 140 chars without any
               | horizontal scroll.
               | 
               | People demanding 80 columns always have some crazy
               | setups, like an IDE where the editor is just a minuscule
               | square in the centre, like an Osbourne 1 computer.
        
               | alpaca128 wrote:
               | And 140 chars aren't enough for two files side by side
               | with 80 chars. With a readable font size and a narrow
               | font about 90 chars is a good limit on a 14" laptop
               | screen. Coincidentally that same limit then allows for
               | three files side by side on the average desktop screen -
               | or a browser window at the side for reference.
               | 
               | If you can live with a single file on screen that's
               | great, but the utility of two is far greater than having
               | a chunk of the screen empty most of the time because of a
               | few long lines.
        
               | whstl wrote:
               | If you need two files on the screen side by side, then
               | it's time to use something bigger than the MacBook 11
               | with zoomed fonts from my example. :)
               | 
               | ...unless you really want to prove grandparent's point.
        
               | jajko wrote:
               | If you do important work frequently on 14" screen and 2
               | files side-by-side (regardless of its resolution), then
               | you are seriously self-limiting yourself and your
               | efficiency, plus hurting your eyes which will inevitably
               | bring regrets later. That's not how 'love for the craft'
               | or ie efficiency looks like.
               | 
               | One reason I like longer lines, in those very few cases
               | (way less than 1% of code lines) - it bundles logically
               | several easy-to-read things, ie more complex 'if' or
               | larger constructors. We talk about Java here just to be
               | clear, for more compact languages those numbers can get
               | lower significantly but same principles apply.
               | 
               | Doing overly smart complex one-liners just for the sake
               | of it goes completely against what we write here, I've
               | seen only (otherwise smart) juniors do those. Harder to
               | debug, harder to read, simply a junior show-off move.
        
               | bluGill wrote:
               | Try saying that again when you are 50 and your eyes no
               | longer as good as they used to be. Back when I was 25 I
               | loved the tiny fonts I could fit on my (then incredibly
               | large) 19 inch monitor which I had pushed to the highest
               | resolution. These days even with special computer glasses
               | (magnification and optimized for computer distance) I
               | can't make such tiny text.
               | 
               | Now get off my lawn you punks!
        
               | whstl wrote:
               | Crazy.
               | 
               | I am.
               | 
               | And that's why I said I use the zoom in VSCode in my
               | previous message. My font is big as fuck compared to
               | everyone else.
        
               | jghn wrote:
               | Also old. Also can not read the fonts my earlier self
               | would use. Still do not understand the love for narrow
               | columns.
        
             | cess11 wrote:
             | Reading vertically is much faster than reading
             | horizontally, so I think 80 is a good soft limit. In some
             | contexts it's hard to not go over it sometimes, e.g. in
             | Java where it's not uncommon with very long type and method
             | names.
        
           | bayindirh wrote:
           | Reporting as an Eclipse user of 20+ years, and a person who
           | cares about the craft:
           | 
           | The choice for me is simple:
           | 
           | If I'm going to view the code I'm writing in a 80x24 terminal
           | later on, I'll break that lines, and will try really hard to
           | not get closer to 80 chars per line.
           | 
           | If that code is only going to be seen in Eclipse and only by
           | me, I won't break that lines.
           | 
           | I omitted your other examples for brevity.
           | 
           | Having bigger screens doesn't make longer lines legit or
           | valid. I may have anything between 4-9 terminals open on my
           | 28" 2K screen anytime, and no, I don't want to see lines
           | going from one side to another like spikes, _even if I have
           | written them_.
        
             | paddy_m wrote:
             | I like 80 columns, I can tolerate 100 or 120. I get really
             | annoyed with formatting standards, JS/TS in particular that
             | waste a whole line for a closing brace. Standard aspect has
             | screens more limited vertically than horizontally.
             | 
             | When dealing with tabular data, particularly test data, I
             | find most formatting lacking. I want to be able to specify
             | blocks that align on the decimal point. Especially when
             | dealing with lists of dicts. This makes reading test
             | fixtures much more intuitive than default indentation
             | styles.
             | 
             | Has anyone seen a formatter where you can specify a block
             | be formatted in that manner?                 [{'a':  3.89,
             | 'b':  10},        {'a': 12.3,  'b': 233}]
             | 
             | instead of                 [{'a': 3.89,         'b': 10},
             | {'a': 12.3,         'b': 233}]
        
           | lr4444lr wrote:
           | Preach!
        
         | WJW wrote:
         | There's a correlation-is-not-causation issue here. Yes, most
         | very good developers pay a lot of attention to details, as well
         | as to the bigger picture. But there are a lot of mediocre to
         | downright bad developers who think that paying a lot of
         | attention to code style, linting rules and other minutia will
         | make them better developers.
        
           | bityard wrote:
           | My experience has been the opposite. Most mediocre to bad
           | developers are so happy that their code works AT ALL that
           | they pay little to no attention to things like sensible
           | variable names and whitespace conventions. We sometimes call
           | these things, "code smell."
        
         | bryanrasmussen wrote:
         | as others note, most of this minutia can be automatically
         | enforced. Anything that can be automated is not craft.
        
           | marsovo wrote:
           | Heartily disagree. I have had to fight with others over
           | automated formatting because it obscured intent or clarity.
           | For example (C#) mandating `var`, mandating one and only one
           | line of whitespace between lines of code, mandating the =>
           | syntax for single-line functions (instead of
           | 
           | Function(vars) { ... } )
           | 
           | I would say, when to use one or the other of each of those
           | options is very much a craft.
        
         | aswerty wrote:
         | In my opinion, I think the author is criticizing bike shedding
         | [1] rather than meaningful decisions. Of course some people
         | will differ on whether a decision is one or the other. But as a
         | whole, not sweating the details is a good quality to have
         | whatever road in life you are on.
         | 
         | [1] https://en.wikipedia.org/wiki/Law_of_triviality
        
           | The_Colonel wrote:
           | Everyone dislikes bikeshedding. But people disagree on which
           | questions are bikeshedding and which aren't.
        
           | bluGill wrote:
           | Details are important though. Some bikeshed type ideas spiral
           | into very expensive changes. This is a large part of why US
           | transit construction is so much more expensive - people
           | asking for lots of little details which add up (large
           | monument stations, bike paths done with the project... those
           | things all add up) - the important safety details are left to
           | experts, but only after they are told to build something far
           | more expensive than needed. (this isn't a plea for brutalism
           | architecture there are nice things you can do that are only
           | minimally more expensive)
        
         | hliyan wrote:
         | There's another way to look at this: if you consider the school
         | of thought that says that the code _is_ the design, and
         | compilation is the construction process, then stressing over
         | code style is equivalent to stressing over the formatting and
         | conventions of the blueprint (to use a civil engineering
         | metaphor), instead of stressing over load bearing, material
         | costs and utility of the space.
         | 
         | I'm fond of saying that anything that doesn't survive the
         | compilation process is not _design_ but code organization.
         | Design would be: which data structures to use (list, map, array
         | etc.), which data to keep in memory, which data to load /save
         | and when, which algorithms to use, how to handle concurrency
         | etc. Keeping the code organized is useful and is a part of
         | basic hygiene, but it's far from the defining characteristic of
         | the craft.
        
           | chrisjj wrote:
           | > the school of thought that says that the code is the design
           | 
           | There's such a school?? Seriously??
        
           | TickleSteve wrote:
           | architecture over implementation (for details).
        
           | Retric wrote:
           | > the formatting and conventions of the blueprint
           | 
           | Some of those formatting conventions are written in blood.
           | The clarity of a blueprint is a big deal when people are
           | using it to convey safety critical information.
           | 
           | I don't think code formatting rises anywhere close to that
           | level, but it's also trying to reduce cognitive load which is
           | a big deal in software development. Nobody wants to look at
           | multiple lines concatenated together, how far beyond that you
           | take things runs into diminishing returns. However at a
           | minimum formatting changes shouldn't regularly complicate
           | doing a diff.
        
             | hliyan wrote:
             | I 100% agree. The problem is that after a half a century,
             | software engineering discipline has been unable to agree on
             | global conventions and standards. I recently had an
             | experience where a repair crew was worried about the odd
             | looking placement of a concrete beam in my house. I brought
             | over the blueprints, and the technician found the schedule
             | of beams and columns within seconds, pinpointed the beam
             | and said, "Ah, that's why. We just need to <solution I
             | won't go into>". Just then it struck me how we can't do
             | this in software engineering, even when the project is
             | basically a bog-standard business app: CRUD API backed by
             | an RDBMS.
        
               | skydhash wrote:
               | That's because the few hard rules you have to comply with
               | have workarounds and matters rarely. In house
               | construction, you have to care about weight, material
               | degradation, the code, etc... there's no such limitation
               | on software so you can get something to work even if it's
               | born out of a LSD trip.
               | 
               | But we do have some common concepts. But they're
               | theoretical, so only the people that read the books knows
               | the jargon.
        
               | namaria wrote:
               | I mean why should we expect _soft_ ware to have _hard_
               | rules? Flexibility is the point, no?
        
               | HeyLaughingBoy wrote:
               | No. Flexibility is a side effect. Sometimes it's a useful
               | side effect, other times it bites you in the ass.
        
               | Ma8ee wrote:
               | The rules are what make it flexible. The rules let me
               | understand what the heck is going on in the code you
               | wrote so I can change it. Code that is faster to rewrite
               | from scratch isn't flexible.
        
               | watt wrote:
               | don't stress about it so much: look how many variations
               | of plugs and sockets are for this one quite simple thing:
               | https://en.wikipedia.org/wiki/AC_power_plugs_and_sockets
        
               | VonGallifrey wrote:
               | > I brought over the blueprints, and the technician found
               | the schedule of beams and columns within seconds
               | 
               | Is that really an example of the standardization you
               | want? It shows that the blueprint was done in a way that
               | the technician expected it to be, but I am not sure that
               | these blueprints are standardized in that way globally.
               | Each country has its standards and language.
               | 
               | If an architect from a different country did that
               | blueprint, I would bet that it would be significantly
               | different from the blueprint you have.
               | 
               | Software Engineering doesn't have a problem with country
               | borders, but different languages would require different
               | standards and conventions. Unless you can convince
               | everyone to use the same language (which would be a bad
               | idea; CRUD apps and rocket systems have different trade-
               | offs), I doubt there could be an industry-wide standard.
        
               | lanstin wrote:
               | But I can't look at the design from my desk-mate and hope
               | to understand it quickly. We wall love to invent as much
               | as possible ourselves, and we lack a common design
               | language for the spaces we are problem solving in.
               | Personally I don't entirely think it's a problem of
               | discipline of software engineering, but a reflection of
               | the fact that the space of possible solutions is so high
               | for software, and the [opportunity] cost of missing a
               | great solution because it is too different from previous
               | solutions is so high (difference between 120 seconds
               | application start and 120 milliseconds application start,
               | for instance).
        
               | wongarsu wrote:
               | Construction and civil engineering have been unable to
               | agree on global conventions and standards, and they have
               | a multi-millenia head start over software engineering.
               | The US may claim to follow the "International Building
               | Code", but it's just called that because a couple of
               | small countries on the Americas have adopted it. For all
               | intents and purposes it's a national standard. Globally
               | we can't even agree on a system of units and
               | measurements, never mind anything more consequential than
               | that.
        
               | Ma8ee wrote:
               | I'd say that globally we have agreed on a system of units
               | and measurements. It's just the US and a handful of third
               | world countries that don't follow that system.
        
               | dranudin wrote:
               | That is largely due to a difference in complexity.I would
               | say that the level of complexity of a blueprint of a
               | house is on par with a 20-30 line python solution of a
               | leet code easy excercise to a programmer. If the one
               | reading the blue print is an engineer and the one reading
               | the python code is a programmer. A crud app is more like
               | the blue prints for a vacuum cleaner or something like
               | that.
        
               | HeyLaughingBoy wrote:
               | I don't know that we'll ever be able to agree on "global
               | standards" though. Software is too specialized for that.
               | 
               | The only software standard that I'm reasonably familiar
               | with is https://en.wikipedia.org/wiki/IEC_62304 which is
               | specific to Medical Devices. In a 62304-compliant
               | project, we _might_ be able to do something like your
               | example, but it could take a while. OTOH, I 'm told that
               | my Aviation counterparts following DO-178 would almost
               | certainly be able to do something comparable.
               | 
               | It is going to be very industry dependent, where
               | "industry" means aviation, or maritime, or railroad, or
               | Healthcare, etc... Just "software" is too general to be
               | meaningful these days.
        
             | desdenova wrote:
             | Fortunately nowadays formatting issues can be delegated to
             | autoformatting in any popular language.
             | 
             | Some people still argue over autoformatter parameters, but
             | then people will always find a bike shed to argue about.
        
               | noahjk wrote:
               | Maybe a new paradigm for code formatting could be local-
               | only. Your editor automatically formats files the way you
               | like to see them, and then de-formats back to match the
               | codebase when pushing, making your changes match the
               | codebase style.
        
               | tele_ski wrote:
               | It's a decent idea, but it's weird reviewing code you
               | wrote in saying GitHub, it looks totally different. Imo
               | not a show stopper but a side effect you have to get used
               | to.
        
               | asdajksah2123 wrote:
               | This is pretty common now. At least my Vim/git combo does
               | this, where I always open source code with my preferred
               | formatting but by the time it's pushed to the server it's
               | changed to match the repo preferences.
        
               | ruined wrote:
               | this works for pure formatting, but falls apart when you
               | start linting to exclude certain syntax or patterns
        
               | withinboredom wrote:
               | This is disastrously easy to implement with just a few
               | filters on git (clean & smudge).
               | 
               | I highly recommend it though, especially if you worked
               | for a long time at one company and are used to a specific
               | way of writing code. Or if you like tabs instead of
               | spaces...
        
               | Braini wrote:
               | This was such a relieve for us. Looking back its
               | unbelievable how much combined time we wasted complaining
               | about and fixing formatting issues in code reviews and
               | reformatting in general.
               | 
               | With clang-format & co. on Save plus possibly a git hook
               | this all went away. It might not always be perfect (which
               | is subjective anyway) but its so worth it.
        
             | drcongo wrote:
             | First thing I thought of was the tiny Stone Henge in Spinal
             | Tap.
        
             | DarkPlayer wrote:
             | > However at a minimum formatting changes shouldn't
             | regularly complicate doing a diff.
             | 
             | If the code needs to be reformatted, this should be done in
             | a separate commit. Fortunately, there are now
             | structural/semantic diff tools available for some languages
             | that can help if someone hasn't properly split their
             | formatting and logic changes.
        
               | gmueckl wrote:
               | Reformatting comitts still leaves the issue that you
               | deprive yourself of any possibility to reliably diff
               | across such commits (what changes from there to there?)
               | Or attribute a line of code to a specific change (why did
               | we introduce this code?).
               | 
               | What we should have instead is syntax-aware diffs that
               | can ignore meaningless changes like curly braces moving
               | into another line or lines getting wrapped for reasons.
        
               | DarkPlayer wrote:
               | > What we should have instead is syntax-aware diffs that
               | can ignore meaningless changes like curly braces moving
               | into another line or lines getting wrapped for reasons.
               | 
               | These diffs already exist (at least for some languages)
               | but aren't yet integrated into the standard tools. For
               | example, if you want a command line tool, you can use
               | https://github.com/Wilfred/difftastic or if you are
               | interested in a VS Code extension / GitHub App instead,
               | you can give https://semanticdiff.com a try.
        
               | oasisbob wrote:
               | Not a full solution, but .git-blame-ignore-revs can help,
               | and is automatically supported by GitHub:
               | 
               | https://gist.github.com/kateinoigakukun/b0bc920e587851bff
               | fa9...
        
             | singron wrote:
             | I'm immediately reminded of Apple's "goto fail" bug, which
             | was in part overlooked because of poor formatting and/or
             | style: https://dwheeler.com/essays/apple-goto-fail.html
        
             | dasil003 wrote:
             | Software, being arbitrary logic, just doesn't have the same
             | physical properties and constraints that have allowed civil
             | engineering and construction code to converge on standards.
             | It's often not clear what the load bearing properties of
             | software systems are since the applications and
             | consequences of errors are so varied. How often does a
             | doghouse you built in your backyard turn into a skyscraper
             | serving the needs of millions over a few short years?
        
             | maccard wrote:
             | This is the best argument I've ever heard for editorconfig,
             | commiting a standardised format to the repos, and viewing
             | it in whatever way you want to view it on your own machine
        
           | binary132 wrote:
           | There is definitely something to be said for the idea that a
           | shitslop engineering blueprint which still conveys correct
           | design (maybe; who knows really?) is shitslop, whether or not
           | the design is sound. In the case of software engineering, the
           | blueprint is the implementation, too, so it's not just
           | shitslop blueprinting, it's also shitslop brickwork (totally
           | sound bones though I promise!), shitslop drywalling, shitslop
           | concrete finishing and rebar work -- and maybe it's all good
           | under the hood! Totally fine if all you're building is a
           | shithouse! But I think you get where I'm going with this.
        
           | skydhash wrote:
           | The value of software is both what it does now (behavior),
           | and what you can get it to do later (structure). What you
           | described as design and the compiled artiface is the
           | behavior.
           | 
           | The craft is what gives you future choices. So when people
           | cares about readability, writing tests, architecture, they're
           | just making easy for them to adjust the current behavior
           | later when requirements change. A software is not an house,
           | it doesn't get build and stays a certain way.
        
             | skeeter2020 wrote:
             | experience gives you some possible ideas for how it will be
             | used in the future, but after a long time I'm coming to the
             | position you're fooling yourself if you think you can
             | predict where with any accuracy. It's still valuable and
             | important to try, just not as critical to be right as I
             | used to think. Example: I've completely flip-flopped from
             | interface simplicity to implementation simplicity.
             | 
             | I agree that a house is a bad analogy, for your reasons and
             | because you can "live" in software that as a building would
             | not be fit for human habitation.
        
               | skydhash wrote:
               | You have to be pragmatic about it, balancing between the
               | speed of only implementing the now and the flexibility of
               | taking care of the future. It's not predicting, mostly
               | it's about recognizing the consequences of each choice
               | (for later modifications) and and either accepting it or
               | ensuring that it will not happen.
        
               | dowager_dan99 wrote:
               | > It's not predicting, mostly it's about recognizing the
               | consequences of each choice (for later modifications)
               | 
               | This is the exact trap I'm describing. It sounds very
               | reasonable, but how is it not prediction when you're
               | asking people to "recognize the <future> consequences of
               | each choice"? You have very little to no understanding of
               | the context, environment or application of today's
               | creations. Smart, experienced people got us into the
               | current microservice, frontend JS, "serverless" cloud
               | messes.
        
               | skydhash wrote:
               | Risk management is a fact of all activities. It's not
               | predicting that some thing is going to happen, but it's
               | evaluating that if we can afford the consequences if it
               | really happens. If we can, let's go ahead with the easy
               | choice. If we cannot, let's make sure that it won't
               | affect us as much.
               | 
               | > _Smart, experienced people got us into the current
               | microservice, frontend JS, "serverless" cloud messes._
               | 
               | Those are solutions to real problems. The real issue is
               | the cargo cult, aka "Google is doing it, let's do it
               | too". If you don't have the problem, don't adopt the
               | solution (which always bring its own issues). It's always
               | a balancing act as there is no silver bullet.
        
           | anuramat wrote:
           | > not the defining characteristic
           | 
           | Did anyone claim otherwise? Besides, I imagine bridges aren't
           | rebuilt every week -- poor blueprints can only cause a finite
           | amount of pain.
        
           | atkevindsouza wrote:
           | Let's talk about in the way you seem to interpret it.
           | 
           | Imagine if Blueprint A used imperial units while others used
           | metric units.
           | 
           | That's what inconsistent code style does to you.
        
           | psychoslave wrote:
           | >I'm fond of saying that anything that doesn't survive the
           | compilation process is not design but code organization.
           | 
           | Maybe not at the same level, but code organization is also a
           | design.
           | 
           | I don't care that much about the exact linter rules applies
           | (but I do prefer blue, hmm, nooo). But getting rid of merge
           | conflicts that come from lake of common linter rules, this is
           | a great pipeline process improvement, and this is some kind
           | of code contribution pipeline design.
        
           | animuchan wrote:
           | In many languages, types don't survive the compilation
           | process (e.g. TypeScript, Java). Yet types describe which
           | data structures are used.
        
           | asdajksah2123 wrote:
           | > stressing over the formatting and conventions of the
           | blueprint (to use a civil engineering metaphor)
           | 
           | This is incredibly important.
           | 
           | This is the kind of stuff that prevents shit like half the
           | team using metric and the other half thinking they're
           | imperial, or you coming up with the perfect design, but then
           | the manufacturer makes a mirrored version of it because you
           | didn't have the conventions agreed upon.
        
             | tehologist wrote:
             | Imperial vs Metric is a hard requirement not a convention
             | or formatting. I have a co-worker who wants everything to
             | be a one liner, doesn't like if/else statements, thinks
             | exception handling is bad and will fail a code review over
             | a variable that he feels isn't cased properly.
             | 
             | This makes code reviews super slow and painful, it also
             | means you aren't focusing on the important stuff. What the
             | code actually does and if it meets the requirements in
             | functionality. You don't have time for that stuff, you are
             | too busy trying to make this one person happy by turning an
             | if else into a ternary and the end of sprint is a day away.
        
               | atq2119 wrote:
               | > will fail a code review over a variable that he feels
               | isn't cased properly
               | 
               | Many projects have fairly strict rules about identifier
               | naming conventions, so this doesn't feel so far fetched
               | to me.
               | 
               | The example about if/else vs ? : is pretty damning
               | though.
        
               | mindcrime wrote:
               | Sure, but if there are actual rules, agreed to and
               | accepted by the entire team (as opposed to one guy's
               | idiosyncratic preferences) then there should be a commit-
               | hook to run the code through a linter and reject the
               | commit if the rules are violated.
        
               | plorkyeran wrote:
               | If a reviewer is regularly rejecting PRs because the
               | variable names have incorrect capitalization then that's
               | a problem with the author, not the reviewer. That is the
               | incredibly basic shit you decide on at the start of a
               | codebase and then follow regardless of your personal
               | thoughts on what scheme is preferable.
               | 
               | If/else vs ternaries is something where consistency is a
               | lot less important, but if you know that a team member
               | has a strong preference for one over the other and you
               | think it's unimportant then you should just write it how
               | they prefer to begin with. Fight over things you think
               | are important, not things that you think don't matter.
        
               | withinboredom wrote:
               | wtf... no.
               | 
               | I worked with a guy where you would try to predict what
               | he would bitch about next. In this example, you would
               | write it as a ternary so you don't have to hear about it
               | ... and he'd suggest it be an if-else statement.
               | 
               | Nobody fucking cares which one it is; is it readable?
               | That's the real question. Your preference of which
               | version of "readable" it is only applies when you are the
               | author. If you're that picky about it, write it yourself.
               | That's what we eventually did to that guy after the team
               | got sick of it. Anytime he'd complain about something
               | like that, we would invite him to write a PR to our PR,
               | otherwise, get over it. Then, we would merge our PR
               | before he could finish.
               | 
               | He eventually got fired for no longer able to keep up
               | with his work due to constantly opening refactor PR's to
               | the dev branch.
        
           | zelphirkalt wrote:
           | And some specific people with lots of experience in teaching
           | as well as in developing real life useful systems will tell
           | you, that code is first and foremost written for people to
           | understand, and only incidentally for a computer to run.
           | Human understanding of what is going on is the one most
           | important thing. If we do not have that, everything else will
           | go to shit.
        
           | ryandrake wrote:
           | Yea, I've always considered craftsmanship to be about paying
           | attention to the details and making everything high quality--
           | even the things that the end user will never see, but _you_
           | know are there. The Steve Jobs quote sums it up nicely:
           | 
           | > "When you're a carpenter making a beautiful chest of
           | drawers, you're not going to use a piece of plywood on the
           | back, even though it faces the wall and nobody will ever see
           | it. You'll know it's there, so you're going to use a
           | beautiful piece of wood on the back. For you to sleep well at
           | night, the aesthetic, the quality, has to be carried all the
           | way through."
        
           | s1mplicissimus wrote:
           | The construction metaphor isn't a very good fit here in my
           | opinion. No building is expected to have the amount of
           | adaptability that is expected of software. It falls
           | completely apart for interpreted languages. When is a PHP app
           | constructed in this metaphor? On every single request? The
           | metaphor assumes a "design once, build once" approach, which
           | is basically no software I've ever seen used in real life.
           | Hardware, OS, language, collaborator/dependency updates all
           | require changes to the application code more often than not.
           | And that's assuming the feature set stays stable, which, in
           | my experience is also quiet rare. Maintainability is
           | therefore a quality dimension of software, and reduced
           | cognitive load usually results in increased maintainability
           | (curious if someone has a counterexample to that)
           | 
           | That is not to say I'm one of those people who need a
           | specific code style to have their weird brain satisfied. But
           | not using a linter/autoformatter at all [when available] in
           | 2025 sounds like the opposite of "work smart, not hard"
        
           | tremon wrote:
           | sowhatyouresayingisthatyoureequallyhappyeditingjavascriptinit
           | sminifiedartifactformastheoriginalcode?imeanifallthatyoucarea
           | boutisthatyourwordsarecorrectlyinterpretedbythemachinetheresn
           | ovalueinmakingsurethatyourcodeisreadableandusablebyanotherhum
           | anbeingamiright?
        
         | bdcravens wrote:
         | I think the line between minutiae and craft is drawn by the
         | effect it has on the product you're creating. Method length
         | makes your code more manageable, for example. Placement of line
         | breaks, not so much.
         | 
         | At the end of the day, we aren't paid to produce code, but
         | working software that works today and is easy to change
         | tomorrow.
        
           | latexr wrote:
           | That is a purely commercial take of the matter. I don't think
           | it's controversial to argue the artisans who stand out do so
           | because they care for the craft itself. Spending an extra
           | hour or two perfecting the shape of the armrest in the chair
           | may not allow you to earn more money from that one
           | commission, but it might improve your knowledge and skill and
           | be slightly more comfortable to the sitter. If they comment
           | on it and appreciate it, so grows your motivation and pride.
           | 
           | Sometimes the code itself, and not its result, is the
           | product. For example, when making tutorials the clarity and
           | beauty of the code matters more than what it does.
           | 
           | I'm not arguing for obsessing over code formatting, but
           | pointing out the line between "master of the craft with
           | extensive attention to detail" and "insane weirdo with
           | prioritisation deficits focusing on minutiae" is subjective
           | to what each person considers important. Most of us seem to
           | agree that being consistent in a code base is more important
           | than any specific rule, but that being consistent _does_
           | matter.
           | 
           | At the end of the day, we aren't paid to eat healthily and
           | taking care of our bodies either. But doing so pays
           | dividends. Same for caring about the quality of your code.
           | Getting in the habit of doing it right primes you to do it
           | like that _from the start_ in every new project. Like most
           | skills, writing quality code becomes easier the more you do
           | it.
        
             | bdcravens wrote:
             | > be slightly more comfortable to the sitter
             | 
             | That's kind of my point: the end cannot see, or feel,
             | minutiae. If they can, it's not minutiae.
             | 
             | > Sometimes the code itself, and not its result, is the
             | product. For example, when making tutorials the clarity and
             | beauty of the code matters more than what it does.
             | 
             | The code still isn't the product in that instance. It's the
             | educational process. In many cases, clarity != beauty. This
             | is why the best written tests often duplicate code, rather
             | than being curated exercises in DRY.
             | 
             | > we aren't paid to eat healthily and taking care of our
             | bodies either
             | 
             | Yet programmers insist to be paid. Obviously taking time to
             | grow on your own, on your own dime, is self-enriching for
             | all the reasons you describe.
        
         | korijn wrote:
         | Is it ironic that this comment has evoked a discussion on
         | minutiae?
        
         | hemant1041 wrote:
         | Interesting read!
        
         | raverbashing wrote:
         | And that's why I don't care anymore
         | 
         | Yup. Doesn't matter.
         | 
         | Code style should be consistent and look nice, probably use the
         | default without too much nitpicking. You have bigger fish to
         | fry
         | 
         | There are better things in life to worry about
         | 
         | "Craft", most code goes to irrelevancy in 5 yrs. And if it
         | doesn't it's fixable (amen for AIs)
         | 
         | Try to sweat up every detail right off the bat and you go
         | nowhere
        
         | oytis wrote:
         | To me "craft" is about keeping code efficient, scalable,
         | extensible, well-tested and documented. Code style is more
         | about what naming convention to use, tabs vs spaces etc. - it's
         | nice to have it consistent, but no need to spend more than 5
         | minutes arguing about it.
        
           | ctxc wrote:
           | Tabs/spaces is a non-issue, agreed - IDEs handle it.
           | 
           | But surely naming convention contributes to keeping code
           | documented, extensible and efficient?
           | 
           | A deviation from the norm leads to people thinking x does not
           | exist in a large code base, leading to them implementing
           | duplicate methods/functionality, leading to one instance
           | evolving differently enough to cause subtle bugs but not
           | enough to be distinct, or leading to one instance getting
           | fixes the other does not etc?
           | 
           | Sample size of 1, but I've seen it happen unfortunately.
        
         | lr4444lr wrote:
         | Following non functional stylistic rules to the letter as if
         | they were on the level of SQL injections or memory leaks isn't
         | "craft". It's cargo culture weirdness.
         | 
         | Sure, have a style and a linter. Be DRY. Don't lose your head
         | over it though.
        
         | lijok wrote:
         | Video game logic: Everyone worse than me is a noob. Everyone
         | better than me has no life.
        
           | alternatex wrote:
           | Today Steam gives us the option of verifying whether a
           | certain player has no life. Only half joking.
        
             | danielbln wrote:
             | My favorite steam reviews are: "This game sucks, would not
             | recommend." - playtime 800h
        
           | mtdrk wrote:
           | This is more like noob logic. Good players are eager to learn
           | from those better than them.
        
         | ozim wrote:
         | If you want to compare to artisans - they were stressing about
         | details that customers see, details that customers don't see
         | were to cut corners on.
         | 
         | Making fuss about indentation in code file is not artisanal. It
         | is insane weirdo if we are charitable and if not clueless and
         | childish.
        
           | sumtechguy wrote:
           | Everyone wants a particular style. Except when they have to
           | use someone elses style.
           | 
           | Pick a style stick with it. Review it every 6 months to year
           | to see if anything needs to be tweaked.
           | 
           | If you hear 'we are professionals' you are about to see code
           | that has 20 different styles and design patterns.
           | 
           | I worked with one guy who could not make up his mind and
           | changed the whole style guide about every 2-3 weeks. It royal
           | made him mad the original style guide fit on a couple of
           | postit notes. Me and two other engineers bashed it out in a
           | 1-2 hour meeting at the start of the project (odd number of
           | people to vote on anything). It came down to the fact he came
           | in after the fact and had no say in it. Then proceeded to
           | change everything. One week it was tabs everywhere then
           | spaces then tabs again. One day camel case, week later all
           | lower, another partial hungarian, upper on random things,
           | etc. Waste of time.
        
             | bluGill wrote:
             | Ideally pick a style from a different large organization
             | that you have no input in. Because the organization is
             | large they will have put a lot of effort into it, but since
             | you have no input you can just follow it without thinking.
             | Sometimes an organization will make some really weird
             | choices and you will be forced to change styles (google as
             | rejected a lot of the latest C++ standard and thus their
             | C++ style guide is not to be used elsewhere, but there are
             | plenty of other good options).
             | 
             | Second best is to start a large cross company standards
             | organization and only allow one representative per
             | organization. Make sure there is a lot of process standing
             | in the way of changes so that changes are only made when
             | really justified (because most are not justified)
        
           | 9rx wrote:
           | To be fair, for most developers code is what their customer
           | is going to see.
        
           | tremon wrote:
           | _they were stressing about details that customers see,
           | details that customers don't see were to cut corners on_
           | 
           | Sure, but there's two differences between artisans and
           | programmers.
           | 
           | Firstly, most artisans produce sellable products. Once the
           | customer has bought an item, they would never see it again.
           | I'm pretty sure that if there was a minor error on a self-
           | produced table or a vase and it was standing in the artisan's
           | own living room, they'd not be able to unsee it, and still
           | work to correct it.
           | 
           | Secondly and more importantly: code is not just the product
           | that programmers work _on_ , it's also the workshop that
           | programmers work _in_. And you bet your ass that artisans are
           | very anal about the layout and organization of their
           | workshop. Put away screws in the wrong box, or throw all the
           | dowels of multiple sizes in the same container? The carpenter
           | will fire his apprentice if it happens more than once; place
           | your knives in the wrong place in a kitchen and the chef will
           | eat you alive; not properly wearing or storing safety
           | equipment can be a fireable offense in many places.
           | 
           | To me, a code review is how you close your workshop for the
           | week: tools are cleaned and stored, floors are tidy enough to
           | walk around, and the work area is available so I can come
           | back on monday and be productive again. I shouldn't have to
           | spend monday cleaning glass shards because someone left a
           | hammer standing straight up on a glass table - or chasing
           | down last week's lunch because someone left the fridge open
           | and now the cheese has grown legs.
           | 
           | So no -- making fuss about code style and quality can
           | certainly be artisanal (maybe not about indents specifically,
           | but can certainly be about textual organization). Because the
           | code is the workshop, and you know the next time you will
           | enter this room it will be because of a high-priority demand
           | and you can't afford to spend half your day cleaning up what
           | you couldn't be bothered to do last time.
        
         | hackflip wrote:
         | Have you ever noticed that anybody driving slower than you is
         | an idiot, and anyone going faster than you is a maniac?
        
           | mixmastamyk wrote:
           | The old Carlin bit, was going to mention. :-D. I think he
           | used, "asshole."
        
         | Cthulhu_ wrote:
         | Thing is, you can care for the craft, but let the code style
         | and linting tools do what they do best and don't stress over
         | them. Code reviews are better now that there's tooling that
         | automatically checks for, fixes, or marks common issues like
         | code style so the reviewer doesn't have to do anything with
         | them.
         | 
         | That is, I'd argue the "stressing" is not about what these
         | tools check, but about the tools and their configuration
         | itself. Just go with all the defaults and focus on bigger
         | issues.
        
         | cardanome wrote:
         | Sure some people that care about minutiae are code artisans but
         | what I have seen more often is co-workers weaponizing these
         | discussions to hide their own incompetence.
         | 
         | I have seen so many people going on and on about best practices
         | and coding styles and whatnot and using big words just in hopes
         | to keep discussions going so no one figures out out that they
         | don't know how to code.
        
         | raincole wrote:
         | When people stress over the details I care, it's craftmanship.
         | When they stress over the ones I don't care, it's nitpicking.
        
         | ghc wrote:
         | To reduce your argument to its essence, you're saying
         | typesetting is part of the craft of writing. I've yet to meet
         | an author who believes this (other than enjoying editing their
         | own work as output from a typewriter), and I think the same
         | broadly applies to code. It's not that everyone thinks these
         | things are unimportant, it's that caring deeply about doing
         | them a particular way is orthogonal to the craft. It's
         | something that has long been lampooned (tabs vs. spaces,
         | braces, etc.) as weird behavior.
        
           | catlifeonmars wrote:
           | I think there are accessibility aspects to formatting.
           | Specifically to different formatting.
           | 
           | Not sure the typesetting analogy is the best, but typesetting
           | absolutely matters for readability. Authors don't need to
           | care about it because typesetting is easy to change (before
           | printing) and because publishers spend time caring about it
           | --- all before it ends up in the hands of readers.
        
           | stonemetal12 wrote:
           | More than one writer refuses to use a computer, preferring
           | typewriters. Harlan Ellison learned how to repair typewriters
           | after he could no longer find anyone to fix his. Stephen King
           | wrote Dreamcatcher with a fountain pen.
           | 
           | Authors totally obsess over details that seem irrelevant to
           | people outside that craft.
        
             | asa400 wrote:
             | And that's totally fine! But there is no correlation
             | whatsoever between writing on a typewriter or using a
             | fountain pen (or the physical experience of writing
             | generally) and the quality of the writing. None.
             | 
             | There is nothing to support this in either writing or
             | programming, at all. For every software craftsman out there
             | obsessing over formatting, editor layout, linters, line
             | length, there is an ancient, horrifyingly laid out C
             | codebase that expertly runs and captures the essence of its
             | domain, serves real traffic and makes real money.
             | 
             | Make your editor work how you like, but if my team lead
             | started to get annoyed after my 4th formatting-only PR I
             | should probably start to think about what I want them to
             | bring up to my manager in my performance review.
        
               | stonemetal12 wrote:
               | I don't disagree with the broader point I just think
               | authors aren't a good example for a non-tool obsessed
               | group of people.
               | 
               | I read https://prog21.dadgum.com/ somewhat regularly when
               | I think I am getting to tool obsessed.
        
               | kod wrote:
               | > But there is no correlation whatsoever between writing
               | on a typewriter or using a fountain pen (or the physical
               | experience of writing generally) and the quality of the
               | writing
               | 
               | I heard neal stephenson say that he writes using a pen
               | rather than a wordprocessor specifically because it does
               | affect the quality of the writing. Because he handwrites
               | slower than he types, he does more thinking and editing
               | in his head rather than after it's on paper.
        
               | asa400 wrote:
               | And if that works for him then he should do that, and I
               | have no problem with that at all. I just don't think
               | there is anything one can say about writing tools that
               | _generalizes_ to writing quality, and the same applies to
               | the type of conversations programmers often engage in
               | like "functions need to be short!" or "line length MUST
               | be less than 90 or else I will reject this PR!" or "dark
               | mode is objectively better to write code in" etc.
               | 
               | I have no problem whatsoever with people having
               | preferences, I just think people mistake preferences for
               | proof.
        
             | blipvert wrote:
             | Personally, I modified a Hollerith reader to accept
             | Jacquard tapes that I cut by hand with a scalpel.
             | 
             | I'm so much more productive now.
        
             | booleandilemma wrote:
             | There is a class of people who refuse to see computer
             | programming as an art.
             | 
             | They try to shoehorn it into being an engineering
             | discipline and comparing it to authoring a book (something
             | you can't give timelines on or T-Shirt size) probably
             | horrifies them.
        
               | tremon wrote:
               | Ah, the joys of overloading. Do you mean "art" as the
               | high-brow stuff we see in galleries and are produced in
               | volumes of dozens per artist-years? Or do you mean "art"
               | as the more common stuff that's produced by artisans are
               | the rate of dozens per week? Because to me it's more the
               | latter -- I'm an artisan, not an artist.
        
               | booleandilemma wrote:
               | Why not both?
        
           | evilduck wrote:
           | If typesetting and a grammar mistake in one sentence were
           | what made a book viable or not, authors would care. I've seen
           | enough (crazy expensive) bugs that could have been caught by
           | linters and bugs introduced through insane formatting and
           | style choices that I can't agree that a book and software are
           | all that comparable.
           | 
           | I'm on team "agree at the beginning and then make it part of
           | CI" and I basically never have to have this conversation more
           | than once or twice per project now but I also think that the
           | people most obsessed with it and dwell on it for their
           | personal daily work are problematic, as are the people who
           | hate any rules whatsoever and want to write complete shit
           | code to just call the job done because "that's the important
           | part".
        
           | s1mplicissimus wrote:
           | The prose writing metaphor also falls apart the moment one
           | admits that prose doesn't have the need (and is actually very
           | terrible at) working collaboratively, concurrently but not
           | perfectly synchronized and continuously on the same body of
           | text, ensuring at the same time that combined changes don't
           | add up to unwanted/wrong semantics, even in the long term.
           | Are consistent indentations, variable names etc. strictly
           | required for that? No, not logically, but the real world in
           | which our software must be built is resource constrained, so
           | every minute I spend parsing weird formatting inconsistencies
           | is one minute less I can focus on the actual problem that
           | needs solving. Just use a formatter/linter everyone. And I
           | promise I don't care how it's configured, as long as it's
           | consistent across the codebase
        
           | patmorgan23 wrote:
           | Type setting is not a good analogy here.
           | 
           | A better one would probably be accounting and spread sheets.
           | Having common formatting conventions between spreadsheets
           | (and code files) allows your brain to filter out the noise
           | better. Obviously you can get too down in the weeds on "what
           | are the best conventions" but the most important part is to
           | have them and stick to them.
        
         | arp242 wrote:
         | Most of these things really don't matter, and it all just boils
         | down to "that's not how I would have written it". Well, okay,
         | but that doesn't mean that's somehow objectively better.
        
         | fsloth wrote:
         | No, focusing on code style is weird. It's tablestakes it should
         | be uniform in style and legible. Automate styling to vanilla
         | defaults. _Leave it_.
         | 
         | It's like obsessing over the font on the packaging of the
         | marker you use to write to the whiteboard in a math seminar.
         | 
         | Now, weird is _beautiful_ but it's not usefull and mostly
         | irritating in a professinal context.
         | 
         | Cherish your weirdness and celebrate when you can find people
         | of same persuasion. But don't bother your colleagues with it.
         | 
         | I'm saying this as a person with very deep weird personal
         | interests as several here do - and I've learned this slowly and
         | painfully.
        
         | swiftcoder wrote:
         | If what you care about deeply can be automated by a linter,
         | it's trivial, and you ought to just setup the linter rules, and
         | go use all that time you just gained to work on something more
         | meaningful.
        
         | jredwards wrote:
         | Related: Anyone who's driving slower than I am is an idiot and
         | anyone who's driving faster than I am is a maniac.
        
         | taurknaut wrote:
         | > Revered artisans are precisely the ones who care for the
         | details.
         | 
         | Well yea, but which detail you care about still matters and
         | reveals a lot about your "craft". Code style is of such little
         | consequence compared to semantics it's always a little eyebrow-
         | raising to see people who are extremely opinionated about it.
         | 
         | I've also noticed that this sort of thing can sort of fade into
         | the background after a couple decades of coding. I know people
         | who go on and on about how "beautiful" code is--to me it's just
         | syntax serving a purpose. Sometimes you can make really elegant
         | code that works well with the language, sometimes you can't.
         | But how the code is presented impacts my reading comprehension
         | very little unless you're doing something very strange (looking
         | at you, early 90s c code with one-letter variable names and
         | heavy macro usage).
         | 
         | Actually, I recant one element of this--Javascript and
         | Typescript are just straight ugly and hard to read.
        
         | drbawb wrote:
         | Somewhat agree and disagree. I bucket people's style into two
         | camps, stressing over the former is largely unproductive, but
         | stressing over the latter is crucial to writing high-quality,
         | maintainable software.
         | 
         | Someone's style can be "different" without being "bad", and you
         | have two basic options to deal with it. One is to
         | authoritatively remove the soul via process (auto-formatters,
         | code review, and to a lesser degree linters, etc. are all
         | designed to create uniformity at the cost of individuality.)
         | The other is to suck it up and deal with it, as this is just an
         | inevitability of creating a team size larger than one: people
         | have different tastes and those have to be reconciled. I
         | somewhat prefer allowing for individuality, and individuals
         | should endeavor to match the style of whatever module they're
         | working in, out of courtesy to its owners/stakeholders if
         | nothing else. However I have only worked independently or on
         | small teams. Most large teams (/ open source projects) have
         | gone the former route of automating all the fun/craftsmanship
         | out of their systems, and even I think that makes sense at a
         | certain scale.
         | 
         | Someone's style can just be objectively "bad", however, and I
         | usually find it's evidence they just don't care about the
         | source artifact that much, and they're focused on the results.
         | (It can also be a sign of an under-performer that spends so
         | much mental capacity just getting the code to work that they
         | have no spare cycles to spend thinking about matters of taste.)
         | If it compiles / works / passes the test-suite that's "good
         | enough" and "their job is done" and they move on to the next
         | task. These people tend to be hyper-literal thinkers that are
         | very micro-task oriented: they see implementing a new feature
         | as a checklist to be conquered, rather than being systems-level
         | thinkers on a journey of discovery & understanding.
         | 
         | If the author is talking about the latter, I have to agree with
         | you that the latter are quite difficult for me to work with;
         | particularly since I know that the source has to be maintained
         | & supported over a much larger time-scale. The source-code is
         | like your house, you live in it, being comfortable to work
         | with/in/on it is the key to success. The deployed artifact may
         | live for only a few weeks, days, or even _hours_ before it gets
         | replaced. The source has evolved over _decades._ You (the
         | organization) are practically married to it. To further the
         | analogy: I don 't mind if somebody wants to hang posters in
         | their room for a band I don't like. (Hell I can even handle if
         | a group of those posters are tastefully hung out-of-level to
         | make some kind of statement.) I do mind if their furniture is
         | blocking a vent, the outlet covers are hanging off, there's a
         | hole in one of the walls, a light has been burnt out for
         | months, and the window-blinds over there are _clearly_ broken
         | but they insist it 's fine because daylight still gets through.
        
         | afavour wrote:
         | Maybe I'm projecting my own views here but I interpreted those
         | two statements as being about different things: the finished
         | product vs the process that gets you there.
         | 
         | I care deeply about the end result that is presented to the
         | user who has no idea what code even looks like. How we put
         | together the UI. How we load data to minimize delays. That's
         | "the craft" to me.
         | 
         | I care much less about code style, linting etc. that no-one
         | other than a small group of developers will ever see. To a
         | certain extent the latter enables the former. But I've often
         | witnessed the latter being valued over the former and that's
         | where things start to go wrong.
        
         | 708145_ wrote:
         | It is a fine balance, and everyone that doesn't "drive the same
         | speed" as me, frustrates me.
        
         | WesolyKubeczek wrote:
         | People, though, tend to spiral down into the bikeshedding
         | abyss. It's one thing to stand your ground about a linting rule
         | that has proven effective in combatting certain classes of
         | errors that you encountered in the field. It's another thing to
         | make every discussion be about linting rules.
         | 
         | I cannot put it into words right, but you can see there's
         | usually a vibe. It will be different coming from an experienced
         | developer knowing what they are talking about from lived
         | experience, and from a clueless one who has seen shit but is
         | hell bent on process and rules.
        
         | vichle wrote:
         | I love that the top comment is a 10 level deep bikeshed about
         | bikeshedding.
        
         | yread wrote:
         | tabs or spaces are ok. Mix of tabs and spaces is not.
        
         | tharne wrote:
         | > What you're essentially saying is "cherish the people who
         | care up to the level I personally and subjectively think is
         | right, and dismiss everyone who cares more as insane weirdos
         | who cannot prioritise".
         | 
         | Theses are bullet points expressing general rules of thumb, not
         | legal treatises. You're reading far too much into these.
        
         | giancarlostoro wrote:
         | I dont care about style as long as you can give me a document
         | that specifies all the rules. It can be a simple text file, but
         | don't expect me to remember them all from one convo.
         | 
         | At least with Python I just push everyone to follow PEP-8 makes
         | it easier.
        
         | unclebucknasty wrote:
         | > _Revered artisans_
         | 
         | This may point to the dividing line. Software is required to be
         | functional, not simply "artistic". You can certainly make the
         | argument that there are non-functional considerations in its
         | construction: readability, maintainability, extensibility, etc.
         | And, these absolutely intersect with style, so it's tempting to
         | apply words like "artistry".
         | 
         | But, is there a point where details veer into personal
         | preference and insistence on style for the sake of style? I
         | think so, and many of us have seen this. For those who haven't
         | yet, stick around!
        
         | Pxtl wrote:
         | "Have you ever noticed that anybody driving slower than you is
         | an idiot, and anyone going faster than you is a maniac?" --
         | George Carlin
        
         | 98codes wrote:
         | Reminds me of the equivalent you see so often about driving
         | where people slower than you are morons, while those faster
         | than you are crazy.
        
         | OptionOfT wrote:
         | Formatting is also important for cohesion. A code base that is
         | formatted is easier to browse.
         | 
         | And I couldn't care less about where you put the {}. I love
         | autoformatters.
         | 
         | Linting is a little more. It's both style and genuine issues,
         | like don't == instead of === in JavaScript.
        
         | Netcob wrote:
         | I think most people who care about code have a bit of OCD over
         | these things, but there is a difference between how the code
         | looks vs. how it is structured. I think that's what the author
         | means.
        
       | lbj wrote:
       | I actually disagree with about half of this.
       | 
       | > Typed languages are essential on teams with mixed experience
       | levels
       | 
       | Essential, meaning 'cannot exist without', it's not. I've seen
       | this work a number of places.
       | 
       | > Blind devotion to functional is dumb.
       | 
       | Managing/limiting state is always a worthwhile pursuit. I'd think
       | he would agree since he seems to value simplicity
       | 
       | > People who stress over code style, linting rules, or other
       | minutia remain insane weirdos to me. Focus on more important
       | things.
       | 
       | That's like saying don't check if your cars tires still have any
       | pattern left, the engine is more important. Until it isn't.
       | Streamlining the smaller details allows the brain to focus on
       | more important stuff, but the details matter and their value
       | increases exponentially with the size of the project.
        
         | Tade0 wrote:
         | Regarding code style etc. I get where he's coming from as
         | plenty of people made entire careers on pursuing the perfect
         | linter configuration. They're a net negative in every project.
        
           | steezeburger wrote:
           | I'd love some clarification if he meant people who bike shed
           | or people who care to setup a linter and formatter as part of
           | their workflow.
        
         | MisterKent wrote:
         | Your rebuttals are all agreeing with him...
         | 
         | I don't think you're grasping the nuance he's putting out
         | there. Instead you're choosing to be overly pedantic over the
         | word essential.
        
       | gunalx wrote:
       | > People who stress over code style, linting rules, or other
       | minutia remain insane weirdos to me. Focus on more important
       | things.
       | 
       | Could not agree more.
        
         | jamil7 wrote:
         | I agree but have been on teams where this slows down PR review
         | or arguments break out. Delegating to the linter and format on
         | save can get the team past this.
        
           | ahoka wrote:
           | Those teams have these weirdos the article talks about.
        
       | pjmlp wrote:
       | After almost 40 years, between hobby coding, education, and
       | professional experience, kind of share a similar view in a couple
       | of topics.
       | 
       | Additionally such an extend experience gives us another point of
       | view on trendy subjects that are experiences from the past newly
       | repacked.
       | 
       | And desilusion, seeing so many great ideas taking decades to
       | become relevant, or never at all.
        
       | mattacular wrote:
       | I strongly agree with almost all of this except the last part
       | about project managers - a good one is invaluable, an ok one can
       | still be helpful. The majority probably are neither (and their
       | ability to be good at managing projects depends a lot on other
       | org functions - not necessarily within their control) but way
       | better than 90%+ that the author suggests.
        
       | gorjusborg wrote:
       | No, objects aren't generally 'good', unless you think keeping
       | multiple state machines in sync is 'good'.
       | 
       | OO is not evil, but it also shouldn't be your default solution to
       | everything.
       | 
       | Also, who is this person? I immediately distrust someone who
       | calls themselves 'a pretty cool guy'. That's for the rest of us
       | to decide.
        
         | Insanity wrote:
         | I had a different read of that point. More along the lines of
         | "don't throw the baby out with the bath water" (might have
         | butchered that saying?).
         | 
         | I'm also more in the FP camp - even wrote a book on the topic
         | of FP. But I also acknowledge OO is not inherently a bad choice
         | for a project, and many languages nowadays do exist along a
         | spectrum of OO and FP rather than being strictly one of the
         | other.
         | 
         | To me a benefit for OO might be the ubiquity - you can
         | generally assume people will understand an OO codebase if they
         | have done a few years of coding. With more strict FP that is
         | just not a given - even if people took a Haskell course in Uni
         | a decade ago :).
        
           | latexr wrote:
           | > More along the lines of "don't throw the baby out with the
           | bath water" (might have butchered that saying?).
           | 
           | No, you got it right.
           | 
           | https://en.wikipedia.org/wiki/Don't_throw_the_baby_out_with_.
           | ..
           | 
           | > even wrote a book on the topic of FP.
           | 
           | Care to share? If not, that's fine.
        
             | Insanity wrote:
             | Sure, "Functional Programming in Go", this is the Amazon
             | link: https://a.co/d/htv3BOu
        
         | karmakaze wrote:
         | The way I like to use OO _(usually not real OO, but rather
         | class-based languages)_ is to minimize its mutable state. Often
         | mutability is merely a lack of using builder patterns. Some
         | state can be useful as long as it 's easy and makes sense to
         | globally reset or control. It's like writing a process as a
         | construction of monads before any data is passed into it.
         | Similarly a tree of processing objects can be assembled before
         | running it on the input.
        
           | patrickmay wrote:
           | Exactly. Automatically adding getters and (especially)
           | setters to a class is something I see far too often.
        
             | MajimasEyepatch wrote:
             | I begrudgingly have had to enter the world of Spring Boot
             | over the last couple years, and this drives me nuts. Every
             | damn thing needs getters and setters so that the ten
             | thousand magic Spring annotations can mutate things all
             | over the place. If the business logic is complex, I try to
             | make immutable domain models separate from the models that
             | have to interact with Spring, but that can require a lot of
             | boilerplate.
        
         | naasking wrote:
         | > No, objects aren't generally 'good', unless you think keeping
         | multiple state machines in sync is 'good'.
         | 
         | Sure, if you disregard good object design, like the single
         | responsibility principle and using mutability only when really
         | needed.
        
         | 9rx wrote:
         | _> OO is not evil, but it also shouldn 't be your default
         | solution to everything._
         | 
         | With Smalltalk and Objective-C both being effectively dead at
         | this point, that really only leaves Ruby (and arguably Erlang)
         | as the only languages that are able to express OO. And neither
         | of those languages are terribly popular either. Chances are it
         | won't be your default solution, even if you want it to be.
        
           | igouy wrote:
           | J ... J ... Java.
        
             | 9rx wrote:
             | Patrick Naughton came from the Smalltalk world, so Java is
             | definitely inspired by Smalltalk, but he didn't bring along
             | the oriented bits. Its object model is a lot closer to
             | C++'s. To have objects does not imply orientation.
        
           | lcnPylGDnU4H9OF wrote:
           | > and arguably Erlang
           | 
           | Curious about your case for this. I don't know a lot about
           | Erlang other than "it's what Elixir is based on" or whatever
           | technical jargon is more accurate. I thought it was
           | functional.
        
             | 9rx wrote:
             | _> Curious about your case for this._
             | 
             | I was mostly riffing on the time Joe Armstrong, creator of
             | Erlang, said that Erlang might be the only object-oriented
             | language in existence. Although he's not exactly wrong, is
             | he?
             | 
             |  _> I thought it was functional._
             | 
             | I think that is reasonable. Objects, describing
             | encapsulation of data, are what define functional. Without
             | encapsulation, you merely have procedural. Of course, that
             | still does not imply the objects are oriented...
             | 
             | For that you need message passing. But Erlang has message
             | passing too! So there is a good case to be made that is
             | object-oriented.
        
       | Tade0 wrote:
       | > Frontend development is a nightmare world of Kafkaesque
       | awfulness I no longer enjoy
       | 
       | My feeling is that a lot of negativity towards the frontend stems
       | from assuming that the entire field is like React and its
       | community. It's really not like that.
        
         | alexchamberlain wrote:
         | I think Frontend (or maybe slightly expanded App Development)
         | is a greatly underappreciated skill. It's easy to throw a UI
         | together, but to do it in a way that is obvious to your user's,
         | can be maintained and can move at the speed the business needs
         | is a tough ask.
        
           | phist_mcgee wrote:
           | I agree, getting all the pieces together and having it be
           | maintainable and enjoyable to work on is part of the craft.
           | 
           | I enjoy the challenge, and have found a great niche for
           | myself doing exactly that.
        
         | vaylian wrote:
         | The much bigger problem is that you not only have to deal with
         | the technical challenges, but also the visual design challenges
         | where non-technical people have all kinds of opinions that you
         | have to deal with. Things get really nasty once you have to
         | implement features that emulate non-web functionality like
         | right-click menus and the UI becomes an inconsistent mess.
        
           | stackskipton wrote:
           | Visual Design Challenges is one I hear most frontend
           | developer complain about. I explained a queen duck
           | (https://bwiggs.com/notebook/queens-duck/) to one of them and
           | he started doing that several times in his project. If you
           | look at this git repo, there would be commits called " _queen
           | duck_ " right before he would demo so he could get feedback
           | about the "mistake" he made, revert the commit and move on
           | with his life.
        
       | CRConrad wrote:
       | He mentions this being a follow-up to a similar earlier post:
       | https://chriskiehl.com/article/thoughts-after-6-years .
       | 
       | HN discussions on that post:
       | https://news.ycombinator.com/item?id=25887373 (4 years ago|686
       | comments), https://news.ycombinator.com/item?id=32162716 (3 years
       | ago|58 comments), and
       | https://news.ycombinator.com/item?id=41633156 (4 months ago|56
       | comments).
        
       | smitty1e wrote:
       | > DynamoDB is a good database (IFF your workload lines up with
       | what it's offering)
       | 
       | "The correct tool for the job."
       | 
       | Seeing a document database used for tabular purposes gives me a
       | sad.
        
       | imjonse wrote:
       | > ORMs are the devil in all languages and all implementations.
       | Just write the damn SQL
       | 
       | It depends on what you're writing. I've seen enough projects
       | writing raw SQL because of aversion to ORMs being bogged down in
       | reinventing a lot of what ORMs offer. Like with other choices it
       | is too often a premature optimization (for perf or DX) and a sign
       | of prioritizing a sense of craftsmanship at the expense of the
       | deliverables and the sanity of other team members.
        
         | qaq wrote:
         | It's not so much optimization but experience that on any
         | sufficiently large project you gonna run into ORM limitation
         | and end up with mix of ORM and direct queries. So might as
         | well...
        
           | The_Colonel wrote:
           | Starting with raw SQL is fun. But at some point you find out
           | you need some caching here, then there, then you have a bunch
           | of custom disconnected caches having bugs with invalidation.
           | Then you need lazy loading and fetch graphs. Step by step
           | you'll build your own (shitty) ORM.
           | 
           | Same thing for people claiming they don't need any
           | frameworks.
        
             | wesselbindt wrote:
             | > you find out you need some caching here, then there
             | 
             | Forgive my ignorance, but how do ORMs help with adding
             | caching? Or are you implying they obviate or reduce the
             | need for caching?
        
               | ivan_gammel wrote:
               | They do caching themselves so that some of your queries
               | via ORM won't hit the actual db.
        
               | capitainenemo wrote:
               | So, given the main issue with ORM is the
               | object/relational part... (https://web.archive.org/web/20
               | 160301022121/http://www.revisi...)
               | 
               | Why is caching not a feature in DB connection pools? I
               | mean, most databases have it on their side, why not have
               | it as an option for the same query sets prior to hitting
               | the db, with configurable invalidations? Or is it, and
               | I've just never thought to look for it.
        
               | The_Colonel wrote:
               | Integrating cache into connection pools brings little
               | added value since connection pools don't have enough
               | context/information to manage the cache intelligently.
               | You'd have to do all the hard work (like invalidation)
               | yourself anyway.
               | 
               | Example: if you execute "UPDATE orders SET x = 5 WHERE id
               | = 10", the connection pool has no idea what entries to
               | invalidate. ORM knows that since it tracks all managed
               | entities, understands their structure, identity.
        
               | capitainenemo wrote:
               | I guess I was thinking more of frequently run queries
               | against infrequently modified data or where stale data
               | doesn't matter so much. The sort of things that are ideal
               | cache targets. You'd think you could tag queries like
               | that. Sort of the things that a CDN caches but more
               | granular. Sure if it's stuff that's frequently changed,
               | an ORM could reason about it just like, well, the
               | database does, but then you're back into all the bad
               | things about running your shadow database with a badly
               | fitting model, and you'd be better off just ensuring all
               | or part of the database ran closer to your app with
               | replication, say, in memory on same server.
        
               | ivan_gammel wrote:
               | That would be a result set layer, not a connection pool.
               | Could make sense if you worked with rows, but if you use
               | ORM, why mapping cached row again and again? ORMs cache
               | hydrated objects, which seems to be more efficient.
        
               | capitainenemo wrote:
               | Yeah, it was more to see if there were any benefits to an
               | ORM that could be used without the, well "ORM" part :)
        
               | The_Colonel wrote:
               | JPA implementations have "managed entities", sometimes
               | called session or 1st level cache which is making sure
               | that every entity is loaded at max. one time within a
               | transaction. Like e.g. checking user/user permissions is
               | something which typically has to be done in several
               | places in course of a single request - you don't want to
               | keep loading them for every check, you don't want to keep
               | passing them across 20 layers, so some form of caching is
               | needed. JPA implementations do it for you automatically
               | (assuming you're fine with transaction-scoped cache)
               | since this is such a core concept to how JPA works (the
               | fact it's also a cache is kind of secondary consequence).
               | JPA implementations typically provide more advanced
               | caching capabilities, caching query results, distributed
               | cache (with proper invalidation) etc.
        
               | wesselbindt wrote:
               | Ah yep, of course! Thanks!
        
             | qaq wrote:
             | caching is orthogonal to using or not using ORM. You might
             | opt to have caching with or without ORM in a consistent
             | manner. You can also opt to add read replicas fronted by
             | say pgcat in Postgres case without having separate caching
             | layer.
        
               | The_Colonel wrote:
               | I guess this is a point where terminology matters. If you
               | work with SQL database in an OOP language, you pretty
               | much always do some object-relational mapping, no matter
               | if you have a big framework or just raw SQL connection.
               | 
               | But this is not what people usually call as ORMs. All the
               | "bad kind of ORM" (JPA impls, Entity Framework,
               | SQLAlchemy, Doctrine, Active Record...) have some concept
               | of an entity session which is tracking the entities being
               | processed. To me, this is a central feature of an ORM,
               | one of its major benefits. It is, incidentally, also
               | serving as a transaction-scoped cache.
               | 
               | I won't of course dispute that you can have caching on
               | other levels as well (which may perform differently, for
               | different use cases).
        
             | stackskipton wrote:
             | As SRE who dealt with more caching errors then I care to.
             | Alot of caching comes down to YAGNI.
             | 
             | To his point: It's very hard to beat decades of RDBMS
             | research and improvements
             | 
             | Your RDBMS internal caching will likely get you extremely
             | far and speed difference of Redis vs RDBMS call is very
             | unlikely to matter in your standard CRUD App.
        
               | lcnPylGDnU4H9OF wrote:
               | > Redis vs RDBMS call is very unlikely to matter in your
               | standard CRUD App
               | 
               | To any juniors reading: cache the response payload (or
               | parts of it), not the results of database queries.
        
             | gilbetron wrote:
             | There are plenty of libraries/packages for SQL that do all
             | of that for you, too. The choice isn't between a
             | sophisticated ORM and just throwing SQL text at a socket.
             | The fundamental assumption of ORMs is broken, but much of
             | the tooling works well and exists in non-ORM places.
        
           | jolt42 wrote:
           | It seemed to me TOPLink had this figured out, and then
           | hibernate took it all away.
        
         | hitchstory wrote:
         | Depends upon the ORM. Like all frameworks, a really good one is
         | a significant productivity boost while a bad one is faworse
         | than none at all.
        
         | magicmicah85 wrote:
         | It's the devil I know and for most of my projects I'll likely
         | never forsake ORM for raw SQL.
        
         | Twirrim wrote:
         | One job I had, we got handed a code base with at least 4
         | different reinventions of an ORM in it.
         | 
         | It became clear that each developer who'd worked on the code
         | had written their own helpers to avoid direct SQL. It took a
         | fair bit of persuading leadership, but the first task ended up
         | being doing a huge reactor of everything SQL. Unsurprisingly
         | enough, lots of bugs got squashed that way.
        
         | nodamage wrote:
         | I've never understood the ORM hate because a good ORM will get
         | out of the way and let you write raw SQL when necessary while
         | still offering all of the benefits you get out of an ORM when
         | working with query results:
         | 
         | 1. Mapping result rows back to objects, especially from joins
         | where you will get back multiple rows per "object" that need to
         | be collated.
         | 
         | 2. Automatic handling of many-to-many relationships so you
         | don't have to track which ids to add/remove from the join table
         | yourself.
         | 
         | 3. Identity mapping so if you query for the same object in
         | different parts of your UI you always get the same underlying
         | instance back.
         | 
         | 4. Unit of work tracking so if you modify two properties of one
         | object and one property of another the correct SQL is issued to
         | only update those three particular columns.
         | 
         | 5. Object change events so if you fetch a list of objects to
         | display in the UI and some other part of your UI (or a
         | background thread) add/updates/deletes an object, your list is
         | automatically updated.
         | 
         | 6. And finally in cases where your SQL is dynamic having a
         | query builder is way cleaner than concatenating strings
         | together.
         | 
         | For those who are against ORMs I am curious how you deal with
         | these problems instead.
        
         | snapetom wrote:
         | > being bogged down in reinventing a lot of what ORMs offer.
         | 
         | There's a saying - if you hate ORMs and don't use them,
         | eventually you're going to write your own ORM.
        
         | arwhatever wrote:
         | Just mentioned to an acquaintance a couple of days ago that
         | Entity Framework is the biggest flip-flop of my personal
         | career. I was a _rabid_ supporter when it was released a decade
         | and a half or so ago, and the appeal has decreased linearly
         | over time, to the present day.
         | 
         | Statically-typed queries written in a mini-DSL within your
         | application language seems like such a joy!
         | 
         | But then the configuration is a hassle. The DbContext
         | lifecycles are a hassle. The DbContext winds up a big ball of
         | mutable state that often gets passed all up and down your call
         | stack, reducing the ability to reason about much of the code
         | locally. Was this instance initialized with or without change
         | tracking? How many and what changes have been applied? Were
         | these navigation properties lazily or eagerly loaded?
         | 
         | And it promises to keep your domain persistence ignorant with
         | its fluent configuration syntax. But then you have compromise
         | on that here, then compromise in it there.
         | 
         | Pretty soon, you realize that you started out building a
         | project for domain X or domain Y, only to realize that you're
         | trying to shoehorn domain X/Y behavior into your Entity
         | Framework app.
        
         | torginus wrote:
         | I'm a hardliner on supporting this - I'd go further - all the
         | DB code should be in SQL, with the database being manipulated
         | by stored procedures and the db schema not even being exposed
         | to the common developer.
         | 
         | As far as I know this is a very oldschool view on how to treat
         | dbs, but I still think this is the only correct one.
         | 
         | I hate ORMs with a passion - they're just a potential source of
         | bugs and performance issues, coming from either bugs in the
         | engine, devs not understanding SQL, devs misjudging what query
         | will get generated, leaky abstractions etc.
         | 
         | It's big enough of an ask to understand SQL itself, it's the
         | height of folly to think you can understand SQL when it's being
         | generated by some Rube-Goldberg SQL generator, especially if
         | said generator advertises that you don't need to know SQL to
         | use it.
        
       | TheCapeGreek wrote:
       | > Most won't care about the craft. Cherish the ones that do, meet
       | the rest where they are
       | 
       | This becomes easier when you've transitioned from someone who
       | cares to someone who doesn't. Some of us burn out from the
       | industry and fall out of love with the job.
       | 
       | I understand my curmudgeon-ly ex-colleagues a lot more nowadays.
        
       | nrjames wrote:
       | Regarding scaling... one thing that drives me bonkers about
       | Apache Superset is that the maintainers are absolutely adamant
       | that it must be deployed with kubernetes because it's meant to
       | scale. The project works just fine with a simple and slim
       | docker/compose deployment, which is easier for small teams to
       | manage. The lead maintainers refuse to document this and have
       | unnecessarily sprinkled the docs with warnings.
        
       | vladde wrote:
       | > Good management is invaluable. (I went most of my career before
       | seeing it done well)
       | 
       | I don't think I've ever seen good management. Anyone care to
       | explain what that would look like?
        
         | zvorygin wrote:
         | Your team gets a clear and simple high-level goal that everyone
         | at the company understands is important and shields you to work
         | on it for a year without interruptions.
         | 
         | You don't know it, but your manager playing up your teams
         | contributions to the company, arranging happy coordination with
         | other teams, occasionally intervening to resolve intra-team
         | disputes, privately managing egos and careers, and jiu
         | jitsu'ing any attempts to distract your team.
         | 
         | They trust your competence and decisions, but they understand
         | enough to keep you on-track and provide a valuable outside view
         | perspective.
        
         | qaq wrote:
         | Key thing good manager shields team from corporate bs as much
         | as possible
        
         | atulatul wrote:
         | A couple of indicators I have seen:
         | 
         | 1. For a non-manager, an indication that there is good
         | management (project, process, etc.) in place is that the
         | management aspect sort of seems to disappear/ moves into the
         | background.
         | 
         | 2. Communication becomes efficient or smooth.
         | 
         | How is it achieved?
         | 
         | 1. High level goals and metric. And incremental upgrades to
         | those. I think people/ teams need to get comfortable with one
         | set of those before you want to improve better those metrics.
         | Jira story points and velocity are not good metrics.
         | 
         | 2. A manager acts as a buffer. A manager absorbs some shock and
         | filters some data/ emotions which would otherwise flow between
         | one (ideally more) pair of layers: one above them and one below
         | them.
         | 
         | 3. One kind of non-sense (from many kinds) is that people-
         | junior or senior- are 'trying to prove their value'. This is
         | why some people speak unnecessarily in meetings, emails go back
         | and forth, senior management chimes in on low level issues,
         | etc. A couple of good managers I saw were able to limit that-
         | over a period of time.
        
         | koonsolo wrote:
         | Here's the problem with good management: you will not notice
         | it, you only notice bad management.
         | 
         | A good manager is at the service of their team. That means they
         | will do anything to keep the team productive. In most cases
         | this means shielding them from corporate bullshit. In practice
         | this also means that you will barely notice them.
         | 
         | So when you notice your management being intervening and bad,
         | it's probably bad. When you barely notice your management and
         | can't see what value they are adding, it's most likely
         | excellent management.
        
         | bluGill wrote:
         | Good managers will help you develop to where you want to be
         | next. Part of this is helping you see where the next place for
         | you is. Then they give you tasks to do that get you there.
         | 
         | They balance the above with the current business needs of
         | course. Generally the two should be inline, but where they are
         | not they help you manage that.
        
       | chrisjj wrote:
       | > There is no pride in managing or understanding complexity
       | 
       | "is"? I see plenty.
        
       | fergie wrote:
       | > Typed languages are essential on teams with mixed experience
       | levels
       | 
       | I'm 30 years in now, and on balance, whilst they have clear
       | advantages, I'm still not convinced that typed languages are
       | essential, particularly for low level or module programming.
        
         | pjc50 wrote:
         | Unless you can happily deal with '"four" + 1' your language is
         | typed. The question is whether you want type errors reported
         | upfront or you have to wait to find them at runtime
         | (necessitating high test coverage).
         | 
         | One of these days I'd like to see a "typed assembler". It still
         | matters what the contents of registers _mean_ , even if they
         | all look the same to the instruction set.
        
         | Insanity wrote:
         | Interesting take, to me it is not so much about the type of
         | coding (high vs low level) but more about the size of the
         | project.
         | 
         | Dynamic languages work great for scripting and rapid
         | prototyping, but if you are working with a team maintaining a
         | large monolith, I would rather have a statically typed language
         | and avoid at least a class of runtime issues due to dynamic
         | typing.
         | 
         | Case in point, I love writing my Jupyter notebooks with Python
         | but am amazed that entire platforms like Dropbox (and
         | instagram?) chose Python as their default language.
        
         | drpossum wrote:
         | I think the sentiment was they help significantly when you have
         | inexperienced programmers. (That has also been my experience)
        
         | arduinomancer wrote:
         | What do you mean low level?
         | 
         | Do you think the Linux kernel could be written in a language
         | without types enforced?
        
       | chmod775 wrote:
       | > Objects are extremely good at what they're good at. Blind
       | devotion to functional is dumb.
       | 
       | Maybe "mutable objects"? Maybe these were intended to be isolated
       | statements? Personally I believe functional programming is great
       | with objects too...
       | 
       | It is however true that many OOP-embracing languages tend to
       | favor an imperative style. Scala is an example of a language that
       | embraces both.
        
         | ikety wrote:
         | C# is becoming one as well. I recommend Zoran Horvat on youtube
         | 
         | And most of the well written react projects I've worked on tend
         | to be overwhelmingly functional in style. Hooks just make sense
         | when thinking about the lifecycle of a UI. Shared state and
         | imperative code with react just feels wrong.
        
       | ZaoLahma wrote:
       | > Most programming should be done long before a single line of
       | code is written
       | 
       | Nah.
       | 
       | I (16+ years developer) prefer to iteratively go between coding
       | and designing. It happens way too often that when you're coding,
       | you stumble across something that makes you go "oh f me, that
       | would NEVER work", which forces you to approach a problem
       | entirely differently.
       | 
       | Quite often you also have eureka moments with better solutions
       | that just would not have happened unless you had code in front of
       | you, which again makes you approach the problem entirely
       | differently.
        
         | gaptoothclan wrote:
         | ok that sounds bad, you should have the option to go back to
         | design, but depending on what point you find that issue,
         | depends on how much time you have wasted?
        
           | ZaoLahma wrote:
           | It's about defining and solving small problems all the way,
           | and avoiding trying to solve big problems.
           | 
           | If you manage to restrict yourself to only solving small
           | problems (THIS is the true challenge with software
           | engineering, in my humble opinion), then you won't ever have
           | wasted too much time if (when) you need to reset.
        
         | gmm1990 wrote:
         | I assume there are people who are able to have those eureka
         | moments before writing any code. I definitely write a lot of
         | code before figuring out the final design but always think I
         | should be designing more.
        
           | bluGill wrote:
           | Always plan to throw one away. You will, so best to plan for
           | it. (paraphrasing Fred Brooks)
        
         | VyseofArcadia wrote:
         | Iterative work is THE way to work in large legacy codebases.
         | The minute you wade into the code, all of your planning is
         | moot. You don't know what's lurking below the surface. No one
         | knows what's lurking under the surface. Except maybe Dave,
         | because he vaguely remembers about 15 years back talking to
         | some guy who wrote some code 30 years back about it.
         | 
         | Greenfield, absolutely design up front you lucky devils, but
         | iterative is the way otherwise.
        
           | renewedrebecca wrote:
           | Every development shop has a Dave.
        
           | bluGill wrote:
           | Greenfield lasts only for at best 2 years or the first public
           | release. After that it is legacy.
           | 
           | I'm am the "Dave" on my current code since I was one of the
           | first engineers on the project and the others before me have
           | long moved to management. There is a lot I don't know about
           | how the code works. There are dark corners we just lifted
           | completely from an earlier project where the guy who wrote it
           | 30 years back is retired. This is normal.
           | 
           | I'm fighting desperately to keep this code in shape as I
           | don't want to go to management to ask for $$$ (billions) to
           | rewrite it. I regret many choices. I'm making other choices
           | in response that I fear someone will regret in 15 more years.
           | I'm hoping to retire before then - better talk to me now
           | because soon the people who have talked to the person who
           | wrote the code 30 years ago will also be a memory. (the guy
           | who write the code 30 years ago is still alive and someone
           | has his phone number - they talk once a year about something
           | weird to see if why is remembered)
        
           | braggerxyz wrote:
           | Today's greenfield is tomorrow's legacy. So this statement
           | still holds true ;)
        
           | devmor wrote:
           | As someone who's spent 12 years working on legacy codebases,
           | I strongly disagree with this.
           | 
           | Iterative work in a large legacy codebase is how you end up
           | making your large legacy codebase larger and even less
           | understood.
           | 
           | Your planning should "wade into the code" from the start. I
           | have always gotten better results by charting out flow
           | diagrams and whiteboarding process changes than just "diving
           | in and changing stuff".
           | 
           | Frankly, I'd say it's the opposite for greenfield
           | development. Doing iterative work to build out a new product
           | and make changes as you discover needs you didn't account for
           | makes a lot more sense that flailing around making holes in
           | something you don't fully understand that is tied to active
           | business needs.
        
             | 9rx wrote:
             | _> I have always gotten better results by charting out flow
             | diagrams and whiteboarding process changes than just
             | "diving in and changing stuff"._
             | 
             | In terms of a broad population, I am not sure there is a
             | meaningful difference, though. You can iterate on your
             | ideas on the whiteboard or you can iterate on your ideas in
             | code, but the intent is the same. Either way you are going
             | to throw it all away once you have settled on what should
             | be the final iteration anyhow.
             | 
             | It just comes down to where you are most comfortable
             | expressing your ideas. Some like the visuals of a diagram,
             | others are more comfortable thinking in code, some prefer
             | to write it out in plain English, and I'm sure others carry
             | out the process in other ways. But at the end of the day it
             | is all the same.
        
               | mjlawson wrote:
               | > Either way you are going to throw it all away once you
               | have settled on what should be the final iteration
               | anyhow.
               | 
               | I think this needs to be highlighted, because while I
               | completely agree, I think it's often implicit, taken for
               | granted, and neglected. Far, far too often I've seen code
               | bases bloat because this never takes place. The sentiment
               | at a lot of places seems to be, if the tests pass, ship
               | it. Arguably, it may even be the right decision.
        
               | devmor wrote:
               | I have never really thought about it that way, but you're
               | right.
               | 
               | Ultimately what matters is the final changeset. How you
               | get there doesn't really matter.
        
         | Kichererbsen wrote:
         | Most programming is actually figuring out what already exists
         | and what (and more importantly: why) the requirements are. This
         | is best done long before a single line of code is written.
         | 
         | I think the author is taking a wider view of "programming" than
         | the actual writing of code as the end product. Some of the most
         | important work I've done is spend the time to argue that
         | something doesn't need to be done at all.
        
           | VyseofArcadia wrote:
           | > what (and more importantly: why) the requirements are
           | 
           | Maybe in a startup? My experience as an IC in larger, more
           | established companies is the requirements are dictated to
           | you. Someone else has already thought carefully about the
           | customer ask, your job is just to implement, maybe push back
           | a little if the requirements they came up with are
           | particularly unreasonable.
        
             | bluGill wrote:
             | If you dig deep you discover they have figured out some
             | requirements in detail, but there is a lot missing. Is this
             | new feature that last one in that line, or will there be
             | more options in the future? Is this new feature really
             | going to be used - many times we have put large effort into
             | features only to discover no customer used them (as
             | evidenced by the critical bug that made the feature
             | unusable outside of the test lab that nobody complained
             | about until 4 years had passed). These things drive how you
             | engineer the thing in the first place.
        
           | polishdude20 wrote:
           | This makes me think it would be really cool to tie code
           | sections to slack conversations or emails. There's always
           | commit messages yes, but most product decisions on why
           | something was done lives in slack at least where I've worked.
           | 
           | Even an AI tool that takes a slack thread and summarizes how
           | that thread informed the code would be cool to try.
        
             | dhosek wrote:
             | I always fight to get this stuff into JIRA (or whatever
             | equivalent tool we're using), and then make sure that all
             | commits have the JIRA ID in them.
        
               | Izkata wrote:
               | Works great until you're not using it anymore. We're on
               | our third system, all the cases from the first one and
               | most from the second one are long since gone. Meanwhile
               | the commit messages survive it all, even across cvs ->
               | svn and svn -> git migrations.
        
           | mmcnl wrote:
           | And how do you figure out what the requirements are? In my
           | 10+ professional years, I have never gotten requirements by
           | asking for them. Almost always I had to show my
           | interpretation of what I think the requirements are, and use
           | the feedback I got to define the actual requirements. The
           | quickest way to get there is by iterating.
        
         | AnimalMuppet wrote:
         | Always think bigger picture than what you're immediately
         | working on. (I don't mean that you can't ever just focus on the
         | problem you're trying to solve for, say, hours. I mean you
         | can't focus like that for the entire time you're in that
         | development phase.)
         | 
         | Think about design and code (and functionality!) before you
         | start coding. Think about design as well as code _while_ you
         | 're coding. Think about design, code, and functionality while
         | you're testing.
        
         | davidw wrote:
         | Yeah, the other stuff seems sensible or at least "Ok, I can see
         | that", but I definitely disagree with this one.
         | 
         | You should spend time thinking about stuff beforehand, sure,
         | but getting your hands dirty is also going to reveal things.
        
           | pinoy420 wrote:
           | Very surprised at this attitude.
           | 
           | Or am I. The typical engineering savant omniscient to all
           | future past and present engineering roadblocks fixed by
           | "Just"(TM) thinking about it beforehand. I expect this from
           | bay area mid level not someone with credentials.
           | 
           | Strange because I agree with so much more of the article
        
             | davidw wrote:
             | TBH, I think it's more of a 'manager' attitude. A lot of
             | actual "hacker" type people are very much in the "rough
             | consensus and working code" category where you see what
             | works by doing it.
        
         | mamcx wrote:
         | What I think is a better way to say this is that you need a
         | `design` phase before actually writing the first `real`
         | implementation code.
         | 
         | Something I do a lot, and even more with the LLMS, is that I
         | make `scratch` projects where I sketch code over and over (and
         | maybe make mockups in Keynote or similar, make some notes,
         | etc), then write from scratch again in the real codebase.
        
         | nerdralph wrote:
         | I agree coding should start early. The design might look good,
         | but might not be easy to implement, so you need to change the
         | design.
         | 
         | The statement sounds like something out of a book on the
         | waterfall method of software development.
        
         | knighthack wrote:
         | 'Programming as theory-building' is an approach that has grown
         | on me in the past few years.
         | 
         | Your first draft may be qualitatively an MVP, but it's still
         | just a theory of a final product you want, which requires a lot
         | of iterative building before you get to that.
         | 
         | As such, there's no way to _not_ shift between code and design,
         | especially when business requirements are involved and which
         | themselves may change over time.
        
         | recroad wrote:
         | Developer for 20+ years. I can't even design anything without
         | coding something.
        
           | jillesvangurp wrote:
           | Exactly. I did a Ph.D. on software engineering and
           | architecture before embarking on a career practicing what I
           | preach. One thing that I realized early is that designs
           | always lag implementations. They are aspirational at best.
           | And people largely stopped using design tools completely when
           | agile became a thing. Some still do. But you'll look in vain
           | for UML diagrams on most software you ever heard off.
           | 
           | I now have a few decades of experience doing technical work,
           | running startups, teams, doing consultancy, etc. Coding is my
           | way of getting hands on. It's quicker for me to just
           | prototype something quickly in code than it is to do whatever
           | on a whiteboard. I always run out of space on whiteboards and
           | they don't have multi level undo, auto completion, etc. They
           | really suck actually. I avoid using them.
           | 
           | Of course, I sometimes chin stroke extensively before coding;
           | or I restart what I'm doing several times. But once I have an
           | idea of what I'm doing in my head, I stub out a solution and
           | start iteratively refining. And if I'm stuck with the chin
           | stroking, the best way to break through that is to just start
           | coding. Usually, I then discover things I hadn't thought
           | about and realize I don't need to over complicate things
           | quite as much. This progressive insight is something you can
           | only gain through doing the work. The finished code is also
           | the finished design; they co-evolve and don't exist as
           | separate artifacts.
           | 
           | The engineering fallacy is believing that they are separate
           | and that developers are just being lazy by not having
           | designs. Here's a counter argument to that: we don't build
           | bridges, rockets, expensive machines, etc. Our designs
           | compile to executable code. Physical things have extensive
           | post design project phases where stuff gets
           | built/constructed/assembled. Changing the design at that
           | stage is really expensive. For software, this phase is pretty
           | much 100% automated in software. And continuous deployment
           | means having working stuff from pretty much as soon as your
           | builds start passing. Of course refactoring your design/code
           | still is important. You risk making it hard to evolve your
           | software otherwise.
           | 
           | The process of designing a bridge is actually more similar to
           | developing software than the process of constructing one. The
           | difference is that when you are done with the bridge design,
           | you still have to build it. But it's a lengthy/risky process
           | with progressive insights about constraints, physics,
           | legislation, requirements, etc. Like software, it's hard to
           | plan the design. And actually modern day architects use a lot
           | of software tools to try out their designs before they hand
           | them over.
           | 
           | Just some simple insights here. There is no blue print for
           | the blue print for either bridges or software. Not a thing,
           | generally.
        
           | declan_roberts wrote:
           | It's like giving an estimate for a bathroom remodel for a
           | house you've never seen. You gotta get in there first.
        
         | jrochkind1 wrote:
         | The OP didn't say what it is they're talking about that should
         | be done before writing any code.
         | 
         | He might have meant design, and I'm not sure about that.
         | 
         | But the other thing i think of is: Understanding the problem.
         | 
         | It's hard to do too much of that before you start coding, and
         | easy to do too little.
         | 
         | It overlaps with design to some extent, because once you
         | understand the problem better, some designs will naturally seem
         | inappropriate or better -- without having to spend time
         | allocated to "designing" necessarily, just when you design
         | you're going to come up with things that work a lot better the
         | better you understand the problem you are trying to solve.
         | 
         | How the stakeholders see it, and what's really going on, and
         | why it's a problem, and what would make an acceptable solution,
         | and what the next steps down the road might be.
        
           | x3n0ph3n3 wrote:
           | Then the author should have said "Most _software development_
           | should be done long before a single line of code is written "
           | 
           | Programming is specifically about the authorship of code.
        
         | dkarl wrote:
         | > I (16+ years developer) prefer to iteratively go between
         | coding and designing
         | 
         | I have an extra ten years on you and couldn't agree more.
         | 
         | There are two jokes:
         | 
         | - A few months of programming can save weeks of design.
         | 
         | - A few months of design can save weeks of programming.
         | 
         | Inexperience is thinking that only one of these jokes is
         | grounded in truth.
         | 
         | Recognizing which kind of situation you're in is an imperfect
         | art, and incremental work that interleaves design with
         | implementation is a hedge against being wrong.
        
         | mmcnl wrote:
         | Yeah, validate your assumptions. Nothing ever works the first
         | time. Quick iterations to get feedback is the way.
        
         | standardUser wrote:
         | Absolutely, though sometimes it's more about reading code or
         | 'playing' with code than writing/committing code. I try to
         | always be hoping around my codebase during meetings.
        
       | andyish wrote:
       | > People who stress over code style, lining
       | 
       | You can do it whatever way you want but match the style of the
       | project. I've worked on too many projects where someone decides
       | their way is best and you end up with a mix of everything.
       | 
       | If you want to change the code style, okay, but change it
       | everywhere and don't forget to test everything you've changed.
       | 
       | > Frontend development is a nightmare
       | 
       | But is it weird I kind of enjoy it every so often/
       | 
       | > Elegance is not a real metric
       | 
       | You're dam right it's not! Next time someone proudly presents a
       | super elegant, refined, and minimalistic solution I'm going to
       | phone them at 3am on a Saturday and get them to debug it while
       | screaming at them about lost revenue or something.
       | 
       | > DynamoDB is the worst possible choice for general application
       | development
       | 
       | Oh man, the amount of times I've seen some form of noSql and it's
       | used as a relational database. 9/10 some rendition of SQL is more
       | than sufficient.
        
         | Twirrim wrote:
         | I've grown to be a big fan of opinionated linters like gofmt,
         | rustfmt, black etc. They avoid so much time spent disagreeing
         | about code formatting and personal preferences. Instead
         | engineers can do mutual grumbling sessions about weird
         | formatting choices they see it do, and move on.
        
           | guappa wrote:
           | black sucks. Everytime you bump version it will reformat all
           | of your already formatted code.
           | 
           | If your product maintains different versions you won't be
           | able to cherry pick changes across versions.
        
           | spc476 wrote:
           | If I didn't want to have opinions, I would join a cult.
        
             | krior wrote:
             | save your opinions for the things that really matter
             | instead of another bikeshed to build! (not telling you to
             | shut up, btw :) )
        
         | Cthulhu_ wrote:
         | Code style is one thing - formatting that is - but there's
         | others like how features are implemented tend to change over
         | time and with different developers as well, which is difficult
         | to automatically test and hard to keep in line except with good
         | code reviews, but for that to work you already need to install
         | a culture of consistency, which also means that innovation may
         | be stifled and developers demotivated (e.g. because the better
         | solution requires the 100 existing solutions to be rewritten,
         | which is too expensive or requires a whole team to be blocked
         | until it's done).
         | 
         | Consistency trumps a lot of things IMO, but not everyone is on
         | board with that... myself included, I'm guilty of breaking with
         | my own consistency all the time.
        
       | v3ss0n wrote:
       | >People who stress over code style, linting rules, or other
       | minutia remain insane weirdos to me. Focus on more important
       | things.
       | 
       | This sticks out like sore thumb to me and I think you are coding
       | solo for 10 years. If you manage to lead a team of developers or
       | work with them you are screwed without linting rules and
       | standardized code style. Even if they are applied it takes months
       | to get to a get a team working in harmony - without them it will
       | be a disaster.
       | 
       | - merge conflict hells because code style diferences - bad for
       | code reviewers - bad to ready everyone's different code sytles.
        
         | pjc50 wrote:
         | He's not saying you shouldn't do it, he's saying you shouldn't
         | stress over it. The "run the language's standard formatter
         | before commit and then get on with your life" approach.
        
           | v3ss0n wrote:
           | Everyone on the team need to agree to the linting rules
           | before using linters. Else they will keep wirting their code
           | according to their habits , and then they start to modify the
           | rule that dosen't fit their bad habits when linters hints to
           | fix the code.
           | 
           | > run the language's standard formatter
           | 
           | Even with very smart linters like `ruff` it cannot fix all of
           | the linting errors. You have to hand fix many of them.
           | 
           | What linter do you use that can just run and forget?
        
             | pjc50 wrote:
             | Dotnet-format for formatting. Can auto fix.
             | 
             | Sonarqube for linting. It's more annoying and not auto
             | fixing, but it achieves the goal of avoiding arguments and
             | does catch some bugs.
        
           | botanical76 wrote:
           | I do think there's value in manual formatting some code
           | sections. For example, very large arrays, or alignment of
           | semantic parts of a group of mathematical expressions.
           | Ultimately, I think the only thing that matters is that the
           | code is readable, consistent and you don't spend much time on
           | how it looks.
           | 
           | That said, if you have team members who somehow can't or
           | won't copy the surrounding code style, then automatic linting
           | sounds necessary.
        
       | olavgg wrote:
       | One thing that I have never been more sure about after 20 years
       | as a software developer, is that Hibernate is awesome! Seriously,
       | it saves me ton of time and tinkering. It has support for native
       | queries, and it is simple to transform your custom query into JPA
       | entities. Using Hibernate has never been easier with the
       | introduction of LLM, tell it what it needs to do, and see
       | beautiful Hibernate examples code.
       | 
       | In my Spring Boot applications I log every SQL that is generated,
       | and quickly spot unoptimizations, like lazy loading of entities
       | instead of using join.
       | 
       | How ORM's behave in other languages and frameworks, like Python,
       | Go, Rust is probably another story.
        
         | hu3 wrote:
         | I'm curious, have you worked with Entity Framework with its
         | legendary LINQ magic?
        
       | SushiFreak wrote:
       | > DynamoDB is a good database
       | 
       | I cannot agree with this. I've constantly ran into issues around
       | where you can insert data into with an attribute name such as
       | "status" and then when you query it, it says you cannot query
       | with a reserved keyword.
       | 
       | There is a myriad of other issues I've found and when asking
       | around chat groups and forums, people universally dislike dynamo
       | db.
        
       | FrustratedMonky wrote:
       | "Objects are extremely good at what they're good at. Blind
       | devotion to functional is dumb. "
       | 
       | Guess this hits home. But Blind anything is bad. I spent a decade
       | blinded by objects being everything (original gang of four book).
       | Then a decade where everything is functions.
       | 
       | Why not pass a list of objects to that function.
        
         | ikety wrote:
         | Objects are also used in functional programming. This feels
         | like a reaction to people being functional evangelists.
         | 
         | There's a reason most modern languages are completely blurring
         | the lines and allowing you to think with multiple paradigms.
         | 
         | I'd be more upset with institutions lacking in functional
         | programming coursework. OOP is dominant, I can't see why people
         | get so irritated by a few annoying functional evangelists. And
         | while annoying, I don't think the motivation there is always
         | "Blind devotion to functional"
        
         | dionian wrote:
         | objects for data, functions for behavior
        
       | osigurdson wrote:
       | I think the ultimate boring language is golang. It is almost too
       | boring though.
        
       | dusted wrote:
       | Interesting, I've been in software development for a little more
       | than 10 years, and just about every point I've read, I more or
       | less agree one, will be interesting to see if it changes the next
       | 10.
        
       | kitd wrote:
       | One more that has opened my eyes recently:
       | 
       | Good, empathetic UI design is _invaluable_.
       | 
       | Get a professional UI designer. Engineers are (in the main)
       | appalling at it and will cost you time and sales.
        
         | yakshaving_jgt wrote:
         | In my experience, finding an actually good UI designer is
         | _hard_.
         | 
         | Obviously they exist, but I don't know how to find them. It
         | seems many -- if not most -- professional UI designers don't
         | even understand that form inputs need labels.
         | 
         | Got any tips?
        
       | pmarreck wrote:
       | Here's mine, FWIW:
       | 
       | 1) Nix. I finally came around after one too many bricked Linux
       | installs, and learning Docker and being kind of unhappy with it.
       | And while I still haven't completely mastered it, you can learn
       | enough in a reasonable amount of time to maintain a Linux
       | install.
       | 
       | > Blind devotion to functional is dumb.
       | 
       | Except when it's not "blind" and informed by hard experience
       | (years of OOP). Which leads me to...
       | 
       | 2) Functional programming/immutable data. For the vast majority
       | of use-cases, these just lead to better code, fewer bugs, and
       | less LOC needed for a given functionality. (I just wish Elixir
       | had the option to compile to a single binary. Roc-lang looks
       | interesting, in that space, if you aren't into Rust.)
       | 
       | 3) Typing. I'm coming around to it, and to a general principle of
       | "happy-path strictness" in general. All to achieve determinism.
       | 
       | > Java is a great language _because_ it 's boring
       | 
       | No. The people who disparage software devs who have tool
       | preferences are a special bunch and not really "software devs"
       | (with apologies to the No True Scotsman fallacy). If everyone was
       | supposed to be "fine" with Java, then no new languages need be
       | developed!
        
       | laurent_du wrote:
       | DynamoDB is not good, it's OK. Capacity upscaling and downscaling
       | is too slow to be useful. You need to over-provision.
        
       | alexfromapex wrote:
       | > Code coverage has absolutely nothing to do with code quality
       | 
       | Ehhh..lots of nuance to this one
        
         | jonhohle wrote:
         | And the inverse is almost always true: lack of code coverage is
         | a strong indicator of lack of both code quality and developer
         | experience.
        
         | commandlinefan wrote:
         | You can achieve 100% code coverage and always have passing
         | tests as long as you don't add any assertions.
        
       | olalonde wrote:
       | It feels like the author is in the middle of the bell curve
       | meme[0], especially with regards to "most programming should be
       | done long before a single line of code is written".
       | 
       | [0] https://i.imgflip.com/8tw3vb.png
        
         | marifjeren wrote:
         | This is an extremely lazy critique
        
           | olalonde wrote:
           | Hard to argue with that but it's a lazy article too - just a
           | collection of opinions with no reasoning or supporting
           | arguments.
        
       | GuB-42 wrote:
       | Just personal opinions, I guess, I agree with most, but here are
       | some I disagree with:
       | 
       | - There is no pride in managing or understanding complexity
       | 
       | Complexity exists, you can't make it go away, managing it and
       | understanding it is the only thing you can do. Simple systems
       | only displace complexity.
       | 
       | - Java is a great language because it's boring
       | 
       | That is if you write Java the boring way. A lot of Java code
       | (looking at you Spring) is everything but boring, and it is not
       | fun either.
       | 
       | - Most programming should be done long before a single line of
       | code is written
       | 
       | I went the opposite extreme. That is, if you are not writing
       | code, you are not programming. If you are not writing code on
       | your first day your are wasting time. It is a personal opinion,
       | but the idea is that without doing something concrete, i.e.
       | writing code, it is too easy to lose track of the reality, the
       | reality being that in the end, you will have a program that runs
       | on a machine. It doesn't mean you will have to keep that code.
       | 
       | - Formal modeling and analysis is an essential skill set
       | 
       | Maybe that explains our difference with regard to the last point.
       | Given the opportunity, I prefer try stuff rather than formalize.
       | It is not that formal modeling is useless, it is just less
       | essential to me than experimentation. To quote Don Knuth out of
       | context: "Beware of bugs in the above code; I have only proved it
       | correct, not tried it." ;)
       | 
       | - You literally cannot add too many comments to test code (I
       | challenge anyone to try)
       | 
       | time++; // increment time
        
         | snapcaster wrote:
         | I agree with you, i'm much more on the "try stuff out" scale
         | vs. formal methods. That being said, i've worked with people
         | who are the other way and still very effective. I think this
         | one is more of a trade-off or personality thing than something
         | that's "true" or "false"
        
           | AnimalMuppet wrote:
           | I agree with you that personality plays a role. But
           | regardless of which way your personality pushes you:
           | 
           | You can _never_ think enough up front to know all you need to
           | know, or even 95%. You 're not omniscient enough, and you
           | never will be. Big Design Up Front fails because of this -
           | you _have_ to be able to iterate.
           | 
           | You also have to know what you're trying to build, and at
           | least roughly how you're going to build it. If you don't, no
           | amount of iteration and experimentation will enable you to
           | converge on a solution. You need to experiment and iterate
           | and explore within at least a sketch of a larger picture, not
           | on a blank canvas.
        
             | snapcaster wrote:
             | True, the extreme version of any of these is usually wrong
        
         | do_not_redeem wrote:
         | > time++; // increment time
         | 
         | This isn't too many comments, it's a poor quality comment. Try:
         | 
         | time++; // advance 1 simulated second
        
           | bluGill wrote:
           | What is wrong with                  time++;
           | 
           | That seem obvious enough to me without any comments.
        
             | smallerfish wrote:
             | Is it ms? seconds? days? weeks? months? How far up do I
             | have to read to figure that out?
             | 
             | When I'm looking at a test case is broken, I ideally want
             | context IN the actual test that lets me understand what the
             | test author was thinking when they wrote it. Why does this
             | test exist as it does? Why are the expectations that are in
             | place valid? Write the comments for you-in-2-years.
        
               | bluGill wrote:
               | Do you not know the conventions of your project? Doesn't
               | your project have a convention that all time is in ms
               | (second, weeks...)?
               | 
               | If your project doesn't have that convention such that
               | everyone knows than the code should be
               | 
               | timeMs++;
               | 
               | You may also have a time type and so you can use your IDE
               | to examine the type.
        
               | rovolo wrote:
               | I agree that the time unit should be in the variable
               | name. The code itself should do a good job of explaining
               | "what" is happening, but you generally need comments to
               | explain "why" this code exists. Why is the test advancing
               | the time, and why are we advancing the time at this line
               | of the test?                   networkTimeMs++; //
               | Callback occurs after timeout              timeSec++; //
               | Advance time to check whether dependent properties update
               | utcTime++; // Leap second, DON'T advance ntpTime
        
               | danjl wrote:
               | I would prefer `somethingSec`, where "something"
               | indicates the usage better than "time". E.g. `delaySec`
               | or `elapsedSec`.
        
               | vunderba wrote:
               | Pedantic but a comment clarifying the unit of measurement
               | belongs with the _declaration of the variable_ , not an
               | increment statement.
        
             | m-zuber wrote:
             | That code (in isolation) does not tell me what unit time is
             | though
        
         | coldpie wrote:
         | > - There is no pride in managing or understanding complexity
         | 
         | > Complexity exists, you can't make it go away, managing it and
         | understanding it is the only thing you can do. Simple systems
         | only displace complexity.
         | 
         | I interpreted that one as a suggestion to avoid welcoming
         | needless complexity because of the false sense of pride it
         | gives you to successfully manage that complexity.
         | 
         | To give an example, I believe C++'s enduring popularity is
         | mostly because of exactly this false sense of pride. You
         | practically need a doctorate-level understanding of the
         | language to use most of its features without stepping on the
         | dozen landmines the language places in your way (I'm so smart
         | because I: remembered to declare my destructors virtual and
         | understand why; can interpret this 2MB of template errors in
         | the compiler output; can """cleverly""" use operator
         | overloads). It can feel nice to be a master of such a complex
         | tool, but that's a false sense of pride. The complexity of your
         | tooling is not the point; the end product is.
        
           | GuB-42 wrote:
           | C++ complexity exists for a reason. It does a lot of things
           | and these things are useful, if not necessary for those who
           | use it. I can't think of any language that can replace C++
           | completely. Plenty can replace C++ incompletely, but then you
           | would need another language for the leftovers, that's
           | displacing complexity.
           | 
           | There are modern languages trying to eat C++ lunch, like Zig
           | and Rust, but you don't get decades of backward
           | compatibility, and they are not particularly simple either.
           | Rust in particular is one of the most complex programming
           | language in use today, it could definitely be simplified by
           | removing the borrow checker and lifetime things and make
           | "unsafe" implicit, leave memory safety to the programmer. But
           | it makes no sense because Rust was designed for memory safety
           | and performance, which is a complex problem, and therefore
           | Rust is complex.
        
           | compiler-guy wrote:
           | C++'s enduring popularity is mostly inertia from the time it
           | was if not the only game in town, the biggest, baddest game
           | in town, and from being the souped-up (if overly complex)
           | successor to the previous biggest, baddest game in town.
           | 
           | Thousands of companies collectively have billions of lines of
           | code in C++. Millions of programmers know it well enough to
           | get the job done. Entire ecosystems with absolutely huge
           | areas are well defined by C++ (and previously C).
           | 
           | Rewriting all this code would be a gargantuan task. It all
           | mostly works (yes, it has bugs, lots of them, but it is still
           | mostly doing the job). The "R" in "ROI" for rewriting it is
           | extremely low and hard to predict, and the "I" is very high.
           | 
           | And that is why old programming languages live on. Not
           | because people take pride in being geniuses or the ability to
           | code in it, but because inertia is really hard to change.
        
         | mbonnet wrote:
         | I think the "most programming" thing has to be determined
         | according to project type. You should have your architecture
         | and data relationships all figured out long before coding when
         | it comes to safety-critical systems.
        
       | tines wrote:
       | How does
       | 
       | > There is no pride in managing or understanding complexity
       | 
       | interact with
       | 
       | > If I think something is easy, that's a sure sign I don't
       | understand it.
       | 
       | ? Is it implying that you must understand the irreducible
       | complexity, but mustn't take pride in that understanding? Or is
       | "difficult" the opposite of "easy" here, rather than "complex?"
        
         | mathw wrote:
         | Both easy and difficult problems can have simple or complex
         | solutions. Two different axes of measurement.
         | 
         | Most problems in software seem to end up being harder than they
         | look, so if I think something is easy I have to suspect I've
         | missed something.
         | 
         | Most solutions in software end up being more complicated than
         | they needed to be, because we don't have the hindsight to
         | realise that until after we've done it and our managers are
         | demanding the next thing.
        
           | tines wrote:
           | Sure, but that's not really what the quote says, it doesn't
           | talk about making things more complicated than they really
           | are, it just talks about "complexity."
        
         | ryathal wrote:
         | It's saying you don't need to be proud of your app that has
         | multiple layers of abstractions to be immune to every possible
         | change. There are hard problems, but the most complex solution
         | is rarely good or best.
        
           | arduinomancer wrote:
           | I think when you first start out as a programmer you're
           | impressed by complexity and complex solutions
           | 
           | But once you're more experienced you realize complexity is
           | arbitrary and anyone can make things more complex
        
           | tines wrote:
           | I'd argue that's a poor way to say that, because "managing"
           | complexity tends to mean "taming" or dealing with complexity
           | in a good way.
        
       | jordanmorgan10 wrote:
       | Huge disagree -
       | 
       | 100% of project managers could disappear with no change in
       | efficiency - not 95% ;)
        
       | dtquad wrote:
       | >Frontend development is a nightmare world of Kafkaesque
       | awfulness I no longer enjoy
       | 
       | As a backend/systems engineer I recently had to look at a React +
       | Typescript + MobX app from 2019/2020. It is true that that some
       | things, especially the webpack config and Typescript loading,
       | were outdated but the overall design and architecture of the app
       | was still understandable and modern. With some help from ChatGPT
       | it took very little time to migrate to Vite and update
       | dependencies. By 2019/2020 React Hooks had already been out for
       | some time but there were still some class components in the app.
       | They were easily migrated to functional components + Hooks using
       | ChatGPT.
        
         | kovacs wrote:
         | it's the best comment in the entire post IMHO and made me LOL
        
         | pinoy420 wrote:
         | With ChatGPT I am enjoying Typescript development and learning
         | a lot. Unfortunately with ChatGPT being - in JavaScript terms -
         | decades behind the state of the art. It becomes a little
         | challenging to get it to do what you want. But it gets me
         | 80-90% of the way there 70% of the time. Which is a huge win.
        
           | knodi123 wrote:
           | I know what you meant, but that phrasing reminds me of the
           | gag from Anchorman, "60% of the time, it works every time."
        
         | phailhaus wrote:
         | Yeah I wonder if his experience is mostly using JavaScript,
         | which is absolutely impossible to maintain at scale. Most of my
         | team comes from primarily backend-dev roles and they've all
         | grown to love TypeScript over Python.
        
           | jghn wrote:
           | Both of his blogs mention Java at least once. It's a good bet
           | this factors heavily in his day to day.
        
           | zelphirkalt wrote:
           | I have done frontend as well as backend and moved to backend
           | only, because the endless hype traing jumping, cv driven
           | development and config and library churn was just too much of
           | a comedy. And it is still happening. Now it is people
           | switching "routers" and version upgrades for nodejs and
           | version upgrades for typescript and deployment platform and
           | ... The list goes on.
           | 
           | This kind of thing is much much less pronounced in the Python
           | ecosystem, but also existent, while many packages are written
           | based on bad conceptual foundations, just like many
           | (majority?) of NPM modules are.
        
             | phist_mcgee wrote:
             | You don't have to follow hype when doing frontend, you can
             | pick whichever technologies you want and stick with them
             | for years.
             | 
             | Part of being a good frontend lead is personally is not
             | falling for the hype, and only adding packages I know will
             | a. be supported for the foreseeable future, b. have an exit
             | plan if those technologies aren't supported, and c. keep an
             | eye on my juniors/seniors to make sure they're writing
             | sensible long-term code.
             | 
             | The gnashing of teeth over the "upgrade cycle" I think
             | speaks to poor team planning/leadership than it does for
             | the actual tech now.
        
               | zelphirkalt wrote:
               | Yeah, you don't have to follow the hype, unless of course
               | you got coworkers blinded by the hype and managers, who
               | do not know how to discern who actually knows something
               | and who is just jumping on bandwagons. Suddenly you will
               | seem like the backwards guy, who does not want to learn
               | the new shiny thing. Then suddenly you do have to follow
               | the hype, even though you warned them.
               | 
               | As a full stack developer, your chances of being or
               | becoming the frontend lead are reduced, as you don't have
               | focus like a frontend only person, who will play that
               | card subtly, that they are the specialist and you are
               | not. And frankly, as a full stack developer, why would I
               | even want to become a frontend lead and sacrifice the
               | part of development, that is much saner? For the frontend
               | lead it also pays well to follow the hype, raise the
               | frontend to "modern level" and get paid senior salary.
        
         | whstl wrote:
         | 5-10 years ago I was just skipping Webpack and Babel, and raw-
         | dogging React.createElement in personal projects in order to be
         | happy and maintain sanity. At work I would just push hard for
         | alternatives like Parcel or Brunch.
         | 
         | Now, with Vite I just don't mind the toolchain anymore, it just
         | helps me instead of getting in the way. Similar to Go.
         | 
         | All the problems I have now are of my own creation.
        
           | dfee wrote:
           | dumb question from someone re-entering the FE world: why is
           | Vite necessary?
           | 
           | My understanding is it basically strips the type information
           | using Go (IIRC) where your typechecking is then a separate
           | step (without transpilation). So feedback is more rapid.
           | 
           | But, with tools like Deno or ts-node, where the type checking
           | is apparently also off the hot path, why does Vite still
           | exist?
           | 
           | Is it because it connects file monitoring with a dev server?
           | Because it also somehow works non-js artifacts like CSS and
           | image imports?
           | 
           | Ultimately, I've found the world of Vite + ESNext imports to
           | be a world of frustration and pain. And, I really want to
           | like Deno, and a lot of it is magical, but ultimately,
           | there's just some splitbrain stuff going on with Deno's
           | concept of a monorepo and their inability to commit to their
           | public projects (e.g. Fresh) leaves me concerned it's risky
           | to build on top of.
           | 
           | (ok, that turned into a rant, but there are some questions in
           | there.)
        
             | ericyd wrote:
             | > Is it because it connects file monitoring with a dev
             | server? Because it also somehow works non-js artifacts like
             | CSS and image imports?
             | 
             | Yes and yes. Also some pre-processing such as compiling JSX
             | into JS.
        
             | dcre wrote:
             | It is also a bundler and minifier and dead code tree-
             | shaker. It combines all your modules into one file (or a
             | few) for production. In development it doesn't do the
             | bundling part (for now -- with Rolldown[0] replacing
             | Rollup[1] in the future, bundling will be fast enough to do
             | the same in dev and prod).
             | 
             | It also serves as an integration point for other kinds of
             | tooling that involves processing or generating code. For
             | example, the latest versions of React Router[2] (which now
             | integrates Remix's features) and Tailwind[3] are designed
             | primarily to be integrated into projects as Vite plugins.
             | 
             | [0]: https://rolldown.rs/
             | 
             | [1]: https://rollupjs.org/
             | 
             | [2]: https://reactrouter.com/home#react-router-as-a-
             | framework
             | 
             | [3]: https://tailwindcss.com/blog/tailwindcss-v4#first-
             | party-vite...
        
         | ge96 wrote:
         | I'll be the Steve Ballmer saying "I love JavaScript" but man it
         | is great, I have made so many apps in different forms: web,
         | deskop, mobile. If I needed to I can go into XCode and work on
         | Swift. I have stuck with one stack though just
         | ReactJS/NodeJS/ReactNative/ElectronJS or PWA. I prefer
         | including SASS styles.
         | 
         | I still think TS is annoying to work with but I'm coming around
         | since I have to use it at work and libraries like React Native
         | are using it by default. Swift/C++ has typing but yeah, I like
         | plain JS for speed development and typing can get annoying
         | especially for a personal app.
        
         | kflgkans wrote:
         | If there is anyone here who has time to explain to me (or link
         | articles about) why functional components and hooks are
         | considered to be better than class components, please enlighten
         | me.
         | 
         | Up until roughly 4-5 years ago I was doing small front-end
         | React apps on the side (I'm a backend engineer) and was feeling
         | very productive with class components. They made sense to me,
         | concerns were nicely separated, and I felt I could reason
         | pretty well about what was called when and how state was
         | manipulated.
         | 
         | Then hooks came around, I tried them a few times, but I just
         | felt so lost. Suddenly everything is intermingled in one
         | function and we're using side effects to react to changes and
         | manipulate state. I could no longer understand when which code
         | was executed, and especially following and manipulating state
         | became impossible for me.
         | 
         | The projects I already, I kept with class components. Haven't
         | done any new front-end projects since then.
        
           | theryan wrote:
           | I'm glad I'm not alone in that sentiment. I haven't touched
           | react since the move to hooks. People seem to like them
           | though?
        
           | ericyd wrote:
           | I only knew React until my current job, which uses Vue. I'd
           | strongly recommend trying a framework other than React for
           | your next project. After you're past the learning curve, it's
           | much more intuitive.
        
             | Medicineguy wrote:
             | > I'd strongly recommend trying a framework other than
             | React for your next project.
             | 
             | This gave me a good chuckle (if you read it as next _.js_ )
        
           | rimunroe wrote:
           | > If there is anyone here who has time to explain to me (or
           | link articles about) why functional components and hooks are
           | considered to be better than class components, please
           | enlighten me.
           | 
           | Static evaluation of which instance properties are being used
           | in a class instance is much harder than evaluating which
           | variables are being referenced in a function. There's no need
           | to worry about calling context or binding instance methods.
           | Functions minify much better because you don't have to worry
           | about preserving long property names like componentDidUpdate.
           | With class components, sharing logic involving state between
           | components required either functions taking a state setter
           | and whatever slice of state you needed, or--more commonly--
           | higher order components. With function components and hooks,
           | the code responsible for initializing and updating state
           | isn't tied to an instance. Now you can share that code with a
           | plain function without needing to pass an entire slice of
           | state and an update function into it. Instead of needing to
           | shove all your update-related code into the same
           | componentDidUpdate or componentWillUnmount methods, you now
           | split them into different calls to useEffect.
           | 
           | > Suddenly everything is intermingled in one function and
           | we're using side effects to react to changes and manipulate
           | state. I could no longer understand when which code was
           | executed, and especially following and manipulating state
           | became impossible for me.
           | 
           | If you're talking about using useEffect to respond to changes
           | by setting state: that's almost always a code smell and
           | sounds like trying to sync state with props. This was an
           | anti-pattern long before hooks, and was called out explicitly
           | in the docs.
           | 
           | Having worked on a _lot_ of class components and function
           | components, class components offer a lot more opportunities
           | for bugs which can 't be statically prevented. On the other
           | hand, most of these bugs can be caught in function components
           | and hooks by a linter, or are just prevented entirely by the
           | design. A frequent question which came up during the class
           | component era was what code belonged in the class's
           | constructor, componentWillMount, or componentDidMount
           | methods. This always came with caveats, because generally
           | component initialization isn't something developers should be
           | thinking about because it can happen many times before
           | anything appears on screen. Function components offer fewer
           | opportunities for this. The useEffect hook forces people to
           | think purely in terms of running effects in response to
           | changes in variables which have been closed over, and about
           | what things need to be done to clean up after the effect has
           | run. Responding to user events (e.g. onClick) is almost
           | exactly the same as it's always been other than cosmetic
           | changes.
           | 
           | I'm not sure how everything being in a single function offers
           | worse organization than everything being within a class.
           | Instead of instance properties you have variables. Instead of
           | methods you have inner functions.
        
           | sesm wrote:
           | React's mental model has always been UI = F(data) and in
           | ideal case any component is a pure function. But, of course,
           | in most real apps there are cases when this mental model
           | breaks: internal state, animations and side effects. The old
           | way to provide escape hatches for those cases was to wrap a
           | function into a class, where original function is 'render'
           | method and the cases above are handled with lifecycle
           | methods. The problem was that one piece of functionality
           | often required updating several lifecycle methods, and for a
           | big component that non-locality made things very hard. Hooks
           | are a different way to express non-purity that keep code more
           | local.
        
             | kflgkans wrote:
             | Thanks, that makes sense. Interesting perspective on the UI
             | = F(data), I did not know that. I still wish the mechanics
             | were a bit more... intuitive... I guess? Personally, I'm a
             | big fan of The Elm Architecture [1]. I felt that is a very
             | nice way to separate state and logic. But I'm not such a
             | big fan of Elm itself (subjectively).
             | 
             | [1] https://guide.elm-lang.org/architecture/
        
         | settsu wrote:
         | While I completely understand OP's sentiment, after literal
         | decades of web/front-end development, I never quite grasped the
         | depth of disdain for Javascript or CSS until being on a team
         | where more than the same 2 or 3 people were actively coding in
         | them.
        
         | jolt42 wrote:
         | "frontend" is the wrong word, he should have said "web".
         | Writing desktop UIs or mobile apps tends to be elegant. And
         | probably "SPA frontend" as server-side UIs are also much
         | cleaner.
        
           | phist_mcgee wrote:
           | These days web/mobile is implied by frontend. I'd say a very
           | large proportion now work on these two compared to desktop.
        
       | donatj wrote:
       | > Most programming should be done long before a single line of
       | code is written
       | 
       | This is the only point I strongly disagree with. I have been
       | doing this for twenty years now and every time we've gone into
       | something with a STRONG plan for how it's going to be built, it's
       | ended up an inflexible nightmare when we inevitably end up having
       | to work around things that were not considered in the design
       | phase.
       | 
       | The plan _always_ ends up bumping into unforeseen realities, and
       | you end up with sunk cost around the planning so instead of
       | pivoting you keep on suboptimal course.
       | 
       | You can spend months planning the smallest feature and there will
       | always be something you did not consider.
       | 
       | Rapid prototyping in my experience is the way. Throw something
       | together that works, see how it can be improved, don't be afraid
       | to throw the entire thing out.
        
         | cardanome wrote:
         | I feel like exploratory and iterative development is more
         | necessary when requirements are unclear or when there is a lack
         | of domain knowledge. Also obviously things like game dev
         | require an iterative style.
         | 
         | For backend web dev though, I can plan it all in advance. I
         | have done it enough times that there are rarely any surprises
         | and I know the pitfalls. I am really just limited by customers
         | not knowing their own requirements.
         | 
         | I really love the iterative style but the problem is that I
         | never worked in a company that allowed for enough time for
         | large scale refactors. They might promise you that but it will
         | never happen. You have to get it right the first time around or
         | you will have to suffer until the system gets rewritten in a
         | decade or two.
         | 
         | Of course plans can absolutely be too rigid but I generally
         | found that more planning results in better products.
        
         | nicce wrote:
         | I would say it depends on your domain expertise and the
         | expertise of the chosen programming language. Of course, for
         | very large projects with multiple unknown integrations this is
         | not the case.
         | 
         | But if you are an expert in both of domain and the technology
         | itself, you can well design it before starting the coding,
         | because you already know the technical issues you are likely
         | facing.
         | 
         | At least I have personally managed to design some projects and
         | implement them without any design changes. But I also read
         | countless blog posts about the limitations of these programming
         | languages every day.
        
         | bluGill wrote:
         | There needs to be a balance of course, but eventually you will
         | have code/interfaces that are too painful to change because of
         | all the users. The more core code is the more painful it will
         | be to change and so the more a well thought out strong design
         | is needed. The less core the code is, the less strong the
         | design needs to be - but often the code code will force some
         | design on you.
         | 
         | Of course there will always be something you didn't consider.
        
       | naasking wrote:
       | > You literally cannot add too many comments to test code (I
       | challenge anyone to try)
       | 
       | I think it is possible, depending how you write them. If you
       | write long comments interspersed with the code, you have a lot of
       | scrolling to do follow the control-flow. Long block comments
       | should go at the top to "set the stage", and then lightly
       | interspersed comments throughout to remind of the specific steps,
       | where necessary.
       | 
       | > Very few abstractions exist in general application development.
       | Just write the code you need
       | 
       | I think they exist, but they're either not well known or are hard
       | to engineer because of missing context; good abstractions are
       | just hard. Solve the immediate problem and you'll maybe,
       | eventually converge on the abstraction and you'll have your
       | "aha!" moment.
        
         | naasking wrote:
         | > ORMs are the devil in all languages and all implementations.
         | Just write the damn SQL
         | 
         | I'm re-evaluating this again. I used to be all-in on ORMs,
         | eventually became annoyed with the shortcomings and the
         | performance problems, but am realizing the disadvantages of
         | foregoing them as well.
         | 
         | * ORMs Bad: ORMs often lead to deep object graphs and tight
         | coupling if you don't know what you're doing / don't factor the
         | model properly. This has serious performance implications.
         | 
         | * ORMs Good: you get a unified, consistent view of all of your
         | data on which you can enforce invariants in a holistic way.
         | 
         | * Only SQL Good: you can easily return and operate on only
         | "slices" of the data, which is great for performance and
         | rapidly iterating on features.
         | 
         | * Only SQL Bad: because you're only operating on "slices", you
         | don't get a unified view of the data on which you can declare
         | invariants. You can declare invariants on the slices and then
         | stitch all of the properties together in your head to make sure
         | you covered everything important (and write what tests you can
         | to validate this), but this is error-prone and less necessary
         | with ORMs.
         | 
         | So yeah, there's no single, clear winner here yet.
        
       | lmm wrote:
       | Hard to have any kind of productive discussion when it's just a
       | set of claims without rationales. I agree with some and disagree
       | with some (RDBMSes are overrated and solve the wrong problem;
       | ORMs are a useful tool and _bypassing_ the ORM because you want
       | to use your l33t SQL skillz is the devil; programming should be
       | done by writing lots of code from the earliest stage on (and
       | throwing most of it away)).
        
       | vincnetas wrote:
       | agree on 10/11 because i have not used DynamoDB ;)
       | 
       | by the way, whats wrong with serverless functions?
       | Given a long enough time horizon, you'll deeply regret building
       | on Serverless Functions
        
         | leptons wrote:
         | Been using AWS Lambda for 10 years, since AWS Lambda was first
         | released, so there really is no longer of a "time horizon" - I
         | have not had any problems that would cause any regret, quite
         | the opposite in fact. I also don't use the "Serverless
         | framework", I rolled my own AWS Lambda toolchain long before
         | the "Serverless framework" was ever a thing. So I'm not sure if
         | the author is referring to "functions as a service" generally
         | or specifically the "Serverless framework".
         | 
         | My team did recently try to set up the "Serverless framework"
         | for a new project, and it was quickly apparent that it wasn't
         | going to work for us. It was kind of messy, honestly. I really
         | wanted it to work, but requiring an account on the Serverless
         | framework website just to get Lambdas deployed was the wrong
         | way forward for us. We just ended up using my own toolchain,
         | which is simple and easy and does everything we need it to do,
         | which is build the Lambda function inside AWS Lambda, and
         | deploy the function with some basic configs.
        
       | xhrpost wrote:
       | > REPLs are not useful design tools
       | 
       | Anyone have more context on this? I've never thought of a repl as
       | a design tool. Does he mean loading your app in a repl, calling
       | functions manually and then manually swapping them out in real
       | time?
        
       | lucasoshiro wrote:
       | Strong opinions, but only telling them doesn't say too much for
       | me.
       | 
       | Constructive criticism: tell the reasoning behind those opinions.
       | I really believe that they are based on facts and experiences, so
       | tell them! Only telling "after 10 years in the industry" may look
       | like the argumentum ab auctoritate fallacy
       | (https://en.wikipedia.org/wiki/Argument_from_authority)
        
       | jagraff wrote:
       | > Contrarily, library development is about abstractions. Spend
       | time hunting for an algebra
       | 
       | This line piqued my interest - what does an algebra mean in this
       | context? Does anyone know of any good resources for further
       | exploration?
        
         | wink wrote:
         | Only guessing but my first thought was about how you have
         | addition and multiplication and they both work for different
         | types of numbers. But not in the generics/C++ template sense,
         | more like working on Sets and Rings and other algebraic
         | structures in the mathematical sense.
        
         | jghn wrote:
         | It comes from the FP world. It's one of those things like
         | monads that seem obvious when explained but sound opaque if
         | you're not in on it.
         | 
         | Basically it's saying to create a formal set of types and
         | formal rules about how they interact. If you search for
         | permutations of phrases like "functional programming" "algebra"
         | "data types" you'll turn up some hits. For instance [1]
         | 
         | [1] https://www.turingtaco.com/algebraic-data-types-
         | structuring-...
        
         | itishappy wrote:
         | Algebraic structure. It's a fancy way of saying that a system
         | follows certain patterns or rules.
         | 
         | As an easy example, you're probably quite familiar with the
         | algebra of addition over integers. It describes rules like
         | _associativity_ and _commutativity_ that describe some general
         | transformations that are guaranteed to always behave
         | predictably. Contrast this with subtraction over integers,
         | which is associative but not commutative. Programs in general
         | are neither associative nor commutative, so sadly no swapping
         | terms or adding parenthesis willy-nilly.
         | 
         | A slightly more advanced example that you're probably still
         | familiar with is mapping over Functors. A functor is just a
         | thing that contains other things, and it includes collections
         | you're familiar with like lists and trees. Well, the action of
         | taking stuff out of a container, modifying it, and returning
         | the results in their original position turns out to be an
         | incredibly common and useful pattern!
         | 
         | https://en.wikipedia.org/wiki/Algebraic_structure
        
       | nailer wrote:
       | > Frontend development is a nightmare world of Kafkaesque
       | awfulness I no longer enjoy
       | 
       | Yep. At some point in React (maybe 5 years in) 'how do I handle
       | state?' started to be 'read this essay about the true nature of
       | FRP from Dan Abramov' and it just seemed to get worse from there.
       | I worry Svelte will do the same in future.
        
       | pinoy420 wrote:
       | > If I think something is easy, that's a sure sign I don't
       | understand it.
       | 
       | A lot of people (definitely here) need to understand this.
        
         | patrickmay wrote:
         | This was the one that resonated the most with me. As soon as I
         | start to think "Why don't they just . . . ." I know I'm in for
         | an epiphany.
        
           | pinoy420 wrote:
           | "Just"(TM)
           | 
           | The bane of my life.
           | 
           | Glad I grew out of that eventually.
           | 
           | I completely agree.
        
       | braggerxyz wrote:
       | > Monoliths remain pretty good
       | 
       | > It's very hard to beat decades of RDBMS research and
       | improvements
       | 
       | > Micro-services require justification (they've increasingly just
       | become assumed)
       | 
       | That is so true. I am still deploying good old .war files to full
       | blown Java app servers backed by simple SQL databases (all
       | clustered and stuff) with some handwritten cli tools and a
       | Jenkins server. Shit is fast, shit scales, shit just works. It is
       | a pleasure to work with
        
         | jeremycarter wrote:
         | 98% of teams I've worked on did not need microservices.
        
       | nerdralph wrote:
       | > Very few abstractions exist in general application development.
       | Just write the code you need.
       | 
       | I don't try to foresee abstractions (premature optimization), but
       | I often encounter them when adding to a codebase. A recent
       | example would be a tool that uses property info from a public
       | database. The first version was hard coded to the database from
       | one jurisdiction. When I added support for a second
       | jurisdictions, abstractions helped avoid code duplication.
        
       | Cyclone_ wrote:
       | "Elegance is not a real metric".
       | 
       | Code maintainability certainly is something to consider that will
       | bite you if you're not thinking about it.
        
         | jghn wrote:
         | Define "code maintainability" in a measurable way.
        
       | markatkinson wrote:
       | > ORMs are the devil in all languages and all implementations.
       | Just write the damn SQL.
       | 
       | I think I might get this tattooed on my chest.
        
       | ikety wrote:
       | Functional programming does not prevent you from using objects
       | 
       | Stop listening to functional programming bros. Watch someone like
       | Zoran Horvat. While I can't cosign all of his opinions, he tries
       | to bridge the functional/OOP gap for OOP programmers. OOP
       | programmers urgently need to distance themselves from this binary
       | narrative. Everyone should understand functional programming and
       | how they can utilize functional approaches in every language or
       | paradigm. For me it is a requirement of understanding software
       | development.
       | 
       | Absolutely every institution teaches OOP practices, they also
       | need to teach functional practices. These aren't sports teams.
        
         | mrkeen wrote:
         | > Functional programming does not prevent you from using
         | objects
         | 
         | It's a bit like how doing single-entry bookkeeping doesn't stop
         | you from doing double-entry bookkeeping.
        
           | beders wrote:
           | That's probably the most incorrect analogy. If I have
           | objects, I can change their state in the middle of any
           | bookkeeping.
           | 
           | There should be a different name for functional programming
           | with mutable objects.
        
             | mrkeen wrote:
             | I think the analogy works. It's all about the tradeoffs.
             | 
             | Double-entry is harder to grasp, but it has certain
             | properties, like being able to sum along rows or columns.
             | With that property, you can then make assertions like "if
             | anything is off by a cent, then there has been a mistake
             | and it needs to be looked at again."
             | 
             | On the other hand, single-entry is much simpler, you can
             | just record a figure for a date with a reason, and be done
             | with it. It widens the pool of employable candidates, it's
             | easier to onboard new employees, and you don't have any
             | elites screaming at you for doing accounting the wrong way.
             | 
             | If you take a hybrid approach and mix the two, then on
             | average you only have to fill in 1.5 entries per
             | transaction, so it's easier and faster than double-entry,
             | but you can still express some transactions with two
             | entries if it's more elegant, on a case-by-base basis.
        
         | geophile wrote:
         | I wrote a comment echoing this point, about the coexistence of
         | FP and OOP. This ties to the article's point about finding an
         | algebra. Once you have an algebra, you have the basis for
         | implementing a lot of your application in the functional style,
         | manipulating objects that are inputs to and outputs from your
         | algebra's operators.
        
           | ikety wrote:
           | Said better than I could have
        
         | ben7799 wrote:
         | Well said and good institutions have been teaching both for
         | decades.
        
       | mikelinsi wrote:
       | > Never go full monad in Java. what? why?
        
         | dionian wrote:
         | because no matter how much java wants to be like scala, it's
         | very painful to work with (verbose). There is no good Option
         | type either. But I believe there are third party libraries out
         | there that do a better job, if you really can't use scala for
         | some reason
        
         | mrkeen wrote:
         | From a use-case perspective, Haskell monads let you restrict
         | where various effects happen. Some code can be allowed to do
         | local mutation, other code can do shared-mutation suitable for
         | (ACID-like) transactions. In Java you can do anything,
         | everywhere (except throw checked exceptions from lambdas for
         | some reason) so the monadic wrappers would give you about as
         | much guarantee as a comment, and be less clear.
         | 
         | From a representational perspective, you need a generic of a
         | generic to represent<M><A> and that doesn't really work. Or if
         | you go for interfaces not type variables, you could have a
         | Monad<A> but you don't know _which_ one you have (List? Future?
         | Parser? Either?). It 's like representing the above as literal
         | 'Object's, you'd be constantly casting.
        
       | qwertox wrote:
       | > Java is a great language because it's boring
       | 
       | My issue with Java is not that it's boring, which it is not, but
       | there is so much that needs to be done to get a simple "Hello
       | World" program to run which also depends on an external library.
       | It feels like you first have to build a castle just to put a bed
       | in a room.
        
         | geophile wrote:
         | Do you mean "public class HelloWorld { public static void
         | main(String[] args) { ... } }"?
         | 
         | Or the ridiculous Spring abstractions that many people insist
         | on?
         | 
         | The former is a minor nuisance, easily filled in by an IDE. The
         | latter is far worse, unnecessary bloat and complexity.
         | Architecture Astronaut stuff.
        
         | MichaelNolan wrote:
         | These days hello world in Java is just:
         | 
         | ```void main() {print("hello world"}``` And you can skip the
         | compile step as well and run it with just `java yourFile.Java`
         | 
         | Since JEP 495 they have made "simple programs" very simple.
        
           | qwertox wrote:
           | yes. main() is the room and print("hello world") the bed.
           | 
           | with the castle I'm referring to the whole myriad of things
           | that must be done to be able to compile this. But, as I said,
           | at least drop in a library, possibly via Gradle.
        
       | pkphilip wrote:
       | I must say that I resonate with almost all of the points stated.
       | 
       | These particularly stood out to me:
       | 
       | Frontend development is a nightmare world of Kafkaesque awfulness
       | I no longer enjoy
       | 
       | ORMs are the devil in all languages and all implementations. Just
       | write the damn SQL
       | 
       | Monoliths remain pretty good
       | 
       | It's very hard to beat decades of RDBMS research and improvements
       | 
       | Micro-services require justification (they've increasingly just
       | become assumed)
       | 
       | Most projects (even inside of AWS!) don't need to "scale" and are
       | damaged by pretending so
       | 
       | I did agree with the following as well:
       | 
       | Typed languages are essential on teams with mixed experience
       | levels
       | 
       | Java is a great language because it's boring
       | 
       | REPLs are not useful design tools (though, they are useful
       | exploratory tools)
       | 
       | Most programming should be done long before a single line of code
       | is written
       | 
       | Given a long enough time horizon, you'll deeply regret building
       | on Serverless Functions
       | 
       | Types are assertions we make about the world
       | 
       | Most won't care about the craft. Cherish the ones that do, meet
       | the rest where they are
       | 
       | Code coverage has absolutely nothing to do with code quality (in
       | many cases, it's inversely proportional)
        
         | leptons wrote:
         | >Given a long enough time horizon, you'll deeply regret
         | building on Serverless Functions
         | 
         | What is the regret about? I've been almost exclusively using
         | AWS Lambda (not using the "Serverless" framework), since 1
         | month after AWS released Lambda in Nov 2014. I've built quite a
         | lot on top of AWS Lambda, and I love it. It just works. It's
         | not difficult to work with, and I don't really have to worry
         | about scaling it. Is 10 years not enough of a "time horizon" to
         | regret it?
        
       | zafka wrote:
       | "93%, maybe 95.2%, of project managers, could disappear tomorrow
       | to either no effect or a net gain in efficiency. (this estimate
       | is up from 4 years ago)"
       | 
       | This made me laugh it is so true. My last big project at "Big Co"
       | ( Knee surgery robot ) My small group went through 4 project
       | managers - just for our small team. The entire project had
       | probably 20. While a few where enjoyable to work with, there was
       | very little value added and a lot of time spent filling them in.
        
         | mystickphoenix wrote:
         | Agree - in my 10+ year career, I've run into exactly 2 PM's
         | that have provided enough value to a team or project to justify
         | their inclusion in the team or project. Both were technical
         | enough to understand what the engineers were working on and
         | talking about and were able to offer genuinely good
         | suggestions.
         | 
         | The rest? At best they were glorified QA/QC with a large stick
         | to hit the engineers with when the spec wasn't met exactly. And
         | when it was, and things still failed, they still hit the
         | engineers with the large stick and were usually promoted for
         | it.
        
         | danjl wrote:
         | You can extend this to all varieties of PM.
         | Product/Project/Program. All should be replaced by people who
         | actually create things. E.g. I prefer to have a UX Designer
         | handle the Product Manager tasks, since they already think
         | about the app from the user's perspective, and can actually
         | create solutions to problems.
        
         | rgblambda wrote:
         | When org charts are from 2 reorgs ago, team members are going
         | straight to members of other teams where collaboration is
         | needed, the backlog is 100% maintained by the developers with
         | no input from managers, I wonder what exactly they do outside
         | of meetings where they usually just relay orders from higher
         | up.
        
         | spc476 wrote:
         | At $PREVIOUS_JOB, the team I was on worked the best when we had
         | no manager. Or rather, we had a director (who should not have
         | been managing us directly) meet with us once a week to tell us
         | "here's what we're headed ... good?" and let us go work in
         | quiet until the next meeting (or meet with us sooner if
         | something really important cropped up).
        
       | nmeofthestate wrote:
       | "Most programming should be done long before a single line of
       | code is written"
       | 
       | I wish this were the case, but have found that "No plan survives
       | first contact with the enemy".
        
       | geophile wrote:
       | After more than 25 years in the industry, and 10 years of
       | retirement, I agree with pretty much everything on this list. A
       | few things that struck me:
       | 
       | - Don't get too fundamentalist about OO or functional
       | programming. Each has its place.
       | 
       | - "Spend time hunting for an algebra" is somewhat obscure, but
       | truly excellent advice, and I have spend a lot of my career doing
       | exactly that. That has never been time wasted. This connects to a
       | couple of other points. 1) Once you have an algebra, you have the
       | basis of a good API for functional programming. (This point is
       | not explicit in the list.) 2) The things manipulated by your
       | algebra are also the basis of a good OO design.
       | 
       | - "Elegance is not a real metric." It is absolutely dangerous as
       | a metric, because it is a subjective goal we all aim for, and can
       | therefore be used to justify anything, no matter how dumb. That
       | said, elegance is something to strive for in your day-to-day
       | programming life. You know it when you see it in someone else's
       | work, and you appreciate it. You see a small set of principles,
       | implemented in one place, that can then combine in many ways to
       | do many useful things. Hmm, sounds a lot like an algebra!
        
         | physicles wrote:
         | As I understood it, the "algebra" is the domain-specific
         | language/abstraction that you build -- and if you're lucky,
         | discover -- that encodes something fundamental about the domain
         | you're working in. Once you've found that, further coding is
         | easier than you'd expect.
         | 
         | I've had the pleasure of finding a few of these over my career.
        
           | geophile wrote:
           | I think it goes beyond that. An algebra has operators that
           | take objects of some type as input and yield objects of the
           | same type as output. E.g. arithmetic (numbers in, numbers
           | out), and relational algebra (tables in, tables out).
        
       | NoMoreNicksLeft wrote:
       | >ORMs are the devil in all languages and all implementations.
       | Just write the damn SQL
       | 
       | This was in the "picked up along the way" category. Better a slow
       | learner than a no-learner.
        
       | weberer wrote:
       | >DynamoDB is a good database (IFF your workload lines up with
       | what it's offering)
       | 
       | >The query planner is a cruel mistress
       | 
       | >ORMs are the devil in all languages and all implementations.
       | Just write the damn SQL
       | 
       | >DynamoDB is the worst possible choice for general application
       | development
       | 
       | >It's very hard to beat decades of RDBMS research and
       | improvements
       | 
       | All these points tell a beautiful story
        
       | ChrisMarshallNY wrote:
       | _> Most programming should be done long before a single line of
       | code is written
       | 
       | > Frontend development is a nightmare world of Kafkaesque
       | awfulness I no longer enjoy_
       | 
       | These two may be interrelated. I do app (frontend) development,
       | and it _greatly_ benefits from an iterative, evolutionary
       | approach.
        
       | ge96 wrote:
       | It's funny I used to think tests are a PITA now I'm arguing for
       | them as I'm seeing the problem they solve, even basic ones like
       | full E2E headless browser testing vs. 100% unit test coverage.
       | 
       | I am holding back on stressing out regarding syntax like PEP 8.
       | My role right now is great where we get to prototype random
       | things.
        
       | marviel wrote:
       | "Typed languages are essential on teams with mixed experience
       | levels"
       | 
       | This is true of working with LLMs, too
        
       | Havoc wrote:
       | > REPLs are not useful design tools
       | 
       | Add Jupyter notebooks to the list.
       | 
       | Currently in a corporate environment where that seems to be the
       | go to way of coding and it's just fuckin awful compared to an IDE
        
       | BenoitEssiambre wrote:
       | These mostly align with the idea of reducing code entropy:
       | https://benoitessiambre.com/entropy.html
        
       | DarkCrusader2 wrote:
       | > You have to actively invest in improving your soft skills (and
       | investments pay back immediately)
       | 
       | Can anyone elaborate how does one do that? I have seen this
       | advice many many times but never anything actionable attached to
       | it.
       | 
       | I believe my soft skills are my biggest weak point right now and
       | is holding me from growing further in my career and I would like
       | to do something about it. But I have no idea how.
        
       | tasuki wrote:
       | > Gradual, dependently typed languages are the future
       | 
       | What's that?
       | 
       | Idris is dependently typed.
       | 
       | > Gradual typing is a type system that lies inbetween static
       | typing and in dynamic typing. Some variables and expressions may
       | be given types and the correctness of the typing is checked at
       | compile time and some expressions may be left untyped and
       | eventual type errors are reported at runtime.
       | 
       | That sounds miserable. I can't see how one would guarantee
       | anything when types of other things aren't known. And I can't see
       | how to connect that to dependent types either.
        
         | aranchelk wrote:
         | Maybe the author meant gradual static typing?
        
         | beders wrote:
         | I can only assume this comes from an observation that once your
         | product matures, the static types become more apparent and you
         | have a better idea how flexible your data modeling should be.
         | 
         | i.e. we are gradually adding more runtime type-checks to our
         | Clojure codebase. (Runtime check are even more powerful than
         | dependent types)
        
         | crvdgc wrote:
         | Imagine adding types to a legacy JavaScript codebase. You can
         | turn everything to valid TypeScript by annotating `any`
         | everywhere, then you can gradually add types here and there.
         | 
         | Or imagine writing Rust with `Rc` everywhere and then using the
         | borrowing style on the hot path.
         | 
         | I can see where the author is coming from, but sadly a
         | difficulty is that dependently typed languages often require
         | the programmer to prove type equality during type checking.
         | It's hard to do if the information is not complete.
        
       | taeric wrote:
       | > The trouble with functional programming is functional
       | programmers
       | 
       | This hilariously works for a lot of things. Biggest trouble with
       | legalization of drugs is the drug use of the ones that love to
       | talk about why it should be legal. Biggest trouble of prohibition
       | policies are the people that love going on about why they are
       | better for not drinking.
       | 
       | I assert that this is, essentially, "The trouble with THING is
       | the group of people that think THING is a panacea at what it
       | does."
        
       | devmor wrote:
       | For the most part, I agree with a lot of this, but there were a
       | couple points I raised an eyebrow on.
       | 
       | > There is no pride in managing or understanding complexity
       | 
       | To the point that intentionally creating complexity or allowing
       | it to continue to exist where it can be simplified, I agree - but
       | some systems are necessarily complex and having pride in
       | understanding and managing them is a good thing. If no one had
       | pride in this, why would anyone care about the things that aren't
       | simple - or bother to train the ability to simplify the complex
       | in the first place!
       | 
       | > Micro-services require justification
       | 
       | I used to believe this, but have changed my mind on it. Micro-
       | services are great in the current CS ecosystem (at least in the
       | US) because they allow smaller parts of the whole to be more
       | easily refactored when you find your development team with none
       | of the people that were present when design decisions were made
       | and a major feature needs to change.
       | 
       | It's an unpleasant situation to be in, and one that you ideally
       | want to avoid happening, but is common enough that preparing for
       | it in your application landscape is reasonable.
        
         | zem wrote:
         | you don't need microservices to accomplish that - a library
         | with a well designed public api and a language that lets you
         | enforce private functions/methods are good enough,
        
       | mr_tristan wrote:
       | This list does resonate, but I'd make some tweaks to express
       | things slightly better. For example:
       | 
       | > Most programming should be done long before a single line of
       | code is written
       | 
       | I would say "most engineering should be done before a single line
       | of _production_ code is written".
       | 
       | Formalizing a "draft process" is something I'm really trying to
       | sell to my team. We work in an old codebase - like, it's now
       | older than most of the new hires. Needless to say, there's a
       | whole world of complexity in just navigating the system. My take:
       | don't try to predict when the production code will be done, focus
       | on the next draft, and iterate until we can define and measure
       | what the right impact will be.
       | 
       | The problem is that there's a _ton_ of neanderthal software
       | engineering management thinking that we're just ticket machines.
       | They think the process is "senior make ticket, anyone implement
       | ticket, unga bunga". What usually happens here is that we write a
       | bunch of crappy code learning the system, then we're supposed to
       | just throw that in a PR. Then management is like "it's done,
       | right" and now there's a ton of implicit pressure to ship crap.
       | And the technical debt grows.
       | 
       | I haven't quite codified a draft process, but I _think_ it's kind
       | of in line with what Chris here is talking about: you shouldn't
       | worry about starting with writing production code until you're
       | very confident you know exactly what to do.
       | 
       | Ah well, it's a fun list of opinions to read. Chris' WIP book is
       | an interesting read as well
        
         | drbawb wrote:
         | >They think the process is "senior make ticket, anyone
         | implement ticket, unga bunga".
         | 
         | The fact that you just summarized about an hour worth of
         | argumentation from my last annual planning meeting with that
         | one sentence has just destroyed me. I kneel.
         | 
         | At this precise moment in time, if anybody seriously thought
         | the above was the way the process works or should work, they
         | should be advocating for firing all the juniors and replacing
         | them with LLMs.
        
           | mr_tristan wrote:
           | > At this precise moment in time, if anybody seriously
           | thought the above was the way the process works or should
           | work, they should be advocating for firing all the juniors
           | and replacing them with LLMs.
           | 
           | Sadly, I think this is happening at some places. Like
           | Salesforce. Sigh
           | 
           | https://www.ktvu.com/news/salesforce-cutting-1000-jobs-
           | hirin...
        
         | smj-edison wrote:
         | Sort of tangent, but is there a semi automated way to select
         | which engineer would be best to implement a ticket? Something
         | like "we need to modify this API, let's run git blame and see
         | who has the most familiarity" and some form of scheduler that
         | prioritizes the most experienced engineers on the parts of code
         | that only they know?
        
           | mr_tristan wrote:
           | Not that I know of.
           | 
           | I do think you could do some analysis to associate code with
           | implementers and create graphs, where you account for
           | additional things like time. I could see LLMs being helpful
           | in maybe doing part of that analysis. But I would use that to
           | see where the biggest "bus factor" is, i.e., finding
           | subsystems where there's really only one active contributor.
           | 
           | For planning or task assignment, it might just help to say
           | "ask X for more detail" when there's no other docs or your
           | LLM is spewing jibberish about a topic
        
       | aranchelk wrote:
       | > Frontend development is a nightmare world of Kafkaesque
       | awfulness I no longer enjoy
       | 
       | > Objects are extremely good at what they're good at. Blind
       | devotion to functional is dumb.
       | 
       | Blind devotion to anything in engineering is dumb, but if you go
       | full functional on the frontend it's definitely not "Kafkaesque"
        
         | tasuki wrote:
         | > if you go full functional on the frontend it's definitely not
         | "Kafkaesque"
         | 
         | This has been my experience too. Elm on the frontend is easy
         | and delightful.
        
           | aranchelk wrote:
           | Right on! I'm using PureScript with an Elm-like framework.
        
       | x3n0ph3n3 wrote:
       | > Most programming should be done long before a single line of
       | code is written
       | 
       | This definitely contradicts a previous article on Discovery
       | Coding [1]. I can't say I agree with it _at all_, despite 20
       | years in the business.
       | 
       | 1. https://news.ycombinator.com/item?id=42860128
        
       | petesergeant wrote:
       | I have a grey beard and have earned my right to have opinions on
       | things, so:
       | 
       | > Most programming should be done long before a single line of
       | code is written
       | 
       | I think via programming, and I think we should be building more
       | prototypes. Upfront design almost always falls apart, and if
       | you've invested too much into the design, you end up with some
       | nasty frankenstein code. Get a good prototyping process in place
       | instead, and write code and interfaces as early as possible, just
       | make sure you're very willing to throw them away, review what
       | worked, etc. The sooner you prototype, the sooner the "natural"
       | design appears, and the less you've invested in it.
       | 
       | > Frontend development is a nightmare world of Kafkaesque
       | awfulness I no longer enjoy
       | 
       | I like React much more than the shit I've enjoyed any of the run-
       | up to it, and I've been building websites since the late 90s,
       | working my way through server-side includes, hidden refreshing
       | iframes, XMLHttpRequest, Prototype.js, jQuery ... and today's
       | React just Makes Sense, man.
        
       | daxfohl wrote:
       | Abstractions are a failure in most libraries too. Invariably
       | something will come up that breaks the abstraction. Either new
       | instances come up that don't quite match, or clients want new
       | functionality that doesn't apply to all instances, or whatever.
       | 
       | I've come to the conclusion that in almost all cases, you should
       | avoid providing any abstraction from your own library / service,
       | and let consumers figure out what abstraction makes sense in
       | their domain. By stipulating the abstraction, you're robbing your
       | consumers of the ability to make things work the way they want,
       | and painting your own thing into a corner.
       | 
       | When you build the abstraction, it seems like you're doing your
       | consumers a favor. But that favor is short lived as the
       | abstraction changes and breaks your consumers.
        
         | daxfohl wrote:
         | Half of my team's work right now is changing our abstractions
         | because a couple clients want something slightly different,
         | without breaking existing clients. The other half of my team's
         | work is KLO forced on us by our dependencies needing to change
         | their own abstractions.
         | 
         | > When you build the abstraction, it seems like you're doing
         | your consumers a favor.
         | 
         | "The road to hell is paved with good intentions."
        
         | Bjartr wrote:
         | The best libraries provide both the abstractions and the
         | building blocks those abstractions were built from so consumers
         | can benefit from the abstraction when they can, but aren't
         | blocked just because the library devs didn't consider a
         | specific use case.
        
       | anacrolix wrote:
       | This list will look different at 20 years. About half will be the
       | same.
        
       | bob1029 wrote:
       | > It's very hard to beat decades of RDBMS research and
       | improvements
       | 
       | This is further complicated by the fact that not all RDBMS
       | engines are created equally.
       | 
       | It took me 2 decades to develop appreciation regarding why one
       | would actually want to pay for something like SQL Server when
       | options like SQLite and Postgres are free and easy to use.
        
       | er4hn wrote:
       | > Code coverage has absolutely nothing to do with code quality
       | (in many cases, it's inversely proportional)
       | 
       | I think this one keeps on being viewed as a % metric. You have
       | 50% code coverage, 75%, 99.9%, 100%, etc. In that sense it is
       | useless. Where I think code coverage has an enormous value is in
       | showing what parts of your logic are/are not covered by test
       | code. Being able to eyeball that and see where key parts of logic
       | are not tested is extremely helpful and tends to get lost in
       | these discussions.
        
       | MajimasEyepatch wrote:
       | > The trouble with functional programming is functional
       | programmers
       | 
       | As a former Scala dev, I feel this in my bones.
        
       | dkarl wrote:
       | > People who stress over code style, linting rules, or other
       | minutia remain insane weirdos to me. Focus on more important
       | things.
       | 
       | I wish he'd say which people are the weirdos: the ones who say
       | let's just pick a standard and rigorously enforce compliance, or
       | the ones who complain about the burdens of compliance and try to
       | undermine enforcement. I'd say the latter. I'm surprised he
       | didn't feel the need to be specific.
        
         | thuanao wrote:
         | Agree. No code standards is a red flag. It betrays a lack of
         | leadership and efficiency. It means the person in charge either
         | doesn't enforce standards, or doesn't see the value in them.
        
       | brodouevencode wrote:
       | > Monoliths remain pretty good
       | 
       | > Micro-services require justification (they've increasingly just
       | become assumed)
       | 
       | I say the opposite is true. Monoliths have a negative value
       | return with the expansion of an application.
        
       | vrnvu wrote:
       | - Elegance: Articulating the value of absence.
       | 
       | https://100r.co/site/computing_and_sustainability.html
        
       | zem wrote:
       | mostly good advice, but he's yet another person who seems to
       | think orms are primarily about sql generation. they're not;
       | they're about serialising/deserialising between objects and db
       | columns!
        
       | KronisLV wrote:
       | > ORMs are the devil in all languages and all implementations.
       | Just write the damn SQL
       | 
       | My take on this would be: ORMs are the devil in all languages and
       | all implementations. Static SQL queries with parameters will have
       | a lot of duplication (lots of similar queries), whereas
       | dynamically generating complex SQL will be hard to debug and
       | maintain (e.g. myBatis). Write some good DB views in SQL.
       | _Generate_ some dumb ORM entities against those views for
       | passable querying /filtering/pagination and do whatever works for
       | altering it. Don't go fully into the opposite direction either
       | and don't put 99% of your business logic into the DB, that will
       | be hard to work with because the tooling isn't very good (e.g.
       | stored procedures).
        
       | debarshri wrote:
       | Software development should also be seen from what stage the org
       | is in.
       | 
       | Software development looks super different when the org is a
       | startup vs when the market fit is established.
       | 
       | When you are a pre-PMF, you have to establish trust. You deliver
       | fast, cut corners, make sure customer needs are met, value is
       | generated. Nothing else matters.
       | 
       | When PMF is established. You have to de-risk everything. All your
       | work is at stake. Then best practices has to be in place to makes
       | things scalable, code quality matters because it is a proxy for
       | enforcing standards.
       | 
       | I don't think Software can be seen in isolation. It has to be
       | seen from thr orgs perspective.
        
         | baq wrote:
         | This. Engineers are hired to solve problems. Sometimes
         | beautiful code and clean architecture are part of the
         | requirements to solve the problem at hand. Sometimes... they
         | aren't.
        
           | debarshri wrote:
           | Beauty is in the eye of the beholder. I would argue you
           | didn't use design patterns enough.
           | 
           | Beautiful code and clean architecture is a rabbit hole.
           | 
           | Code should be clean enough to communicate. As long as team
           | understand and accepts the risk, it is good enough.
        
             | baq wrote:
             | I equate design patterns with language deficiencies, so not
             | sure what to answer. I know 'beautiful' won't be part of
             | the response, though.
             | 
             | Code is a liability, unless you're selling it. The less you
             | have of it, the better off you are in the long run. That
             | doesn't mean I don't agree that it should be clean, as an
             | engineer. As a customer making a decision whether to buy a
             | product or not, I couldn't care less. If you're hunting for
             | product-market fit, you can do it with clean code, nothing
             | is stopping you, except perhaps if there's enough runway to
             | make paycheck.
        
       | ljm wrote:
       | > Good management is invaluable
       | 
       | Good management is life and death, particularly for a startup. If
       | you think you can do without it and you're not a good manager
       | yourself then it's going to be a struggle to execute.
       | 
       | > ...you'll deeply regret building on Serverless Functions
       | 
       | Whatever serverless functions promise in scalability, they'll
       | cost you in terms of complexity. Trying to build a cohesive
       | backend entirely in a serverless environment just isn't worth it
       | when it's trivial to boot up a simple, long-running server. Even
       | running locally is a pain in the ass compared to `rails s` or
       | `fastapi dev`.
       | 
       | God forbid your serverless environment is actually on the edge,
       | at which point most of the stuff you're used to using won't work.
        
       | mprast wrote:
       | "Objects are extremely good at what they're good at. Blind
       | devotion to functional is dumb."
       | 
       | sure, but I think the status quo is to way overuse objects. my
       | preferred style is to bias heavily towards value objects, and to
       | never ever use things like inheritance for control flow
       | 
       | "ORMs are the devil in all languages and all implementations."
       | hard agree lol
        
       | juhanakristian wrote:
       | > ORMs are the devil in all languages and all implementations.
       | Just write the damn SQL
       | 
       | What are the main issues people run into with ORMs? I've used
       | Django ORM for years and written some relatively large
       | applications using it without much problems. Complex queries and
       | aggregations can result in quite hairy code though.
        
         | ramon156 wrote:
         | I can give an example for Prisma.
         | 
         | It joins in code, not in SQL. We realized this way too late
         | because we _assumed_ an ORM is optimally structuring code. It
         | wasn 't.
         | 
         | This, along with the fact that SQL is already a definitive
         | language, made us realize that ORM's are stupid and utterly
         | useless. I'm talking about the ones that try to pretend they're
         | code, and not a query.
         | 
         | There are multiple ways you can design an ORM though, and one
         | way is to let the user fully manage how they want the query to
         | run, so you're pretty much structuring a query already. Why not
         | go the extra mile and make an SQL query?
         | 
         | I get that ORM's are fine when you don't want to deal with
         | writing queries (e.g. school projects) but for real world apps
         | just take the extra minute...
        
           | gniting wrote:
           | Perhaps this information will be helpful context for you and
           | for anyone else who happens to land on this post: -
           | https://www.prisma.io/blog/prisma-orm-now-lets-you-choose-
           | th...
           | 
           | - https://www.prisma.io/blog/database-vs-application-
           | demystify...
        
       | lainproliant wrote:
       | In response to "There is no pride in managing or understanding
       | complexity.", I posit the following based on my experience:
       | 
       | Understanding and managing complexity is one of the first steps
       | required in order to eliminate complexity. Some of the greatest
       | achievements in my software development career have been
       | instances where I carefully pulled apart inscruitable solutions,
       | often short-term and built in desperation, and re-constituted
       | them into well tested and much less complex solutions which were
       | more understandable by devs and users.
       | 
       | I agree with most of Chris' observations and enjoyed reading his
       | insights. Makes me want to do the same!
        
       | the_gipsy wrote:
       | > Typed languages are essential on teams with mixed experience
       | levels > Java is a great language because it's boring
       | 
       | Stopped reading there. Ironic that one is right below the other.
        
       | gspencley wrote:
       | > Elegance is not a real metric
       | 
       | While I agree with this in spirit, I once made the observation
       | that:
       | 
       | "Code quality can be measured by the number of occurrences of
       | 'WTF' uttered by other developers per minute when reading a PR."
       | 
       | Elegance might be subjective, but how easy code is to read and
       | understand probably _can_ be quantified even if we don 't have
       | the best tooling for that yet.
       | 
       | Meaning that if 10 engineers less experienced than me all tell me
       | that they think expressing something one way is easier to
       | understand than another, I take that as objective feedback and
       | change course.
        
       | sesm wrote:
       | Articles like this always remind me of 'The 57 Precepts of Zote'.
        
       | charlieflowers wrote:
       | Good stuff!
        
       | throwaway2037 wrote:
       | > 3%, maybe 95.2%, of project managers, could disappear tomorrow
       | to either no effect or a net gain in efficiency. (this estimate
       | is up from 4 years ago)
       | 
       | This is 100% of immediate line manager that I have had in my
       | career.
       | 
       | Anyone else?
        
       | asalahli wrote:
       | > You literally cannot add too many comments to test code
       | 
       | In my opinion, almost every developer I've worked with who
       | advocated for generous amounts of comments has overestimated
       | their (and or others') ability to write good quality comments.
       | 
       | Obvious ones like `a = b; // set a to b` while useless are also
       | mostly harmless, but I've been lead astray by outright factually
       | wrong comments, many more times than I can count. I certainly
       | don't feel confident in my own ability to not write factually
       | incorrect comments. So yeah, I'd rather the code do the talking.
        
         | adamtaylor_13 wrote:
         | That's why your comments should be on things you know to be
         | factual like WHY you made a certain decision. Things like that
         | cannot always be communicated by good variables and functions.
        
       ___________________________________________________________________
       (page generated 2025-02-05 23:01 UTC)