{"thread":{"id":"44895","subject":"[RFH - Tcl/Tk] use of procedure before declaration?","startedAt":"2017-01-16T22:45:09Z","lastAt":"2017-01-18T06:58:14Z","messageCount":4,"participants":["Philip Oakley","Johannes Schindelin","Konstantin Khomoutov"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"309504","messageId":"F9099DB3F0374D898776BD2621BF36FA@PhilipOakley","threadId":"44895","inReplyTo":null,"subject":"[RFH - Tcl/Tk] use of procedure before declaration?","fromName":"Philip Oakley","fromEmail":"philipoakley@iee.org","sentAt":null,"receivedAt":"2017-01-16T22:45:09Z","isPatch":false,"sender":{"key":"philipoakley@iee.email","avatar":"https://avatars.githubusercontent.com/u/914343?v=4"},"body":"I'm looking into a user git-gui problem\n(https://github.com/git-for-windows/git/issues/1014) that I'd seen in the\npast - I'd started some patches back in Dec 2015\nhttp://public-inbox.org/git/1450310287-4936-1-git-send-email-philipoakley@iee.org/\n\nI'm trying to make sure I have covered the corner cases correctly, and I'm\nnot sure if the current code actually works as advertised.\n\nIn\nhttps://github.com/git/git/blob/master/git-gui/lib/choose_repository.tcl#L242\nthe procedure `_unset_recentrepo` is called, however the procedure isn't\ndeclared until line 248. My reading of the various Tcl tutorials suggest\n(but not explictly) that this isn't the right way.\n\nShould 3c6a287 (\"git-gui: Keep repo_config(gui.recentrepos) and .gitconfig\nin sync\", 2010-01-23) have declared `proc _unset_recentrepo {p}` before\n`proc _get_recentrepos {}` ?\n\n--\n\nPhilip\n\n"},{"id":"309513","messageId":"alpine.DEB.2.20.1701171218260.3469@virtualbox","threadId":"44895","inReplyTo":"F9099DB3F0374D898776BD2621BF36FA@PhilipOakley","subject":"Re: [RFH - Tcl/Tk] use of procedure before declaration?","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-01-17T11:29:23Z","receivedAt":"2017-01-17T11:36:28Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Philip,\n\nOn Mon, 16 Jan 2017, Philip Oakley wrote:\n\n> In\n> https://github.com/git/git/blob/master/git-gui/lib/choose_repository.tcl#L242\n> the procedure `_unset_recentrepo` is called, however the procedure isn't\n> declared until line 248. My reading of the various Tcl tutorials suggest\n> (but not explictly) that this isn't the right way.\n\nIndeed, calling a procedure before it is declared sounds incorrect.\n\nSince documentation can be treacherous, let's just test it. With a `tclsh`\nwhose `$tcl_version` variable claims that this is version 8.6, this\nscript:\n\n```tcl\nhello Philip\n\nproc hello {arg} {\n        puts \"Hi, $arg\"\n}\n```\n\n... yields the error message:\n\n\tinvalid command name \"hello\"\n\t    while executing\n\t\"hello Philip\"\n\n... while this script:\n\n```tcl\nproc hello {arg} {\n        puts \"Hi, $arg\"\n}\n\nhello Philip\n```\n\n... prints the expected \"Hi, Philip\".\n\nHaving said that, in the code to which you linked, the procedure is not\nactually called before it is declared, as the call is inside another\nprocedure.\n\nIndeed, the entire file declares one object-oriented class, so no code\ngets executed in that file:\n\nhttps://github.com/git/git/blob/d7dffce1c/git-gui/lib/choose_repository.tcl#L4\n\n(I guess proper indentation would make it easier to understand that this\nfile is defining a class, not executing anything yet).\n\nAnd it is perfectly legitimate to use not-yet-declared procedures in other\nprocedures, otherwise recursion would not work.\n\n> Should 3c6a287 (\"git-gui: Keep repo_config(gui.recentrepos) and .gitconfig\n> in sync\", 2010-01-23) have declared `proc _unset_recentrepo {p}` before\n> `proc _get_recentrepos {}` ?\n\nGiven the findings above, I believe that the patch is actually correct.\n\nCiao,\nDscho\n"},{"id":"309574","messageId":"826895153F394EB29B0D27F3EB9A67C9@PhilipOakley","threadId":"44895","inReplyTo":"alpine.DEB.2.20.1701171218260.3469@virtualbox","subject":"Re: [RFH - Tcl/Tk] use of procedure before declaration?","fromName":"Philip Oakley","fromEmail":"philipoakley@iee.org","sentAt":null,"receivedAt":"2017-01-17T23:33:05Z","isPatch":false,"sender":{"key":"philipoakley@iee.email","avatar":"https://avatars.githubusercontent.com/u/914343?v=4"},"body":"From: \"Johannes Schindelin\" <Johannes.Schindelin@gmx.de>\n> Hi Philip,\n>\n> On Mon, 16 Jan 2017, Philip Oakley wrote:\n>\n>> In\n>> https://github.com/git/git/blob/master/git-gui/lib/choose_repository.tcl#L242\n>> the procedure `_unset_recentrepo` is called, however the procedure isn't\n>> declared until line 248. My reading of the various Tcl tutorials suggest\n>> (but not explictly) that this isn't the right way.\n>\n> Indeed, calling a procedure before it is declared sounds incorrect.\n>\n> Since documentation can be treacherous, let's just test it. With a `tclsh`\n> whose `$tcl_version` variable claims that this is version 8.6, this\n> script:\n>\n> ```tcl\n> hello Philip\n>\n> proc hello {arg} {\n>        puts \"Hi, $arg\"\n> }\n> ```\n>\n> ... yields the error message:\n>\n> invalid command name \"hello\"\n>     while executing\n> \"hello Philip\"\n>\n> ... while this script:\n>\n> ```tcl\n> proc hello {arg} {\n>        puts \"Hi, $arg\"\n> }\n>\n> hello Philip\n> ```\n>\n> ... prints the expected \"Hi, Philip\".\n>\n> Having said that, in the code to which you linked, the procedure is not\n> actually called before it is declared, as the call is inside another\n> procedure.\n>\n> Indeed, the entire file declares one object-oriented class, so no code\n> gets executed in that file:\n>\n> https://github.com/git/git/blob/d7dffce1c/git-gui/lib/choose_repository.tcl#L4\n>\n> (I guess proper indentation would make it easier to understand that this\n> file is defining a class, not executing anything yet).\n>\n> And it is perfectly legitimate to use not-yet-declared procedures in other\n> procedures, otherwise recursion would not work.\n>\n>> Should 3c6a287 (\"git-gui: Keep repo_config(gui.recentrepos) and \n>> .gitconfig\n>> in sync\", 2010-01-23) have declared `proc _unset_recentrepo {p}` before\n>> `proc _get_recentrepos {}` ?\n>\n> Given the findings above, I believe that the patch is actually correct.\n>\n> Ciao,\n> Dscho\n>\nThanks for the clarification. I'll update the old patch series and see if we \ncan get this fixed.\n\nPhilip \n\n"},{"id":"309613","messageId":"20170118094306.a17083eecd94c0f39b760081@domain007.com","threadId":"44895","inReplyTo":"alpine.DEB.2.20.1701171218260.3469@virtualbox","subject":"Re: [RFH - Tcl/Tk] use of procedure before declaration?","fromName":"Konstantin Khomoutov","fromEmail":"kostix+git@007spb.ru","sentAt":"2017-01-18T06:43:06Z","receivedAt":"2017-01-18T06:58:14Z","isPatch":false,"sender":{"key":"kostix+git@007spb.ru","avatar":null},"body":"On Tue, 17 Jan 2017 12:29:23 +0100 (CET)\nJohannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n\n> > In\n> > https://github.com/git/git/blob/master/git-gui/lib/choose_repository.tcl#L242\n> > the procedure `_unset_recentrepo` is called, however the procedure\n> > isn't declared until line 248. My reading of the various Tcl\n> > tutorials suggest (but not explictly) that this isn't the right way.\n> \n> Indeed, calling a procedure before it is declared sounds incorrect.\n[...]\n> And it is perfectly legitimate to use not-yet-declared procedures in\n> other procedures, otherwise recursion would not work.\n[...]\n\nSorry for chiming in too late, but I'd throw a bit of theory in.\n\nSince Tcl is an interpreter (though it automatically compiles certain\nstuff to bytecode as it goes through the script, and caches this\nrepresentation), everything is interpreted in the normal script order --\ntop to bottom as we usually see it in a text editor.\n\nThat is, there are simply no declaration vs definition: the main script\npassed to tclsh / wish is read and interpreted from top to bottom;\nas soon as it calls the [source] command, the specified script is read\nand interpreted from top to bottom etc; after that the control is back\nto the original script and its interpretation continues.\n\nHence when Tcl sees a command (everything it executes is a command; this\nincludes stuff like [proc], [foreach] and others, which are syntax in\nother languages) it looks up this command in the current list of\ncommands it knows and this either succeeds or fails.  The built-in\ncommand [proc] defines a new Tcl procedure with the given name, and\nregisters it in that list of known commands.\n\nSo the general rule for user-defined procedures is relatively\nstraightforward: to call a procedure, the interpreter should have read\nand executed its definition before the attempted call.\n"}]}