BlackBoxCenter / blackbox

BlackBox Component Builder is an IDE and framework for the Component Pascal programming language.
http://blackboxframework.org
BSD 2-Clause "Simplified" License
52 stars 4 forks source link

Should Add(16)(25) and GetProc()() calls be supported both? #229

Open Oleg-N-Cher opened 6 months ago

Oleg-N-Cher commented 6 months ago

Sorry to post this here, I can't log into the community.blackboxframework.org - the password is long forgotten and the password recovery mechanism doesn't work.

BlackBox allows and compiles a such code:

MODULE Test1;

TYPE f = PROCEDURE(b: INTEGER): INTEGER;

VAR i: INTEGER;

PROCEDURE F (b: INTEGER): INTEGER;
BEGIN
  RETURN 1
END F;

PROCEDURE Add(a: INTEGER): f;
BEGIN
  RETURN F
END Add;

BEGIN
  i := Add(16)(25); (* We're talking specifically about this call. *)
                    (* Are you surprised? Me too. But here's a user who checked it out. *)
END Test1.

But BlackBox does not allow this code:

MODULE Test2;

TYPE Proc = PROCEDURE;

PROCEDURE proc; END proc;

PROCEDURE GetProc (): Proc; BEGIN RETURN proc END getProc;

BEGIN
  GetProc()() (* err 55: procedure call of a function *)
END Test2.

I don't claim to "improve" Component Pascal. But if the example code in Test1 is allowed, it is logical to allow the code in Test2 for symmetry. Or disallow both. At your discretion. Repost to the forum and discuss. I can't since I have read-only access to the forum.blackboxframework.org

Thank you.

jtempl commented 6 months ago

Surprising indeed. It is possible that this anomaly, if I remember correctly, is related to a syntactical detail in Oberon (BlackBox?) where a parameterless procedure can be called with or without an empty parameter list. As a work around it should be possible to assign the intermediate result to a procedure variable and call that variable in a separate statement.

Am Fr., 15. März 2024 um 03:46 Uhr schrieb Oleg N. Cher < @.***>:

Sorry to post this here, I can't log into the community.blackboxframework.org - the password is long forgotten and the password recovery mechanism doesn't work.

BlackBox allows and compiles a such code:

MODULE Test1;

TYPE f = PROCEDURE(b: INTEGER): INTEGER;

VAR i: INTEGER;

PROCEDURE F (b: INTEGER): INTEGER; BEGIN RETURN 1 END F;

PROCEDURE Add(a: INTEGER): f; BEGIN RETURN F END Add;

BEGIN i := Add(16)(25); ( We're talking specifically about this call. ) ( Are you surprised? Me too. But here's a user who checked it out. ) END Test1.

But BlackBox does not allow this code:

MODULE Test2;

TYPE Proc = PROCEDURE;

PROCEDURE proc; END proc;

PROCEDURE GetProc (): Proc; BEGIN RETURN proc END getProc;

BEGIN GetProc()() ( err 55: procedure call of a function ) END Test2.

I don't claim to "improve" Component Pascal. But if the example code in Test1 is allowed, it is logical to allow the code in Test2 for symmetry. Or disallow both. At your discretion. Repost to the forum and discuss. I can't since I have read-only access to the forum.blackboxframework.org

Thank you.

— Reply to this email directly, view it on GitHub https://github.com/BlackBoxCenter/blackbox/issues/229, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAWTI2YSSM5VZQZOYT2CJDLYYJOKDAVCNFSM6AAAAABEXHLVPOVHI2DSMVQWIX3LMV43ASLTON2WKOZSGE4DONRRGM2DKMQ . You are receiving this because you are subscribed to this thread.Message ID: @.***>

Oleg-N-Cher commented 6 months ago

Thank you for the answer. We are not so interested in a work around, but in the ideology of whether or not to allow such a call in BlackBox.

I would accept such a challenge. But it's up to you. I understand you're now the chief ideologue of BlackBox at the Center.

In Ofront+, I only allow such call in my Oberon-3 dialect. This is not allowed for Component Pascal. But if you decide to allow it in BlackBox too, I will allow it too. Compatibility is very important, even in such small things.

Only thanks to the fine compatibility of Ofront (OMinc version) and BlackBox was it possible to get a BlackBox port on ARMv7 with a little effort.

jtempl commented 6 months ago

How is it handled by my ofront? ofront is based on a pretty old compiler front end, very close to the original Oberon compilers.

Is there any hint in the Oberon or CP language report about this anomaly?

Oleg N. Cher @.***> schrieb am Mo., 18. März 2024, 22:43:

Thank you for the answer. We are not so interested in a work around, but in the ideology of whether or not to allow such a call in BlackBox.

I would accept such a challenge. But it's up to you. I understand you're now the chief ideologue of BlackBox at the Center.

In Ofront+, I only allow such call in my Oberon-3 dialect. This is not allowed for Component Pascal. But if you decide to allow it in BlackBox too, I will allow it too. Compatibility is very important, even in such small things.

Only thanks to the fine compatibility of Ofront (OMinc version) and BlackBox was it possible to get a BlackBox port on ARMv7 with a little effort.

— Reply to this email directly, view it on GitHub https://github.com/BlackBoxCenter/blackbox/issues/229#issuecomment-2005086718, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAWTI25E7WGT6GNTUFAPI2LYY5NWVAVCNFSM6AAAAABEXHLVPOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMBVGA4DMNZRHA . You are receiving this because you commented.Message ID: @.***>

Oleg-N-Cher commented 6 months ago

Ofront v1.2.3 for BlackBox:

image

image

OPCL (based on ETH PlugIn Oberon 2.4):

image

image

As far as I know, the Oberon or CP language report doesn't mention anything like that in any way.

Since you say "anomaly", I infer that you don't like this feature? 😊

jtempl commented 5 months ago

I still think that it must be related somehow to the syntactical alternatives of calling a parameterless non-function procedure with or without a parameter list.

Assume there is no parameter list.

If there is an assignment statement p:=GetProc(); and the right hand side evaluates to a procedure, it means to assign the procedure, not to call it. If there is no assignment but only a function call GetProc(); it means ?

  1. Call the returned procedure, or
  2. Error: procedure call of a function.

In a compiler that generates code in a strictly context free way, such as all compilers by N. Wirth, this leads to an ambiguity because without the knowledge of the context the code generator does not know which alternative to chose for GetProc(). It is my guess that the observed anomaly is rooted in this ambiguity.

It could be argued that in case of an existing parameter list, the ambiguity is removed. But this rare case was probably not considered worth a complication in the original compiler by N. Wirth and has been taken over by newer compiler front ends for reasons of compatibility.

In the CP Language Report in Chapter 8.1 (Operands) we find a subtle hint regarding this behavior, I think: If it [the designated object] is a procedure, the designator refers to that procedure unless it is followed by a (possibly empty) parameter list in which case it implies an activation of that procedure and stands for the value resulting from its execution.

This implicitly rules out calling non-function procedures as in the non-function GetProc()() example because there is no value resulting from its execution.