9 hours ago by optymizer

The topic of how we as developers implement solutions in code has been on my mind for years.

The one insightful idea I found in this essay is that coding is a lossy one-way operation, from which you cannot fully derive the original idea or the 'theory'. That seems similar to losing information when compiling source code, making it impossible to restore the exact source code from its machine code representation.

So if we work backwards, it's: machine code (bits) -> source code (text) -> idea/solution (human thought?)

Despite losing some information, machine and source code have interesting properties, such as being able to copy them easily, transpile to different format, etc.

What I'd like to ask the HN brain is if anyone can think of another way to express a higher level thought other than language? In his essay, Naur implies that there is no such thing. I wonder if we had made any progress on that front in the 35 years that have elapsed since this essay was written.

The only thing I can think of is something like UML, which has tons of diagram types for structural and behavioral properties of a system, but I've always found it hard to 'see' the real idea they're trying to describe, in the same way how I find it hard to imagine a 4D object by looking at its 3D projections. With enough effort its certainly doable, but I wouldn't say the process is intuitive or easy, so to me, diagrams are like projections of an idea from different points of view, but how do we encode the idea/thought/theory itself?

What is it about language and apprenticeship that makes conveying ideas or theories possible? I view this process as an inefficient way of serializing an idea and transmitting it over voice to another person, who has to unserialize the sounds, convert them to words, then they have to create the associations in their brain based on the meaning of those words, and then probe into the correctness of the associations by asking clarifying questions.

Is this really the best we can do in 2020? How are other fields conveying complex abstract notions and ideas?

8 hours ago by thristian

You're butting your head against the fundamental paradox of communication: in order to communicate an idea that's in your head to somebody else, you have to encode it in a way that the other person will recognise and decode; that is, you need to already have some shared context. However, if you have a new idea then by definition it can't be part of the shared context, so it can't be communicated.

We get around this by invoking combinations of existing ideas and hoping that the recipient puts them together in more or less the right way: we might say "a leopard sits in the tree to your left", invoking the existing ideas "leopard", "tree", "to your left" and "sits", which can be combined in the obvious way. UML, musical notation, mathematics... all these are variations on "language" in the sense that they have a vocabulary of existing ideas, and a grammar of natural ways to combine them, and so you can bootstrap ideas in another person's brain by giving them pieces they already know and hoping they can assemble the idea correctly.

Language is messy and non-portable and unreliable, and it is exactly those properties which allow it to convey novel ideas from one person to another.

5 hours ago by mjburgess

We get "around" this by ostentation: words in a spoken (natural) language refer to the world.

I point to examples of trees and say "tree", etc.

"New" ideas are acquired by example -- language is not a closed system.

4 hours ago by Ma8ee

Which is harder than it sounds if you are trying to do it from scratch. Even pointing is a part of language, and trying to convey that concept is far from trivial. I think a big part of language learning in children involve the child seeing other people react to language and imitates. E.g., father points and mother gaze in the direction of finger, child follows mother's gaze.

2 hours ago by amelius

8 hours ago by kd5bjo

Ryle’s use of the term “theory,” which Naur adopts here, is a bit counter-intuitive; it’s really referring to a kind of operational knowledge.

One of Ryle’s central points is that there’s a categorical difference between being able to perform a skill yourself and knowing facts about how that skill is performed. Books, language, and observing other practitioners can only provide the latter kind of knowledge, but the former is what’s actually valuable.

Learning how to do something can only be achieved through practice. This practice can be guided and improved by rote learning, but cannot be replaced by it. Also, no two practitioners approach a skill in exactly the same way: As only rote knowledge can be transferred between people, each person builds their own structure of operational knowledge based on their particular experiences.

Naur’s argument here, then, is that this operational knowledge is dominated not by knowledge of building software in general, but instead by the understanding of how a particular piece of software functions internally and interacts with external factors. These external factors are both concrete, like protocol specifications, and abstract, like the competitive landscape the company is operating in.

Further, Naur argues that the primary value in developing a piece of software isn’t the software itself, but the expertise that the programming team had to develop in order to produce it. In this view, dismissing the programmers and keeping the software is a grave mistake that will surface when one of the external factors changes and there is noone qualified to update the software.

8 hours ago by ssivark

> What I'd like to ask the HN brain is if anyone can think of another way to express a higher level thought other than language? In his essay, Naur implies that there is no such thing. I wonder if we had made any progress on that front in the 35 years that have elapsed since this essay was written.

I think it could be argued that category theory, and categorical thinking more generally are basically in this spirit. There’s a reason why a lot of folks think it’s the best thing since sliced bread.

The basic idea is that it has a sharply crystallized notion of what it means to have an analogy, which can piggy back on top of a bunch of essential structures from math to provide a language that is very effective for communication. Of course it’s only effective in communicating with people who share enough of that context.

As an example of this spirit of using rigorous reasoning to communicate better is the Haskell motto that the existence of “design patterns” imply a failure of the language for lack of expressiveness (more of a relative statement than absolute). If your language is any good, and your understanding of the pattern is sharp enough, then you should just be able to factorize it into a library. This lends to a programming style with highly modular, declarative and terse code.

Disclaimer: I’m not a Haskell expert by any means, so YMMV.

7 hours ago by mbrock

"His hair is a flat-top; his mouth frowns in near grimace. He strides to my seat, looks down and says in a Texas drawl, 'and the key is simply this: Abstractions. New and better abstractions. With them we can solve all our programming problems.'"

— Richard P. Gabriel, “Patterns of Software”

34 minutes ago by HPsquared

More generally, there is a similar issue with deriving "meaning" from human actions. The question "what did he mean by that?"

