Spinning off a new thread because I really like this comment:

https://cybre.space/@jauntywunderkind420/104956363785764927

<< What I do see as a pure virtue that stood for something clear was 9p. Expose your state. Let it span systems. Use common os tools to manipulate state. >>

I like this because I think "expose state and use common tools" is a key design principle in big systems that work (eg, HTTP / REST) - but it also seems the opposite of OOP's "hide state" mantra.

Do we know why?

@jauntywunderkind420 @enkiv2 @byron

JauntyWunderKind (@[email protected])

@[email protected] @[email protected] @[email protected] I take to think those examples are good but also kind of irrelevant. They had good characteristics but only some aspects, amid a lot of things going on. It's too complicated to be clear. What I do see as a pure virtue that stood for something clear was 9p. Expose your state. Let it span systems. Use common os tools to manipulate state.

cybre.space

@jauntywunderkind420 @enkiv2 @byron

Eg: I think hiding state is important too! There are many secrets we have to keep private, everything would fall apart if we didn't have information hiding as a key abstraction.

But... for getting things working, it feels like "let sealed objects handle everything" just kind of... doesn't work, because programmers always do bad things in their objects and never fix them, and so exposing state seems to be the only way we can route around bad programs?

@jauntywunderkind420 @enkiv2 @byron

Or is it more like "expose all state *that was transmitted to you*, and don't hide any inherited state?" Because that's usually data loss.

I don't know. I really don't know. Nothing much about what actually historically happened with these technologies seems to make sense.

Smalltalk was all about messaging, and was inspired by ARPANET, but the early Web doesn't seem like it was at all Smalltalky, though it was extremely ARPANETty. Do we understand why?

@jauntywunderkind420 @enkiv2 @byron

The Web 1.0 wasn't built on Javascript, but the 2020 Web is built on Javascript over CSS over SGML over HTTP over (webapp server) over SQL - at least six completely separate syntax / semantic layers. This seems non-optimal.

What if we removed everything except the somewhat-Smalltalky Javascript?

Could we rebuild the Web on just JS? Would it be better? It would be reasonably trivial to try, because Node.js would be the webapp server.

@jauntywunderkind420 @enkiv2 @byron

Alternatively, if rebuilding the entire Web on Javascript message sends (modulo maybe a NotUnderstood facility like Smalltalk had, or whatever else might be needed) demonstrably *doesn't* work, maybe because it's true that state needs to be exposed in some reliable manner...

.. could we go the other way, build a full-stack programming language on an analog of HTTP/REST?

Why or why not?

If 'not' to either of these, what are we missing?

@jauntywunderkind420 @enkiv2 @byron

One thing that has always bugged me deeply about OOP is that although it's supposedly all about messages, there is no standard or reliable way to represent 'just a chunk of structured data'.

I mean, you *could* conceivably represent 'a foo with parameters bar, baz' as something like

new foo(bar,baz)

or (something).foo(bar,baz)

but.... those aren't really defined in any sense, and aren't good for large messages (kilobytes to gigabytes).

Do we know why?

@jauntywunderkind420 @enkiv2 @byron

You'd *think* that since constructors are a pretty universal part of OOP, that every conceivable data type or structured message WOULD be an instance (sic) of

new foo(bar,baz)

BUT

that just gives you a local reference to an instance of foo

Once you've got that reference... how do you communicate it to another system? It's not a 'message' in any meaningful sense now. Messages can be 'sent'. Objects... are not designed to be 'sent'.

It feels incomplete.

@natecull @jauntywunderkind420 @enkiv2 @byron Talking about method calls as "messages" is something that came out of Smalltalk, and is in my opinion incredibly misleading.

I've had debates with people online who strongly claim there is a difference between method calls in most Java-style object oriented languages and something like Smalltalk that talks about "messages". Most of the arguments seems to revolve around the idea that you can send messages (i.e. call methods) on instances that have not previously been declared to support such method calls.

At the end of the day, it all boils down to dynamic vs. static dispatch. But even for dynamic dispatch, referring to method calls as "messages" does nothing but confuse users and make it seem to complex than it actually is.

