Live data from Hacker News

Software Engineering principles to make teams better

principles.dev

81–90 of 105 posts

Re: Software Engineering principles to make teams better

#81

I think i’ve got a slightly different take - i’m not saying my take is any better though. If we’re talking engineering principles, not team dynamics, then it’s: 1. Use immutability by default, even in languages that make that harder than it should be 2. Understand how liberating idempotency is 3. Divide and conquer, use abstraction to make hard problems manageable 4. Delete code, delete tests, re-write stuff, re-writ…

> 1. Use immutability by default, even in languages that make that harder than it should be What I've come to realize is that whenever people talk about wanting immutability, they really want value semantics. Value semantics can be achieved without immutability - the best example is Swift's structs. They can be both mutable or immutable, but they can never be shared, i.e. there can never be more than one reference to…

Can you explain in more detail? I agree that local reasoning is the end goal, but as soon as you change things (i.e. mutate) then it doesn't work anymore. Or in other words: if modifying a value has no effect on anything else, then why would you modify it? I don't get it - maybe a code example would help.

Re: Software Engineering principles to make teams better

#82

Earlier quoted context omitted.

Next time my boss asks why I rewrote that component for the third time instead of doing real work, I'll answer "learning". ;) In all seriousness, from a business standpoint, it's almost never worth rewriting anything unless you're already making significant changes to that code. The opportunity cost of not spending that time building things that get you paid is just too high—not to mention all the new bugs that you'r…

I wrote it a bit tongue in cheek, but honestly, I've recently started to consider writing the first solution as a pure learning exercise. I.e. when writing a new module/feature, I lean towards getting a solution implemented quickly, fully expecting to immediately scrap most (or all) of it, and write it again. Most of the time, this happens way before the code goes into review phase, so nobody knows I've actually writ…

I don't think this is what people mean by a rewrite here. I expect any code that makes it to review to undergo some kind of refactoring. Sometimes it's going to be refactored as part of the review. And if throwing away your first draft works for you to create better software, that's fine! I still consider this as some kind of refactoring.

Throwing away a whole repository that was tested and running in production or on some dev environment, is something different in my point of view. And I think that's what people mean by "rewrite".

Re: Software Engineering principles to make teams better

#83

Earlier quoted context omitted.

