<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div>On Dec 17, 2015, at 09:12, SAVEANT Pierre <<a href="mailto:pierre.saveant@thalesgroup.com">pierre.saveant@thalesgroup.com</a>> wrote:</div><div><br></div><blockquote type="cite"><div><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"><meta name="Generator" content="Microsoft Word 14 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri","sans-serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:"Calibri","sans-serif";
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri","sans-serif";}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:70.85pt 70.85pt 70.85pt 70.85pt;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--><div class="WordSection1"><p class="MsoNormal">Hi,<o:p></o:p></p><p class="MsoNormal"><o:p> </o:p></p><p class="MsoNormal">I got a proposal for a new feature in Python in order to perform hypothetical reasoning in a very simple way.<o:p></o:p></p><p class="MsoNormal">Hypothetical reasoning is mainly used in problem solving search algorithms.<o:p></o:p></p><p class="MsoNormal"><o:p> </o:p></p><p class="MsoNormal">In such a process, variables are temporally assigned and later restored to their preceding value.<o:p></o:p></p><p class="MsoNormal">With the assumption that only a small fraction of the variables changes at the same time, it is more efficient to store undo information instead of copying the entire state. <o:p></o:p></p><p class="MsoNormal">The basic data structure to handle these moves efficiently is called a trail which is mainly a stack with markers.<o:p></o:p></p><p class="MsoNormal">Potentially this mechanism can be provided to any object type of Python.<o:p></o:p></p><p class="MsoNormal">Only few lines are needed to implement the mechanism using the reflexive power of Python. <o:p></o:p></p><p class="MsoNormal">A deeper implementation could hide the process in the internal data representation in order to offer this new feature in a seamless way.<o:p></o:p></p><p class="MsoNormal"><o:p> </o:p></p><p class="MsoNormal">This new feature is activated with the specification of thee primitives:<o:p></o:p></p><p class="MsoNormal">- push()<o:p></o:p></p><p class="MsoNormal">- back()<o:p></o:p></p><p class="MsoNormal">- assign(object, attribute, value)<o:p></o:p></p><p class="MsoNormal"><o:p> </o:p></p><p class="MsoNormal">push : declare a new hypothetical state.<o:p></o:p></p><p class="MsoNormal">back : restore the previous state.<o:p></o:p></p><p class="MsoNormal">assign(object, attribute, value) : assign the value to the attribute of the object in the current state.<o:p></o:p></p><p class="MsoNormal"><o:p> </o:p></p><p class="MsoNormal">In addition a primitive can be provided to go back to a specific state:<o:p></o:p></p><p class="MsoNormal">backtrack(n): restore the state number n.<o:p></o:p></p><p class="MsoNormal"><o:p> </o:p></p><p class="MsoNormal">EXAMPLES<o:p></o:p></p><p class="MsoNormal"><o:p> </o:p></p><p class="MsoNormal">class Var:<o:p></o:p></p><p class="MsoNormal">    def __init__(self, value):<o:p></o:p></p><p class="MsoNormal">        self.value = value<o:p></o:p></p><p class="MsoNormal">    def __str__(self): return"{}".format(self.value)<o:p></o:p></p><p class="MsoNormal"><o:p> </o:p></p><p class="MsoNormal">def test1():<o:p></o:p></p><p class="MsoNormal">    V1 = Var(10)<o:p></o:p></p><p class="MsoNormal">    assert V1.value == 10<o:p></o:p></p><p class="MsoNormal">    push()<o:p></o:p></p><p class="MsoNormal">    assign(V1, 'value', 100)<o:p></o:p></p><p class="MsoNormal">    assert V1.value == 100<o:p></o:p></p><p class="MsoNormal">    back()<o:p></o:p></p><p class="MsoNormal">    assert V1.value == 10<o:p></o:p></p><p class="MsoNormal"><o:p> </o:p></p><p class="MsoNormal">def test2():<o:p></o:p></p><p class="MsoNormal">    V1 = Var(0)<o:p></o:p></p><p class="MsoNormal">    for i in range(8):<o:p></o:p></p><p class="MsoNormal">        push()<o:p></o:p></p><p class="MsoNormal">        for j in range(5):<o:p></o:p></p><p class="MsoNormal">            assign(V1, 'value',(j+1)+i*5-1)<o:p></o:p></p><p class="MsoNormal">    assert V1.value == 39<o:p></o:p></p><p class="MsoNormal">    assert current() == 8<o:p></o:p></p><p class="MsoNormal">    backtrack(6)<o:p></o:p></p><p class="MsoNormal">    assert V1.value == 29<o:p></o:p></p><p class="MsoNormal">    assert current() == 6<o:p></o:p></p><p class="MsoNormal">    backtrack(4)<o:p></o:p></p><p class="MsoNormal">    assert V1.value == 19<o:p></o:p></p><p class="MsoNormal">    assert current() == 4<o:p></o:p></p><p class="MsoNormal">    backtrack(0)<o:p></o:p></p><p class="MsoNormal">    assert V1.value == 0<o:p></o:p></p><p class="MsoNormal">    assert current() == 0<o:p></o:p></p><p class="MsoNormal"><o:p> </o:p></p><p class="MsoNormal">The assign procedure is used in place of the standard assignment denoted by the "=" operator.</p></div></div></blockquote><div><br></div><div>It seems like all of that can be implemented in Python today (presumably storing the set of trailed Vars as a global or as a class attribute of Var, since there doesn't seem to be any scoping involved). So, why not just build it and put it on PyPI?</div><br><blockquote type="cite"><div><div class="WordSection1"><p class="MsoNormal"><o:p></o:p></p><p class="MsoNormal">In a seamless integration the "=" assignment operator could be overridden when the variable has been previously declared as "recordable" (require a declaration primitive or a type declaration).</p></div></div></blockquote><div><br></div><div>That's one thing that couldn't be implemented in Python today, because = can't be overridden (it's a binding-and-possibly-declaring statement, not an assignment operator, in Python). But if you just made all these things attributes on some object, then you could hook its __setattr__. Plus, you could have different sets of trails in parallel, and implement whatever kind of scoping you want instead of everything being sort of global but sort of Python-scoped, and so on.</div><br><blockquote type="cite"><div class="WordSection1"><p class="MsoNormal"><o:p></o:p></p><p class="MsoNormal"><br></p><p class="MsoNormal">Is anybody interested by this new feature?<o:p></o:p></p><p class="MsoNormal"><o:p> </o:p></p><p class="MsoNormal"><o:p> </o:p></p><p class="MsoNormal">Pierre Savéant<o:p></o:p></p><p class="MsoNormal"><o:p> </o:p></p><p class="MsoNormal"><o:p> </o:p></p><p class="MsoNormal"><span lang="FR"><o:p> </o:p></span></p></div></blockquote><blockquote type="cite"><div><span>_______________________________________________</span><br><span>Python-ideas mailing list</span><br><span><a href="mailto:Python-ideas@python.org">Python-ideas@python.org</a></span><br><span><a href="https://mail.python.org/mailman/listinfo/python-ideas">https://mail.python.org/mailman/listinfo/python-ideas</a></span><br><span>Code of Conduct: <a href="http://python.org/psf/codeofconduct/">http://python.org/psf/codeofconduct/</a></span></div></blockquote></body></html>