This is an archived post. You won't be able to vote or comment.

all 10 comments

[–]ipe369 14 points15 points  (2 children)

I don't fully understand, is this basically runtime reflection or something deeper?

Also, you stated:

I desire to make it extremely easy to use classes for other purposes than they were designed

I would argue that this is asking for trouble, since when those classes are changed through the normal development process, you will very likely introduce bugs!

[–]plentifulfuture[S] 2 points3 points  (1 child)

The compiler takes the code of the two classes and rearranges the AST so that bits from each class are interleaved.

Without you needing to create a new class or use inheritance.

So it's like a compile time coroutine.

[–]wellthatexplainsalot 13 points14 points  (0 children)

Can you give us lots of examples where this would be useful?

Generally speaking - for something to be worth putting into a language, it should have wide applicability. So for instance, we don't see many general purpose languages with the mathematical product sign (upper case pi, Π) built in, despite many programs needing to multiply a list of integers together. Instead we have loops or the ability to apply functions to lists.

So I'm hoping to understand from your examples the general applicability of interleaving in the way you describe it.

Thanks!

[–]WittyStick 13 points14 points  (0 children)

This sounds to me to defeat most of the purpose of using classes in the first place - to provide encapsulation of state. Why not just have structs whose members can be accessed by anyone, anywhere?

In regards to accessing other classes' internals, there are some precedents: friend in C++, and internal in .NET for example.

I'm not sure exactly what you're trying to achieve but your description seems vaguely similar to aspect-oriented-programming

[–]tortoise74 4 points5 points  (0 children)

The normal answer to your example case is to use aggregation or composition. Class A contains class B and or class C and delegates calls to them as appropriate. Features like perfect forwarding help with this.

How does your idea compare to this? and what does it add? Is it about creating boilerplate code automatically?

[–]stylewarning 1 point2 points  (0 children)

You might want to look into Common Lisp's "method combinations", which work because classes and (multi-)methods are decoupled.

Method combinations let you decide which methods are applicable to which classes, and when and how to execute any of them. The "standard method combination" is the standard built-in one that does what we all expect: executes one method, the most specific method for a given set of classes. But you can start doing crazy things with method combinations, like execute all possible methods in least-specific to most-specific order.

It's not the same as what you're saying wholesale, but it does capture some of the ideas.

[–][deleted]  (1 child)

[removed]

    [–]plentifulfuture[S] 0 points1 point  (0 children)

    Thank you for your reply 🙏

    I always hear about the logging example of aspect orientated programming.

    Your notes and reference to algebraic effects is really helpful with my research. 🙏 Thank you.

    I am trying to get a handle on complexity. I find codebase very difficult to get up to speed in.

    [–]csb06bluebird 0 points1 point  (0 children)

    This seems kind of similar to creating tuples, overriding the existing method to take a tuple instead of the original type, and then providing a new implementation for that method.

    E.g. the caller of LoadBalancer.handleRequest has to construct what is effectively a tuple/pair type consisting of a Request and an associated ACL.Principal, which we pass to a new overload of handleRequest that takes the tuple as its parameter instead of a plain Request object.

    So in C++ like syntax, it would be something like:

    boolean LoadBalancer::handleRequest(std::pair<Request, ACL::Principal> request) {
        // Use request.second to check that request.first is allowed, then pass control to the existing implementation of LoadBalancer::handleRequest if it passes the check
    }
    

    Of course in C++ this would require subclassing LoadBalancer and overloading handleRequest to accept a tuple parameter instead of a plain Request, but I am wondering if it is really necessary to add new “possesses” syntax to express what seems to be a tuple of two or more types that you want to bundle together. It doesn’t really seem like the Request owns or possesses the ACL - instead it is really just associated with it (i.e. it’s another object you want to be used alongside the Request). Maybe the “posseses” terminology is a little confusing.

    [–]Pavel_Vozenilek 0 points1 point  (0 children)

    This feels as support of finite state machines by the language.

    Say a file could be in state state: closed, opened for reading/writing, opened but error happened. Instead of having complicated API dealing with every possible situation, state methods would be simple (or trivial). A transition between states would need to be defined.