You may just learned that there's no more meaningful improvement to be made. That should probably be documented somewhere after that discovery is made. Somewhat relatedly, I've refactored processes down from 25 hours to 20 minutes. It got to 20 minutes, and other people started nitpicking that it could 'be faster' (the same people who'd let it get to 25 hours, then threw up their hands and said "it can't be fixed").…

Meaningful improvement is in the eye of the beholder. There's the old tale of how Google found out 500ms in latency was a 1% drop in traffic. http://glinden.blogspot.com/2006/11/marissa-mayer-at-web-20.... 20 to 17 minutes is a 15% time savings still.

25 hours to 20 minutes is insane. The process ran daily and only needed to run daily. 20->17 was unnecessary and a waste of time.

Re: Software Engineering principles to make teams better

#84
post #53

Earlier quoted context omitted.

Reading a variable isn't side-effect free either :P

In the sense that you're moving data in to a register and updating the program counter?

And potentially changing the contents of processor caches.

Re: Software Engineering principles to make teams better

#85

I think i’ve got a slightly different take - i’m not saying my take is any better though. If we’re talking engineering principles, not team dynamics, then it’s: 1. Use immutability by default, even in languages that make that harder than it should be 2. Understand how liberating idempotency is 3. Divide and conquer, use abstraction to make hard problems manageable 4. Delete code, delete tests, re-write stuff, re-writ…

> Use immutability by default, even in languages that make that harder than it should be That and referential transparency are huge wins. It is a shame languages like Python make it such a challenge.

Immutability isn't so difficult to do with Python language itself for any object. The push back is culture and practice of "we are all adults here" and that influences the language to make it forcing immutability awkward.

For example, let's assign a constant variable to a sequence; should you do use list or tuple (FOO = [1,2,3] or FOO = (1,2,3) )? It doesn't matter, the constant capitalization discourages you to mutate it.

Re: Software Engineering principles to make teams better

#86

Earlier quoted context omitted.

Next time my boss asks why I rewrote that component for the third time instead of doing real work, I'll answer "learning". ;) In all seriousness, from a business standpoint, it's almost never worth rewriting anything unless you're already making significant changes to that code. The opportunity cost of not spending that time building things that get you paid is just too high—not to mention all the new bugs that you'r…

I wrote it a bit tongue in cheek, but honestly, I've recently started to consider writing the first solution as a pure learning exercise. I.e. when writing a new module/feature, I lean towards getting a solution implemented quickly, fully expecting to immediately scrap most (or all) of it, and write it again. Most of the time, this happens way before the code goes into review phase, so nobody knows I've actually writ…

> so nobody knows I've actually written something twice.

that's not really what a rewrite is. A rewrite is when something has already been in production, and the engineer re-do the same feature set, but refactored or rewritten in a different (possibly better, but not guaranteed) form. This rewrite takes up the time that would've been spent on something else.

If you were doing a "rewrite" during implementation, but still delivered on time, that's not a rewrite - that's just good engineering, doing exploratory coding! If you couldn't deliver on time because of the rewrite, then i guess you can call it a rewrite.

Re: Software Engineering principles to make teams better

#87

Earlier quoted context omitted.

> 1. Use immutability by default, even in languages that make that harder than it should be What I've come to realize is that whenever people talk about wanting immutability, they really want value semantics. Value semantics can be achieved without immutability - the best example is Swift's structs. They can be both mutable or immutable, but they can never be shared, i.e. there can never be more than one reference to…

Can you explain in more detail? I agree that local reasoning is the end goal, but as soon as you change things (i.e. mutate) then it doesn't work anymore. Or in other words: if modifying a value has no effect on anything else, then why would you modify it? I don't get it - maybe a code example would help.

An example might be a function that takes a vector3, adds 5 to the x value, then returns the vector's length. You could model that as "make a second vector v_2 {x = v.x + 5, y = v.y, z = v.z}; return v_2.length", but if you have struct semantics, you can just do "v.x += 5; return v.length", and be confident that you're not modifying the vector that the caller has.

Re: Software Engineering principles to make teams better

#88

Earlier quoted context omitted.

> Use immutability by default, even in languages that make that harder than it should be That and referential transparency are huge wins. It is a shame languages like Python make it such a challenge.

This was the first time I've encountered the mention of "referential transparency", so I looked it up and went down a deep rabbit hole. It seems that it's normally used to describe the property of not having side effects, however, I also found this long explanation on Stack Overflow: https://stackoverflow.com/a/9859966/58099 So now I'm more confused than when I initially read your comment. Do you mean "referential tr…

It's more subtle than than "no side effects". Take Python prior to version 3, for example, which made possible the most egregious violation of referential transparency I've ever seen: `True, False = False, True`

Python code (pre-v3) that branches cannot be referentially transparent by definition because runtime context (the state of True/False bindings) is a hidden input in every boolean expression. You could have millions of lines of side effect free code and it will break completely if that one statement is run before the rest of the code.

Programmers depend on the referential transparency of keywords like "true", "false", "for", etc whether they're writing pure functional code or imperative spaghetti messes.

Re: Software Engineering principles to make teams better

#89
post #86

Earlier quoted context omitted.

I wrote it a bit tongue in cheek, but honestly, I've recently started to consider writing the first solution as a pure learning exercise. I.e. when writing a new module/feature, I lean towards getting a solution implemented quickly, fully expecting to immediately scrap most (or all) of it, and write it again. Most of the time, this happens way before the code goes into review phase, so nobody knows I've actually writ…

> so nobody knows I've actually written something twice. that's not really what a rewrite is. A rewrite is when something has already been in production, and the engineer re-do the same feature set, but refactored or rewritten in a different (possibly better, but not guaranteed) form. This rewrite takes up the time that would've been spent on something else. If you were doing a "rewrite" during implementation, but st…

[deleted]

Re: Software Engineering principles to make teams better

#90

Earlier quoted context omitted.

Can you explain in more detail? I agree that local reasoning is the end goal, but as soon as you change things (i.e. mutate) then it doesn't work anymore. Or in other words: if modifying a value has no effect on anything else, then why would you modify it? I don't get it - maybe a code example would help.

An example might be a function that takes a vector3, adds 5 to the x value, then returns the vector's length. You could model that as "make a second vector v_2 {x = v.x + 5, y = v.y, z = v.z}; return v_2.length", but if you have struct semantics, you can just do "v.x += 5; return v.length", and be confident that you're not modifying the vector that the caller has.

I see - but then you would still not have guaranteed local reasoning within the part of the code that modifies the vector.

Is that really worth it?

Also, creating the second vector should really look like "v2 = v.copy(x = x + 5); return v2.length". Or even just "return v.copy(x = x + 5).length".

Post reply on HN