Live data from Hacker News

The Design of Software is a Thing Apart

pathsensitive.com

111–120 of 124 posts

Re: The Design of Software is a Thing Apart

#111
post #91
post #29

Earlier quoted context omitted.

See my recent comment: > We need model based editing environments that will allow us to have a much richer set of software building blocks. https://news.ycombinator.com/item?id=16117668

I've had similar thoughts, notably as a way to side-stepping the composability limits of current parsing theory. But these limitation are increasingly worked around... And looking at rust, I can start to imagine a future where macros are powerful enough to support a lot of declarative coding. When coding javascript today I write code like: // can be imported, and api.router() mounted in express let api = new API(...)…

We can't and don't have to give up text.

Text is essential for humans and could be a significant part of the interface (both reading and typing).

The problem is more about the underlying unit being text.

The problematic part of text is when we just write it freely and then have to parse it back and make sense of it which has very severe consequences.

This is because in the programming environment world we are forever stuck with a "text editor" mindset.

This means we shift the complexity away from the environment and pass it on to the compiler and the programmer which is not a good place for it to be.

So you can use "nano" to write very complex programs. Some people consider that a benefit, and in one way it is. However it is also simultaneously very problematic. Because it perfectly demonstrates just how far removed the authoring tool is from the problem domain.

The way I see it is that to unlock a new generation of software development experiences there's no way but to accept that we can't forever confine the act of programming to the primitive act of writing text like a book in a text editor.

The environment needs to be much more closely connected to the problem domain so that it can further empower you to do stuff.

Re: The Design of Software is a Thing Apart

#112
post #30
post #2

the information of a program’s design is largely not present in its code And that's the problem. We need ways to make those higher level designs (~architecture) code.

