final variables are not functioning well in jshell - final

I am working with jshell of JDK9.
I just created a final variable and assigned a value to it.
And in the next line i just modified the value. And to my surprise, there was no error when modifying the final variables.
Here is the code snippets:
jshell> final int r = 0;
| Warning:
| Modifier 'final' not permitted in top-level declarations, ignored
| final int r = 0;
| ^---^
r ==> 0
jshell> r = 1;
r ==> 1
jshell> System.out.println("r = "+r)
r = 1
Is it what is expected from jshell? or there is some other way to work with final variables in jshell?

While creating a final variable at the top-level is not supposed to be practiced. But I guess there is no hard way of restricting such usages.
From the documentation around JShell.eval
The modifiers public, protected, private, static, and final are not
allowed on op-level declarations and are ignored with a warning.
Synchronized, native, abstract, and default top-level methods are not
allowed and are errors.
If a previous definition of a declaration is
overwritten then there will be an event showing its status changed to
OVERWRITTEN, this will not occur for dropped, rejected, or already
overwritten declarations.
The warning stated above is quite visible when you execute jshell in verbose mode as follows:

Related

unable to use Sigilless variables with WHERE clause in CLASS?

Module A has a member variable name c, with a WHERE clause:
unit class A;
my \MAXVALUE = 1000_000;
has $.c where 0 < * < MAXVALUE;
method gist() {
"$!c";
}
set RAKULIB environment variable:
set RAKULIB="d:\scripts\Raku\A\lib" # Windows
export RAKULIB="/opt/scripts/Raku/A/lib" # Linux
use Module A like this:
use A;
my $a = A.new(c => 1);
say $a;
but got type check error:
Type check failed in binding to parameter '<anon>'; expected Any but got Mu (Mu)
in whatevercode at D:\scripts\Raku\Raku\A\lib\.precomp\C6EB86CB837D3BCAAA3D85B66CE337C820700C08\6D\6DCD4CE23D88E2EE9568BA546C007C63D9131C1B line 1
in block <unit> at basic.rakutest line 3
Is this a bug?
raku version:
raku -v
This is Rakudo version 2020.05.1 built on MoarVM version 2020.05
implementing Raku 6.d.
Golfed to: BEGIN say 1 < Mu displays essentially the same error message.
In your code, MAXVALUE is initialized with the value Mu at compile time. You must alter your code so evaluation of ... < MAXVALUE comes after MAXVALUE has been initialized to have a value other than Mu.
In the rest of this answer:
What are the simplest compile time solutions?
What if you want to use a run-time value?
What's going on behind the scenes?
Is the error message LTA?
What are the simplest compile time solutions?
You yourself provide a good compile time solution in your comment below this answer in response to my first version of it.
That said, if you wish to keep the symbol purely lexically scoped, you should start with a my:
my constant MAXVALUE = 1000_000;
Problem solved.
What if you want to use a run-time value?
The variables/symbols/expressions in a where clause will be evaluated at compile-time if they're in a WhateverCode expression.
But that might not be the case if you use a lambda (with { ... } syntax) instead. If the line in your code:
has $.c where 0 < * < MAXVALUE;
was changed to:
has $.c where { 0 < $_ < MAXVALUE }
then your code would work.
BUT...
If you add an explicit initial value to the has line...
has $.c where { 0 < $_ < MAXVALUE } = 10;
^^^^ Explicit initialization
...then the error would return because now the where clause is invoked during compile time due to a chain reaction:
The compiler decides to check that the initialization value passes the where check.
To do that the compiler evaluates the where clause at compile-time;
That in turn causes MAXVALUE to be evaluated -- and it contains Mu at compile-time, causing the error to return.
What's going on behind the scenes?
There are both compile-time and run-time phases in initializing has variables:
During compile-time, when a class is being composed, the default value that instances will have for each has variable is determined. Three common scenarios are:
has statement
default value
has $foo;
Any
has $foo where some-condition;
<anon>
has $foo = 42;
42
During run-time, when an instance of a class is being built, the values of the has variables of that particular instance are set, possibly initializing them to values other than the class's default values.
The following code is intended to demonstrate the process:
BEGIN say 'code compile-time, start, outside class';
say 'code run-time, start, outside class';
sub init (*%_) { say "initializing {|%_}" }
class foo {
has $.bar;
has $.baz where init(baz => $_);
has $.buz where init(buz => $_) = 42;
say 'run-time, at end of class';
BEGIN say 'compile-time, at end of class';
}
BEGIN say 'compile-time, outside class again';
say 'run-time, outside class again';
say foo.new(buz => 99);
displays:
code compile-time, start, outside class
compile-time, at end of class
initializing buz 42
compile-time, outside class again
code run-time, start, outside class
run-time, at end of class
run-time, outside class again
initializing buz 99
foo.new(bar => Any, baz => <anon>, buz => 99)
Note the completed initializations of the three has variables in the fully built instance:
bar => Any.
This is the usual default initialization of a variable.
baz => <anon>.
cf say my Int $var; which displays (Int), because the default value of a variable with a type constraint but no explicit initializing value is the type object corresponding to the type constraint, and say my $var where 1; which displays (<anon>), reflecting the anonymous nature of a where constraint (as contrasted with a subset). So has $.baz where init(baz => $_); results in a default value of (<anon>).
buz => 99.
This is the only has variable for which an initializing ... line was displayed -- and, importantly, there are two lines, not one:
The first line is displayed immediately after compile-time, at end of class, i.e. when the compiler reaches the closing curly of the class declaration. This is when Raku does class composition, and buz gets the default value 42.
Then, during evaluation of foo.new(buz => 99);, which builds an instance of the class at run-time, comes initializing 99.
Is the error message LTA?
In my first version of this answer I wrote:
I'm not myself able to provide a coherent explanation ... whether it's considered a bug. I do currently consider the error message LTA.
Now it's time for me to carefully discuss the error message:
Type check failed in binding to parameter '<anon>'; expected Any but got Mu (Mu)
in whatevercode at ... A\lib ... line 1
in block <unit> at ... line 3
Type check failed ...
The where check failed. It is referred to as a "type check". Given normal Raku use of the word "type", I'm going to count this as fine.
... in binding to parameter '<anon>';
I'm not sure what "parameter" refers to, nor '<anon>'. Imhh (in my humble hypothesizing) "parameter" refers to a parameter of the infix:«<» function and '<anon>' to the value stored in $.c at compile-time before the anonymous where constraint is attempted at run-time.
LTA? Perhaps something like <where clause> instead of <anon> would be viable and appropriate?
expected Any but got Mu (Mu)
By default, has variables expect Mu, not Any. So this bit of the message seems not to refer to the $.c. So, as with my hypothesis about "parameter", I think this is about a parameter of the infix:«<» function.
This is really useful info. Any time you see but got Mu (Mu) you can be pretty sure a failure to initialize some value is part of the problem, as was indeed the case here.
in whatevercode
The blow up is happening in a WhateverCode, so this part is useful for someone who knows what a WhateverCode is.
LTA? If someone does not know what a WhateverCode is, this part is cryptic. I think in WhateverCode instead of in whatevercode would be a worthwhile improvement. Perhaps in WhateverCode (eg '* < 42'), where the '* < 42' is fixed as literally that rather than being the actual source whatevercode, because I don't think that's doable, would be better?
at ... A\lib ...
The paths parts I've elided (...) are both helpful (full) and awful (long non-human friendly strings).
LTA? Perhaps moving the paths to the end would help:
Type check failed ... got Mu (Mu)
in whatevercode at A\lib line 1
(Full path to A\lib: D:\scripts\Raku\Raku\A\lib\.precomp\
C6EB86CB837D3BCAAA3D85B66CE337C820700C08\
6D\6DCD4CE23D88E2EE9568BA546C007C63D9131C1B)
... line 1
"line 1" presumably refers to either line 1 in the whatevercode or line 1 in the A\lib. Either way, it's not especially helpful.
LTA? Perhaps it's viable and appropriate to make it clearer what the line 1 refers to, and, if it refers to A\lib, then make it accurately point to the whatevercode.
in block <unit> at line 3
That's useful.

Nullable variable in Kotlin

I have this code example.
var nullAbleName: String? = null
var v = "I cannot be null"
//! v = nullAbleName // mismatch
nullAbleName = "abc"
v = nullAbleName // Now OK.
nullAbleName is a variable, and its value should be determined in run-time. What is the logic that 2nd assignment of v is OK? Is it that I am lucky because the compiler happens to know the nullAbleName has a value?
This is called smart-casting. The compiler is able to see that the local variable was most recently set to an explicit String, so it treats it as non-null. You may notice that the assignment is colored/highlighted differently by the IDE to show that is employing smart-casting.
This only works with local variables that have not been captured by a closure that modifies them (for instance, creating a callback instance that modifies the value of the local variable). So properties are ineligible for smart casting because they aren't local variables (and could be changed elsewhere) and local variables captured in closures aren't eligible (because they could be changed elsewhere by the closure).

how to find out if a c++/cli heap variable has <undefined value>

I've not been using C++ for about 4 years and came back to it a month ago, and that was where I also have first heard about the CLI extension. I still have to get used to it, but this website helps a lot! Thank you!! Anyway, I couldn't find an answer to the following problem:
When I declare a variable
int iStack;
then it is declared but not defined, so it can have any value like
iStack = -858993460
depending on what the value at the stack position is, where the variable is created.
But when I declare a variable on the heap
int^ iHeap
then as far as I know the handle is created but the variable is not instantiated (don't know if you call it instantiation here) or defined and I can only see
iHeap = <Nicht definierter Wert> (which means <undefined value>)
Is there any way to detect if this value is defined?I particularly don't need it for int, but for example for
array<array<c_LocationRef^,2>^>^ arrTest2D_1D = gcnew array<array<c_LocationRef^,2>^>(2);
to find out if the elements of the outer or inner array are instantiated (I'm sure here it is an instantiation ;-) )
arrTest2D_1D = {Length=2}
[0] = {Length=20}
[1] = <Nicht definierter Wert> (=<undefined value>)
As far as I know, the CLR automatically initialise your variables and references in C++ CLI.
In .NET, the Common Language Runtime (CLR) expressly initializes all
variables as soon as they are created. Value types are initialized to
0 and reference types are initialized to null.
To detect if your variable is initialised, you should compare the value of your hat variable to nullptr :
int^ iHeap;
if(iHeap == nullptr){
Console::WriteLine(L"iHeap not initialised");
}
This works on my VS2010 ; it outputs iHeap not initialised
It should work for your specific problem as well (arrays).
By the way, value types are initialised to zero hence your first example should output 0 (I've tested it, and it does output 0) :
int iStack;
Console::WriteLine(L"iStrack = {0}", iStack); // outputs 0
Quote is from codeproject
MSDN page for nullptr
EDIT: Here is an other quote, from Microsoft this time :
When you declare a handle it is automatically initialized with null, so it will not refer to anything.
Quote from MSDN see the paragraph "Tracking Handles"

Statement goto can not cross variable definition?

Suppose these code compiled in g++:
#include <stdlib.h>
int main() {
int a =0;
goto exit;
int *b = NULL;
exit:
return 0;
}
g++ will throw errors:
goto_test.c:10:1: error: jump to label ‘exit’ [-fpermissive]
goto_test.c:6:10: error: from here [-fpermissive]
goto_test.c:8:10: error: crosses initialization of ‘int* b’
It seems like that the goto can not cross pointer definition, but gcc compiles them ok, nothing complained.
After fixed the error, we must declare all the pointers before any of the goto statement, that is to say you must declare these pointers even though you do not need them at the present (and violation with some principles).
What the origin design consideration that g++ forbidden the useful tail-goto statement?
Update:
goto can cross variable (any type of variable, not limited to pointer) declaration, but except those that got a initialize value. If we remove the NULL assignment above, g++ keep silent now. So if you want to declare variables that between goto-cross-area, do not initialize them (and still violate some principles).
Goto can't skip over initializations of variables, because the respective objects would not exist after the jump, since lifetime of object with non-trivial initialization starts when that initialization is executed:
C++11 §3.8/1:
[…] The lifetime of an object of type T begins when:
storage with the proper alignment and size for type T is obtained, and
if the object has non-trivial initialization, its initialization is complete.
C++11 §6.7/3:
It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A
program that jumps from a point where a variable with automatic storage duration is not in scope to a
point where it is in scope is ill-formed unless the variable has scalar type, class type with a trivial default
constructor and a trivial destructor, a cv-qualified version of one of these types, or an array of one of the
preceding types and is declared without an initializer (8.5).
Since the error mentions [-fpermissive], you can turn it to warning by specifying that compiler flag. This indicates two things. That it used to be allowed (the variable would exist, but be uninitialized after the jump) and that gcc developers believe the specification forbids it.
The compiler only checks whether the variable should be initialized, not whether it's used, otherwise the results would be rather inconsistent. But if you don't need the variable anymore, you can end it's lifetime yourself, making the "tail-goto" viable:
int main() {
int a =0;
goto exit;
{
int *b = NULL;
}
exit:
return 0;
}
is perfectly valid.
On a side-note, the file has extension .c, which suggests it is C and not C++. If you compile it with gcc instead of g++, the original version should compile, because C does not have that restriction (it only has the restriction for variable-length arrays—which don't exist in C++ at all).
There is an easy work-around for those primitive types like int:
// --- original form, subject to cross initialization error. ---
// int foo = 0;
// --- work-around form: no more cross initialization error. ---
int foo; foo = 0;

lua variables scope

I am aware there are other similar topics but could not find an straight answer for my question.
Suppose you have a function such as:
function aFunction()
local aLuaTable = {}
if (something) then
aLuaTable = {}
end
end
For the aLuaTable variable inside the if statement, it is still local right?. Basically what I am asking is if I define a variable as local for the first time and then I use it again and again any number of times will it remain local for the rest of the program's life, how does this work exactly?.
Additionally I read this definition for Lua global variables:
Any variable not in a defined block is said to be in the global scope.
Anything in the global scope is accessible by all inner scopes.
What is it meant by not in a defined block?, my understanding is that if I "declare" a variable anywhere it will always be global is that not correct?.
Sorry if the questions are too simple, but coming from Java and objective-c, lua is very odd to me.
"Any variable not in a defined block is said to be in the global scope."
This is simply wrong, so your confusion is understandable. Looks like you got that from the user wiki. I just updated the page with the correction information:
Any variable that's not defined as local is global.
my understanding is that if I "declare" a variable anywhere it will always be global
If you don't define it as local, it will be global. However, if you then create a local with the same name, it will take precedence over the global (i.e. Lua "sees" locals first when trying to resolve a variable name). See the example at the bottom of this post.
If I define a variable as local for the first time and then I use it again and again any number of times will it remain local for the rest of the program's life, how does this work exactly?
When your code is compiled, Lua tracks any local variables you define and knows which are available in a given scope. Whenever you read/write a variable, if there is a local in scope with that name, it's used. If there isn't, the read/write is translated (at compile time) into a table read/write (via the table _ENV).
local x = 10 -- stored in a VM register (a C array)
y = 20 -- translated to _ENV["y"] = 20
x = 20 -- writes to the VM register associated with x
y = 30 -- translated to _ENV["y"] = 30
print(x) -- reads from the VM register
print(y) -- translated to print(_ENV["y"])
Locals are lexically scoped. Everything else goes in _ENV.
x = 999
do -- create a new scope
local x = 2
print(x) -- uses the local x, so we print 2
x = 3 -- writing to the same local
print(_ENV.x) -- explicitly reference the global x our local x is hiding
end
print(x) -- 999
For the aLuaTable variable inside the if statement, it is still local right?
I don't understand how you're confused here; the rule is the exact same as it is for Java. The variable is still within scope, so therefore it continues to exist.
A local variable is the equivalent of defining a "stack" variable in Java. The variable exists within the block scope that defined it, and ceases to exist when that block ends.
Consider this Java code:
public static void main()
{
if(...)
{
int aVar = 5; //aVar exists.
if(...)
{
aVar = 10; //aVar continues to exist.
}
}
aVar = 20; //compile error: aVar stopped existing at the }
}
A "global" is simply any variable name that is not local. Consider the equivalent Lua code to the above:
function MyFuncName()
if(...) then
local aVar = 5 --aVar exists and is a local variable.
if(...) then
aVar = 10 --Since the most recent declaration of the symbol `aVar` in scope
--is a `local`, this use of `aVar` refers to the `local` defined above.
end
end
aVar = 20 --The previous `local aVar` is *not in scope*. That scope ended with
--the above `end`. Therefore, this `aVar` refers to the *global* aVar.
end
What in Java would be a compile error is perfectly valid Lua code, though it's probably not what you intended.