0

There is one thing I can't really understand in JavaScript or Python, and that's the delete or del syntax.

In JavaScript:

obj = {ha: 123, hi: 3.14}
delete obj.ha               # now obj is {hi: 3.14}

In Python:

d1 = {"ha" : 123, "hi" : 3.14}
del d1["ha"]                # now d1 is {'hi': 3.14}

But, what does delete obj.ha or del d1["ha"] mean?

In JavaScript, delete obj.ha can mean delete 123, because obj.ha evaluates to 123.

Likewise, in Python, del d1["ha"] can mean del 123 because d1["ha"] evaluates to 123.

So it doesn't make sense to delete 123 in either case.

So are we saying, well, most of the time, the rules of evaluating something and then apply it to the delete or del operator work, but sometimes, they just "magically" work the other way?

For example, I think Smalltalk or Ruby's way make a whole lot more sense, which is h.delete("ha"), which is to say, pass the message to the h object, which is a dictionary or hash, that for the key ha, please remove it. This is coherent with everything else. Then we don't have the weird thing as delete obj.ha -- oh it is not the same as delete 123.

(Python's h.pop(key) has the same effect of del h[key], it seems, by the way, but having the syntax del h[key] still seems weird).

4
  • For Javascript, the only reason I can come up with is that it's an operator because that looks familiar to OOP veterans from C++/Java/etc, even though what the operator does in JS has nothing to do with what it does in those languages. The new operator is in a very similar but far more confusing position (at least delete's behavior is extremely simple).
    – Ixrec
    Commented Mar 7, 2016 at 7:40
  • simple but confusing Commented Mar 7, 2016 at 7:43
  • @太極者無極而生: Not really confusing if you think of it as the inverse of assignment. You don't call a method to create a field either, you use an operator (=).
    – JacquesB
    Commented Mar 7, 2016 at 8:54
  • Note: Ruby has the same thing with the defined? operator, for example, and both Ruby and Smalltalk have the same thing with assignment, as pointed out by @JacquesB both in this comment and in his answer. There are languages where there is no assignment, and this is done with method calls, but they are not very mainstream. Ioke and Seph, for example. Commented Mar 7, 2016 at 9:50

1 Answer 1

3

What we have after delete is an lvalue, which means the expression is not evaluated to the value in the field, but rater to an reference to the field itself.

The same happens in a more well-known construct:

obj.ha = 456

If the expression on the left hand were evaluated to the value first, it would be equivalent to this:

123 = 456

Which does not make any sense, because you cannot assign to an integer.

It is specified in the language grammar that expressions in certain contexts are not evaluated to a value but rater to a reference to a variable or field. The example are the left side of an assignment, and after the delete keyword.

Therefore it is pretty restricted what you can put in an lvalue position: It has to be a variable or a field. Any other expressions, like say a function call, is disallowed.

del/delete is basically the inverse of assignment, which creates a field/variable if it doesn't exist already. So I would argue it is not really weird or confusing but rather pretty logical. After all, you don't have to call obj.createField("ha") to create a field either, but use an operator (=).

5
  • does lvalue have the name due to the fact that it appears at the left? So delete d.ha is having a lvalue at the right... and so I suppose you have to know when is an lvalue appearing at the right... or left, besides the assignment statement Commented Mar 7, 2016 at 7:56
  • I believe it means location value, because you return the location of a field or variable rather than the value it contains.
    – JacquesB
    Commented Mar 7, 2016 at 8:00
  • I think if we are to think of obj.ha as a reference, and 1 + obj.ha means to "dereference" it and give you 123, while obj.ha = 345 means to make the reference point to 345. And delete obj.ha... to make the reference ha disappear from obj. I suppose most of the time, it is affecting the reference ha -- or I tend to think about it related to ha, but in the case of delete it is affecting the obj... to remove something from obj Commented Mar 7, 2016 at 8:05
  • If we think about it in low-level C code, we may think of it as, p being a pointer, and high level language's 1 + obj.p means 1 + *(obj.p) in C -- to dereference the pointer and take the value. If it is "location", then it means, in high level language obj.p = 123, the same as in C's obj.p = &(123) meaning the p is set to point to the address of the address of the object 123, assuming 123 is an Integer object... so both cases, they are affecting p. Now delete obj.p doesn't affect p. It affects obj Commented Mar 7, 2016 at 8:11
  • Think about it in terms of method calls, which C doesn't have, so it's not a really good model for languages that do have them. obj.p = 123 as obj.p.setValue(123) and delete obj.p as obj.p.delete(). The type of obj.p is probably some sort of "dictionary key", it's delete method will have the effect of removing itself from its container.
    – Mat
    Commented Mar 7, 2016 at 9:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.