4 ms·
Long time ago I wanted to make a small contribution to Stellarium. I have a telescope and "surface brightness" is a much better metric than what it showed at th
by marcodiego 3y ago
Long time ago I wanted to make a small contribution to Stellarium. I have a telescope and "surface brightness" is a much better metric than what it showed at the time. I downloaded the code and with a quick inspection found out how to implement it. I modified the code and prepared a patch. When I was going to send it, I discovered someone else had simply implemented it a few days earlier. Nice. It saved me a little work.
Now, what impressed me: I didn't explore it much but it gave me a very good impression of the code. I could find what I needed to change and someone else, without talking to me about it had the exact same idea. The changes were EXACTLY the same. I can only think this code is extremely high quality. It seems to be a standard developers should aim for.
- cbolton 3y agoInteresting measure of code quality! I think it's the first time I see it.
- tantalor 3y agoThere should be one-- and preferably only one --obvious way to do it.
- cbolton 3y agoHaha right :) Though I feel we're talking of different levels of granularity: I've seen that quote applied at a level close to single operations, which makes sense when you're making judgment on a programming language or API. In OP's case I imagined a somewhat larger piece of code.
- throwaway_8462 3y agoI think it also is a measure for technical debt. If someone can easily understand the code and make changes, it is a sign of low technical debt. Too often developers measure code quality by applying personal subjective measures, like number of lines per method, DRY or choice of programming language and start making major refactoring based on personal preferences. If someone without knowledge of the code can swoop in and make meaningful changes, it does not matter how many lines of code there is or if it is built with X or Y. It's the end result that matters.
- vendiddy 3y agoNot sure why this post is anonymous. I wish most folks would treat code quality this way! How hard is it for a developer make this particular change? And I mean literally observe this up close: navigating the directory structure, reading the docs, typing the code, running the app to check if everything works as expected. Was it easy? What can change about the code, tests, docs, etc so future changes can be easier? That's what really matters. Other measures are just proxies to the above analysis.
- throwaway_8462 3y ago> Not sure why this post is anonymous Honestly, my work place is filled with inexperienced people who have decided what the right approach should be. I'm older and more experienced than most and have learned that I can't win all battles, and bite my tongue when I see them making bad decisions. It's a form of age discrimination where even the management thinks that "young people see problems with fresh eyes". I don't want to come across as an "ok boomer" developer stuck in their old ways. "Rewrite everything in the new untested framework? Sure why not. The code is over 2 years old, so it's full of crusty legacy code". I may seem a bit bitter in my comments, but I'm mostly disillusioned and are trying to see it as a learning experience. I'll give my opinion sometimes, and if they don't follow it it's not my problem. They will just need to learn the hard way and will probably end up in my situation in a few years. I'm just collecting my pay check and planning to move on to a work place with more balanced demographics.
- turdprincess 3y agoAs a converse view point, in my experience, in terms of huge methods and huge files / classes, its rare to see developers who have the mindset of "in general, I prefer small files and classes, but in this case, it makes sense to have a huge function, so I make an exception." What I do see every day is "oh yeah, this method / file is pretty big, lets add one more thing to it anyways, I dont have time to refactor", and things grow and grow out of control. I think one basic, and yet rare ability of a professional software engineer, and the skill that should separate you from a hobby programmer, is writing your code in a way which can scale and grow. The strategy for this cannot just be "let me put everything in one file, class, method and lets just see what happens". That can be an OK first draft approach, but there needs to be a second step. And ultimately, if you set the architectural pattern of "big hairball", everyone else will happily follow it since its not their fault the architecture is like that - they are just adding one more thing. That can be OK for a first draft, but you will have to go back and introduce architecture and modularity at some point, or watch the project collapse under the weight of its own mess. Once you see enough of those failures, you can start sensing basic patterns for introducing modularity, boundaries and structure to a project, to its modules, and to its classes and methods. As you keep flexing that muscle, in my experience, the "this code is best written as a huge single method" approach basically never seems like a good idea anymore.
- kristopolous 3y agoCheck out the NetBSD or OpenSSH source. Both are exceptional
- derefr 3y agoI think this is the sort of thing that developers really want, when they consider introducing a Domain Specific Language into their project: to take changes that, for either language-level or project-architecture reasons, currently have to be made, painfully, across N different parts of the code, ensuring they're all coherent with one-another and that none are missed; and to replace that with such changes requiring that only one piece of code be changed, where that code communicates the central spirit of the business constraint, from which all of the changes to disparate concerns in different modules, can then be derived. But, of course, even more ideally, you can 1. choose a language and 2. architect your project in such a way, that you don't even need any DSLs in order to accomplish that. :)
- nine_k 3y agoUsually it's not a full-blown DSL, but a good set of data structures, interfaces, and functions, all implemented within some general-purpose language. Usually you need to have your data model right, and all else follows more easily.
- d0mine 3y ago> data model "The building of the program is the same as the building of the theory of it by and in the team of programmers" https://pablo.rauzy.name/dev/naur1985programming.pdf https://pablo.rauzy.name/dev/naur1985programming.pdf
- derefr 3y ago"A good set of data structures, interfaces, and functions" is great at the design stage. It's also great for implementing an elegant reference implementation (i.e. one that is meant more for documentation than use — one that you'd describe in a journal paper to communicate the algorithms and data structures involved, for example.) But I bring up choice of (programming) language as an issue, because in many languages, once you need to operationalize your codebase — make it efficient and scalable, optimizing it with respect to real use in the field, then you'll begin to need things like: • static data in user-defined complex data structures (incl. ones like graphs with cycles) burned into the program at compile time • memoization / dynamic programming caches to accelerate costly computations of otherwise-pure functions, esp. for computations done to instances of data structures but where the memoization only helps if done globally across all data structures • ADTs that are actually implemented in terms of multiple different underlying data structures depending on the properties of the data itself; where, upon mutation of the data, the implementation — and thus the representation of the data — can be swapped out transparently (think: lists in CPython; or Integers vs BigIntegers in Ruby; or most data structures in Redis with their "ziplist" variants) ...and so forth; then often the language will start actively fighting you, as the language has been designed to do everything at runtime; and especially has no consideration for mixing compile-time, runtime-memoized, and runtime-pure sourced data using the same set of algorithms. So you have to write two or three different implementations of the same code, and store your static data in special ways, and mess up your ADTs with indirections, and your data structure constructors with heuristics, and define global caches where much of your data actually lives, turning your concrete modules inside out and making it very hard to reason about them... and so on. This all gets fixed if you define a DSL. You're basically turning all of the above operationalized logic, into just an opaque "platform" runtime. But you still do have to maintain that "platform." But some programming languages are already essentially such an operationalized "platform" runtime! Though, such languages are almost always only operationalized for specific use-cases. They're not quite domain-specific languages (insofar as a domain is a vertical); but they are always extremely "opinionated" languages.
- doubloon 3y agoi was working on internationalization for a big C++ / QT project and I basically just copied the technique + strategy that Stellarium used. worked great.