#1562 goto in EO
#1562 goto in EO
@mximp how about this:
[f] > goto
memory 0 > m
random.pseudo > badge!
while. > @
m.eq 0
[i]
try > @
[]
seq > @
m.write 1
f token
[e]
if. > @
e.b.eq badge
e.v
error e
nop
# callback object for generating errors
[] > token
# forward jump
[r] > forward
error > @
[]
r > v
badge > b
seq > backward
m.write 0
error
[]
TRUE > v
badge > b
@mximp maybe random.pseudo can be replaced with $.< -- it's always unique, while random numbers are not
@mximp maybe
random.pseudocan be replaced with$.<-- it's always unique, while random numbers are not
@yegor256 great idea to have identifier of a token to distinguish to let the exception flowing up. The only question is in this case eo-runtime becomes dependant on eo-math (if we use random). We can try $.< though.
@mximp maybe
random.pseudocan be replaced with$.<-- it's always unique, while random numbers are not@yegor256 great idea to have identifier of a token to distinguish to let the exception flowing up. The only question is in this case
eo-runtimebecomes dependant oneo-math(if we userandom). We can try$.<though.
@yegor256 Surprisingly it worked with little effort :) Please review and merge
@MikhailLipanin please, take a look at this one, curious about your opinion
@mximp I believe, the problem is that the try object is still not declarative. It dataizes the body instead of returning it. Also, it dataizes the "catch" and "finally" blocks, instead of returning them. This is what causes the "double-dataization" problem you faces here.
Try to change the way try deals with catch-finally blocks. Return them without dataization. I think the issue will be fixed in this branch.
Try to change the way
trydeals with catch-finally blocks. Return them without dataization. I think the issue will be fixed in this branch.
@yegor256 We will have double-dataization issue as we have with while. try has to dataize its body in order to catch exceptions, and after that the body (or catch body) will be returned and dataized. Moreover in case of try inside while (case for goto) this will lead to even more counterintuitive results.
For example the following code will produce 13:
memory 0 > i
seq
i.write 1
goto
[g]
seq > @
i.write (i.plus 1)
if.
i.lt 10
g.backward
TRUE
stdout "Finished!"
i
Is that what we want?
Try to change the way try deals with catch-finally blocks. Return them without dataization...
@yegor256 Also finally body must be either never returned or returned always. I believe you meant that either main body or catch body has to be returned.
@mximp check this, maybe will help: https://news.eolang.org/2022-12-22-declarative-while.html (the example at the end of the article)
@mximp check this, maybe will help: https://news.eolang.org/2022-12-22-declarative-while.html (the example at the end of the article)
@yegor256 I've read the post... We will probably need the same for try and goto ))
I've updated try - please recheck and merge
@yegor256 please check and merge
@yegor256 reminder
@mximp this is too dangerous to make such a change. You are breaking the contract of the goto atom and leaving the puzzle, which may not be solved soon. It's better to try to find a final solution here or drop this change.
@yegor256 I believe, these changes are not as significant as changing the behavior of the while object. We almost never use goto in our code.
So why while object changing doesn't break the contract of the while atom, while goto does?
@yegor256 And what are the limitations of using the PDD methodology?
@yegor256 I believe, these changes are not as significant as changing the behavior of the
whileobject. We almost never usegotoin our code. So whywhileobject changing doesn't break the contract of thewhileatom, whilegotodoes?
@yegor256 I support this... Why can't we follow the same approach as with while: commit the changes, release new version of runtime, build home and fix all issues? I believe we will have not that many issues.
@yegor256 I believe, these changes are not as significant as changing the behavior of the
whileobject. We almost never usegotoin our code. So whywhileobject changing doesn't break the contract of thewhileatom, whilegotodoes?
@Graur, you mean that if we changed the behavior of while object via rewriting EObool$EOwhile.java, we need to do this with goto?
May be goal of this is to get the same result of behavior for object goto, but with minimizing number of atoms (like here, we remove EO_goto.java to make it use try object)
@Graur the changes with the while atom were final, we just introduced them and never except to roll them back. Here, the changes just introduced are temporary, since they break the logic of goto and are supposed to be reverted (that's why the puzzle). It's not a good idea to use PDD this way. PDD is supposed to introduce partial code, but not broken code. I suggest we try to implement the goto atom correctly, or leave it in Java without any changes.
@yegor256, As I understand, we now have to change objects as lazy-style, like it has been done with while.
Rewriting a goto to .eo is just an enhancement.
So, may be for a first time, we just change EO$goto.java to a lazy style, and later, remove this object using goto.eo and try object, WDYT?
@MikhailLipanin I don't see why and how we should change the logic of goto. It seems to be working correctly as it is now (in Java).
@Graur, you mean that if we changed the behavior of
whileobject via rewritingEObool$EOwhile.java, we need to do this withgoto? May be goal of this is to get the same result of behavior for objectgoto, but with minimizing number ofatoms(like here, we removeEO_goto.javato make it usetryobject)
@MikhailLipanin No, I just want to understand why these changes are so dangerous.
@yegor256, I meant that if earlier the while object has been returning the "data" --- now it returns the "last body".
Do we need this for EOgoto.java?
so this code:
[] > main
memory 0 > x
memory 0 > y
seq > @
foo
bar
stdout
sprintf "x is %d\n"
x
stdout
sprintf "y is %d\n"
y
while. > foo
x.lt 10
[i]
x.write > @
x.plus 1
goto > bar
[g]
if. > @
y.lt 10
seq
y.write (y.plus 1)
g.backward
y
Now returns:
x is 11
y is 10
Should it return the following?
x is 11
y is 11
Correct me if I'm wrong somewhere
Should it return the following?
x is 11 y is 11Correct me if I'm wrong somewhere
@yegor256 @MikhailLipanin I would ask the same question: shouldn't goto follow the same semantics as while and try, i.e. return body-object it wraps (which in turn means additional dataization of it)?
@Graur the changes with the
whileatom were final, we just introduced them and never except to roll them back. Here, the changes just introduced are temporary, since they break the logic ofgotoand are supposed to be reverted (that's why the puzzle). It's not a good idea to use PDD this way. PDD is supposed to introduce partial code, but not broken code. I suggest we try to implement thegotoatom correctly, or leave it in Java without any changes.
@yegor256 As for me, it looks similar to how while object was updated. What is the difference between partial code and broken code in this case? Both pass all checks and have only part of their own functionality.
@mximp let's change the Java implementation of goto first, making it "declarative" as we did with while. Then, we'll try to transfer it to EO and get rid of Java. So, I suggest submitting a new PR where you will only modify Java code (and maybe some tests).
@mximp let's change the Java implementation of
gotofirst, making it "declarative" as we did withwhile. Then, we'll try to transfer it to EO and get rid of Java. So, I suggest submitting a new PR where you will only modify Java code (and maybe some tests).
@yegor256 making goto declarative (even within Java implementation) will force additional dataization anyway. So the expected result will be changed. How will that be different from suggested implementation in pure EO?
@mximp if we do it in Java first, we will clearly separate a feature from a bug. If you change Java implementation and EO tests will fail, we will understand that it's a feature. With the current PR it's hard to say whether the changes you are making are a new feature of the goto atom or a bug in the implementation.
Changes from master which related to try and goto need to be picked up. It is also needed to think of a way to get rid of unexpected side effects.
The suggested approach to use .@.< for avoiding double datataization works only for atoms.
The following example:
[] > goto-jumps-backwards-without-last-datization
memory 0 > i
assert-that > @
seq
i.write 1
goto
[g]
seq > @
i.write (i.plus 1)
if.
i.lt 10
g.backward
TRUE
.@
.<
stdout "Finished!"
i
$.equal-to 10
works only if goto is implemented as atom since it defines @ attribute as AtComposite which is an expression running all the logic for goto (dataization) and is executed once .get() is requested (i.e. the expression is executed every time we asking for @).
On the other hand when goto is implemented in EO it defines its @ as new AtOnce(new AtComposite()), where AtComposite is an expression which constructing the internals of the goto but not dataizing it:
this.add("φ", new AtOnce(new AtComposite(this, rho -> {
Phi ret = Phi.Φ.attr("org").get().attr("eolang").get().attr("seq").get();
ret = new PhLocated(ret, 69, 2);
ret = new PhCopy(ret);
Phi ret_1_base = new EOgoto$EOt4$EOt0$EOa0(rho);
ret_1_base = new PhLocated(ret_1_base, 71, 6);
Phi ret_1 = new PhMethod(ret_1_base, "while");
ret_1 = new PhLocated(ret_1, 70, 4);
ret_1 = new PhCopy(ret_1);
Phi ret_1_1 = Phi.Φ.attr("org").get().attr("eolang").get().attr("nop").get();
ret_1_1 = new PhLocated(ret_1_1, 92, 6);
ret_1 = new PhWith(ret_1, 0, ret_1_1);
Phi ret_2 = new PhMethod(rho, "c");
ret_2 = new PhLocated(ret_2, 93, 4);
ret = new PhWith(ret, 0, ret_1);
ret = new PhWith(ret, 1, ret_2);
return ret;
})));
In the latter case goto.@.< would just construct the object which is seq and return its vertex without dataizatation.
That means if we rewrite goto in EO it would be impossible to avoid double (even triple) dataization.
@yegor256 Any solution you see here to overcome this?
Alternatively we will leave goto as atom.
@yegor256 reminder