vermaseren / form

The FORM project for symbolic manipulation of very big expressions
GNU General Public License v3.0
1.14k stars 136 forks source link

Relaxing the order of statements for some declarations/module options #188

Open tueda opened 7 years ago

tueda commented 7 years ago

The fact that FORM forces users to follow the strict order of statements gives unnecessary complexity for some cases.

Consider a procedure containing executable statements with local $-variables, for example,

#procedure Foo()
  $FooPRIVATEx = term_;
* Use $FooPRIVATEx locally.
#endprocedure

which can be called like

if (count(SomeLabel,1));
  #call Foo()
endif;

A problem occurs when one wants to parallelize the program, which requires ModuleOption local,$FooPRIVATEx at the end of the module due to the order of the statements.

A solution for this would be to pass temporary $-variables as arguments of a procedure

#procedure ProcWithManyTempVars(tmp1,...,tmp9)
  `tmp1' = term_;
* ...
#endprocedure

* ...
#call ProcWithManyTempVars(<$tmp1>,...,<$tmp9>)
* ...
ModuleOption local,<$tmp1>,...,<$tmp9>;
.sort

Another solution that I saw is to make an additional procedure just for the module options

#procedure ProcWithManyTempVars()
  $procPRIVATEx = term_;
* ...
#endprocedure

#procedure ProcWithManyTempVarsModuleOptons()
  ModuleOption local,$procPRIVATEx;
* ...
#endprocedure

* ...
#call ProcWithManyTempVars()
* ...
#call ProcWithManyTempVarsModuleOptions()
.sort

But it would be smart to allow ModuleOption local to be at any places. Then we could write

#procedure Foo()
  $FooPRIVATEx = term_;
* Use $FooPRIVATEx locally.
  ModuleOption local,$FooPRIVATEx;  * Nice if allowed!
#endprocedure

A test implementation is at https://github.com/tueda/form/commit/loosedecl. This patch also relaxes the order for some of declarations (for example Symbols) such that the following code works

#procedure deriv(x)
  S derivPRIVATEy;
  id `x'^derivPRIVATEy? = derivPRIVATEy * `x'^derivPRIVATEy / `x';
#endprocedure

S y;
L F = y^3;
#call deriv(y)
#call deriv(y)
P;
.end

Am I missing any potential problems that could be caused by this change?

vermaseren commented 7 years ago

Hi Takahiro,

How about if the ordering information is kind of ‘reset’ inside the procedure? This would mean that from the viewpoint of the procedure it is a module by itself (or more than one if there are .sort’s inside. Hence the declarations (if there is no .sort) have to be at the beginning and the ModuleOption has to be at the end. That keeps it a bit cleaner and it does not affect the ordering outside the procedures. Just a question. You may have counter-arguments.

Cheers

Jos

On 30 mei 2017, at 22:22, Takahiro Ueda notifications@github.com wrote:

The fact that FORM forces users to follow the strict order of statements gives unnecessary complexity for some cases.

Consider a procedure containing executable statements with local $-variables, for example,

procedure Foo()

$FooPRIVATEx = term_;

  • Use $FooPRIVATEx locally.

    endprocedure

    which can be called like

if (count(SomeLabel,1));

call Foo()

endif; A problem occurs when one wants to parallelize the program, which requires ModuleOption local,$FooPRIVATEx at the end of the module due to the order of the statements.

A solution for this would be to pass temporary $-variables as arguments of a procedure

procedure ProcWithManyTempVars(tmp1,...,tmp9)

`tmp1' = term_;

  • ...

    endprocedure

  • ...

    call ProcWithManyTempVars(<$tmp1>,...,<$tmp9>)

  • ... ModuleOption local,<$tmp1>,...,<$tmp9>; .sort Another solution that I saw is to make an additional procedure just for the module options

procedure ProcWithManyTempVars()

$procPRIVATEx = term_;

  • ...

    endprocedure

procedure ProcWithManyTempVarsModuleOptons()

ModuleOption local,$procPRIVATEx;

  • ...

    endprocedure

  • ...

    call ProcWithManyTempVars()

  • ...

    call ProcWithManyTempVarsModuleOptions()

    .sort But it would be smart to allow ModuleOption local to be at any places. Then we could write

procedure Foo()

$FooPRIVATEx = term_;

  • Use $FooPRIVATEx locally. ModuleOption local,$FooPRIVATEx; * Nice if allowed!

    endprocedure

    A test implementation is at tueda/form@loosede https://github.com/tueda/form/commit/loosedecl. This patch also relaxes the order for some of declarations (for example Symbols) such that the following code works

procedure deriv(x)

S derivPRIVATEy; id x'^derivPRIVATEy? = derivPRIVATEy *x'^derivPRIVATEy / `x';

endprocedure

S y; L F = y^3;

call deriv(y)

call deriv(y)

P; .end — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/vermaseren/form/issues/188, or mute the thread https://github.com/notifications/unsubscribe-auth/AFLxEqkK2_wopDV7z0umicOKdZbNDq84ks5r_HppgaJpZM4NqzLa.

tueda commented 7 years ago

Hi Jos, a counter argument would be how to forbid dirty additonal definitions in procedures:

#procedure proc()
  L F2 = x;
#endprocedure

L F1 = x;
id x = 1;
#call proc()
.end

which is a reason why the order of the statements was introduced, as far as I understood. Resetting the order in the procedure would be too much and may cause this kind of ambiguity.

vermaseren commented 7 years ago

OK, that is a pity and does not have such an easy solution, because just vetoing definitions is no good either and remembering where you were for a partial reset does not work when calling a procedure from a procedure. Of course it can be solved, but it will not be completely easy. But your solution is also not 100% clean.

do i = 1,10

#call proc()

enddo

will pile up the declarations and ModuleOptions. FORM will accept the declarations but I am not sure about the ModuleOptions. Better check that. (plus whatever else?).

Cheers

Jos (still thinking)

On 30 mei 2017, at 22:43, Takahiro Ueda notifications@github.com wrote:

Hi Jos, a counter argument would be how to forbid dirty additonal definitions in procedures:

procedure proc()

L F2 = x;

endprocedure

L F1 = x; id x = 1;

call proc()

.end which is a reason why the order of the statements was introduced, as far as I understood. Resetting the order in the procedure would be too much and may cause this kind of ambiguity.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/vermaseren/form/issues/188#issuecomment-305002407, or mute the thread https://github.com/notifications/unsubscribe-auth/AFLxEuCo1vfR8XUXXI1tMVK6Hb7oPKfSks5r_H-JgaJpZM4NqzLa.

tueda commented 7 years ago

I think repeating the same ModuleOption,local has no problem:

On name;

#procedure foo()
  $x = term_;
  P "%$", $x;
  ModuleOption local,$x;
#endprocedure

L F = 1;
#do i=1,10
  #call foo()
#enddo
.end
FORM 4.1 (May 30 2017, v4.1-20131025-347-g024988f) 64-bits  Run: Tue May 30 23:02:58 2017

 Expressions
   F(local)
 Dollar variables
   $x
 Dollar variables to be modified
   $x(local)
1
1
1
1
1
1
1
1
1
1
tueda commented 7 years ago

Another example that gives messy code without local module option is the case with #if...#endif.

#if `OPTIONALSWITCH'
* Use $x, $y.
#endif

* Many lines...

* Module option also needs #if ... #endif.
#if `OPTIONALSWITCH'
ModuleOption local $x,$y;
#endif
.sort

It violates the Principle of Locality and makes the program less readable.

tueda commented 6 years ago

I found it is also useful to write ModuleOption noparallel at anywhere, because sometimes it is very difficult to find the next .sort in complicated programs (effectively in all practical FORM programs with highly nested calls of procedures), and Exit statements in tform sometimes try to fill all my disk quota by writing a neverending log file with random data due to #14.