Live data from Hacker News

Evolutionary couplings between files reveal poor software design choices

ergoso.me

61–70 of 85 posts

Re: Evolutionary couplings between files reveal poor software design choices

#61
post #4

I think it is a mistake to think of coupling caused by TDD to be a false positive. What this outlines really is that TDD will force you to edit two files instead of one for many changes. This is a clear indication of how TDD will slow you down.

You'd probably see something similar when looking at a C/C++ project. I would expect significant coupling between header and source files. The solution there was for future languages to combine the two. Maybe we'll see a future language combine unit tests and source into the same file. Heh, maybe such a language would refuse to compile if public functions did not have an associated test.

> refuse to compile if public functions did not have an associated test

Sounds like my worst nightmare.

Re: Evolutionary couplings between files reveal poor software design choices

#62

There's some really interesting thinking here, but interpreting this naively would suggest that the perfect software project has only 1 file.

That's where the Cohesion metric comes into play for OO (and maybe other programming paradigms?). Aka: is each class a single cohesive unit, or do you effectively have two (or more) classes melded together with disjoint data and methods.

Something I think is particularly interesting about this approach is that it is language agnostic. It's probably even independent of "programming". It could also be useful for general documents: if I edit wiki page A and always edit B too, should they be the same page instead?

Re: Evolutionary couplings between files reveal poor software design choices

#63
> I was thinking about writing up a small application paper for this project, but I am really terrible at reading papers from the Computer Science field, let alone writing them.

Thank goodness for that. This blog post was so much easier to read then a formal paper.

Why are formal papers so tedious to read? Imagine how much time we'd waste as a group if he written this as a paper. Many of us would give up before finding the actual information, and those of us that /did/ identify the actual information would have invested a lot more time than it took to read this excellent blog post.

Re: Evolutionary couplings between files reveal poor software design choices

#64
post #3

A "correctly layered" app with UI view separate from UI logic separate from server-side logic etc. will show up as coupling, if commits are feature oriented. There's certainly a hint as to where to look for bad coupling, but expected "coupling", like tests, need to be discounted.

Tests should have some coupling, but good tests need to change less frequently than the target code. Bad tests need to change every time. It seems like there's still value to explore there.

Re: Evolutionary couplings between files reveal poor software design choices

#65
post #4

I think it is a mistake to think of coupling caused by TDD to be a false positive. What this outlines really is that TDD will force you to edit two files instead of one for many changes. This is a clear indication of how TDD will slow you down.

You'd probably see something similar when looking at a C/C++ project. I would expect significant coupling between header and source files. The solution there was for future languages to combine the two. Maybe we'll see a future language combine unit tests and source into the same file. Heh, maybe such a language would refuse to compile if public functions did not have an associated test.

No need to wait. Rust has basic unit tests inside the source files doc.rust-lang.org/0.12.0/guide-testing.html

Re: Evolutionary couplings between files reveal poor software design choices

#66

> I was thinking about writing up a small application paper for this project, but I am really terrible at reading papers from the Computer Science field, let alone writing them. Thank goodness for that. This blog post was so much easier to read then a formal paper. Why are formal papers so tedious to read? Imagine how much time we'd waste as a group if he written this as a paper. Many of us would give up before findi…

I have found that the best papers are hard to read because they’re informationally dense, so you have to slow down to really process every sentence and unpack the author’s thinking in your head—but once you do, you get a lot of knowledge from just a few pages. So it ends up being worthwhile.

Average papers are hard to read because they’re trying to emulate the style of the good papers, but without having enough actual content. The length and register of a blog post are definitely a good fit for the average essay.

Crappy papers are hard to read because they’re crappy, and recasting them into a different format would reveal that they contain no information at all. :)

Re: Evolutionary couplings between files reveal poor software design choices

#68

> I was thinking about writing up a small application paper for this project, but I am really terrible at reading papers from the Computer Science field, let alone writing them. Thank goodness for that. This blog post was so much easier to read then a formal paper. Why are formal papers so tedious to read? Imagine how much time we'd waste as a group if he written this as a paper. Many of us would give up before findi…

I have found that the best papers are hard to read because they’re informationally dense, so you have to slow down to really process every sentence and unpack the author’s thinking in your head—but once you do, you get a lot of knowledge from just a few pages. So it ends up being worthwhile. Average papers are hard to read because they’re trying to emulate the style of the good papers, but without having enough actua…

True, but it is also true that the best papers would be even better if they were written in less terse and cryptic style so that the same information could be obtained more easily.

Re: Evolutionary couplings between files reveal poor software design choices

#69
post #30
post #12

Earlier quoted context omitted.

> This is a clear indication of how TDD will slow you down. Not shown: the part where the critical production bug you introduced was caught by your test suite, thus saving you countless hours of agony, angry customers, and lost revenue.

Instead of writing tests in a separate file, why not express the same logic in the form of types in the lines directly above the code which implements that logic? This has the added benefit of making your code self-documenting and giving rise to powerful tools such as type-guided implementation inference and search.

How do you write a type which fully describes, for example, "given a user, some content, and various bits of metadata, this function transforms them into a blog post with all the data in the right places"?

Re: Evolutionary couplings between files reveal poor software design choices

#70

Earlier quoted context omitted.

I have found that the best papers are hard to read because they’re informationally dense, so you have to slow down to really process every sentence and unpack the author’s thinking in your head—but once you do, you get a lot of knowledge from just a few pages. So it ends up being worthwhile. Average papers are hard to read because they’re trying to emulate the style of the good papers, but without having enough actua…

True, but it is also true that the best papers would be even better if they were written in less terse and cryptic style so that the same information could be obtained more easily.

I’m not sure about that. For example, the first time I read them, each of these statements in the declarative specification of Hindley–Milner type inference took me a long time to unpack.

    x : σ ∈ Γ
    --------- [Var]
    Γ ⊢ x : σ

    Γ ⊢ e₀ : τ → τ′  Γ ⊢ e₁ : τ
    --------------------------- [App]
    Γ ⊢ e₀ e₁ : τ′

    Γ, x : τ ⊢ e : τ′
    ------------------ [Abs]
    Γ ⊢ λx. e : τ → τ′

    Γ ⊢ e₀ : σ  Γ, x : σ ⊢ e₁ : τ
    ----------------------------- [Let]
    Γ ⊢ let x = e₀ in e₁ : τ

    Γ ⊢ e : σ′  σ′ ⊑ σ
    ------------------ [Inst]
    Γ ⊢ e : σ

    Γ ⊢ e : σ  α ∉ free(Γ)
    ---------------------- [Gen]
    Γ ⊢ e : ∀α. σ
Each one takes a sentence or two of relatively dense English text to explain:

[Var]: If the context indicates that it has a particular type, a variable is inferred to have that type.

[App]: If a function is inferred to have some type, and a value is inferred to have the same type as the parameter of that function, then the application of that function to that argument value is inferred to have the type of the result of the function.

[Abs]: If the body of a function is inferred to have some type, given an arbitrary type for its parameter, then the type of such a function is a function type from that parameter type to the type inferred for the body.

[Let]: If an expression is inferred to have some polymorphic type, and another expression would be inferred to have some monomorphic type given that a particular name were bound to that polymorphic type, then a let-expression binding that name to the former expression within the latter expression would have the same type as inferred for the latter.

[Inst]: If an expression has a polymorphic type, and that type is an instance of some more polymorphic type, then the expression can be said to have the more polymorphic type.

[Gen]: The type of an expression can be generalised over its free variables into a polymorphic type.

But having learned this notation, I can now read and write specifications of type systems with ease, and do so much more quickly and compactly than I could in a more approachable notation. To me, that’s a win.

Of course, I’m the sort of person who finds Java programs hard to read because they seem to take so long to say anything. So opinions are going to vary on this!

Post reply on HN