I would also be skeptical of an "all-dancing" connector.
Fortunately, this isn't one of those.
The concept of "connector" is not something I came up with, it's a core concept of the field of software architecture and has been for at least 30 years.
This is the paper that the title riffs off:
Procedure Calls Are the Assembly Language of Software Interconnection: Connectors Deserve First-Class Status
282 citations so far, so probably not total BS. So basically these connectors exist in real software, and though the list may not be complete, it is pretty comprehensive. And there's the taxonomy.
My key insight is that "first class" is the wrong layer for connectors. They belong at the "meta class layer", basically in the language.
Which is where they actually have been all along. Procedure call is a connector (type), and general-purpose languages tend to have support for some form of procedure call. Data access is also a connector (type), and most languages have some way to access data.
But they tend to be monomorphic, to have support for exactly one way of accessing data, for exactly one kind of procedure call. If you want something different: good luck!
Another option would be what you describe, some really general mechanism, but with that approach you get into the problem you describe of "one size fits all" connectors: they just don't work.
So instead you define a metaobject protocol for each of the various connector types and allow many different implementations of the basic connector types that were identified by the taxonomists.
At the same time, architectural concepts really help out metaprogramming:
"I would suggest that more progress could be made if the smart and talented Squeak list would think more about what the next step in metaprogramming should be -- how can we get great power, parsimony, AND security of meaning?"
Things that implement one of the metaobject protocols can then be used (and sometimes defined) using a convenient and common syntax. So I don't just "loosen the definition" of a function call, though I do that as well, I also topple the dominant position of function calling. It's a lot looser than what you propose. Which makes it sometimes difficult to get your head around.
But then you get to model systems with any of the supported connectors (and that is open-ended) using appropriate linguistic tools.
If something is appropriately modeled as a dataflow system, you can conveniently express a dataflow system, without having the shoehorn that into the syntax and semantics of function calling.
If something is appropriately modeled as data access, you can conveniently express a data access system, without having the shoehorn that into the syntax and semantics of function calling.
You can combine these.
The common metaobject protocol means that any abstraction that you can make fit one of the provided protocols gets to participate, gets the convenient syntax.
Steve Sinowsky wrote: "Does developer convenience really trump correctness, scalability, performance, separation of concerns, extensibility, and accidental complexity?"
Turns out that in many if not most cases, it empirically does. How about we don't have to choose?
In addition, when you adhere to these metaobject protocols, you also get syntactic composability. The interfaces are compatible, so you can plug them together. It does not guarantee semantic compatibility, just like the fact that you can plug any Unix filters together does not guarantee that they do something useful together. But you can plug them together without additional glue code (just the pipe operator | )
> start building real programs and seeing how they do in the field.
Been there, done that, bought the T-Shirt. That's why this has been a very long time coming: you need the meta-abstraction, with which you build abstractions, with which you build actual frameworks/libraries/systems.
And you don't know what the right meta-abstraction is at the start.
As I said, if you pull it off, you'll be celebrated by me all the more for the fact that it was hard. I just don't have time to verify whether it actually is.
(I feel the same way about quantum computing, for instance; I'm skeptical, but if someone builds one, I'm not going to insist it doesn't exist, I'm going to give them more credit for doing something hard.)
If you don't think about it, it just does what you expect it to do. And if you look at the details, it also makes sense. This is explained in section 3.
It turns out that → is not the actual connector. In software architecture, the connector does not directly connect components. It goes via the ports on the component(s), which are "connected" (different kind of "connected") to the roles on the connector.
Nominally, the → does this hooking up, so in theory it goes something like this:
So the → "really" hooks up components to connectors via their respective ports and roles, it's not the connector and does not represent the connector. So there are no different semantics, it's always "please hook up this port to this role".
For the vast majority of cases, this much detail is way too cumbersome, which is probably one reason architecture description languages did not catch on. Fortunately it is also unnecessary in the vast majority of cases.
Objective-S takes advantage of this by making → polymorphic. So you can leave out the ports, the roles and often even the specific connector, and → figures it out anyway, filling in the blanks. This has been working extremely well so far.
If either it becomes necessary because there is ambiguity or you want to document what's going on, you can specify all these intermediate elements that → figures out for you.
I have thought about a syntax to make connectors explicit and still look like connectors, something along the lines of
filterA -pipe-> filterB
So you put the name of the connector inside the arrow. But it seems a bit wonky and so far just hasn't been proved necessary.
Fortunately, this isn't one of those.
The concept of "connector" is not something I came up with, it's a core concept of the field of software architecture and has been for at least 30 years.
This is the paper that the title riffs off:
Procedure Calls Are the Assembly Language of Software Interconnection: Connectors Deserve First-Class Status
https://insights.sei.cmu.edu/library/procedure-calls-are-the...
So if you're going to argue that the concept of connector is ill-founded, well good luck with that.
The taxonomy is also not mine:
Towards a taxonomy of software connectors
https://dl.acm.org/doi/10.1145/337180.337201
282 citations so far, so probably not total BS. So basically these connectors exist in real software, and though the list may not be complete, it is pretty comprehensive. And there's the taxonomy.
My key insight is that "first class" is the wrong layer for connectors. They belong at the "meta class layer", basically in the language.
Which is where they actually have been all along. Procedure call is a connector (type), and general-purpose languages tend to have support for some form of procedure call. Data access is also a connector (type), and most languages have some way to access data.
But they tend to be monomorphic, to have support for exactly one way of accessing data, for exactly one kind of procedure call. If you want something different: good luck!
Another option would be what you describe, some really general mechanism, but with that approach you get into the problem you describe of "one size fits all" connectors: they just don't work.
So instead you define a metaobject protocol for each of the various connector types and allow many different implementations of the basic connector types that were identified by the taxonomists.
At the same time, architectural concepts really help out metaprogramming:
"I would suggest that more progress could be made if the smart and talented Squeak list would think more about what the next step in metaprogramming should be -- how can we get great power, parsimony, AND security of meaning?"
https://lists.squeakfoundation.org/pipermail/squeak-dev/1998...
Things that implement one of the metaobject protocols can then be used (and sometimes defined) using a convenient and common syntax. So I don't just "loosen the definition" of a function call, though I do that as well, I also topple the dominant position of function calling. It's a lot looser than what you propose. Which makes it sometimes difficult to get your head around.
But then you get to model systems with any of the supported connectors (and that is open-ended) using appropriate linguistic tools.
If something is appropriately modeled as a dataflow system, you can conveniently express a dataflow system, without having the shoehorn that into the syntax and semantics of function calling.
If something is appropriately modeled as data access, you can conveniently express a data access system, without having the shoehorn that into the syntax and semantics of function calling.
You can combine these.
The common metaobject protocol means that any abstraction that you can make fit one of the provided protocols gets to participate, gets the convenient syntax.
Steve Sinowsky wrote: "Does developer convenience really trump correctness, scalability, performance, separation of concerns, extensibility, and accidental complexity?"
https://darkcoding.net/research/IEEE-Convenience_Over_Correc...
Turns out that in many if not most cases, it empirically does. How about we don't have to choose?
In addition, when you adhere to these metaobject protocols, you also get syntactic composability. The interfaces are compatible, so you can plug them together. It does not guarantee semantic compatibility, just like the fact that you can plug any Unix filters together does not guarantee that they do something useful together. But you can plug them together without additional glue code (just the pipe operator | )
> start building real programs and seeing how they do in the field.
Been there, done that, bought the T-Shirt. That's why this has been a very long time coming: you need the meta-abstraction, with which you build abstractions, with which you build actual frameworks/libraries/systems.
And you don't know what the right meta-abstraction is at the start.
This has been a LOT of work.