Recent

Author Topic: Why with allows assignment  (Read 43504 times)

Thaddy

  • Hero Member
  • *****
  • Posts: 16653
  • Kallstadt seems a good place to evict Trump to.
Re: Why with allows assignment
« Reply #105 on: January 07, 2025, 05:35:38 pm »
It is a scope declaration statement.
Yes, intentionally.
For that matter it does not differ from other scope declaration statements except for the exception I described earlier for interfaces. Although that also limits scope to the underlying class.
« Last Edit: January 07, 2025, 05:38:41 pm by Thaddy »
But I am sure they don't want the Trumps back...

BrunoK

  • Hero Member
  • *****
  • Posts: 683
  • Retired programmer
Re: Why with allows assignment
« Reply #106 on: January 07, 2025, 05:41:23 pm »
"Convenience" is what make a language usable as opposed to dogmatic construct that make things useless.

If it is convenient, in my little living area to use a flat map on a sheet of paper, I'll, ruthlessly use it instead of thinking to the rotundity of the earth.

Warfley

  • Hero Member
  • *****
  • Posts: 1870
Re: Why with allows assignment
« Reply #107 on: January 07, 2025, 06:57:32 pm »
No, it's because FPC does not automatically generate code to initialize one variable with the value of another or the value of a function (which C supports.)
What I meant it that the way the FPC is currently implemented, initialization cannot be dynamic, because the code that parses the initialization directly spits out an assembly list (there is no intermediate layer like the node tree which allows the initialization to represent more complex concepts). It's literally: Read number -> Write to assembly.
It's very fast, but very limited, so it's not just values of a function, it's anything thats not a static data known at compile time. So for example you can't initialize managed records because the static assignment cannot execute the initialization operator (which is a bug).
It's just a technical limitation on how the FPC is currently build.

I find that very difficult to believe given that you have demonstrated having no grasp whatsoever of some of the most _basic_ concepts of compilers.  What scope things are in is one of the most basic things there is and, btw, what is/belongs in one scope or another is independent of implementation.  I don't care if you've read clang source or anything else.  It has nothing to do with it.
What do you think a scope is? A scope is a set of symbols, represented through a symbol table. Scopes are spanned through syntax structures, in a strictly formal compiler (usually based on parsing tables), they would be strictly associated with AST nodes (which correspond to reduction rules in the grammar definition), while in a less formal compiler like a hand crafted recursive decent LL parser such as the FPC, scopes can be more dynamically managed (e.g. with statements do not have their own representation in the AST, they are basically macros based on an ephemeral symtable). But let's stick to the formal case.
Because you can do forward declarations in Pascal, functions are seperated in a function header and a function body. A forward declaration is a function header without a body and a function implementation is a header plus body.
Code: XML  [Select][+][-]
  1. <Function> ::= <Function Header>
  2.              | <Function Header> <Function Body>
Because the parameter symbols are defined in the function header, it must have it's own symtable independen of that of the function body (which contains any local declarations).

Additionally, if we look at the history of Pascal, while FPC is quite strict with scoping, TurboPascal isnt:
Code: Pascal  [Select][+][-]
  1. {$mode tp}
  2. function foo: Integer;
  3. var
  4.   foo: Double;
  5. begin
  6.  
  7. end;
Here the variable foo shadows the function name (and thereby name of the result variable) foo. This is because the function header and the function body have different scopes.

Quote
When it comes to scanning and parsing, very little has changed in the last 60 or so years.  There have been improvements but nothing that is a game changer.  Moreover, some of the "improvements" have resulted in poorer language quality ("creative" compilers...)

It's not "creative", it's all based on formalisms. The problem is when the formalism doesn't make sense (like in JavaScript [2] == "2"). But even that was a mistake from 30 years ago that pretty much everyone agrees was a bad idea. Most of the current developments are in proving formalistic rules especially over the typesystem. Especially Algebraic typesystems with type inference that allow strict and static typing without losing flexibility in generic code. I mean the first version of that was introduced with ML already in the 80s, and all goes back to Prolog from the 70s, but the current developments both technologically (solving these constraint sets requires a lot of computing power) but also theoretically (as I mentioned before the CST has gone through some major discoveries with respect to new heuristics for efficient solving) make things possible which in the 70s and 80s where not feasable to be used on real world systems.

The automatic creation of a temporary in the "with" turns the "with" statement into a hidden assignment statement.  The "with" statement is NOT an assignment statement.  It is a scope declaration statement.

god forbid we "force" programmers to assign the result of a function to a variable.  It's so much "easier" to create a hidden variable that represents the result and violate every principle of programming by allowing a value to be assigned to the functions' result outside the function.  Convenience over correctness... that's the way to go.
With is what it is built to be. There is no fundamental rule on what with is supposed to be. Yes with declares a scope, but it declares a scope around an object. Either an already existing object, in case of a variable, or a newly allocated temporary object.
In my office I have a big fancy coffee machine. This machine fills coffee into a cup. If you bring your own cup great, it fills coffee in there. If you don't it gives you a new disposable cup to fill coffee into. Does this make the coffee machine now a cup dispenser? Not really, it's just a coffee machine which has a cup dispenser build into to fulfill it's role even if the user does not bring their own cup.
Similar with with. It creates a scope around an object. But if that object does not exist, it creates a new temporary object, limited to the scope of the with statement, to perform the action. Without it it could not provide it's functionality as intended

440bx

  • Hero Member
  • *****
  • Posts: 5077
Re: Why with allows assignment
« Reply #108 on: January 07, 2025, 09:22:44 pm »
Nice try but... you claimed that in the following code (your code btw):
Code: Pascal  [Select][+][-]
  1.  procedure foo(x: Integer);
  2. var
  3.   x: Double;
  4. begin
  5. end;
that the parameter "x" and the local variable variable "x" are not in the same scope, I emphasize this is _your_ claim, most definitely NOT mine.

As I asked you in the previous post, IF the parameter "x" is not in the same scope as the local variable "x" then explain why the compiler claims "x" is a duplicate identifier. As I stated in the previous post, you got some explaining to do.

BTW, you are correct that the procedure _name_ is not in the same scope as its parameters and its locals.  I can show you a post that is a few years old where I make that point along with showing that FPC does not always resolve scopes correctly.

I won't put the link to that post to keep the focus on the current subject which is: parameters and local variables are in the same scope. 

Once this has been established as the fact it is, if you are interested, I'll link to the other post that shows FPC's "unusual' scope resolution methods.  OTH, that has nothing to do with Delphi's and FPC's incorrect handling of the "with" statement and, for that reason I'd rather leave that old post alone even though it does show additional "deficiencies" in FPC's scope resolutions methods.


(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Warfley

  • Hero Member
  • *****
  • Posts: 1870
Re: Why with allows assignment
« Reply #109 on: January 07, 2025, 09:56:40 pm »
As I asked you in the previous post, IF the parameter "x" is not in the same scope as the local variable "x" then explain why the compiler claims "x" is a duplicate identifier. As I stated in the previous post, you got some explaining to do.
I already answered that. Because the message "duplicate identifier" has nothing to do with scope.

So let's take what you said next:
Quote
BTW, you are correct that the procedure _name_ is not in the same scope as its parameters and its locals.
So we agree that local variables and function name are in a different scope, so this is why the FPC does not throw a "duplicate identifier" error right?
Well...
Code: Pascal  [Select][+][-]
  1. {$mode fpc}
  2. procedure foo;
  3. var foo: Integer;
  4. begin
  5. end;
Same message even though we both agree it's in a different scope.
FPC has shadowing rules which are not dependent on scope. Another example:
Code: Pascal  [Select][+][-]
  1. {$Mode ObjFPC}
  2. TMyObject = object
  3.   i: Integer;
  4.   procedure Foo(i: Integer);
  5. end;
Also not same scope but same error message.

The error message does not give any indication if it's the same scope or not. It's also used for shadowing.

Also with that point:
Quote
BTW, you are correct that the procedure _name_ is not in the same scope as its parameters and its locals.  I can show you a post that is a few years old where I make that point along with showing that FPC does not always resolve scopes correctly.
I was talking about the function name as the result variable. So the function name as function symbol, used to call the function is semantically different from the function name as return variable symbol, depending on the scope. In the scope where the function is registered, it's solely the symbol for calling the function, in the scope of the function body it doubles as a symbol for the result variable.

So you can create a local variable which shadows the local result value variable.

Again two things are in a different scope if they are in a different symtable on the symtable stack. And I have not seen a single compiler so far where the local variables and the parameters are in the same symtable. I don't say it doesn't exist, but it's very uncommon to have local variables and parameters in the same scope.

But also I do not know why we discuss shadowing here to begin with, it was just an example that you want to avoid shadowing, because it introduces errors, infact the example from above:
Code: Pascal  [Select][+][-]
  1. {$Mode TP}
  2. function foo: Integer;
  3. var foo: Double;
  4. begin
  5.  
  6. end;
Completely breaks the function because you cannot return a value if you shadow the return variable.

And because shadowing is bad, and in modern day LCL Component based programs most of the with statements will inevitibly introduce shadowing, using with is not a good idea.
Also it's not even that with gives any benefit (aside from the creation of the temporary object), it's just a concept of lazieness, and potentially introducing errors just to save up a few characters is a bad idea.

440bx

  • Hero Member
  • *****
  • Posts: 5077
Re: Why with allows assignment
« Reply #110 on: January 07, 2025, 10:23:11 pm »
As I asked you in the previous post, IF the parameter "x" is not in the same scope as the local variable "x" then explain why the compiler claims "x" is a duplicate identifier. As I stated in the previous post, you got some explaining to do.
I already answered that. Because the message "duplicate identifier" has nothing to do with scope.
No, you did not.  Additionally, it has _everything_ to do with scopes because there can only be duplicates if they are in the same scope.  if they were in different scopes they wouldn't be duplicates... doh!

One more time, given _your_ code:
Code: Pascal  [Select][+][-]
  1.  procedure foo(x: Integer);
  2. var
  3.   x: Double;
  4. begin
  5. end;
Are the parameter "x" and local variable "x" in the same scope ?  Answer that first.

if your answer is "no", which would be obviously incorrect then, how do you explain that the compiler is stating there is a "duplicate identifier" ? 

You got some explaining to do.  Try again.


(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Warfley

  • Hero Member
  • *****
  • Posts: 1870
Re: Why with allows assignment
« Reply #111 on: January 07, 2025, 11:00:43 pm »
Are the parameter "x" and local variable "x" in the same scope ?  Answer that first.
I answered this before. The local variable is in the local var symtable and the parameter x is in the param symtable. These two symtables are independent entities in the symbol search hierachy and therefore are different scopes.

Simple as that.

if your answer is "no", which would be obviously incorrect then, how do you explain that the compiler is stating there is a "duplicate identifier" ? 

You got some explaining to do.  Try again.
It's not because the compiler uses the "duplicate identifier" for any kind of name collision, including when two symbols in the same scope have the same name, but also, as I have demonstrated above, if two symbols from different scopes violate the shadowing rules of the FPC.

The message is not wrong, just imprecise.

So now answer my question:
Code: Pascal  [Select][+][-]
  1. {$Mode ObjFpc}
  2. TMyObject = object
  3.   i: Integer;
  4.   procedure Foo(i: Integer);
  5. end;
Is the field i and the parameter i in the same scope? And if the answer is no, then why is the error message "duplicate identifier"?

I answered all your points, but whenever I brought that up 3 times now, so why don't you want to answer that? Because you can't? Or because you only use FPCs error messages as an argument when it agrees with you and when FPC does something that doesn't agree with you it's obviously a bug, because you are absolutely infallable?

Also you always claim that I don't know what a scope is, define what a scope is according to you. I gave my definition above.

And lastly, before you read the following example, do you agree that fundamental principle of a scope is that two identifiers within the scope resolve to the same entity?

Because here I have news for you:
Code: Pascal  [Select][+][-]
  1. type
  2.   TTest = integer;
  3.  
  4. procedure Foo(x: TTest);
  5. type
  6.   TTest = Double;
  7. var
  8.   y: TTest;
  9. begin
  10. end;
The type of x has the same identifier as the type of y, but they resolve to different types. Therefore they cannot be in the same scope.

And if you want to claim that the introduction of the new type creates a new scope,  I surely should be able to rename y to x and not get a duplicate name error right?
« Last Edit: January 07, 2025, 11:23:07 pm by Warfley »

LV

  • Full Member
  • ***
  • Posts: 239
Re: Why with allows assignment
« Reply #112 on: January 07, 2025, 11:04:26 pm »
Let's get back to OP's question.
Possible answer: :)

Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. type
  4.   TTest = record
  5.     V: integer;
  6.   end;
  7.   TP = ^TTest;
  8.  
  9. var
  10.   X: TTest;
  11.  
  12.   function Test: TP;
  13.   begin
  14.     Result := @X;
  15.   end;
  16.  
  17. begin
  18.  
  19.   WriteLn(X.V);
  20.  
  21.   with Test^ do
  22.   begin
  23.     V := 1; //No Error
  24.     WriteLn(X.V);
  25.   end;
  26.  
  27.   WriteLn(X.V);
  28.  
  29.   Test^.V := 2; //No Error
  30.  
  31.   WriteLn(X.V);
  32.  
  33.   readln;
  34. end.
  35.  

Output:
0
1
1
2

440bx

  • Hero Member
  • *****
  • Posts: 5077
Re: Why with allows assignment
« Reply #113 on: January 07, 2025, 11:46:05 pm »
I answered this before. The local variable is in the local var symtable and the parameter x is in the param symtable. These two symtables are independent entities in the symbol search hierachy and therefore are different scopes.

Simple as that.
No, you didn't answer then and the above is not an answer.  I don't want implementation b.s.

The question is simple, in the following code, which is _your_ code:
Code: Pascal  [Select][+][-]
  1.  procedure foo(x: Integer);
  2. var
  3.   x: Double;
  4. begin
  5. end;
are the parameter "x" and the local variable "x" in the same scope ?  The answer is either "yes" or "no", nothing else.

if you answer "no" then you must explain why the compiler emits a "duplicate identifier" error message.

That's it.  No more b.s., answer the question. 



(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Warfley

  • Hero Member
  • *****
  • Posts: 1870
Re: Why with allows assignment
« Reply #114 on: January 08, 2025, 12:02:38 am »
That's it.  No more b.s., answer the question.

I answered that question multiple times, and if you don't understand the answer thats not my problem. The last three words of my answer to that question before are without any ambiguity an answer to that question:
Quote
are different scopes.
If you cannot comprehend 3 words and need me to boil it down to one, I can't help you.

What I find quite curious, you ask questions over questions and I answer every single one of them, yet you have not answered a single of my questions. Why do you refuse to answer any of my questions? I asked two very simple questions:
1. What is your definition of a scope? I gave my definition and a very detailed explaination (twice) why the parameter and the variables are not in the same scope.
2. If the "duplicate identifier" means that two things are in the same scope, what about the other 2 examples I've shown before that yield the same message, are these in the same scope as well?
« Last Edit: January 08, 2025, 12:04:37 am by Warfley »

440bx

  • Hero Member
  • *****
  • Posts: 5077
Re: Why with allows assignment
« Reply #115 on: January 08, 2025, 01:19:23 am »
I answered that question multiple times, and if you don't understand the answer thats not my problem.
I understand, you want to hide your ignorance and mistakes under a thick coat of b.s.

It's really simple, a "yes" or a "no" along with an explanation of why.  This is totally independent of implementation. Your going back every time to implementation details that are not applicable and totally meaningless highlights your awareness of being wrong.

It's that simple.

Any chance you can manage to say "yes" or "no" and explain why the compiler emits an error message stating there is a "duplicate identifier" ?  There you go... I'm giving you one more chance... are you going to offer more b.s or finally do the right thing and admit you are wrong ?  My guess is, most likely not.

(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Warfley

  • Hero Member
  • *****
  • Posts: 1870
Re: Why with allows assignment
« Reply #116 on: January 08, 2025, 01:50:14 am »
I understand, you want to hide your ignorance and mistakes under a thick coat of b.s.
You are the one avoiding to answer the questions. I gave you exactly what you ask for, I gave a clear definition of what a scope is and why from that definition it follows that parameters and variables are in a different scope.

You either do not understand that, which granted compiler construction is not an easy topic, it's no shame if it's over your head, or you use a different definition of scope and therefore what I consider to be in the same scope is different than what you consider to be... But then again why do you refuse to tell me what your definition is?

Just quit the b.s. and answer my question already: What is your definition of scope?

440bx

  • Hero Member
  • *****
  • Posts: 5077
Re: Why with allows assignment
« Reply #117 on: January 08, 2025, 02:22:45 am »
You provided the following garbage to the question:
I answered this before. The local variable is in the local var symtable and the parameter x is in the param symtable. These two symtables are independent entities in the symbol search hierachy and therefore are different scopes.

Simple as that.
It is irrelevant whether the local variable is in some symbol table or in Beijing.   

What's relevant in the following code (your code):
Code: Pascal  [Select][+][-]
  1.  procedure foo(x: Integer);
  2. var
  3.   x: Double;
  4. begin
  5. end;
is the reason why the compiler emits an error message stating there is a duplicate identifier. 

That's the question.  What's the reason for the compiler emitting a duplicate identifier error message. The answer does not involve implementation details such as symbol table(s) b.s.

I'll tell you why the compiler complains: because the local variable and the parameter are in the same scope.  That fact and the fact that they are named the same is what makes them duplicates.  Compiler construction 0.00000001

Read Per Brinch Hansen On Pascal Compilers.  It covers the basics and, among other things, it explains scopes.  The text is available online at Hansotten's Pascal web site but, I recommend you don't stop there.  There is a lot more than what that introductory book covers.

 
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Warfley

  • Hero Member
  • *****
  • Posts: 1870
Re: Why with allows assignment
« Reply #118 on: January 08, 2025, 02:28:26 am »
Read Per Brinch Hansen On Pascal Compilers.  It covers the basics and, among other things, it explains scopes.  The text is available online at Hansotten's Pascal web site but, I recommend you don't stop there.  There is a lot more than what that introductory book covers.

Just tell me the definition of a scope you use. Don't hide behind me having to buy a book. If you go by the definition of scope in that book, quote it to me... But I know you won't because making such a concrete claim would mean your argument would be falsifiable...

You always assert things without any evidence for it, while discarding anything that's going against your view. Take the shadowing debate earlier... It's really emblematic for your Modus operandi.
I used the term shadowing, and you didn't know it, that's nor an issue, no one knows everything, but instead of googling you asserted that because you didn't know it it doesn't make sense.
Then I showed you the Wikipedia page, and you boltly asserted, again without doing any cross checking that no major compilers uses that term. Then I did a quick search and figured that literally all major compiler and languages use that term and only after being proven wrong by multiple people you conceided.
And it's not just that you didn't know a word and you've been wrong. It's that every single time you made a concrete and falsifiable statement, which you don't do very often (see your refusal to post the definition of a scope), you have been proven wrong, and whenever you are , your first instinct is to question or outright disregard the evidence.

You always assume you are correct and never put on any work. You never provide any resources on your own to make your point but demand from others to provide more and more evidence because you simply cannot fathom being wrong.

So maybe just for once, provide something to underly your point, provide a definition of a scope. I think you cannot do that, because you don't have a concrete definition of a scope. You always operate on the basis of vaguely remembering things or how you feel things should be.

I remember our first discussion, where I literally surveyed all the academic literature on the topic of programming patterns and code quality and you didn't even read a single of the papers Ive referenced, to the point that you claimed things which the papers specifically ruled out in the first paragraphs. I spent tens of hours reading research papers, because I cared about getting the facts right. You didn't even spend 5 minutes reading anything, because you didn't want your worldview challenged
You don't engage with reality if reality doesn't align with you fantasy world. You just avoid and deflect with questions, change the topic, or just belatedly claim things that you've already been proven wrong on either just ignoring the evidence that proved you wrong, or just claim it's wrong without giving any reason why this is the case.
I rarely post anything without verifying that what I'm claiming is correct beforehand. I always try to look up anything I say before posting, you clearly don't do that. Before any of my posts here I've looked up things by looking into the sources of FPC and clang, reading the documentation on other compilers, hell even reading up on the old Compiler construction course scripts from university... Meanwhile you deny shadowing exists even though 2 seconds of googling will find you it being mentioned everywhere in documentation for pretty much any programming system

If you really think you are right, how comes you never have evidence for it?
« Last Edit: January 08, 2025, 02:49:11 am by Warfley »

440bx

  • Hero Member
  • *****
  • Posts: 5077
Re: Why with allows assignment
« Reply #119 on: January 08, 2025, 05:35:44 am »
You just can't admit being wrong.

The only reason I insist and will not stop insisting is because you are misleading other readers of this thread.

I've given you many opportunities to correct yourself but, evidently that is beyond you.

By never answering the question clearly, you have proved to be dishonest in addition to rather poorly versed in compiler theory. 
 
For the record, in the following code:
Code: Pascal  [Select][+][-]
  1.  procedure foo(x: Integer);
  2. var
  3.   x: Double;
  4. begin
  5. end;
the parameter "x" and local variable "x" are in the same scope which is the reason any Pascal compiler, including FPC, will declare there is a duplicate identifier.  This is rather simple stuff, no rocket science here.

Nobody should take my word for it, instead read the chapter on scopes in Per Brinch Hansen's book which you can find at:
http://pascal.hansotten.com/uploads/pbh/brinch%20hansen%20on%20pascal%20compilers%20OCR.pdf

The chapter starts at page 95 (book page number) or page 105 (online pdf reader page number)

Specifically, read section "6.3 COMPILATION METHOD" and pay particular attention to Figure 1's first column which clearly shows that parameters, local variables, types and constants are all in the same scope _within_ a procedure or function.  These are pages 110 & 111 (online pdf reader page numbers.)

Anyway, for anyone interested in compilers I highly recommend reading the entire book (several times if possible.)  To see a more complex example Brinch Hansen's SuperPascal is a good second step, after that, I recommend going over the source code of the P4 Pascal compiler guided by Pemberton's book.   After that you'll have a reasonably good foundation to follow with other books.  I'd suggest "Engineering a Compiler" by Cooper and Torczon.    It wouldn't hurt to read the Dragon book, you'll get plenty of useful algorithms there, you'll eventually need them.

Now, let's give the obvious answer: the reason FPC emits a "duplicate identifier" error message is because the parameter and the local variable are in the same scope.  It's that simple.  Period.

It's not rocket science and it has absolutely nothing to do with how a compiler chooses to implement scope resolution.

(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

 

TinyPortal © 2005-2018