@loke @natecull @jauntywunderkind420 @enkiv2 @byron C++ and subsequently Java made that mistake in understanding,, as event based gui systems were not widely experienced yet. . messages are more like events than method calls. you can think of it as tthe difference between desugaring to
sendmsg(objectId, methodname, params) : void
vs
methodname(objectpointer, parans) : somevalue

the difference seems subtle but the former, with an extra level of indirection guves the dispatcher more freedom

@zensaiyuki @loke @natecull @jauntywunderkind420 @enkiv2 (Finally coming back to this discussion...) It's fascinating how syntactic sugar can matter. It seems C++/Java sort of said "oh hey, if message passing is implemented as method calls, why not just build an OOP language using method calls directly?"

But exposing that implementation detail, so ironically, limits what can be done -- like why OOP prefers setters/getters to direct variable access: so implementations can change.

@zensaiyuki @loke @natecull @jauntywunderkind420 @enkiv2 It's fascinating how I see both web development and game engines using message passing and event paradigms. Clearly it can be efficient enough, and it's a really flexible approach.

This leads me to why I think CORBA sucked (I remember trying to learn it, sounded neat but was a nightmare in practice) and the web isn't C++ style OOP.

The C++ era OOP idea was coupling methods to data, which is super limited vs. message passing.

@zensaiyuki @loke @natecull @jauntywunderkind420 @enkiv2 This is why we see this OOP vs FP stuff I think: the original Smalltalk idea (I think???) was that data types weren't inherently coupled to a class. You just send the data and it decides whether to react and how.

By coupling methods to data suddenly you have all these "design patterns" to play twister around the way different classes want to interact with the data, versus in FP where a function can just operate on data if it knows how.

@zensaiyuki @loke @natecull @jauntywunderkind420 @enkiv2 In a sense polymorphism is a limited version of what true message passing offers, where message passing just says "you send a message, no guarantee how it will be received" and polymorphism says "whoah, that sounds way too free, how about we just let you sometimes create different methods with the same name and pretend you have one slightly flexible method?"

@byron @zensaiyuki @loke @jauntywunderkind420 @enkiv2

I feel like a few things changed from the original OOP idea of "message sending":

1) The introduction of classes (or prototypes) as a way to answer 'what the heck kind of thing am I sending a message to, and what will it do?' Functional programming has a similar problem and 'types' is FP's answer. Both answers have problems.

2) Removing 'NotUnderstood' and making a message *instantly do a thing* instead of *be data that can be parsed*.

@byron @zensaiyuki @loke @jauntywunderkind420 @enkiv2

Re 1) I think we need a much more flexible idea of 'contracts' to replace both classes/prototypes and types. We need to be able to probe, prove and constrain what an object will do in response to messages (or else all security and testability dies in fire). But 'this is a Thing X, child of Thing Y' is far too simplistic.

1a) 'Inheritance' I think came from AI and 'frame logic' and I'd like to see more digging into that ancient idea.

@byron @zensaiyuki @loke @jauntywunderkind420 @enkiv2

Re 2) I want to see messages which are proper objects and can be stored, filtered, re-routed, created, etc. You can't do most of that with 'methods' in most post-Smalltalk OOP systems. I don't even know how easy it is to reify a message as an object in Smalltalk. But messages being inspectable objects that can be changed in transit is *exactly* what made both TCP/IP and the Web work. It's also the Net's biggest security flaw.

@byron @zensaiyuki @loke @jauntywunderkind420 @enkiv2

But, eg, since OOP is usually used alongside the GUI message loop, it's always shocked me that the message loop almost never operates on anything that remotely resembles an OOP 'message'.

Here's a programming paradigm based on 'objects send events', implemented in a programming language based on 'objects send messages' - but messages themselves aren't events! Madness!

@natecull @byron @zensaiyuki @loke @jauntywunderkind420 @enkiv2 Depending on exactly what you mean, this is either already being done in some systems or likely impossible.

How familiar are you with Java enterprise development? Due to how miserable Java is, the name of the game is to avoid writing Java. This has led to some very unusual systems emerging, some of which sound kinda like what you're proposing.

@natecull @byron @zensaiyuki @loke @jauntywunderkind420 @enkiv2 On the other hand, if what you are proposing is object oriented networking, then it's unlikely to succeed. Consider the simpler problem of transmitting an object: this was tried and has serious problems, especially if you want a wire format that isn't pure madness.

Maybe something like this is possible with some new ideas though.

@natecull @byron @zensaiyuki @loke @jauntywunderkind420 @enkiv2 The general consensus these days is to abandon OOP entirely, either explicitly or implicitly. It's being replaced by functional programming and sending either streams of fundamental data or structs (sometimes called data classes, since many are still in denial about this trend).

Admittedly, the "OOP" found in Java and the like isn't true OOP...

@urusan @byron @zensaiyuki @loke @jauntywunderkind420 @enkiv2

Yeah, I seem to be watching the functional programming people slowly and haltingly reinvent the idea of "object" but call it a "record". Since eventually, once they make contact with real data, they find that all their functions need to operate on something that is a "key-value structured chunk of data that also maybe has an overall type" and... that's what an object is.

@urusan @byron @zensaiyuki @loke @jauntywunderkind420 @enkiv2

But maybe the functions that operate on a record don't need to be quite so closely bound to it as OOP tried to do.

I think we need to be able to take a record of type X created by person A and then have persons B, C, D in different systems run their own functions against that record. And OOP's encapsulation philosophy really doesn't want us to do that. OOP doesn't think data travels between systems

(Newt voice)

but it does

@natecull @byron @zensaiyuki @loke @jauntywunderkind420 @enkiv2 There's at least 4 big problems with OOP and transmission/serialization:
1. Your point out here, you can't really encapsulate/hide what you serialize.
2. Objects form a graph (it's even called an "object graph") which is hard to serialize and has identity issues
3. You have to serialize the type too
4. There's often disagreement over what a type is

@natecull @byron @zensaiyuki @loke @jauntywunderkind420 @enkiv2

If you can't hide internal state from the network, then it can be altered between point A and point B. Maybe you could do something that works in practice using cryptography, but then your format is not at all readable, and it's still possible to alter, just much more difficult.

This necessitates machinery for deserialization, validation, etc.

@natecull @byron @zensaiyuki @loke @jauntywunderkind420 @enkiv2 Problems 2 and 3 aren't that interesting, but the straightforward solutions to them are very inelegant and quite expensive. Plus, you'd have to get everyone to agree on types and identification systems, no small feat
@natecull @byron @zensaiyuki @loke @jauntywunderkind420 @enkiv2 The 4th problem is the most severe. The two ends of data transmission could be very far apart in time, especially since you could store serialized data and read it back at any time. The class could have changed dramatically between when you serialized the object and when you deserialized it again. If they disagree, who's right?

@urusan @byron @zensaiyuki @loke @jauntywunderkind420 @enkiv2

Oh yeah that's another good problem with object systems with orthogonal persistence - if classes are code, then, that code is gonna go through revisions, and each time you push out a new revision of your code, whoops, what happens to all your already saved or published objects? You might have completely redefined what that class does.

I've never seen an OOP language that even *admits* that this problem exists.

@urusan @byron @zensaiyuki @loke @jauntywunderkind420 @enkiv2

(which is why most of them just vaporise all objects as soon as a process closes, because those things are just toxic waste)

@urusan @byron @zensaiyuki @loke @jauntywunderkind420 @enkiv2

Like I GUESS you could approach this cryptographically. Have the 'class identifier' of an object be a secure hash of its class's source code or bytecode.

But now all your persistent objects are extremely fragile and might as well be in-RAM and vaporised on process exit.

@urusan @byron @zensaiyuki @loke @jauntywunderkind420 @enkiv2

Which is why I think instead of a 'class' we should have some kind of set of type-like identifiers more like contracts or interfaces. If an object is tagged X, then it returns Y (and/or modifies itself with delta-set Z) when you feed it an X-like message. Defined in some minimal way.