-
Notifications
You must be signed in to change notification settings - Fork 15
Description
The following three blocks...
- delete 0 / 0 of list
- delete 0 of list
- delete 4 of list
...are converted into the following three(-ish) scripts:
- Depends:
<list>.splice(this.toNumber(0 / 0) - 1, 1)w/ traits or strict NaN; this is equivalent to<list>.splice(-1, 1)<list>.splice(0 / 0 - 1, 1)in curr. Leopard; this is equivalent to<list>.splice(NaN, 1), which JavaScript treats the same as<list>.splice(0, 1)
<list>.splice(-1, 1)(0 - 1 = -1)<list>.splice(3, 1)(4 - 1 = 3)
This is trouble, because splice wraps behind the start. To summarize the real effects:
- Depends:
- w/ traits or strict NaN:
.splice(-1, 1)is the same as.pop() - w/ curr. Leopard:
.splice(NaN, 1)is the same as.shift()
- w/ traits or strict NaN:
.splice(-1, 1)is the same as.pop().splice(3, 1)works correctly - splice only wraps negative numbers, it does nothing if the positive number is beyond the list's length. Or it deletes the fourth item, of course!
In Scratch, specifying zero or a negative number for the index to delete means no item will be deleted at all - the list will be left as it is. Of course, we're not reflecting that here, and this makes for project incompatibility.
The question is, what approach do we want to take to fix this?
The easiest is to just add a new function in Leopard specifically for "delete item of". For example, this.deleteItem(this.stage.vars.list, -1) would correctly do nothing. We already have functions that help us deal with lists, indexInArray and itemOf. So maybe adding a new function isn't so bad? We're already missing out on indexOf, and even plain old array[index] item accessing.
Of course, it'd be nice to just get to use splice and indexOf and normal item accessing (and even shift and pop). I feel like some of it must be possible - at least making certain combinations of blocks convert more nicely, even if we can't arbitrarily convert all scripts into the nicest form. Some of this might depend on inspecting the shape/traits/even opcode of a contained block (#98), some might be possible just with smarter use of desired traits (#150). We'd like to work it out but right now it feels, uh, to put it simply, too intimidating to treat as a high-pressure project — better to implement a simple if clumsy, universally applicable fix (this.deleteItem) and work out nicer, more particular solutions after.
@PullJosh Mainly we've assigned you asking for a blessing on adding deleteItem to Leopard, and checking if you think a different name would be better.
Does it make sense for the args to be (1. array, 2. index), sort of like array.splice(index), or should they be flipped to line up closer with Scratch? I think of it as "delete an item of (array) at (index)"... of course, I'm used to that because I use splice and I usually specify child things after parent things... but, I figure that if we can't use splice, we may as well get closer to it in our custom syntax, right? But there's a case to be made that dot syntax (list.splice(index)) is fundamentally different from "act on the thing I've passed" syntax (splice(list, index)), so if you feel a different name or argument order is better, we probably wouldn't argue with it much.
Thanks for your time taking a close look at this fairly awkward corner in the guts of Leopard project conversion!