Re: Why do immutable variables need reference counting?

2022-04-14 Thread ag0aep6g via Digitalmars-d-learn

On 14.04.22 13:42, wjoe wrote:
Undefined behavior yes, but regardless the example proves it can be done 
in @system code.
A few versions ago, possibly due to a bug or regression, the compiler 
didn't complain in @safe code either.


Of course you are correct academically. However, since it's possible, 
I'd wager my last hat that code like this is out in the wild.


No, it cannot be done in @system code. The example only proves that you 
can write nonsense code that has no defined meaning.


Note that the nonsense you wrote behaves as you describe only in 
Windows. Elsewhere, you get a segfault.


But it doesn't matter how the executable actually behaves. You cannot 
cite the result of undefined behavior when arguing language semantics.


Re: Why do immutable variables need reference counting?

2022-04-14 Thread wjoe via Digitalmars-d-learn

On Tuesday, 12 April 2022 at 23:23:59 UTC, Ali Çehreli wrote:

[...]


Looking at this from a technical perspective - everything you say 
is true - and thanks for clearing up some of my confusion in that 
department.


Looking at this from a natural language (English) perspective - 
words prompt ideas and expectations. If these expectations aren't 
met confusion and misunderstanding happens (and that's not just 
true for software development).
Although, perhaps, that's only a problem for (some) non native 
English speakers ? The fact remains that there's confusion and 
misunderstandings regarding const, immutable and const 2.




Re: Why do immutable variables need reference counting?

2022-04-14 Thread wjoe via Digitalmars-d-learn

On Tuesday, 12 April 2022 at 22:23:18 UTC, ag0aep6g wrote:

On Tuesday, 12 April 2022 at 19:54:13 UTC, wjoe wrote:
Especially since it's only a promise and the compiler accepts 
this:


void foo (const(char)[] arr)
{
  cast(char[])arr[0..3] = "baz";
}
string bar = "123";
foo(bar);
assert(bar=="baz");

But I could cast away const and modify the string bar.


No, you could not. You're relying on undefined behavior there. 
Just because the compiler accepts something, doesn't mean it's 
ok.


If you want to be guarded against wandering into undefined 
territory, that's what @safe does. With @safe, the cast doesn't 
compile.


Undefined behavior yes, but regardless the example proves it can 
be done in @system code.
A few versions ago, possibly due to a bug or regression, the 
compiler didn't complain in @safe code either.


Of course you are correct academically. However, since it's 
possible, I'd wager my last hat that code like this is out in the 
wild.


Re: Nested function requires forward declaration?

2022-04-14 Thread Salih Dincer via Digitalmars-d-learn

On Thursday, 14 April 2022 at 08:55:25 UTC, Chris Katko wrote:

[...]
It appears the nested function's variable capture depends on 
forward declaration (the right term?). Whereas, I was under the 
impression most/all of D worked on a multiple pass compilation 
so the order of declarations shouldn't matter.


Is this a D spec, or a compiler parsing error/oversight?
[...]


This is cross-module what you're talking about, eg outside of 
main(). Something with most programming languages, it's not about 
nested function. Do it with lambda if you want, and you'll get 
the same result:


```d
/* auto is_Key = (ALLEGRO_KEY key) =>
 (event.keyboard.keycode == key); // Not 
compiling! */

ALLEGRO_EVENT event;
```

You have one more option, and that is to use OOP. You can even 
briefly encapsulate it into a struct.


SDB@79


Re: Nested function requires forward declaration?

2022-04-14 Thread Mike Parker via Digitalmars-d-learn

On Thursday, 14 April 2022 at 08:55:25 UTC, Chris Katko wrote:

I imagine this is a really odd edge case but it's piqued my 
interest.


Consider this:

```d
void main() {
void foo() { initRuntimeState(i); }
foo();
if(!modifyRutimeState()) return;
int i = getRandomValue();
i = returnSomethingBasedOnRuntimeState(i);
}
```

Which value of `i` should `foo` use? What if `modifyRuntimeState` 
and `returnSomethingBasedOnRuntimeState` are dependent on 
`initRuntimeState`?


At module scope, and in class/struct declarations, only 
compile-time values can be used to initialize variables and 
assignment is illegal, so the compiler can jump around 
initializing things in any order it wants. It has a well-defined 
and limited set of rules it can work with.


That just isn't the case in local scopes, where a variable's 
lifetime begins at the point of declaration, the scope can exit 
at any time, and the order of evaluation can have side effects 
that change the run-time state.


Re: Nested function requires forward declaration?

2022-04-14 Thread Stanislav Blinov via Digitalmars-d-learn

On Thursday, 14 April 2022 at 08:55:25 UTC, Chris Katko wrote:

Using DMD. v2.098-beta-2

Not sure if right terminology. But I just wrote a nested 
function that uses a variable outside its body. The capture 
(right term?) is obvious where the invocation is. However, I 
have to move the declaration of the variable to above the 
nested function for it to compile.


Declarations in function scope are processed in order. This 
includes nested functions:


https://dlang.org/spec/function.html#nested (see #8).




Nested function requires forward declaration?

2022-04-14 Thread Chris Katko via Digitalmars-d-learn

Using DMD. v2.098-beta-2

Not sure if right terminology. But I just wrote a nested function 
that uses a variable outside its body. The capture (right term?) 
is obvious where the invocation is. However, I have to move the 
declaration of the variable to above the nested function for it 
to compile.


Here is the code that wont compile:
D
void execute()
{
bool isKey(ALLEGRO_KEY key)
{
return (event.keyboard.keycode == key);
}
ALLEGRO_EVENT event;
// later
isKey(ALLEGRO_KEY_W);

// main.d(491): Error: undefined identifier `event`


This however, will compile:
D
void execute()
{
ALLEGRO_EVENT event; // <--Only change
bool isKey(ALLEGRO_KEY key)
{
return (event.keyboard.keycode == key);
}
// later
isKey(ALLEGRO_KEY_W);


It appears the nested function's variable capture depends on 
forward declaration (the right term?). Whereas, I was under the 
impression most/all of D worked on a multiple pass compilation so 
the order of declarations shouldn't matter.


Is this a D spec, or a compiler parsing error/oversight?

I guess if I had two different variables called event, this could 
become confusing code to read except that, mentally these should 
still link up, right?


Hypothetical:
D
void execute()
{
bool isKey(ALLEGRO_KEY key)
{
return (event.keyboard.keycode == key);
}

   {
   ALLEGRO_EVENT event;
   isKey(ALLEGRO_KEY_W);
   } //lets say this does some memory housekeeping/deleting so 
that's why we use scope

   {
   ALLEGRO_EVENT event; //new 'event', same name, new memory
   isKey(ALLEGRO_KEY_W);
   }
}


in this case, 'event' under-the-hood could be renamed, say, 
"event2" and have the same expected compile time symbol linking 
occur. The second isKey call is obviously connected to the second 
'event' variable.


I imagine this is a really odd edge case but it's piqued my 
interest.