Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Here's the graphic transcribed as text for non-English speakers.

Software Engineering: Requirements, Modifiability, Design Patterns, Usability, Safety, Scalability, Portability, Team Process, Maintainability, Estimation, Testability, Architecture Styles.

Computer Science: Computability, Formal Specification, Correctness Proofs, Network Analysis, OS Paging/Scheduling, Queueing Theory, Language Syntax/Semantics, Automatic Programming, Complexity, Algorithms, Cryptography, Compilers.

In my opinion, some of those could be on the other side of the line (estimation could be CS, language syntax/semantics and network analysis could be SE). But I agree with the general division.

I studied Electronic Systems Engineering, but somehow always found jobs in software companies. One problem I struggle with is the division between DRY (Don't Repeat Yourself) and WET (Write Everything Twice) coding styles.

Most programmers hate it when code is repeated. They prefer to spend days trying to integrate external libraries instead of just copying the necessary functions into the main branch. There are good reasons for this (benefiting from new features when the library gets updated), but there are also risks (the code breaking when the library gets updated).

Software Engineering priorities include Safety, Portability, Modifiability, and Testability. I interpret that as a WET programming style. "If you want it done well, do it yourself." There's no arguing about responsibility then - the code is mine, and I should fix it if it breaks.



I don't think you understand DRY. It's a concern within the code you write rather than without. Whether you choose to freeze your dependencies is an entirely different concern.

Say, for example, you have a complicated condition you test for frequently within your code. DRY is when you decide to extract that condition into a testable function you can rely on everywhere in your code (e.g. `isLastThursdayOfMonth(date)`) You can extend this same DRY thinking to all the other abstraction tools (e.g. types/classes) you have as an engineer too. I'm sure you'd agree that it would be an enormous liability and maintainability nightmare to rewrite the logic for that function everywhere. God forbid you're ever asked to change your littered logic to the equivalent of `isLastWeekendOfMonth(date)`.


> Software Engineering priorities include Safety, Portability, Modifiability, and Testability. I interpret that as a WET programming style. "If you want it done well, do it yourself.

None of those demand “write everything yourself”, only setting the same criteria for external code you integrate as you would have for code you write yourself.


> but there are also risks (the code breaking when the library gets updated).

This is the entire point of Semantic Versioning: to communicate breaking changes through the version number, and to build tooling to programmatically avoid breaking dependent code.

(No, it isn't generally perfect: it does require that human realize what the API is that that a given change is breaking it. If we had some programmatic language for specifying the API… type systems start this, but tend to not capture everything¹)

¹I suspect there are some formal analysis folks who know more than I do here, screaming that there is a better way. I work in Python day-to-day, so generally, it's all on the human.


See this talk [0] about this addition to Clojure called core.spec [1]. I read the paper first, and it isn't until the end of the presentation that I understood how it was related to the feature at all. Basically, core.spec is a kind of formal verification tool designed to deal with the growth of software. It is not a type system, though it resembles one in some ways. The objective is to support comparisons between the signatures of a function at two different points and say, are these compatible? Is this a breaking change? You have to design for growth: make no assumptions about unspecified keys and always assume that later versions may return more than they used to. And so on.

If you're a fan of semver, be warned.

[0] https://www.youtube.com/watch?v=oyLBGkS5ICk

    https://news.ycombinator.com/item?id=13085952
[1] https://clojure.org/about/spec


Elm has automatic semantic versioning based on the type system:

https://github.com/elm-lang/elm-package/blob/master/README.m...


And freezing / pinning dependencies (and their dependencies...) to avoid deploying a version of a library you haven't already tested first.


> Computer Science: Computability, Formal Specification, Correctness Proofs, Network Analysis, OS Paging/Scheduling, Queueing Theory, Language Syntax/Semantics, Automatic Programming, Complexity, Algorithms, Cryptography, Compilers.

It's interesting/funny that when talking about CS, or more academic point of views around software development, the terms "Formal Specification" and "Correctness" are often mentioned, yet most CS students/labs still use languages that are really badly suited for this job, such as dynamically typed languages like Python.


There are various fields in computer science, nobody claims formal specification and correctness in a NLP/ML library nor in a graphics library. Formal verification is orthogonal to other fields.


Are languages like C & C++ that much better?


Neither are "better". Its all about tradeoffs.

I hate large python code bases with no strict types specified anywhere. It's a nightmare to maintain that code.


Of course not, but Haskell/F#/OCaml/F*/Rust are.


No, but languages like Haskell, Ocaml, F#, Idris, Purescript, Elm etc are definitely, when talking about correctness.


How does copying the english words from the image to english words as text help non-English speakers?


Makes it easier to look up (copy/paste) and/or use dictionary tools.


They can copy and paste them into google translate?


Software Engineering looks like Systems Engineering with code applied.


That's a wonderful description, thank you! Yes. Software Engineering is applying Systems Engineering principles to the field of programming. It's a pretty good field to work in, because the biggest risk I face is only data loss, unlike other engineering disciplines where the stakes are much higher.


Software Engineering definitely has jobs/applications that can cause catastrophic loss if done incorrectly. For example, software in commercial airlines.


WET is "we enjoy typing" where I'm from


Its a naivety of early programming that DRY is the chief principle of software engineering. Try understanding the underlying patterns and applying the right design patterns for the job and you will realize that DRY without deeper thought is just shuffling the problem around like a kid throwing his mess in the closet.


It's a misunderstanding of DRY that leads to most of the nonsense. The original formulation, in the Pragmatic Programmer, was: "Every piece of knowledge must have a single, unambiguous, authoritative representation within a system."

This very much requires "understanding underlying patterns" - what knowledge does your program encode? How can that be broken apart and localized?

Obsession with repetition of surface syntax isn't DRY and isn't useful. It goes wrong in two ways. First, knowledge can be repeated without repetition of syntax. If I'm telling my HTML "there is a button here", and my CSS "there is a button here", and my javascript "there is a button here", those three statements may look nothing alike but that's not DRY.

Second, if two pieces of code happen to look identical, but each is the way they are for different reasons, they encode different pieces of knowledge and collapsing them is not DRYer. As I've said before, in that case you're not improving your code, you're compressing it. I like to call that kind of overzealous misapplication of DRY "Huffman Coding".




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: