Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I started teaching undergraduate computer science courses a year ago, after ~20 years in various other careers. My campus has relatively low enrollment, but has seen a massive increase in CS majors recently (for reasons I won’t go into) so they are hiring a lot without much instructional support in place. I was basically given zero preparation other than a zip file with the current instructor’s tests and homeworks (which are on paper, btw).

I thought that I would be using LLMs for coding, but it turns out that they have been much more useful as a sounding board for conceptual framing that I’d like to use while teaching. I have strong opinions about good software design, some of them unconventional, and these conversations have been incredibly helpful for turning my vague notions into precise, repeatable explanations for difficult abstractions.





I found Geoffrey Hinton's hypothesis of LLMs interesting in this regard. They have to compress the world knowledge into a few billion parameters, much denser than the human brain, so they have to be very good at analogies, in order to obtain that compression.

I feel this has causality reversed. I'd say they are good at analogies because they have to compress well, which they do by encoding relationships in stupidly high-dimensional space.

Analogies then could sort of fall out naturally out of this. It might really still be just the simple (yet profound) "King - Man + Woman = Queen" style vector math.


That's essentially the manifold hypothesis of machine learning, right?

> I have strong opinions about good software design, some of them unconventional

I'm jealous of your undergrads - can you share some of the unconventional opinions?


Another principle that builds on the other two, and is specifically applicable to Java:

- To the greatest extent possible, base interfaces should define a single abstract method which allows them to be functional and instantiated through lambdas for easy mocking.

- Terminal interfaces (which are intended to be implemented directly by a concrete class) should always provide an abstract decorator implementation that wraps the concrete class for (1) interface isolation that can’t be bypassed by runtime reflection, and (2) decoration as an automatic extension point.


I’m required to teach DSA in Java, so I lay down a couple rules early in the course that prohibit 95% of the nonsense garbage that unconstrained OOP allows. Granted, neither of these rules is original or novel, but they are rarely acknowledged in educational settings:

1. All public methods must implement an interface, no exceptions. 2. The super implementation must be called if overriding a non-abstract method.

The end result of strict adherence to these rules is basically that every feature will look like a GoF design pattern. True creative freedom emerges through constraints, because the only allowable designs are the ones that are proven to be maximally extensible and composable.


but sometimes that is not worth it... IOW, it optimizes only to a couple of variables.

it's important not to lose sight of the ultimate goal: to get the machine to do what we want with the least amount of total human attention throughout the entire lifetime of the software.

it's a typical trap for good/idealist programmers to spend too much time on code that should already have been re-written, or not even written to begin with (because faster iteration can help refining the model/understanding, which in turn may lead to abandoning bad paths whose implementation should never have been refined to a better quality implementation).

i think it's a more important principle to always mark kludges and punts in the code and the design.

IOW sloppiness is allowed, but only when it's explicitly marked formally in code, and when not possible, then informally in comments and docs.

but then this entire discussion highly depends on the problem domain (e.g. on the cost of the various failures, etc).


I don’t completely disagree, just like 90%. Junior developers typically aren’t taught the design patterns in the first place so they dig deeper holes rather than immediately recognizing that they need to refactor, pull out an interface and decorate/delegate/etc.

I’m also going to point out that this is a data structures course that I’m teaching, so extensibility and composability are paramount concerns because the interfaces we implement are at the heart of almost everything else in an application.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: