Why julia has no clear(variable)?

question

#1

Here is a quote from the documentation

Julia does not have an analog of MATLAB’s clear function; once a name is defined in a Julia session (technically, in module Main), it is always present.

If memory usage is your concern, you can always replace objects with ones that consume less memory. For example, if A is a gigabyte-sized array that you no longer need, you can free the memory with A = 0. The memory will be released the next time the garbage collector runs; you can force this to happen with gc().

Is there a reason for this? The proposed workaround, A = 0, has the problem that if I attempt to use the variable A at a later point, there will be no error, which can be unsafe when my intended behaviour wast to clear the variable to prevent its future use.


#2

It cannot be a function and it’ll have very different semantics from the matlab function. It is easily implementable in local scope though in most cases what you can use is simply let. Ones that cannot be represented by let scope of a variable is likely very hard for human to understand too.


#3

As I understand it, let is preventive, not therapeutic. If you already have a declared variable that you want to get rid off, let will not help you.


#4

Well, what I mean is that you only assign that variable in the let scope and the end of the let will clear the variable for you. You can do

local A
let A
   A = ...
end
A # error()

#5

But there is nothing fundamental that prevents adding a clear keyword to the language someday, right? Is there a reason not to?


#6

It’ll likely be a macro instead of a keyword. The biggest issue I can think of is that it can’t operate on global variables (const or non-const)


#7

Maybe try:

A = nothing

Most methods won’t be defined on A which is of type Void, so you should get an error.


#8

I like this. I don’t know why I did not think of it before. I think the Julia docs (the quote is from here: https://docs.julialang.org/en/stable/manual/faq/) should use this example, instead of A = 0.


#9

#10

Wouldn’t it be better to update the documentation to use a let block so that the variable is cleared when the block ends? (Maybe keeping the A = nothing hack as a not-recommended-but-also-works option.)

Some methods are defined for Void input, so there’s no guarantee that A = nothing will always give errors when A is used incorrectly. But more importantly, letting the variable fall out of scope will also give information to linters, so the editor might flag the incorrect use of A as soon as the line is written, without ever running the code.


#11

I agree that perhaps the let block is a better approach. But the issue is when you already have a variable that you defined in global scope. I use the REPL for quick and dirty prototyping, which means I usually have a lot of global variables lying around. I don’t have time to think about structuring my code using let blocks in this context.

So the issue here is what to do with a variable that you defined in the global scope already. Not whether it would have been better to define it with a let block. You can’t change the past :stuck_out_tongue:


#12

I think this is really what needs to be in the FAQ, along with the explanation of the quoted statement. I’ve accepted that there isn’t a way to delete objects, but I think people would stop asking if it was more clear why its a hard/impossible problem.


#13

“It cannot be a function” does not explain why the language was not designed with a keyword to delete bindings (like del in Python).


#14

Re cossio: del in python does not delete objects, it deletes symbols. In the python3 REPL:

x = [1,2,3]
y= x
del x #equivalent to del globals()[‘x’]
print(y)
[1, 2, 3]

This is a very different thing. C does not remove symbols from the scope (but the preprocessor does, i.e. you can remove macro definitions; it is an interpreted language, after all, and not compiled).

Python has no keyword or function for deleting objects (freeing their memory). This is not so bad in python, since it is reference-counted; hence, unless you created a cycle, the object will be free’d immediately once it goes out of scope (normally by leaving the scope, possibly by del).

You could legitimately ask why julia does not expose the global symbol table to you, i.e. does not provide an analogue of
del globals()[‘x’]
on the REPL (removing entries from dictionaries is easy in julia). I find that I don’t particularly care, I have no need to access the global symbol table programatically.

One possible answer: Defining the semantics of the language in view of such changes would be really hard. In python this is not an issue, because python functions are essentially interpreted (bindings are call-time), whereas many bindings in julia are compile-time or parse-time.

A more interesting question would be how to manually free the memory pointed at by an object reference (expecting memory corruption / segfault / pwnage if other references survive). You would do this to relieve gc pressure while avoiding the cost of actually garbage collecting.


#15

I am sorry, I meant deleting a variable binding. Note that deleting symbols is precisely what I want. It’s not about memory, it’s about removing a symbol from scope for safety, so that I don’t inadvertently misuse it later.