Hi, another conceptual question.
I have a closure like functionality:
z = function outer1(x0::Int)
x = x0
function inner1()
println(x)
end
function inner1(y::Int64)
println(y)
end
return inner1
end
Not sure if it works just only for Symbol type z = :( function...
I read in the documentation ( Performance Tips · The Julia Language ) and as far as I understand it says for each of the type used in function, that whole process of creating some compiler methods and structure is needed.
I was thinking about it, and trying to make it lazy. So, the compiler “compiles” the code, only when it needs it. So, if the z is not called, the compiler doesn’t run/compile it, thus whole machinery around it is not executed.
How can I achieve something like this?
In the code above, where the push! and machinery code will be created, in the namespace of ‘z’ or in the global namespace?
If in z namespace, if the garbage collector, will be called and z is candidate for cleaning, does the gc removes also the functions and compiler's related functionality?
:() isn’t part of the provided code, and z = isn’t necessary or typical.
That’s already how Julia’s JIT compiler works.
There’s no push! anywhere in your code. z is a variable, not a namespace. A function scope is also not a namespace. A namespace is a persistent container for names you can access; Julia has modules containing global variables.
Compiled method code does not ever go away, to my knowledge, it remains in older world ages. The garbage collector may remove the overlying function objects if they have no more references. function outer1 assigns the function to a const name outer1, so it will always have a reference, even if only in an older world age. These are implementation details, not language specifications, so it could potentially change within v1.
I was thinking, that some part of the code is in global namespace (I mean non-local), e.g. something related with macros?. Thus, does a function can be also in the global namespace?
But I am not sure how can I be sure where it is put, cannot find some analogy similar to python (locals/globals) at least for interactive/REPL mode.
So, the whole idea was, that if the compiler compiles ,in some cases e.g: function, to global namespace, and based on documentation, it has to call whole machinery, then the compilation time can take a lot of time. Thus, I create some my own local namespaces with variables and via closures I return to appropriate method. => My namespace (hidden behind the variable) has limited impact of the global space, and also if the variable is not used anymore, my namespace and some related things to dynamic dispatch will be cleaned.
That was basically mentioned in the documentation, I know that it is not in the code. My apologise, I didn’t create own type. As I understand, that if you create some a new type, some Base functions for that types are also generated…(not sure)?
I think you’re mixing a lot of things up, which is understandable because programming terminology is extremely vague and contextual. So I’ll explain it in terms typical for Julia users, and you need to understand that it can be different in other languages.
The only namespace in the core Julia language is a module, and the names it holds are global variables. A module is also a global scope. Local scopes are not called namespaces, so if you want to distinguish global from local scopes, say scope.
Scopes only contain names, also known as variables, not the objects the variables are assigned. We may refer to an object via an assigned variable, like the “outer1 function in the global scope,” but that strictly means outer1 is in the global scope and is assigned a function. This by the way is how Python works too; these are not languages where variables can be synonymous with owned objects.
Where a function object, its methods, and compiled method code are stored is an implementation detail, not part of the language specification. Nested functions and closures don’t literally store functions inside another function, the placement is only about what variables their scopes can access. In the current implementation, the written definitions of the outer1 and inner1 methods added separate entries to one global method table, before any calls. The outer1 function is assigned to the global const variable outer1, and inner1 functions are instantiated by outer1 calls, where the definitions are. If it sounds strange that inner1 methods existed before its functions do, it should be known that the functions’ type was also made at definition and assigned a hidden global const variable, you can check Base.return_types(outer1) before any calls.
The compiler does not approach globally defined methods and closures’ methods differently, though closures can access local variables that can be uninferrable in their own ways. There’s no point in making closures to optimize compilation, and it is completely unrelated to the Performance Tips section you linked about compiling for too many concrete and likely parametric types.
I have no idea where these ideas come from or what they could mean, I think you should just ignore it.