Hacker Newsnew | past | comments | ask | show | jobs | submit | rmckayfleming's commentslogin

It was ridiculous. He got it less than a year into his presidency.

Oh neat, I've been working with claude on an NES emulator in Racket using an SDL3 wrapper also written mostly by Claude.


"I feel uneasy about design patterns. On the one hand, my university class on design patterns revived my interest in programming. On the other hand, I find most patterns in the Gang of Four book to be irrelevant to my daily work; they solve problems that a choice of programming language or paradigm creates."

My relationship with design patterns changed when I stopped viewing them as prescriptive and started viewing them as descriptive.


Descriptive of the kinds of workarounds that a lack of proper abstraction capabilities made necessary in ancient Java.


The GoF book uses C++ and was written before the first version of Java existed.

Furthermore, the purpose of design patterns is not to introduce anything new, it’s to provide a catalog of repeatedly occurring existing patterns in software development, including the respective situations each pattern is applicable in, and their individual benefits and drawbacks. An important motivation was to name each pattern, so that when one software engineer says “builder”, the other engineers know what it means. Previously developers encountered certain patterns sooner or later, but didn’t know what to call each pattern, or each developer invented their own names, or meant different things by the same name.

The set of relevant patterns will change over time to some extent as software development changes, but that is orthogonal to the concept of design patterns. It’s a mistake to think of design patterns as specifically the set of 23 GoF patterns. Though some GoF patterns are unlikely to ever become irrelevant, like Adapter, Decorator, Composite, Proxy, Interpreter, Strategy.


Or any other major commercially used language right now?

Look, I'm glad you work in a language where you don't need to describe those things any more, but the vast majority of people still do. And for that group of people, understanding that "Design Patterns" is a dictionary, not a recipe book, is a really important thing.


What modern version of a "commercially used language" needs patterns a la GoF? Most of them simply disappear as the language is made more expressive than the horror that was pre-standard C++. Modern Java or C# are not at all like that.

It's not a bad book if you read it as positive account rather than a normative prescription, I have the dead tree version on my bookshelf, but it's also a narrow, historically-informed perspective. Nothing about patterns is a fundamental concept that persists across languages (or even time), unlike things like SICP, algorithms, CS concepts, etc.


How are (for example) Adapter and Proxy not fundamental patterns applicable in most programming languages? Many people take them for granted today and maybe don’t think about them as design patterns, and a modern description will use different examples than the GoF book, but they are patterns nonetheless, and the GoF book contributed a lot to them having universally agreed and well-recognized names.


Neither of them is a fundamental idea about programming in general, unless the only languages we are considering are Java, C#, and Python spoken with a thick Java accent.

Adapter is an OOP-ism. If you take, for example, any ML-family language, you won't find anything of the sort. Even staying in OOP-land, in a language where inheritance goes on the prototypal chain, you wouldn't solve the problem like that.

Proxy is a more general concept, but the way it's described in GoF is still tied to a class/interface/implementation mechanism. In other languages it would often just be a function. I don't know what overarching lesson you would draw from it except "write code to do things".

As I said I don't think it's a bad book, it's definitely something you should read, even just for the meta-level language it (successfully!) introduced. Where I differ is that I don't believe the book is quite as successful at transcending the "traditional" OOP mechanisms. It's mostly "how to accomplish things in Java 1.5".


> Adapter is an OOP-ism. If you take, for example, any ML-family language, you won't find anything of the sort.

This is incorrect. For example in SML you have signatures and structures, which are roughly analogous to interfaces and implementing classes in OOP. And SML functors are adapters that can adapt a structure of one signature to a different signature. Or they may create a proxy structure for a given structure. Furthermore, you could easily imagine a derived language where functors are just regular functions and structures are regular values.


I would argue that ML functors are significantly more general than Adapter as presented in Design Patterns, the transferable "big idea" being the underlying type theory (functors as high-kindered types) as opposed to the pattern.

> you could easily imagine a derived language where functors are just regular functions and structures are regular values

I'm pretty sure someone taught me this some time ago but I have forgotten it, can you do it that easily? Aren't you at least supposed to make a distinction about types and kinds? I really don't remember, I'm genuinely asking.


These are still relevant even in modern Java or C# or C++. Just because the language can express things in a more modern way doesn't mean you always will. Or should. Or can.

And I agree that it's a historically informed perspective. But guess how much code is modern code versus historic^W legacy code. Nobody is arguing (well, at least I'm not) it's a foundation of CS. Nor is any reasonable person arguing it's a normative prescription - see the comment about "not a recipe book".

It's the equivalent of a dictionary/thesaurus for a writer - necessary, but not world-changing. Always has been. Still is.


I have heard this said, mainly because some patterns can be made unnecessary with first-class functions and pattern matching. Closures are emulated with explicit objects, and the visitor pattern is equivalent to pattern matching. Something that's pretty interesting, though, is that it's a transform called defunctionalization. There's an article about it [1] that has been shared before on HN.

One form of defunctionalization is the well-known transformation of a recursive function into one that uses an explicit stack.

The thing is, I don't think defunctionalization (from the equivalent functional form) present in object-oriented languages is strictly worse. Defining things with explicit objects may sometimes be more understandable, and more extensible; for example, the command pattern could be implemented as a closure, but then you can't later add an "undo" method to it later.

Here's an example where defunctionalization makes the code more readable, not less.

Haskell has a difference list [0] data structure; the purpose of it is that you can concatenate two difference lists in constant time, and then turn it into one long normal linked list in O(n) time. This gives much better performance than concatenating lists directly all the time. It's a lot like a rope, except for lists, not strings, and it's immutable.

But the code is somewhat cryptic; it makes use of partial application and stores the tree in terms of partially applied functions. The "Demystifying DList" [0] article I shared shows a defunctionalized form explicitly defined as a tree in concrete data types.

To those interested in it, if you're familiar with the syntax of ML-like languages, I'd recommend the papers [2], [3], and [4].

[0]: http://h2.jaguarpaw.co.uk/posts/demystifying-dlist/

[1]: https://blog.sigplan.org/2019/12/30/defunctionalization-ever...

[2]: "Defunctionalization at work": https://www.cs.purdue.edu/homes/suresh/502-Fall2008/papers/d...

[3]: "Refunctionalization at work": https://www.brics.dk/RS/07/7/BRICS-RS-07-7.pdf

[4]: "Continuation-Passing Style, Defunctionalization, Accumulations, and Associativity": https://www.cs.ox.ac.uk/jeremy.gibbons/publications/continue...


There are definitely cases where a structured value is clearer than a function. But at that point you're just modelling your domain and it's not really a "command pattern" at all. The point of the command pattern is that you have an object that really and truly is just a function, you're only representing it as an object because you need to pass it around - but in that case it really is just a workaround for your language lacking first-class functions.

A good language makes it easy to use both functions-as-values and structured-objects-as-callables, and use whichever representation is appropriate to the situation.


That's a fair point; not having first-class functions is a flaw for a high-level programming language, and the command pattern is just making up for a deficiency in the case that it would never need to be anything more than a closure in a language that does have one.


Not just dirt cheap, the turn around time to manufacture was significantly lower. Sony had an existing CD manufacturing business and could produce runs of discs in the span of a week or so, whereas cartridges typically took months. That was already a huge plus to publishers since it meant they could respond more quickly if a game happened to be a runaway success. With cartridges they could end up undershooting, and losing sales, or overshooting and end up with expensive, excess inventory.

Then to top it all off, Sony had much lower licensing fees! So publishers got “free” margin to boot. The Playstation was a sweet deal for publishers.


Yea, people generally don't think about these things. People were genuinely surprised to find out that 70% of our expenses as a software business were... salaries. The next largest category? Rent. Everything else was effectively a rounding error.


I just bought a house this year, the previous owners lived in it for about 2 years from brand new. Thankfully it has an ethernet drop to every room upstairs, and in reasonable places on the main floor. Far better than the situation at the last place I lived in.

But annoyingly, it's all Cat5e! Sure, it's fine for gigabit, but now that I have proper networking equipment, I wish they'd have spent the extra few bucks and put in Cat6A or Cat7 so that I could get 10Gbps to my office from the rack in the basement...


Cat5e is rated for higher than 1gbps for lengths you're likely to find in a home.


If they didn't screw up too bad installing it (which is not a given), you may be able to tie off a new cable to it and use the existing cable as a pull.


Have you used the 7900XT with LLMs at all?


Yup, works just fine. Overall pytorch on ROCm 5.6 has been working very well. I'm impressed with how stable it is, given how much hate AMD driver stack has been getting.


same on my end, the biggest issue sometimes is finding the correct torch/torchvision version that go with different projects as AMD users are still rare. So, the problem is still the AMD ecosystem is pretty niche and will be pretty stable unless you pick a dev or wrong version, then it may happen to cause kernel panics! In any case, things looks to be improving, but rocm has a lot to support (xformers and other core ML libraries)


I do wonder how much of an impact the PS5 and Xbox Series have on this though since they both have RDNA2 GPUs. Consoles tend to face higher optimization pressure, especially as the generation wears on. It might be why AMD has kept so competitive in gaming as of late.


It's more that it's easier to use C for two reasons. The first is that C is really popular and therefore pretty portable. It's a lingua franca. The other is that because the hosts are largely defined in C, it's easier to interact with. Of course, the host doesn't actually "speak C", it follows some form of ABI. But the reality is that implementing each ABI is non-trivial and you can avoid a lot of pain by just using the host's C compiler/linker/etc. that implements it for you.


Like, SBCL compiles and assembles directly to machine code, that's very much the Lisp way. But SBCL has a lot of C that's involved in getting the SBCL image running and interacting with the host.


I know. I've been spending a lot of time with CL, Scheme, and Clojure the past few years, and the ideal Lisp is some combination of them all. There are aspects of each that I miss in the others. CL has the nicest environment and development story (generally speaking). Scheme feels more refined in the small. And although they can be divisive, I really appreciate Clojure's data structure literals.


CL is the x86 of the Lisps. Successful because of backwards compatibility, but also ugly because of it.


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

Search: