A pain point I hit really quickly with trying to use operator macro was trying to permit operator overloading using macros, but I quickly realised there doesn't seem to be any way to access the original operator, because even if I try to implement another operator which has the original it also gets replaced.
As an example:
operator + left 12 = (left, right) => {
return #`(${ left })[Symbol.add](${ right })`
}
Symbol.add = Symbol('Symbol.add')
Number.prototype[Symbol.add] = function(other) {
// Obviously this a no-go as the operator will get replaced
return this + other
}
console.log(3 + 4)
So that doesn't work as all operators get replaced in all contexts which is fine, but then I tried adding a second operator to access the original:
operator $plus left 13 = (left, right) => {
return #`${ left } + ${ right }`
}
operator + left 13 = (left, right) => {
return #`(${ left })[Symbol.add](${ right })`
}
Symbol.add = Symbol('Symbol.add')
Number.prototype[Symbol.add] = function(other) {
"use strict"
return this $plus other
}
console.log(3 + 4)
But this still doesn't work because this $plus other gets replaced with this + other then replaced again with this[Symbol.add](other).
What'd be nice is if we could protect some code from being affected by macros:
Number.prototype[Symbol.add] = function(other) {
#nomacro {
return this + other
}
// Or maybe if we could exclude specific macros
#nomacro + {
return this + other
}
// Such blocks would be scopable as nearby as needed:
return #nomacro + { this + other }
}
The syntax above is just for exposition, while not strictly necessary (I could just define a library of normal operators and import it) I think it would make operator a lot more usable.
EDIT: The library definition operators workaround I suggested won't work at all for lazy operators or special tokens like => that aren't really operators just tokens.
A pain point I hit really quickly with trying to use
operator
macro was trying to permit operator overloading using macros, but I quickly realised there doesn't seem to be any way to access the original operator, because even if I try to implement another operator which has the original it also gets replaced.As an example:
So that doesn't work as all operators get replaced in all contexts which is fine, but then I tried adding a second operator to access the original:
But this still doesn't work because
this $plus other
gets replaced withthis + other
then replaced again withthis[Symbol.add](other)
.What'd be nice is if we could protect some code from being affected by macros:
The syntax above is just for exposition, while not strictly necessary (I could just define a library of normal operators and import it) I think it would make
operator
a lot more usable.EDIT: The library definition operators workaround I suggested won't work at all for lazy operators or special tokens like
=>
that aren't really operators just tokens.