Live data from Hacker News

Interfaces – The Most Important Software Engineering Concept

blog.robertelder.org

21–30 of 43 posts

Re: Interfaces – The Most Important Software Engineering Concept

#21
post #8

I think coupling and cohesion stand out as fundamental software design principles. (I wouldn't say it's "interfaces" as I can imagine interfaces with tight coupling or low cohesion.)

"Coupling" I understand, as sort of opposed to "modularity". What do you mean by "cohesion" in this context?

That the code that is stuck together forms a single unified whole instead of representing a mish-mash of unrelated ideas.

Re: Interfaces – The Most Important Software Engineering Concept

#22

Earlier quoted context omitted.

> I think statically typed languages go too far in the other direction. Tyr type and API definitions are too strict leading in a ton of unnecessary effort (ie boilerplate), increased surface area for potential bugs, and overly restrictive limits that require 'creative' workarounds to effectively write code. Given this description of statically typed languages, I'm guessing you haven't tried OCaml or Haskell.

I was specifically referring to statically typed OOP. You're right, I haven't tried OCaml or Haskell so I can't make a qualitative judgement on how easy/hard type coercion is in either.

The need for type coercion is a very good indicator of a bad design. Haskell just forces you to deal with it right now instead of never.

Re: Interfaces – The Most Important Software Engineering Concept

#23
post #17

I have been skeptical of the notion of "interface" lately. First of all, there is comment from Erik Meijer who said something like "interface without laws is useless" (he was referring to "interface" as a concept in OOP languages, and by "laws" he meant some algebraic laws). Basically what he wanted to know was the algebra, not just interface. And if you look at it from Curry-Howard correspondence perspective, where…

I somehow wanted to say that. Interface are only the surface of an algebra. Having an iterator interface doesn't mean a lot, but when you study linearly recursive structures you somehow understand the car / cdr, next / hasNext relationship. Otherwise it looks very awkward and shallow.

That said, even without this, Interfaces forces to think toward minimal assumptions which is a very important property.

Re: Interfaces – The Most Important Software Engineering Concept

#24
post #17

I have been skeptical of the notion of "interface" lately. First of all, there is comment from Erik Meijer who said something like "interface without laws is useless" (he was referring to "interface" as a concept in OOP languages, and by "laws" he meant some algebraic laws). Basically what he wanted to know was the algebra, not just interface. And if you look at it from Curry-Howard correspondence perspective, where…

Indeed, this quickly becomes obvious after writing Haskell for awhile. Lawless typeclasses just seem clunky and get less reuse compared to their lawyer'd up brethren.

You also can get a very slight taste of this in C#, Java, etc as well where larger interfaces seem clunky and get less reuse than smaller interfaces. In C#, if an interface has some nice properties, typically the extension methods on these interfaces with allow for a combinational explosion of generic utility functions. So this might be one way to judge the "algebraicness" of interfaces. You see this a lot of the LINQ collections libraries, which seem to have put some thought into laws.

Unfortunately in these languages you can only go so far due to the lack of higher kinded polymorphism (T types vs just Type types).

Re: Interfaces – The Most Important Software Engineering Concept

#25
post #12

Opinion: If interfaces is the most important software engineering concept, then the most important interface is the one used to control I/O. Different approaches. Fun to think about.

Programmer interfaces surely will look different from interfaces consumed y the general public.

Re: Interfaces – The Most Important Software Engineering Concept

#26

Hi, I'm the author. I submitted this yesterday, but I didn't even get 1 upvote, so I'm glad to see it here today as I think it is a very important topic for discussion. Feedback from the submission on Reddit has suggested that this article is too long which I now acknowledge. I'd be happy to hear any critiques you have.

Why does the line "add_numbers 3 4 = 7" qualify as part of the interface for the haskell function, while the interface part for c/python is taken to include only the name/arity/type-signature of the function?

Re: Interfaces – The Most Important Software Engineering Concept

#27
post #20

Hi, I'm the author. I submitted this yesterday, but I didn't even get 1 upvote, so I'm glad to see it here today as I think it is a very important topic for discussion. Feedback from the submission on Reddit has suggested that this article is too long which I now acknowledge. I'd be happy to hear any critiques you have.

An interface is the intersection between the system and the environment. An implementation is the system minus the interface These definitions seem at odds with each other. The first sentence would imply that the interface is part of the implementation, but the second says that the implementation and the interface are exclusive. What do you feel you gain by defining things in this way, as opposed to saying something…

Yes, this was something that bugged me as well. In the article, I touched on this by noting that it makes sense to also think of the "contract" definition of an interface. Meaning that the "contract" is really just a set of intentions or guarantees, so it doesn't really 'take up any space'. It would almost seem appropriate to use infinitesimals from calculus when trying to measure how much of the system is composed of the interface. A good interface should be clearly visible from the outside, but it should be as lean as possible to avoid overconstraining what the system can do.

Re: Interfaces – The Most Important Software Engineering Concept

#28
post #19

Earlier quoted context omitted.

"Coupling" I understand, as sort of opposed to "modularity". What do you mean by "cohesion" in this context?

The ideal is low coupling and high cohesion. That's supposed to mean your system is composed of parts that can be understood separately. Low coupling means that the innards of each module are isolated from the others. High cohesion means that each module presents a clear and distinct purpose. Thinking in terms of interfaces (in the general sense) helps towards this ideal. If an interface is cluttered with dozens of f…

> Low coupling means that the innards of each module are isolated from the others.

Isn't coupling just the complexity of the dependency graph? I would say depending on an interface is coupling as well. In my experience complex static typesystems encourage highly abstracted interfaces which are sometimes even more cancerous dependencies (that doesn't apply for really basic and practical things like Iterables which come with the language).

For this reason, IMHO an even better ideal than coding against interfaces is relying on concrete datatypes that are just a given, like structures and arrays of integers.

Re: Interfaces – The Most Important Software Engineering Concept

#29
post #8

I think coupling and cohesion stand out as fundamental software design principles. (I wouldn't say it's "interfaces" as I can imagine interfaces with tight coupling or low cohesion.)

"Coupling" I understand, as sort of opposed to "modularity". What do you mean by "cohesion" in this context?

https://en.m.wikipedia.org/wiki/Cohesion_(computer_science)

Re: Interfaces – The Most Important Software Engineering Concept

#30
post #19

Earlier quoted context omitted.

The ideal is low coupling and high cohesion. That's supposed to mean your system is composed of parts that can be understood separately. Low coupling means that the innards of each module are isolated from the others. High cohesion means that each module presents a clear and distinct purpose. Thinking in terms of interfaces (in the general sense) helps towards this ideal. If an interface is cluttered with dozens of f…

> Low coupling means that the innards of each module are isolated from the others. Isn't coupling just the complexity of the dependency graph? I would say depending on an interface is coupling as well. In my experience complex static typesystems encourage highly abstracted interfaces which are sometimes even more cancerous dependencies (that doesn't apply for really basic and practical things like Iterables which com…

Maybe my understanding is idiosyncratic, but I see low coupling as most essentially meaning that the modules interact at small and well-defined boundaries, which gives you flexibility when you want to do things with the units like test them, replace them, etc.

Depending on an interface can be a kind of coupling, sure, but I think it depends. I think abstract interfaces, or at least statically typed data types, can be great for understandable systems...

In Haskell, there's work being done on allowing some kind of module signature, so that you can have several implementations of the same API be compatible with the same source code. I'm interested to see how that will play out.

You could see a Java-style interface as a specific global name given to a set of method signatures. Using that name incurs a dependency on the library that defines it. Sometimes it makes sense to redefine the interface in your own library, and then you can use adapters to make other implementations compatible—but this is all kind of boilerplate stuff that you wouldn't need if Java was more flexible with interfaces...

Post reply on HN