Giter Club home page Giter Club logo

Comments (11)

norayr avatar norayr commented on September 14, 2024 1

I am not sure this is a bug. Isn't this about strong typing?
In Oberon (and Modula-2), if you declare

TYPE
   a = RECORD x,y : INTEGER END;
   b = RECORD x,y : INTEGER END;

then variables of types a and b cannot be assigned to each other.
Same happens here, right?

In your example it is not obvious for a compiler, that the parameter which function SetUp receives has the same type as setUp variable's type. When compiler meets VAR setUp : PROCEDURE; it creates an anonymous type, and variables of two different anonymous procedure types should not be assigned.

In this example we explicitly declare different procedural types:

MODULE Test0;

TYPE  p0 = PROCEDURE;
      p1 = PROCEDURE;
VAR
  setUp : p0;
  count : INTEGER;

PROCEDURE SetUp*(pr : p0);
BEGIN setUp := pr
END SetUp;


BEGIN count := 0;
END Test0.

I have checked with oo2c and BlackBox, both are able to compile Armen's code. I guess this means that the type checking rules of oo2c and BlackBox are weaker.
Other opinions?

from compiler.

MarkowEduard avatar MarkowEduard commented on September 14, 2024 1

Norayr is right: This is due to strong typing.
Probably the same happens with Modula-2 and Pascal.
There is a long term discussion about the difference between types of variables and procedures. There is no explicit type declaration for procedures; the type of a procedure is declared implicitly. For procedures the compiler has to check type compatibility of assignments by comparing the structures, for variables the check is done by comparing names (or nodes in the compiler data structure).
One proposal is to relax the rules and also compare the structures when variables are assigned, another proposal is to relax the rules and compare the structures when procedure variables are involved only.
It seems that the implementors of OO2C and Component Pascal have choosen to relax the rules at least for procedure variables.
I think to relax the rules for procedure variables is okay if it only needs a few lines in the compiler, but I don't think that this has any relevance for object oriented development because there procedure variables aren't used anymore.

from compiler.

norayr avatar norayr commented on September 14, 2024

checked with voc-1.1 on x86, the same problem exists. thank you.

from compiler.

norayr avatar norayr commented on September 14, 2024

update: OP2 compiler from OLR project also issues 'incompatible assignment' error.

from compiler.

armenbadal avatar armenbadal commented on September 14, 2024

Maybe it is my misunderstanding of the type PROCEDURE. If after declaration:

TYPE Test = PROCEDURE;

Test means "a procedure which has no parameters and no return value" (like void(*)(void)), then, I assume, there is n problem with assignment.

But if Type means "any procedure" (like void*), then, yes, it is not obvious for compiler that sides of assignment have the same type.

from compiler.

diegosardina avatar diegosardina commented on September 14, 2024

OP2 and voc implementations are correct.

In Oberon assignment among procedure variables follows name equivalence, i.e. it holds if they have the same type. But there is an exception in the case of assignment of a procedure constant to a procedure variable, in this case structural equivalence applies, i.e. they have the same structure or signature.

VAR
   varproc1, varproc2 : PROCEDURE(i : INTEGER);
   varproc3 : PROCEDURE(i : INTEGER);

PROCEDURE ConstProc1(i : INTEGER); BEGIN END ConstProc1;
PROCEDURE ConstProc2(r : REAL); BEGIN END ConstProc2;

PROCEDURE TestAssign(parproc : PROCEDURE(i : INTEGER)); BEGIN END TestAssign;

(* Name equivalence *)
varproc1 := varproc2; (* Valid, varproc1 and varproc2 have the same (anonymous) type *)
varproc1 := varproc3; (* Error, varproc1 and varproc3 have different (anonymous) types *)
TestAssign(varproc1); (* Error, parproc  and varproc1 have different (anonymous) types *)

(* Structural equivalence *)
varproc1 := ConstProc1; (* Valid, varproc1 and ConstProc1 have the same signature *)
varproc1 := ConstProc2; (* Error, varproc1 and ConstProc2 have different signatures *)
TestAssign(ConstProc1); (* Valid, parproc  and ConstProc1 have the same signature *)

In the code posted above, a procedure constant is passed as a parameter, in this case assignment rules apply with structural equivalence. But inside the procedure, 'pr' is a procedure variable, so name equivalence applies in this case and it has a different (anonymous) type from the (anonymous) 'setUp' type.
So the assignment is not valid.

from compiler.

armenbadal avatar armenbadal commented on September 14, 2024

OK. Now everything is clear. I think, there is no need to keep this issue in open state.

from compiler.

diegosardina avatar diegosardina commented on September 14, 2024

This issue should be reopened, just to clarify better what is going on.

While I was around in the Oberon-2 Report, I happen to see the definition of equal types and same types:

Same types

Two variables a and b with types Ta and Tb are of the same type if
1. Ta and Tb are both denoted by the same type identifier, or
2. Ta is declared to equal Tb in a type declaration of the form Ta = Tb or
3. a and b appear in the same identifier list in a variable, record field, or formal parameter declaration and are not open arrays.

Equal types

Two types Ta and Tb are equal if

  1. Ta and Tb are the same type, or
  2. Ta and Tb are open array types with equal element types, or
    3. Ta and Tb are procedure types whose formal parameter lists match.

Assignment compatible

An expression e of type Te is assignment compatible with a variable v of type Tv if one of the following conditions hold:
1. Te and Tv are the same type;
[...]
7. Tv is a procedure type and e is the name of a procedure whose formal parameters match those of Tv.

http://www.ssw.uni-linz.ac.at/Research/Papers/Oberon2.pdf

Assignment among procedure variables follow name equivalence, due to (1) in Assignment compatible and in the case of an assignment of a procedure constant to a procedure variable follow structural equivalence due to (7).

Same types and equal types mean different things and this is why many Oberon-2 implementations failed to conform the Oberon-2 report.
It seems that the introduction of equal types makes the type checking weaken in the case of open arrays and procedure types, so they follow structural equivalence.

In my opinion it is better to clarify these points, since a lot of Oberon-2 implementations are wrong.

from compiler.

diegosardina avatar diegosardina commented on September 14, 2024

In Component Pascal (a superset of Oberon-2) it is different:

Assignment compatible

An expression e of type Te is assignment compatible with a variable v of type Tv if one of the following conditions hold:
1. Te and Tv are equal [...] type;

So in Component Pascal procedure variables follow structural equivalence.

I wonder if Oberon-2 report contains a mistake in Assignment compatible section.
Same types should be equal types, like in Component Pascal.

from compiler.

MarkowEduard avatar MarkowEduard commented on September 14, 2024

OP2 conforms to the Oberon-2 report with respect to assignment compatibilty.
This holds for all ETH OP2 versions (SPARC, PowerPC etc.) and also for the Linz OP2 versions (Windows, Mac, Linux); this holds also for VOC.

Assignment compatible

An expression e of type Te is assignment compatible with a variable v of type Tv if one of the following conditions hold:

  1. Te and Tv are the same type;
  2. Te and Tv are numeric types and Tv includes Te;
  3. Te and Tv are record types and Te is an extension of Tv and the dynamic type of v is Tv ;
  4. Te and Tv are pointer types and Te is an extension of Tv;
  5. Tv is a pointer or a procedure type and e is NIL;
  6. Tv is ARRAY n OF CHAR, e is a string constant with m characters, and m < n;
  7. Tv is a procedure type and e is the name of a procedure whose formal parameters match those of Tv.

We only have to look at (1) and (7), the definition of equal types is not used.

(1) requires that the types are the same. Since the types of both variables, the global variable and the parameter, are anonymous condition (1) is not fulfilled.

(7) requires that the variable of the left side has a declard, i.e. not anonymous, type. Therefore condition (7) is also not fulfilled.

Conditions (2) through (6) are obviously also not fulfilled, hence the assignment is illegal which is exactly what the compiler reports.

The topic should be closed.

from compiler.

diegosardina avatar diegosardina commented on September 14, 2024

@MarkowEduard it's not that easy.

I already wrote that Oberon-2 report states name equivalence for procedure variables but this was my interpretation. We are talking about a very concise language report that often had led to wrong interpretations and it happened more than once.

In my opinion further investigations were needed, since non-OP2 implementations and Oberon-07 did it wrong. Component Pascal clearly states in the report that procedure variables follow structural equivalence, althought not documented in What's New document.

Prof. Moessenboeck and Prof. Wirth confirmed that procedure variables follow the principle of name equivalence, with the exceptional case of procedure constant.

Then why some implementations did it wrong? I came to the conclusion that all this started by Dr. Martin Reiser, who stated on his book Programming in Oberon - Steps beyond Pascal and Modula, that procedure variables are compatible by their structure. He was wrong or didn't express his arguments precisely. This book was taken in account as reference when some Oberon implementors began to write a compiler.

Now that everything is clear, this issue may be closed.

from compiler.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.