I don't think it's possible (at least with today's technology). The high-level design/specification is intentionally vague; if it wasn't vague, we wouldn't need the low-level code, we could have a compiler generate it from the high-level specification. As far as we can tell, the technology that can create a piece of exact code from a vague specification is called strong AI. Heck, we don't even have a language to desc…

I think there is at least one and probably several layers between "code as is written now" and "vague intents".

Of course I could be wrong.

Re: The Design of Software is a Thing Apart

#113
post #2

the information of a program’s design is largely not present in its code And that's the problem. We need ways to make those higher level designs (~architecture) code.

I guess that is at least sort of what they are working on at VPRI. http://www.vpri.org/

Absolutely, they're probably very much at the top of people trying to solve this.

Re: The Design of Software is a Thing Apart

#114

Earlier quoted context omitted.

How do you express "X is a dead end; we tried it and it didn't work because Y, so this is Z" as a unit test? The strength of prose is that it can be used express concepts with an efficiency and fluency that syntactically-correct cannot do. Sometimes you just have to pick the right tool for the job, and sometimes that tool is prose. I think if you get too stuck on using one tool (e.g. unit tests), you sometimes get to…

Literate commit messages. The tool TRAC did a great job of surfacing project activity into timelines and exposing views like that. It's possible with GH but I'm usually the only one on projects to write commit messages that aren't dismissive like "words" or "fdsafdasfas"... soooo.... Release Notes are the best I can do for now. Bigger still, is what happens when a project spills beyond a single repo, but not even Goo…

> Literate commit messages.

That's a form of written-in-prose documentation like the OP was arguing for, and unlike writing unit tests. Documentation doesn't have to be in a separate file.

Re: The Design of Software is a Thing Apart

#115
post #19

Earlier quoted context omitted.

> But you’re channeling some crazy madness suggesting that someone would use ‘A’ to mean 65. Or just an encoding scheme.

Where 65 means ‘A’? Madness.

You could have a binary file format with a header of ABBA. You could choose to check the signature by doing an integer comparison of 65666665, 0x41424241 or "ABBA". Like I said, ASCII_A is a bit silly, but the maintenance value of extracting constant literals to constant variables with an explicit name & documentation explaining where the constant comes from is pretty solid, at least in my experience.

Re: The Design of Software is a Thing Apart

#116
post #44

Earlier quoted context omitted.

In this strawman example, perhaps. However, code is usually surrounded by other code. So you could have the 'A' in multiple places. By using an explicit identifier you are protecting yourself against typos (depending on the language, it could be a compile-time error or at worst a very clear runtime error instead of a logic error). The other benefit of ASCII_A is that you are signalling that you are doing ASCII compar…

> In this strawman example, perhaps. I'm not so sure it's a straw man, I often see defining constants like this cargo culted even if there are only one or two uses. In that case 'A' is great because it's value is right there, I don't have to look at the assignment and then go look up what the actual value is, so it's more readable. When it's used in several disparate places then ASCII_A is better and your arguments a…

It's a strawman in the sense that it's completely devoid of context with a contrived example. FWIW, I found 0 instances of something like this on GitHub (https://github.com/search?q=%22ASCII_A%22&type=Code&utf8=%E2...). I concur that cargo culting it to the extreme can lead to absurdness, but that's true of all maintenanability rules of thumb. Any rule of thumbs can be over-applied. However, in my experience the inverse is generally more true.

Re: The Design of Software is a Thing Apart

#117
post #101

Earlier quoted context omitted.

> a complex method that you feel can be explained in documentation yet not in tests, I'm happy to take a crack at writing the tests. // This implementation is unnatural but it is needed in order to mitigate a hardware bug on TI Sitara AM437x, see http://some.url (that's an obvious one; but there are plenty of other cases where documentation is easier than a test)

Turns out this is a great example of why tests are better than documentation. One way to implement this is by using two methods: one normal and one with the hardware mitigation code, with a dispatch that chooses between them. This separation of concerns ensures that your normal code runs normally on normal hardware, and your specialized code runs in a specialized way on the buggy hardware. This separation also makes…

A. You took it too literally ( maybe it's not a hw bug on some exotic processor, maybe it's a mitigation for a security vulnerability that affects a broad set of OS distros).

B. Your solution is not obviously better, it's a different trade-off. And it's not immediately apparent to me how exactly you would write the test for the affected hardware, in the first place. What if the hardware bug is extremely hard to reproduce?

Re: The Design of Software is a Thing Apart

#118
post #54

Earlier quoted context omitted.

IMO tests should never do this unless the function's role is obvious. This prevents internal restructuring (Which is bad!). What you should instead prefer is end-to-end testing. So for a lexer, you'd create a dummy program with the output of each token on a newline, and then test that the tokenizer's output matches what you expect from the input. But you shouldn't test whether the functions themselves are correct. Th…

Completely disagree here. If you test this way you'll be sure to have a correct implementation for this dummy program. Further, if the test fails you now have to try and figure out what component caused the failure. A unit test should test a specific unit; commonly a class. You should have unit tests for the interface of that unit (never private or even protected methods). This absolutely does not prevent internal re…

> If you test this way you'll be sure to have a correct implementation for this dummy program.

That's the point. If the dummy program fails then your implementation is bad.

> Further, if the test fails you now have to try and figure out what component caused the failure.

Have you heard of logging?

> A unit test should test a specific unit; commonly a class. You should have unit tests for the interface of that unit (never private or even protected methods).

This is almost exactly what I suggested. I stated 'dummy programs' for individual tests because it's more modular and closer to actual usage than mocking. If your language has an equivalent, use that.

Re: The Design of Software is a Thing Apart

#119
post #101

Earlier quoted context omitted.

Turns out this is a great example of why tests are better than documentation. One way to implement this is by using two methods: one normal and one with the hardware mitigation code, with a dispatch that chooses between them. This separation of concerns ensures that your normal code runs normally on normal hardware, and your specialized code runs in a specialized way on the buggy hardware. This separation also makes…

A. You took it too literally ( maybe it's not a hw bug on some exotic processor, maybe it's a mitigation for a security vulnerability that affects a broad set of OS distros). B. Your solution is not obviously better, it's a different trade-off. And it's not immediately apparent to me how exactly you would write the test for the affected hardware, in the first place. What if the hardware bug is extremely hard to repro…

Fair points.

A. When I encounter areas that need specialized workarounds (such as a mitigation for a security vuln) then I advocate using two methods: one of the normal condition and one for the specialized workaround. Same reasons as above, i.e. separation of concerns, easier/clearer normal path, easier to end of life the workaround.

B. In my experience tests are better than documentation for any kind of mitigation code for an external dependency bug, because these are unexpected cases, and also the mitigation code is temporary until the external bug is fixed.

Imagine this way: if a team uses just documentation, not tests, then what's your ideal for the team to track when the external bug is fixed, and also phasing out the mitigation code?

Re: The Design of Software is a Thing Apart

#120
post #84

Earlier quoted context omitted.

For example, here's one way to write a test that sufficiently explains "gets within a certain error margin of the correct answer yet is much much faster than the naive way". Using Ruby and its built-in minitest gem: 1. Write a test that does minitest assert_in_epsilon(x,y,e) 2. Write a minitest benchmark test that compares the speed of the fast function with the speed of the naive function. Notice the big advantage f…

> Exactly. We have the code file, but not any documentation separate from the code, such as notes, plans, attempts, reasoning, etc. I agree with you that it can be tested. But it doesn't explain anything about why it works, or what methods the author tried that didn't work as well. If you ever had to make it faster, or make it work better on different hardware, you'd be starting from scratch again.

> If you ever had to make it faster, or make it work better on different hardware, you'd be starting from scratch again.

Optimizations like these a great area for tests because the test files can keep all the various implementations and can benchmark them as you like.

This enables the tests to prove that the a new implementation is indeed optimal over all previous implementations, and continues to be optimal even when there are changes in external dependencies such as hardware, libraries, etc.

> But it doesn't explain anything about why it works

IMHO it does, for all the areas expressed in the original link and the parent comment.

Here are the original link examples:

1. "What [TDD] doesn’t do is get you to separate the code’s goals from its implementation details."

IMHO first write the code's goals as tests, then write the method implementations. The tests may need new kinds of instrumentation, benchmarking, test doubles, etc.

2. "[D]oes the description of what Module 3 does need to be written in terms of the description of what Module 1 does? The answer is: it depends."

IMHO write modules with separation of concerns, and with clear APIs that use API tests. If you want to integrate modules, then write integration tests.

3. "Quick! What does this line of code accomplish? return x >= 65;"

IMHO write code more akin to this pseudocode:

    return age >= US_RETIREMENT_AGE

    return letter >= ASCII_A
Post reply on HN