LiveScript
LiveScript copied to clipboard
Reintroduce +++ operator to mean concatenation with mutation
Can you tell why deprecate +++
operator? It doesn't mess with ++
right, must be the same precendence with ++
, so could be "recovered" easily? Any story about it maybe :]
my "projected" use-case:
# inside of object constructor function...
# ...
@item = item = {} # all
@list = list = [root] # all ordered
####
list +++ (querySelectorChildren box, '.item')
a = -1
while ++a < list.length
if b = querySelectorChild list[a], '.section'
list +++ (querySelectorChildren b, '.item')
# ...
# end of example
It's just been renamed to ++
(note the spaces; unspaced ++
is increment). Your example works if you replace all the +++
with ++=
(you need the =
because ++
doesn't mutate the lists, it only returns their concatenation).
ye, i figured only ++
won't go, so thanks, didn't know about ++=
, will check
one more thing about it (generated from ++=
):
while (++a < list.length) {
if (b = querySelectorChild(list[a], '.section')) {
list = list.concat(querySelectorChildren(b, '.item'));
}
the assignment is not needed, right, should be only list.concat(..)
No, that's what I was trying to say at the end of my comment:
oh, my, i've missed the bug then..
any chance to resurrect +++
from the imperative hell?
+++ did exactly the same as ++ does
maybe let's tweak it to Array.splice
? so it will mutate the left operand? i mean new +++
with .splice
Why? just use ++=
because +++
is a sister of <<<
with ++=
i have to follow this path:
# ...
item = {} # all
list = [root] # all ordered
####
list ++= (querySelectorChildren box, '.item')
a = -1
while ++a < list.length
if b = querySelectorChild list[a], '.section'
list ++= (querySelectorChildren b, '.item')
# assign one more time :(
@item = item
@list = list
# ...
see, i could assign it one-line at the top, have to add 2 more lines.
with the .splice
as +++
it would be
# ...
@item = item = {} # all
@list = list = [root] # all ordered
####
list +++ (querySelectorChildren box, '.item')
a = -1
while ++a < list.length
if b = querySelectorChild list[a], '.section'
list +++ (querySelectorChildren b, '.item')
# ...
makes sense?
@determin1st Why can't you use @list
and @item
during the operations?
# ...
@item = {} # all
@list = [root] # all ordered
####
@list ++= (querySelectorChildren box, '.item')
a = -1
while ++a < @list.length
if b = querySelectorChild @list[a], '.section'
@list ++= (querySelectorChildren b, '.item')
# ...
What is wrong with above code?
IMO, if you want to mutate an array by appending new elements, you should just call .push
on it. This is subjective, but based on experience with similarly-spelled operators I wouldn't expect an expression spelled a +++ b
to mutate a
, or even treat a
and b
fundamentally differently.¹ a <<< b
is at least visually asymmetric enough to hint at the side effect. I know LiveScript has a whole mess of operators, but I don't think more operators need to be introduced just as aliases to methods. a.push ...b
is much clearer about what's going on, is already familiar to every JavaScript programmer, and is, what, 9 characters instead of 5? Not exactly a huge downside. It doesn't look as mathematical, but since what's happening isn't a mathematical concatenation but rather an impure mutation, I think that's a positive.
- In Haskell, which is the only language I know with a
+++
operator in the core library,+++
is a way to combine functions²;f +++ g
is a function that can take a value taggedLeft
and applyf
to it, or a value taggedRight
and applyg
to it. Haskell's++
operator means the same thing as in LiveScript. - Well, arrows, but anyone who needs this explanation probably doesn't need to worry about the difference.
@ceremcem well ye, i only wanted a bit of perfectionism, that can be done in multiple ways, but somehow +++
appeared as a natural thing when i wrote the initializer's code.
@rhendric 9 characters plus engine implementation dependent, can't say how much arguments allowed to push(...b), i mean just a loop would be more solid and maybe faster
Which implementations don't support push
with multiple arguments? It's in the ES3 spec, which is the version of JS that LiveScript nominally targets as a baseline when not using features that more or less explicitly require more modern engines, like generators and promises.
i mean here, the "Merging two arrays" section: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push
says:
Do not use this method if the second array (moreVegs in the example) is very large because the maximum number of parameters that one function can take is limited in practice. See apply() for more details.
i checked the limit was 65535 for the second array in Chromium. Sure, it's hard to reach but still..
.splice
is presumably subject to the same limitation, right? So if this matters to you, the only viable approach would be to use (either manually, or have some syntax compile into) a loop. But I'm guessing that for such large arrays, .concat
would be faster than a loop, so the best thing for large arrays would be ++=
and the best thing for small arrays would be .push ...
. Since PureScript can't know how big your arrays are, the programmer has to select the best approach. So I think you would need to make the case that whatever +++
would compile to is better than .push ...
for small arrays, or better than ++=
for large arrays. What do you think about that?
i thought that .splice
takes array as an argument first, it doesn't, so it doesn't fit.
i've made some tests: http://jsbench.github.io/#482b62ecdddfeffcea89d30ded47adb6
so, by the number of elements (in the second array):
20: loop is 18% faster 200: push is 38% faster 2000: push is 36% faster 20000: push is 50% faster 200000: push is dead, maximum call stack exceeded
.push is becoming faster starting from 60 elements in the second array .concat is becoming faster starting from 50 elements in the second array
so, for small arrays <60 elements and also for super huge arrays the loop is better
i doubt that speed should be the driving factor of +++
, the main point (feature) is the mutation, right