Hacker News new | past | comments | ask | show | jobs | submit login

Uncle Bob in particular is a funny case. I feel like his books are largely credited as the being source those very particular OOP obsessions

But he eventually turned to the dark side. He claims clojure, a functional lisp, is his absolute favorite language.

He’s even got blog posts about it! Multiple!

I stumbled on this while reading about clojure. I really like his blog!

https://blog.cleancoder.com/uncle-bob/2019/08/22/WhyClojure....




Holub [1] helped clarify this for me. Functional programming can express patterns just as well as OOP. Implementations--idioms--of a pattern can appear different but still retain its design purpose.

Previously, I thought FP was a way to happy-path incidental habits to avoid studying every pattern. But if patterns are discovered, arise out of independently invented idioms, then the best I could do is reinvent what everyone else has found worked for them (and turned out to be a design pattern).

It has also helped me look at Gang of Four (GoF) examples less literally--if we don't have exactly these classes, it's wrong--to context matching a potential solution with a given problem.

The light bulb moment is when OS artifacts like filesystem, programming constructs like modules, and even some one-off scripts can also participate in a pattern implementation, not just having a specific constellation of classes.

[1] Holub on Design Patterns


> Functional programming can express patterns just as well as OOP.

No! Patterns are just crutches for missing language features or "design patterns are bug reports against your programming language." GoF patterns are concepts useful in OOP, but the recurring patterns and architectures you see in other paradigms are totally different. And they don't apply to Lisp: https://www.norvig.com/design-patterns/ Most don't even apply in Go: https://alexalejandre.com/programming/software-architecture-...

> visitor is type switching, singleton global variables, command and strategy are first class functions with closures, state is building a state machine with first class functions

If you could perfectly compress your code, repeated patterns would be factored away. Macros do this. In Lisp, when you find a pattern, you write code which generates that pattern, so you don't have to.

https://mishadoff.com/blog/clojure-design-patterns/

> if patterns are discovered, arise out of independently invented idioms

Yes. That's the point behind Christopher Alexander's pattern concept - he found architectural patterns which seemed to promote good social habits, happiness etc. Gabriel's Patterns of Software presents this far better than GoF. I strongly suggest you read it: https://www.dreamsongs.com/Files/PatternsOfSoftware.pdf


>No! Patterns are just crutches for missing language features > visitor is type switching, singleton global variables, command and strategy are first class functions with closures

Another aspect of FP is compositionnality.

    Singleton -> memoization of zero-arg fn (pro: initialization is implicit)
    Memoization -> fn accepting a fn and returning a memoized version
    Command & Strategy -> just a lambda then ?
Objects/classes are complex. Composing them is not simple, it means composing every single method. In fact composition is handled as a special case of class derivation, interface implementation or wrapper class implementation usually, i.e. you gotta write another class. OOP has given up on this issue from the beginning. There is no point in building a framework to create classes by composing other classes because you'll have to control how each single method compose with its counterpart. Say farewell to your neat composition expressions, the granularity is not there. Just write another class instead.


> missing language features

Yes, Holub mentions C folks had to make do with what they had--but that those implementations, despite differences, would point to one or another common pattern (or done enough times similarly to be a pattern).

> bug reports against your programming language

Yes and no. I daresay no programming language can expect to be a universal one and still have the same ergonomics as a purposeful one or even a DSL.

At the same time, with so many amazing languages out now, new language authors may see adopters clamor for features seen in those contemporary ones.

> Macros... Lisp... Clojure

Yes, definitely have tooling for boilerplate. But that also doesn't mean the pattern could have been implemented differently as yet another idiom, or written in a way that isn't idiomatic according to one group or another.

Thank-you for the references.

We've only been speaking in terms of single languages, though. Have you combined different programs together before and thought, "Hmm, this is kind of like a pattern for..."?

That would speak to the universality of patterns.


> We've only been speaking in terms of single languages, though. Have you combined different programs together before and thought, "Hmm, this is kind of like a pattern for..."?

It's metacircular all the way down. In Forth or Tcl, every command can be its own program. Deploying over many machines has similar dynamics to multithreading on one etc. The same concepts, notation etc. apply - you abstract over them and voila. Better primitive sets make things manageable, or don't.

You have reversed the point of patterns, to be a tool of thought and something to aim for. Instead, they are something you notice by a certain outcome, which guides you when you want that result again.

> Lisp ... tooling for boilerplate

That's where you've missed it. This isn't some functional propaganda; there are many paradigms, OOP and functional are just single ones. You are thinking in terms of boilerplate when these other paradigms just don't have any of it. You can even do OOP without the boilerplate - it's incidental to your tools, Common Lisp with CLOS is an OOP language. The patterns in Lisp architecture are about fundamental issues of domain modeling, how to structure teams, organizations and manage who should implement what. But you can even jump higher in scope and model that in code and "compile your company". As the code executes, at some points it will ask for user input, having an accountant do so and so action or asking a committee to assemble for something else. My company works this way.

-------

> no programming language can expect to be a universal one and still have the same ergonomics as a purposeful one or even a DSL

Yes and no. Yes, overfitting a tool to the current problem space restricts it, but DSLs can have the exact same ergonomics as any other language. Cf. Language Oriented Programming: https://beautifulracket.com/appendix/why-lop-why-racket.html


> OOP without the boilerplate

Agreed. Dr. Samek says as much too and presents an object-oriented version of C, C+, in Practical Statecharts in C/C++.

Thank-you for your replies. If you happen to see this comment, I wanted to ask about reification.

The pattern is the idea, the design reifies--"makes real"--the pattern. Something else--whether code, constellation of programs, or pigeons--implements the design.

There can be many reifications of a pattern, and there can be many implementations of a design.

Do those ideas ring true?

> compile your company

I've seen this done. Human-readable instructions coexist with SQL snippets and scripts. However, once it becomes tribal knowledge, folks may not understand it.

If manual approvals had also been processed through a pipeline instead of emails and "stop and start," it may have still been in use.




Join us for AI Startup School this June 16-17 in San Francisco!

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

Search: