Open leafo opened 8 years ago
I feel that adding this special-case syntax would make Moonscript code less readable and harder to maintain. (If we get into a habit of adding such special-case syntax, Moonscript might end up looking quite a bit like C++.)
The '@\counter\increment!' syntax looks erroneous, and seems to me to be calling a function on 'self' such as
self.increment counter
or
@counter\increment!
Right now, one would expect the function call to relate (mostly) to the item which directly references it, not the items three or four steps up the call chain:
something\hello.world\okay 5, 4, 3
Personally, I would (mistakenly) expect the above to be the same as:
something\hello!.world\okay 5, 4, 3
And adding this new syntax opens up some really-hard-to-find bugs such as if I meant to type the above, but forgot to put in the (!).
In my opinion, this potential addition would make reading code too complicated. I am a strong supporter of the Pythonic style: simple and clear without lots of special cases.
I propose a syntax that is dissimilar to the current chain syntax:
class MyThing
extra: {
write_title: (e, title) =>
print "title:", title
}
some_method: =>
@->extra->write_name "hello"
-- or even a different syntax that uses '::' since ':' in Lua passes the 'self' param.
-- so '::' could be read as meaning 'keep passing down ____'
some_method2: =>
@::extra::write_name "hello" -- @.extra.write_name(@, extra, 'hello')
because the member to the left of -> is being 'passed' down (to the right) to the function call. This new syntax would help prevent any I-forgot-to-press-* mistakes., and I think it looks nicer than having a bunch of already-used symbols next to each other.
Here's something I'm considering, feel free to leave any feedback:
The
\
operator is used to control the receiver (first argument) of a function that you're calling on a table. This is how we work with methods. Currently:Is equivalent to:
What if the
\
operator could be chained to accumulate multiple receivers. The proposed addition would look like thisWould compile to
Each name that appears before a
\
would be a receiver.Additionally, bound functions will also work:
Compiles to (about):
With
@
and a class:Note we have to use
@\
since@extra\write_name
is already common syntax.conflicts
No conflicts, this syntax currently throws a compiler error (oops)
The
@\
approach for calling a method could be considered a minor conflict.use case
I see this as a different way to think about mixins. Typically I've encouraged copying functions into classes/tables in order to bring in more functionality. Issues with this approach is expensive setup when copying many things and dealing with name conflicts. The other approach to mixins is to set up a multiplexing
__index
metamethod but there are performance penaltiesThis will effectively create a new way to extend the functionality of objects while keeping the new functions and properties namespaced. In order to install the mixin only one copy is necessary, and if the mixin is changed later those changes will be available in that module since we are working with a reference to that table.
downsides
The order of the receivers might not be ideal in some situations, for example:
An alternative way to write the mixin method that does work:
Another approach would be to reverse the order in which the receivers are sent to the function, with the closest on to the right being the first argument.
The distinction between
@hello
and@\hello
might make things confusing to new users.extensions
We could also add some variations, like mixing
.
and\
:compiles to
Or...
To: