ES6 modules - why can I use a const before it is declared? - import

I've tried searching for an explanation on this exact scenario but couldn't find anything. I have a module that looks like the following (simplified):
export default function(name) {
return map[name];
}
const map = {
'a': 'b',
'b': 'c'
};
Clearly the const definition above is hoisted but it should be undefined when being used in the function. I'm trying to find an exact explanation for why this function works when imported and used. Shouldn't a reference error be thrown? The only thing I can think of is that the entire module is loaded prior to when this function is called, but how exactly does that happen or where is this specific behavior explained? Any information would be really appreciated.

JS uses lexical scoping, meaning that a scope is defined as part of the nested structure of the code. Anything referencing the name of a variable anywhere in that scope can attempt to access the value. What the actual value is depends on when the value is initialized, which is a runtime property of the code.
When people talk about hoisting in JS generally it is not super clear which of these things they are describing. In JS, because scopes are lexically-based, the existence of a given variable is hoisted, in that it always exists within that scope.
The actual initialization of a variable in a scope depends on the way the variable is declared.
function foo(){} declarations have their initialization hoisted, so the variable foo will always be available in the body of the function, even if the declaration comes later. e.g.
foo();
function foo(){}
is perfectly valid valid.
var foo = 4; hoists initialization, but the value is initialized to undefined until the declaration has executed, e.g.
foo; // undefined
var foo = 4;
foo; // 4
let/const performs initialization only when executed, and attempts to access uninitialized variables will throw an exception.
foo; // would throw because it is not initialized yet
let foo = 4;
foo; // 4
So taking those together, the behavior of variables is only determined at runtime. For your code example, it depends on when the function is called. Since let foo = 4; only initialized foo when it runs, if the function were called first, it would fail, and if the function were called after, it would work.
function log(){
console.log(foo);
}
log(); // would throw because foo has not been initialized
let foo = 4;
log(); // would log 4
This behavior of delayed initialization for let and const is commonly referred to as the "temporal dead zone".
At the end of the day, as long as the variable has been initialized and has the value you care about by the time you access it, your code is fine. Whether you have access to the variable in the first place only depends on the nesting of your code.

The call can only be made (outside of this module) after the whole module you provided is executed (which means that map is already initialized by the time the function is called)
This observation is based on the fact that when you import a module, all of the code inside it will be executed.
To call the function, one would have to import the module you provided.
See Does ES6 module importing execute the code inside the imported file? for when code executes on import.

Related

local object in lua class constructor?

I'm new to Lua "classes" (metatables) and I have a doubt.
In the following constructor code that I wrote, I declared the variable obj as local. But in most examples on the web, this variable is just assigned to without a local declaration. So in my understanding, it becomes a global variable (not efficient from what I understood). But is there a reason for that?
A = {}
A.__index = A
function A:new(obj_init)
local obj = obj_init or {val = 0}
setmetatable(obj, A)
return obj
end
I also noticed that members of the class can be accessed directly, even from another Lua module:
x = A:new{val = 2}
print(x.val)
But is there a way to make val a private member? Maybe also using local?
First, let's look at what these examples you found might have looked like.
Parameters: Implicit locals
function A:new(obj)
obj = obj or {val = 0}
...
end
in this snippet, obj is a local variable. This is because all function parameters in Lua are local variables. We may rewrite the function as follows to highlight this:
function A:new(...)
local obj = ...
obj = obj or {val = 0}
end
I assume this is what you saw e.g. in the PIL. You probably renamed the parameter to obj_init, losing the implicit local declaration of obj.
Global assignment
If you happened to consume particularly bad resources, you might have seen the following:
function A:new(obj_init)
obj = obj_init or {val = 0}
...
end
in this snippet, obj is indeed a global variable. This is very bad for multiple reasons:
Efficiency: You are right - excepting pathological cases, global variables are always slower than local variables as global variables are entries in the (hash part of the) _G table whereas locals are stored in fast registers of the Lua VM.
Code quality: Global pollution: This constructor now has a side effect: It modifies the global variable obj and expects it to not be modified during its execution. This might lead to this function overwriting a global variable obj and, even worse, you may not yield from a coroutine in the constructor now, because you're dependent on a global state which may not be altered.
Private members
The typical way to implement private table fields in Lua is by convention: You may prefix the field names with an underscore to indicate that these fields may not be modified from outside. Of course programmers are free to circumvent this.
Otherwise, the concept of "private" variables doesn't mesh too well with the scripting language nature of Lua; you can shoehorn full-fledged OOP onto Lua using metatables, but it will be neither idiomatic nor efficient.
Upvalues
The most idiomatic way to implement private members in Lua is to have them be upvalues of closures ("accessors"):
A = {}
A.__index = A
function A:new(obj_init)
local obj = {} -- empty object: only member is private
local val = obj.val
-- note: this does not need `self`, thus no `:` is used;
-- for setters you might want to discard `self` for consistency
function obj.getVal()
return val
end
setmetatable(obj, A)
return obj
end
x = A:new{val = 2}
print(x.getVal())
-- val can not be set from outside (excepting the debug library);
-- it is "private" and only accessible through the getter method
The downside is that all functions accessing your private members will have to be instantiated with each object creation.
Note that even upvalues aren't fully "private" as they may be accessed through the debug library.
debug library workarounds
The debug library allows you to inspect the stack. This allows you to tell which method triggered your __index metamethod. You could thus return different values to different callers. This may be nice for a proof-of-concept to showcase Lua's metaprogramming capabilities, but should not be done in practice as it is very inefficient and hacky.

Does global variable used in a function need to be defined before the def block?

I must admit that I didn't expect the following code could work (code sample from a collegue of mine):
def foo():
li.append(3)
li = [1, 2]
foo()
print(li) # gives [1, 2, 3]
My questions are:
why is 'global li' not needed in the 'def foo()'?
why is 'li = [1, 2]' not needed to be put before the 'def foo()'?
ps. Python 3.6.1 is used for the listed code sample.
Global keyword is a keyword that allows a user to modify a variable outside of the current scope.
Rules of global keyword:
If a variable is assigned a value anywhere within the function’s
body, it’s assumed to be a local unless explicitly declared as
global.
Variables that are only referenced inside a function are
implicitly global.
We Use global keyword to use a global variable inside a
function.
There is no need to use global keyword outside a function.
Your code , you are not changing or assigning a 'li' value
2.Here list is defined before foo() is called, so it working fine.suppose if you call foo() before li is defined, it will throw a error like NameError: name 'li' is not defined
Since the list is defined before foo() is called, hence there is no error.
global keyword is only required when we want to do assignment or change the global variable. Accessing the methods or printing the variable does not require the global keyword

Are initializer expressions part of the constructor in D?

In D, can I initialize directly on declaration and expect the initializer expressions are part of the constructor?
I came from C# and there this is the case. But with DMD 2.071.0 Im getting other behavior.
class Other { }
class Test { Other nonStaticMember = new Other; }
void test()
{
auto t1 = new Test;
auto t2 = new Test;
// Assert is failing, the two Test instances are
// being initialized to the same reference
// instead of execute the Other constructor twice.
assert(t1.nonStaticMember !is t2.nonStaticMember);
}
If this is the intented behavior it should be documented here: https://dlang.org/spec/class.html right?
This code doesn't do in D what it would do in C#.
In your example, Other is instantiated during compilation.
I.e. Other is instantiated once, during compilation, and is placed in the program's data segment. Then, nonStaticMember's initial value will, by default, point to that instance of Other, for all Test instances.
So, everything is working exactly as designed, even if it may be surprising when coming from other languages.
If this is the intented behavior it should be documented here: https://dlang.org/spec/class.html right?
Perhaps, but note that this behavior is not at all specific to classes. A pointer to any value allocated on the heap, as the initial value of a global or local static variable, will behave the same. Whenever the value of an expression is demanded during compilation (and that includes initializers for global/static variables), D attempts to evaluate it at compile-time. A few years ago, this has been extended to allocating values on the "heap" too, which then end up in the program's initial data segment.

Why is 'init' not assignable?

I just read that the init method can't be used as a value. Meaning:
var x = SomeClass.someClassFunction // ok
var y = SomeClass.init // error
Example found on Language reference
Why should it be like that? Is it a way to enforce language level that too dirty tricks come into place, because of some cohertion or maybe because it interferes with another feature?
Unlike Obj-C, where the init function can be called multiple times without problems, in Swift there actually is no method called init.
init is just a keyword meaning "the following is a constructor". The constructor is called always via MyClass() during the creation of a new instance. It's never called separately as a method myInstance.init(). You can't get a reference to the underlying function because it would be impossible to call it.
This is also connected with the fact that constructors cannot be inherited. Code
var y = SomeClass.init
would also break subtyping because the subtypes are not required to have the same initializers.
Why should it be like that?
init is a special member, not a regular method.
Beyond that, there's no reason that you'd ever need to store init in a variable. The only objects that could use that function in a valid way are instances of the class where that particular init is defined, and any such object will have already been initialized before you could possibly make the assignment.
Initializers don't have a return value. In order to assign it to something, it should be able to return something - and it doesn't.

What's the point of self evaluating function generated by Coffeescript if I can't access the variable outside the scope?

foo = 'var'
basically coffeescript generates
(function(){var foo = 'bar';}).call(this);
But in the console I can't access the variable foo
console.log(foo);// error ReferenceError: Can't find variable: foo
How can I access the variable, and what's the point coffeescript do something like this?
This ensures that variables declared within that file don't accidentally leak into the global namespace. It forces the programmer to be more explicit about the variables that he chooses to expose.
If you'd like to expose foo do (exports ? this).foo = 'bar'.
Take a look at this question and answers for reference: How do I define global variables in CoffeeScript?