8 hours ago by onlurking

OP here, much of this paper resonates around the knowledge we need to build a system, lot of this is like the understanding of business rules, is the context we need to build a working software in the first place.

The problem is that knowledge is mostly "tacit", and tends to grow as the software evolves. For example, several development tasks are normally completed not only based on the documented user stories, but they also carry the context from meetings or discussions that aren't documented.

When you lose the original authors of the program, it becomes very difficult to rebuild the necessary context to understand how the system works - tasks like adding new features or modifying existing behavior becomes very hard. Also in the "The Metaphor as a Theory" part, much of the work is a shared knowledge between the developers, when you have several programmers working in parallel as fast as they can, the design of the program can become highly incoherent.

Nowdays we have practices like testing which could be a really helpful companion when it comes to understanding how the system works and the expected behavior of it's parts, which can be treated as a documentation, also we have code reviews that can guarantee that any addition to the system is consistent according to the system's design if is done right.

But still, this dependency of the context it's a very hard problem to resolve.

2 hours ago by ximm

> the primary aim of programming is to have the programmers build a theory

I don't agree with that statement, but I don't think the primary aim is to produce a program either.

I believe the primary aim is to enable users to use a program. For that they need a mental model. Maintaining a consistent and simple theory among developers is a means to that end.

5 hours ago by fsloth

Peter Naur is one of the unsung(?) giants of software. His name should be instantly recognizable.

This is perhaps the best paper ever to explain the nature of collaborative program development and maintenance.

If I had a company I would make this mandatory reading for everybody - everybody, not just programmers.

3 hours ago by munichpavel

I am currently leading a topic group at work on code documentation in AI development. I was already planning to skip the lists of dos and don'ts, as well as the usual best practice language, but maybe I should just refer everyone to this gist and Naur ...

6 hours ago by akavel

The basic notion of program as theory fits into what I personally stumbled upon recently on my own. Notably, expanding on it, I like to see every execution of a program as an Experiment - in that it may support or invalidate the Theory (by manifesting bugs/undesired behaviors). I'm happy to see I'm not the first one to think of this idea. However, I am not necessarily convinced by the main claim the article seems to make based on it, that the Theory cannot be resurrected from the code of the program + documentation. I think it may be very hard, and depend a lot on many factors (quality of code, docs, the resurrecting team, their time, and as suggested, access to the domain where the program is used), but it may still be possible to a huge extent. I believe some sentences used by the author actually provide hints in support of this claim. Also, in other sciences like math or physics, albeit not easily, knowledge/theory transfer through writing can be done, or at least helped significantly.

4 hours ago by p4bl0

Very interesting article. Thanks for sharing. I think it explains very well why software developed by large IT companies¹ that puts developers after developers for a few months on their clients projects are systematically very bad, to stay polite.

[1] I refer to what are called SSII (société de services en ingénierie informatique) in France.

9 hours ago by imprettycool

I only read the abstract (first paragraph), so maybe I'm way off base here. I'm about to go to bed and want to bang this out:

I think it's three pieces that need to come together. The source, the system it's running on, and the user. You don't necessarily need all 3

1. If you only have the user and the source but not the system then you're screwed. I could print out the entire FreeBSD source and docs, go back in time to 1820 and it would be pretty much useless since I need a C compiler and a million transistors, power supply and a bunch of other stuff. Obviously this is an extreme example, since most of the time you'd just have a slightly incomplete system (e.g. crappy build scripts but you know they built it on a unix system 2 years ago) so it's usually workable

2. If it's the user and the system then that's basically proprietary software. You can reverse engineer the source. Tedious but doable

3. If it's the source and the system, then you might be able to get a new user study both and understand everything again. Depends on the complexity of the source/system and the docs.

I think of it as an organism, like it can be damaged and heal itself. There is redundancy between these 3 axes. Depending the circumstances, you can heal it or it might be permanently damaged

7 hours ago by bonestormii

This concept evokes many familiar memories of reading other people's code, which is always extremely hard. I feel multiple ways about this concept. On the one hand, I believe programs can be sectionally reduced to a inputs, outputs, and a sequence of states in between, and a programmer can understand those things well enough to extend an existing programmer competently in many cases. It must be true, because it does happen.

On the other hand, while a programmer can learn from source and documentation the wheres, whens, and whats of the program, there is always the remaining question of "Why?", which is central to this discussion. Here, I think good high-level examples of usage tend to do a good job of covering the inputs and outputs. But with regard to all of the intermediary states of the program... there is too much detail there to really document it. Those details evolve as an evolution more than a design. There is code added, then replaced or omitted entirely. Things are designed which work, but then are restructured for performance, organization, or to eliminate repetition. In these cases, there is information that is manifested in the absence of code, and the second rendering of the code better captures its function, but obscures its evolutionary history.

Here's something I've been consuming lately: https://www.youtube.com/watch?v=wbpMiKiSKm8

This game programmer (Sebastian Lague, who is excellent, by the way) walks through the development of procedural terrain generation in Unity. What's fascinating to me is the way he does it does this really effective job of "theory building". Things are implemented; results are observed; some code is deleted altogether that was only ever present to allow building up to that illustration, but will no longer be necessary at the next stage of evolution.

This is the way programmers work. Information is lost. If you weren't there to experience it at inception, only a great imagination and testing can replace it--at which point, you may find yourself actually rewriting the code, using existing code as a reference.

2 hours ago by ximm

So if reading code means reconstructing a theory, that could explain why we have so much NIH.

Daily Digest

Get a daily email with the the top stories from Hacker News. No spam, unsubscribe at any time.