-
Notifications
You must be signed in to change notification settings - Fork 556
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC] Object method message passing syntax #1160
Comments
If we need language support for this then, to my mind, the nicer syntax of the two would be: receiver@(symbol, arg0, arg1) If #1154 lands, then Although I note what you say about having the symbol string as the last parameter, placing it first seems more natural to me. |
If #1161 lands, second syntax will become viable. It would only cost a ".toString" call which should not allocate in the general case. So it is an overhead I'm willing to pay |
Added a commend about how it can help with the constructor of different name issue. |
Yes, that's a point worth making as the current situation of not being able to directly call a parent constructor with a different name using Another thing I noticed recently is that one can have both a constructor and a static method with the same signature - apparently the last one to be declared always wins! |
This is by design, and is one of the things I really don't like. It defeat the point of named constructors in some way... class Foo {
construct foo() {} // That creates `static foo()` and `"init foo()" so that it is not accessible by normal means
} So what you are probably trying to do is: class Foo {
construct foo(...) { foo(...) }
foo(...)
} |
There's actually a fix for it, namely #820, which is how I came to notice it in the first place. Not sure why this wasn't merged into Wren 0.4.0 unless there's some problem with it. |
For me that behavior is broken. It would make more sense to have them as a regular function. It would be callable from constructor by normal mean, and would allow to create some constructors and modifiers in one go. |
I implemented the Thought there is something that I don't really like. class Foo {
static foo() { "bar()"() }
static bar() { }
} This should technically be valid, but it is too much complicated for the compiler, because of string interpolation. Using the class Foo {
static foo() {
@("bar()") // This feels more awkward to me than
."bar()"() // that
}
static bar() { }
} I'll probably will not bother for wren, and only allow them with an explicit receiver. |
Why don't you just specify that if the If nothing else, that will prevent people from mixing it up with ordinary strings. |
For wren, I'll remain simple and impose explicit receiver. The thing is that, by allowing the |
I just thought about another syntax that is a mix of both: receiver.@"method"(args)
@"method"(args) // implicit this More interesting? |
I hadn't really thought it through before but if This is because if people could write
|
True, and interesting. Thought it would mean the support for full fledged expression would need to be added. So |
Yeah, logically the method signature would have to be an arbitrary expression which evaluated to a string. It starts to get a bit complicated though as you could have function calls and all sorts of stuff in that expression. Having said that, even if you restricted it to string literals you could still have arbitrary interpolated expressions within that! As long as it's manageable, perhaps this sort of complication isn't a bad thing as it gives folks more freedom to define the method signature. However from an aesthetic viewpoint it's not so nice. One thing you could do would be to restrict the expression following |
If we take the simple example of the visitor pattern, it make the thing a
little bit more simple. The visitor can directly dispatch, enforcing some
method name convention. Like `visitor@"visit%(receiver.type)"(receiver)`.
It is a double edge sword, since there is a direct correlation between the
method name and type, but it is good for the simplicity it brings.
|
I'm not sure the average user of an embedded scripting language would be sufficiently versed in OO design to consider stuff such as the Visitor pattern but I agree it could make things simpler for those who are. |
I'm debating to add the |
If it's not too difficult, I think I'd add it for completeness sake. Incidentally, I'm pleased you mentioned the Visitor pattern as it gave me an idea for a new Rosetta Code task. Whilst I've used this pattern in the past in C#, I haven't used it in Wren so it was quite interesting to code some examples :) |
With the implementation of the |
Hmm, one thing I've found with several of the Gang of Four patterns is that they seem great in theory using simple examples. But when they collide with the reality of a complex application it can be a different story making one wonder whether it's better just to slog through repetitive (but simple) code and forget about the pattern. |
@PureFox48 why did you not consider doing They are conceptual tools that works great. But usually, they are not used as this, and are usually blend with many other considerations. |
If you're talking about the RC Java example, I did consider it but, as the actions were very simple, I decided instead to have a single method which checked the run time type of the element and then performed the associated action. In a more realistic example, the actions would be more complicated and I'd then have separate methods for each element type. |
Well, since it is somehow teaching material, I think you should reconsider. But, I'm not forcing you. |
The C# example uses different 'visit' methods for the There are, in any case, likely to be a wide range of task solutions as many of the languages used on RC are not OO at all. It will be interesting to see how they approach it. |
About handling |
Wow, that's a lot of extra opcodes! Is the reason why you need so many because you're trying to get good performance? In C# for example, the last time I looked, it was taking about 5 times longer to call a method via reflection as it was to call it directly. The devs (and by and large the users) just accept this penalty as it's not something that needs to be done very often. |
No, it is to mirror how |
I have the implementation done. It is integrated inside #1006 (because it obviously use it for method mirroring invocation). I can split both on demand. |
Hi,
One of the last features that retains me from updating #1006, is that I lack a way to implement method invocation. While ideally it should look like:
some_method_mirror.call(receiver, args)
there are some technical issues that forbid to do that in a module (basically I need at minimum a primitive or language support). And that issue makes me struggling since a while.
One idea that came to my mind (after viewing a video about OOP today), would be to add language support for that feature.
I think about 2 ideas for the syntax:
Implementation wise, it would more sense to have the symbol string as the last parameter. So the opcode would not need to shift all the arguments on the stack after resolving the symbol index. But these syntax feels quite natural.
With the first syntax, since the symbol is evaluated as a regular value, it must be inside the parenthesis to avoid parsing hell problems with mixed getter/setter syntax shown in the following example:
The second syntax has the advantage of not consuming a token for that feature. But cost the allocation of a string in what I consider it the more general usage. edit Thinking at it again the syntax is viable, by optimizing the string interpolation implementation and
String.+(_)
(which are really under optimized right now...)edit: It should help to solve a not solvable problem of the constructor syntax. Because of the way constructors are implemented, you can't call a constructor named differently. With
super
, we end up having chains ofconstruct new
which defeat the point of having named constructor. It is a secondary usage that I would not recommend, and usesuper
where possible, but it at least gives a solution to that problem.The text was updated successfully, but these errors were encountered: