• How do I make a proc return the output of a sub proc?

    From Luc@21:1/5 to All on Fri Nov 4 03:36:58 2022
    Gentlemen, please:

    --------------------
    #!/usr/bin/env tclsh

    proc outside {} {

    proc inside {} {
    return "deep thoughts"
    }
    inside
    return "shallow thoughts"
    }

    puts [outside]
    --------------------

    How do I get the outside proc to return "deep thoughts"?


    --
    Luc


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Arjen Markus@21:1/5 to Luc on Fri Nov 4 00:33:18 2022
    On Friday, November 4, 2022 at 7:37:09 AM UTC+1, Luc wrote:
    Gentlemen, please:

    --------------------
    #!/usr/bin/env tclsh

    proc outside {} {

    proc inside {} {
    return "deep thoughts"
    }
    inside
    return "shallow thoughts"
    }

    puts [outside]
    --------------------

    How do I get the outside proc to return "deep thoughts"?


    --
    Luc


    You can do:

    proc outside {} {

    proc inside {} {
    return "deep thoughts"
    }
    return [inside]
    # return "shallow thoughts" --- wil not be reached
    }
    puts [outside]

    But you should note that by putting the definition of "inside" inside the body of "outside", it is created each time "outside" is called.

    Perhaps you should explain to us what you want to do?

    Regards,

    Arjen

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From heinrichmartin@21:1/5 to Arjen on Fri Nov 4 01:05:30 2022
    On Friday, November 4, 2022 at 8:33:20 AM UTC+1, Arjen wrote:
    On Friday, November 4, 2022 at 7:37:09 AM UTC+1, Luc wrote:
    Gentlemen, please:

    --------------------
    #!/usr/bin/env tclsh

    proc outside {} {

    proc inside {} {
    return "deep thoughts"
    }
    inside
    return "shallow thoughts"
    }

    puts [outside]
    --------------------

    How do I get the outside proc to return "deep thoughts"?

    Not returning "shallow thoughts" would implicitly return the return value of "inside".
    A bit more code is needed, if inside should be hidden from return codes/levels. Pointing to the docs: catch or try or tailcall

    Btw, I recall someone or some doc mention that explicit return is preferable over implicit return values.
    I never fully understood that statement; maybe it is just defensive coding wrt maintainability.

    Perhaps you should explain to us what you want to do?

    Luc, (if you were defining the proc inside the proc intentionally) are you looking for: apply or coroutine or namespace code?

    Btw, looking at the doc of "namespace code", I think that "eval $script [list x y]" should be replaced with "{*}$script x y" in modern Tcl.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Luc@21:1/5 to Arjen Markus on Fri Nov 4 05:06:46 2022
    **************************
    On Fri, 4 Nov 2022 00:33:18 -0700 (PDT), Arjen Markus wrote:

    On Friday, November 4, 2022 at 7:37:09 AM UTC+1, Luc wrote:
    Gentlemen, please:

    --------------------
    #!/usr/bin/env tclsh

    proc outside {} {

    proc inside {} {
    return "deep thoughts"
    }
    inside
    return "shallow thoughts"
    }

    puts [outside]
    --------------------

    How do I get the outside proc to return "deep thoughts"?


    --
    Luc


    You can do:

    proc outside {} {

    proc inside {} {
    return "deep thoughts"
    }
    return [inside]
    # return "shallow thoughts" --- wil not be reached
    }
    puts [outside]

    But you should note that by putting the definition of "inside" inside the body of "outside", it is created each time "outside" is called.

    Perhaps you should explain to us what you want to do?

    Regards,

    Arjen


    OK, you're right. That doesn't work for me. I tried.

    I have proc1.

    Inside proc1, there is proc2.
    Then proc2 creates widgets.
    Multiple widgets may be manipulated until a decision is taken.
    A button in a widget calls proc3.
    Then proc 3 may or may not decide it's time for the entire
    machine (proc1 *is* the entire machine) to return an output.
    May or may not.

    That's it.

    --
    Luc


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Harald Oehlmann@21:1/5 to All on Fri Nov 4 09:44:03 2022
    Am 04.11.2022 um 09:26 schrieb Luc:
    No, that doesn't work either. I forgot I am prototyping the whole thing
    as an independent creature, but it's supposed to be a proc once it's ready. So it can't just exit. The entire application would die with it.

    Never let anyone ask me to code for airports or railways.


    Luc,

    I am not sure, if this was mentioned.
    A "one time use proc" may be defined with the "apply" command.

    So, the following is a bit the same:

    Create a proc, use it and remove it:

    proc pn {a} {puts $a}
    pn val1
    rename pn ""

    Now, with apply:

    apply { {a} {
    puts $a
    }} val1

    Take care,
    Harald

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Luc@21:1/5 to Luc on Fri Nov 4 05:26:25 2022
    No, that doesn't work either. I forgot I am prototyping the whole thing
    as an independent creature, but it's supposed to be a proc once it's ready.
    So it can't just exit. The entire application would die with it.

    Never let anyone ask me to code for airports or railways.

    --
    Luc


    **************************
    On Fri, 4 Nov 2022 05:22:43 -0300, Luc wrote:

    Hey, you know what works?

    if {[condition ismet $_foobar]} {puts "Yes!"; exit}

    But I'm afraid my tcler license will be revoked if I do that... :-)

    Seriously, though. There must be a more "proper" way.

    ************************

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Luc@21:1/5 to All on Fri Nov 4 05:22:43 2022
    Hey, you know what works?

    if {[condition ismet $_foobar]} {puts "Yes!"; exit}

    But I'm afraid my tcler license will be revoked if I do that... :-)

    Seriously, though. There must be a more "proper" way.

    --
    Luc


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ralf Fassel@21:1/5 to All on Fri Nov 4 10:54:24 2022
    * Luc <[email protected]>
    | I have proc1.

    | Inside proc1, there is proc2.

    Why is proc2 *inside* proc1?
    Usually procs are defined at global scope and not inside other procs
    (yes I know, there might be uses for that, but until explained by the OP
    I'd rather assume some confusion about basic concepts here).

    R'

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Ralf Fassel on Fri Nov 4 13:36:14 2022
    Ralf Fassel <[email protected]> wrote:
    * Luc <[email protected]>
    | I have proc1.

    | Inside proc1, there is proc2.

    Why is proc2 *inside* proc1?

    Indeed, an answer to this question is important.

    Usually procs are defined at global scope and not inside other procs
    (yes I know, there might be uses for that, but until explained by the OP
    I'd rather assume some confusion about basic concepts here).

    Defining a proc during runtime within another proc is an advanced Tcl
    technique that is in most cases not needed for instrumenting a GUI
    (which is what the OP seems to be doing based on another post in this
    thread).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Luc on Fri Nov 4 13:44:04 2022
    Luc <[email protected]> wrote:
    Gentlemen, please:

    --------------------
    #!/usr/bin/env tclsh

    proc outside {} {

    proc inside {} {
    return "deep thoughts"
    }
    inside
    return "shallow thoughts"
    }

    puts [outside]
    --------------------

    How do I get the outside proc to return "deep thoughts"?

    Until we get an answer to Ralf's question, we can only offer replies
    based upon your confusion about defining vs. calling.

    However, guessing as to what you might mean (as in, you might mean "how
    can I cause 'inside' to abort further execution of 'outside' and
    instead cause 'outside' to return a value) here is one way to get
    "outside" to return "deep thoughts":

    #!/usr/bin/tclsh

    # this below also fixes the confusion between 'defining' and
    # 'calling' a proc

    proc outside {} {
    inside
    return "shallow thoughts"
    }

    proc inside {} {
    if {rand() < 0.5} {
    return -code return "deep thoughts"
    }
    }

    for {set i 0} {$i < 10} {incr i} {
    puts "$i: [outside]"
    }

    Running this provides:

    0: deep thoughts
    1: shallow thoughts
    2: shallow thoughts
    3: shallow thoughts
    4: deep thoughts
    5: shallow thoughts
    6: deep thoughts
    7: shallow thoughts
    8: shallow thoughts
    9: shallow thoughts

    Note that due to 'inside' using rand() to decide what to do, your
    output will naturally be different (and each run will output a
    different set of 'deep' vs. 'shallow' lines.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Luc@21:1/5 to Rich on Fri Nov 4 11:34:27 2022
    **************************
    On Fri, 4 Nov 2022 13:36:14 -0000 (UTC), Rich wrote:

    Ralf Fassel <[email protected]> wrote:
    Why is proc2 *inside* proc1?

    Indeed, an answer to this question is important.

    ************************

    I believe the answer is pretty obvious.

    It's a large proc. I need to organize everything in sub functions
    inside the function.

    I have been quite clear about what I need. Again:

    I have proc1.

    Inside proc1, there is proc2 and about 20 other procs.
    Then proc2 creates widgets AND it calls many other procs in the process.
    Multiple widgets may be manipulated until a decision is taken. Each one
    of them also calls a number of procs. It's all a matter of organization.
    A button in a widget calls proc3.
    Then proc 3 also calls a bunch of other procs and meanwhile it may
    or may not decide it's time for the big parent proc to return an output.

    It's all a matter of organization.

    It's 1,900 lines of code. And yes, I'm afraid it may be a little spaghetti
    here and there. I will improve it later. But this is not the best time to post more code. Please consider just the description above. The entire code will be published eventually and I will be very open to criticism, but I can't publish something that doesn't work.

    I was almost sure someone would suggest uplevel, but nobody has and I have tried it on my own, it doesn't seem to work.

    The return -code return "deep thoughts" idea doesn't work either.
    The "deep thoughts" example I posted previously is too simple to reflect
    what I have here. I basically need a command that says
    STOP EVERYTHING RIGHT NOW, RETURN THIS STRING AND DISAPPEAR


    --
    Luc


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gerald Lester@21:1/5 to Luc on Fri Nov 4 10:17:17 2022
    On 11/4/22 09:34, Luc wrote:
    **************************
    On Fri, 4 Nov 2022 13:36:14 -0000 (UTC), Rich wrote:

    Ralf Fassel <[email protected]> wrote:
    Why is proc2 *inside* proc1?

    Indeed, an answer to this question is important.

    ************************

    I believe the answer is pretty obvious.

    It's a large proc. I need to organize everything in sub functions
    inside the function.

    Ah, you do realize that all procs are globally addressable -- there is
    no such thing as a sub function in Tcl.

    A Tcl proc, can have another proc declared inside of it -- but that just
    causes it to be defined/redefined at runtime and it can be called by anyone.

    Now a Tcl proc can *call* another function, but that does not make it
    "inside" nor does it make it a aub function.

    ...
    The return -code return "deep thoughts" idea doesn't work either.
    The "deep thoughts" example I posted previously is too simple to reflect
    what I have here. I basically need a command that says
    STOP EVERYTHING RIGHT NOW, RETURN THIS STRING AND DISAPPEAR

    You need to combine [info level] with [return] -- please read both
    man/help pages in detail and pay close attention to the level option on
    the return.


    --
    +----------------------------------------------------------------------+
    | Gerald W. Lester, President, KNG Consulting LLC |
    | Email: [email protected] | +----------------------------------------------------------------------+

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robert Heller@21:1/5 to [email protected] on Fri Nov 4 16:00:21 2022
    At Fri, 4 Nov 2022 10:17:17 -0500 Gerald Lester <[email protected]> wrote:


    On 11/4/22 09:34, Luc wrote:
    **************************
    On Fri, 4 Nov 2022 13:36:14 -0000 (UTC), Rich wrote:

    Ralf Fassel <[email protected]> wrote:
    Why is proc2 *inside* proc1?

    Indeed, an answer to this question is important.

    ************************

    I believe the answer is pretty obvious.

    It's a large proc. I need to organize everything in sub functions
    inside the function.

    Ah, you do realize that all procs are globally addressable -- there is
    no such thing as a sub function in Tcl.

    You can sort of get that with OOP with member functions (eg SNIT, incrTcl, BWidget). You can also use namespaces to "protect" things and avoid problems with name clashes.


    A Tcl proc, can have another proc declared inside of it -- but that just causes it to be defined/redefined at runtime and it can be called by anyone.

    Now a Tcl proc can *call* another function, but that does not make it "inside" nor does it make it a aub function.

    It sounds like that OP wants to create a class with "private" members (or something like that). Tcl has OOP extensions, but I don't think any implement strickly private (or protected) members or methods (AFAIK). (SNIT doesn't.)


    ...
    The return -code return "deep thoughts" idea doesn't work either.
    The "deep thoughts" example I posted previously is too simple to reflect what I have here. I basically need a command that says
    STOP EVERYTHING RIGHT NOW, RETURN THIS STRING AND DISAPPEAR

    You need to combine [info level] with [return] -- please read both
    man/help pages in detail and pay close attention to the level option on
    the return.

    I suspect that this won't help either. He wants to exit a proc on a button click. The button -command is running at level 0 and the proc is somewhere else (or maybe already exited).

    I suspect he really wants tkwait:

    proc main {} {
    global theanswer
    ## build widgets and start processing
    set theanswer {}
    tkwait variable theanswer
    return $theanswer
    }

    And somewhere there is a button with a -command bound to a proc like:

    proc buttonpress {} {
    global theanswer
    set theanswer "This is the answer"
    }





    --
    Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
    Deepwoods Software -- Custom Software Services
    http://www.deepsoft.com/ -- Linux Administration Services
    [email protected] -- Webhosting Services

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robert Heller@21:1/5 to [email protected] on Fri Nov 4 15:45:05 2022
    At Fri, 4 Nov 2022 11:34:27 -0300 Luc <[email protected]> wrote:


    **************************
    On Fri, 4 Nov 2022 13:36:14 -0000 (UTC), Rich wrote:

    Ralf Fassel <[email protected]> wrote:
    Why is proc2 *inside* proc1?

    Indeed, an answer to this question is important.

    ************************

    I believe the answer is pretty obvious.

    It's a large proc. I need to organize everything in sub functions
    inside the function.

    I have been quite clear about what I need. Again:

    I have proc1.

    Inside proc1, there is proc2 and about 20 other procs.
    Then proc2 creates widgets AND it calls many other procs in the process.
    Multiple widgets may be manipulated until a decision is taken. Each one
    of them also calls a number of procs. It's all a matter of organization.
    A button in a widget calls proc3.
    Then proc 3 also calls a bunch of other procs and meanwhile it may
    or may not decide it's time for the big parent proc to return an output.


    This sounds like you need to use wait:

    proc proc2 {args} {
    ### create widgets here
    global answer
    set answer 0
    button .foo -command proc3
    }

    proc proc3 {} {
    # this is bound to button
    global answer
    incr answer
    }



    proc proc1 {args} {
    proc2
    global answer
    vwait answer
    return $answer
    }

    It's all a matter of organization.


    SNIT can be your friend here (see below).



    It's 1,900 lines of code. And yes, I'm afraid it may be a little spaghetti here and there. I will improve it later. But this is not the best time to post
    more code. Please consider just the description above. The entire code will be
    published eventually and I will be very open to criticism, but I can't publish
    something that doesn't work.

    Why not? Someone might look at the "broken" code and suggest a fix to make it work.

    Rather then post 1,900 lines of code to a newsgroup, you might want to put it up on GitHub and post the link here.


    I was almost sure someone would suggest uplevel, but nobody has and I have tried it on my own, it doesn't seem to work.

    Uplevel is a completely different beast. The use of 'return -code ...' is the usual way of jumping a return out-of-band. (One can also use error, with
    catch or try as well and might be the only way to jump multiple levels.)


    The return -code return "deep thoughts" idea doesn't work either.

    Then something else is going on. Are you wanting to jump multiple levels? Or trying to do some *syncroniously* from an asyncronious event? Maybe you want to use [tk]wait...

    The "deep thoughts" example I posted previously is too simple to reflect
    what I have here. I basically need a command that says
    STOP EVERYTHING RIGHT NOW, RETURN THIS STRING AND DISAPPEAR

    What it sounds like is that you are reinventing an irregular polygonal
    wheel... :-)

    You can probably do all of this with SNIT. Much more cleanly and efficently and probably with better organization.

    (you need to install tcllib)

    package require snit
    package require Tk

    snit::widget MyMegaWidget {
    variable answer 0
    ## add more instance variables (like globals)
    component button
    ## add more components (sub-widgets you might need to access)
    delegate option -buttonlabel to button as -label
    ## maybe add more options
    constructor {args} {
    ## build the mega widget
    install button using button $win.button \
    -command [mymethod RecordAnswer] \
    -state disabled
    ### build more widgets
    ## configure everything
    $self configurelist $args
    }
    method Run {args} {
    # do some processing (be sure to call update idle from time to time)
    # wait for the button
    set answer 0
    $button configure -state normal
    tkwait variable [myvar answer]
    return "The answer is 42"
    }
    method RecordAnswer {
    # tickle the vwait above
    incr answer
    }
    }


    proc main {} {
    ## build the GUI
    pack [MyMegaWidget .bigwidget -buttonlabel "Hit me!"]
    ## process pending idle events (eg exposure events, etc.)
    update idle
    ## start the processing (note: this might actually be started by some
    ## GUI element, in which case the next line vanishes)
    .bigwidget Run
    }

    main




    --
    Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
    Deepwoods Software -- Custom Software Services
    http://www.deepsoft.com/ -- Linux Administration Services
    [email protected] -- Webhosting Services

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Luc@21:1/5 to Gerald Lester on Fri Nov 4 13:54:50 2022
    On Fri, 4 Nov 2022 10:17:17 -0500, Gerald Lester wrote:

    Ah, you do realize that all procs are globally addressable -- there is
    no such thing as a sub function in Tcl.

    I don't understand what you mean.

    proc out {} {
    proc in {} {
    return "deep thoughts"
    }
    return "shallow thoughts"
    }

    % puts [out]
    shallow thoughts

    % puts [in]
    invalid command name "in"
    while executing
    "in"
    invoked from within
    "puts [in]"
    (file "procproc.tcl" line 9)
    Compilation failed.


    proc "in" only works inside "out."
    That is not my idea of "globally addressable."


    You need to combine [info level] with [return] -- please read both
    man/help pages in detail and pay close attention to the level option on
    the return.

    I've been reading that already. I don't know how to use it.

    [info level] outputs 1, but I don't see how that 1 can be useful.

    {return $_selection} doesn't work
    {return -level 0 $_selection} doesn't work
    {return -level 1 $_selection} doesn't work
    {return -level 2 $_selection} doesn't work
    {puts $_selection; return -level 0} doesn't work
    {puts $_selection; return -level 1} doesn't work
    {puts $_selection; return -level 2} doesn't work

    --
    Luc


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Luc@21:1/5 to Robert Heller on Fri Nov 4 13:43:34 2022
    On Fri, 04 Nov 2022 15:45:05 +0000, Robert Heller wrote:

    This sounds like you need to use wait:

    proc proc2 {args} {
    ### create widgets here
    global answer
    set answer 0
    button .foo -command proc3
    }

    proc proc3 {} {
    # this is bound to button
    global answer
    incr answer
    }



    proc proc1 {args} {
    proc2
    global answer
    vwait answer
    return $answer
    }

    ************************

    I suspected for some time that vwait would be the answer. But I don't know
    how to use it. There are parts of Tcl that I never learned properly.

    Your method with vwait kind of works.

    proc bigproc {} {
    ...
    }
    puts [bigproc]

    The expected output prints, but the... um, application doesn't close.
    That I could have achieved with puts.

    The entire thing is in a proc. If it returns, it should be extinguished immediately after printing output, shouldn't it?

    --
    Luc


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Luc on Fri Nov 4 16:48:50 2022
    Luc <[email protected]> wrote:
    **************************
    On Fri, 4 Nov 2022 13:36:14 -0000 (UTC), Rich wrote:

    Ralf Fassel <[email protected]> wrote:
    Why is proc2 *inside* proc1?

    Indeed, an answer to this question is important.

    ************************

    I believe the answer is pretty obvious.

    It is not. As defining a proc, inside another proc, is only rarely
    done, and even then, generally for very advanced "dynamic code
    generation" reasons. None of which your example, nor initial question,
    implied was happening.

    It's a large proc. I need to organize everything in sub functions
    inside the function.

    Except, that is not how Tcl code is parsed (nor how it is organized).

    By defining a proc, inside another proc, you are repeating the
    creation of that 'inner' proc every time you execute the outer proc
    (which if the outer proc is executed multiple times can result in a
    rather significant performance loss).

    That is also not how the procs are organized once defined. Without any namespace qualifiers, they are all created, at the same level, in the
    current namespace. I.e., note below:

    State, before defining any additional procs.

    $ rlwrap tclsh
    % info procs
    auto_load_index unknown auto_import auto_execok auto_qualify auto_load history tclLog

    Define a proc, that when executed, will as part of being executed
    define another proc.

    % proc outer {} { proc inner {} {} }

    Execute the outer proc.

    % outer

    Note the changes to 'info procs':

    % info procs
    auto_load_index unknown auto_import auto_execok inner auto_qualify auto_load outer history tclLog
    %

    Both 'inner' and 'outer' are present at global level. The 'inner' proc
    is not *inside* the outer proc.

    I have been quite clear about what I need. Again:

    Maybe you find it clear. For us who have only your posting to go on,
    it is very murky and confusing.

    The return -code return "deep thoughts" idea doesn't work either.
    The "deep thoughts" example I posted previously is too simple to reflect
    what I have here. I basically need a command that says
    STOP EVERYTHING RIGHT NOW, RETURN THIS STRING AND DISAPPEAR

    Which is exactly what the 'code return' example I posted does. Outer
    stops at the point where it called 'inner', returns the string given
    back from 'inner' and disappears.

    Will it work from a five level deep call stack? Not if what you want
    to do is abort the first proc in the stack. For that, you likely may
    need to combine both uplevel and return -code return, and count your
    nesting level, and such will be fragile and subject to breakage from
    making code changes.

    Do do what it sounds like you want, which is:

    p1 calls p2 which calls p3 which calls p4 -- p4 decides to abort all of
    p1 through p3

    Then your best way is to have each one return some sentinel data, and
    you wrap each call with a check for the procs return sentinel data, and
    if the sentinel says "abort" the check aborts and returns a further
    sentinel up the stack.

    Ie.

    proc p1 {} {
    lassign [p2] sentinel value
    if {$sentinel eq "abort"} { return $value }
    # other stuff done with $value here if sentinel is not "abort"
    #
    }

    proc p2 {} {
    lassign [p3] sentinel value
    if {$sentinel eq "abort"} { return [list abort $value] }
    # other stuff done with $value here if sentinel is not "abort"
    }

    proc p3 {} {
    lassign [p4] sentinel value
    if {$sentinel eq "abort"} { return [list abort $value] }
    # other stuff done with $value here if sentinel is not "abort"
    }

    proc p4 {} {
    if {rand() < 0.5} {
    return [list abort "The string to pass up the call chain"]
    }
    # other stuff to do if we are not aborting the call chain
    }

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ted Nolan @21:1/5 to [email protected] on Fri Nov 4 17:00:34 2022
    In article <[email protected]>, Luc <[email protected]> wrote:
    On Fri, 4 Nov 2022 10:17:17 -0500, Gerald Lester wrote:

    Ah, you do realize that all procs are globally addressable -- there is
    no such thing as a sub function in Tcl.

    I don't understand what you mean.

    proc out {} {
    proc in {} {
    return "deep thoughts"
    }
    return "shallow thoughts"
    }

    % puts [out]
    shallow thoughts

    % puts [in]
    invalid command name "in"
    while executing
    "in"
    invoked from within
    "puts [in]"
    (file "procproc.tcl" line 9)
    Compilation failed.


    proc "in" only works inside "out."
    That is not my idea of "globally addressable."



    I think he means this:

    Create a file like:

    ============
    #!/usr/local/bin/tclsh8.6

    proc a {} {
    puts "Hello from a!"

    proc b {} {
    puts "hello from b!"
    }

    }
    a
    b
    ============

    and run it. The output will be:

    Hello from a!
    hello from b!

    --
    columbiaclosings.com
    What's not in Columbia anymore..

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Luc on Fri Nov 4 17:15:06 2022
    Luc <[email protected]> wrote:
    The entire thing is in a proc. If it returns, it should be extinguished immediately after printing output, shouldn't it?

    Not if you are running Tk.

    If you are running Tk then returning from the last called proc causes
    Tk to enter the event loop and wait for GUI events to trigger.

    If you really want to "exit" the entire GUI, then "exit" is the command
    you want. No matter where you call "exit" the entire application will disappear.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Luc@21:1/5 to Rich on Fri Nov 4 14:28:26 2022
    **************************
    On Fri, 4 Nov 2022 17:16:53 -0000 (UTC), Rich wrote:

    Something is broken in your Tcl interpreter (or you did not actually
    run the same code you posted):

    $ rlwrap tclsh
    proc out {} {
    proc in {} {
    return "deep thoughts"
    }
    return "shallow thoughts"
    }
    % puts [out]
    shallow thoughts
    % puts [in]
    deep thoughts
    %


    True.

    I think I ran it the other way around:

    puts [in]
    puts [out]

    --
    Luc


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From saitology9@21:1/5 to Luc on Fri Nov 4 13:34:39 2022
    On 11/4/2022 1:20 PM, Luc wrote:


    and run it. The output will be:

    Hello from a!
    hello from b!


    Yes, because [puts] has a way of piercing through armour.

    Now, if only I could do that with [return]...


    Your inlined example and file-d versions are both identical in their
    effects. If you call [in] first, you will get an error. [puts] does
    nothing special here. You can just issue "in" and "out" at the prompt.

    What is relevant for the point here is that, the inner proc is not
    defined until the outer proc is called at least once. It then creates
    the inner proc, which then becomes available to call.

    Call sequence must be in that order.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Luc on Fri Nov 4 17:16:53 2022
    Luc <[email protected]> wrote:
    On Fri, 4 Nov 2022 10:17:17 -0500, Gerald Lester wrote:

    Ah, you do realize that all procs are globally addressable -- there is
    no such thing as a sub function in Tcl.

    I don't understand what you mean.

    proc out {} {
    proc in {} {
    return "deep thoughts"
    }
    return "shallow thoughts"
    }

    % puts [out]
    shallow thoughts

    % puts [in]
    invalid command name "in"
    while executing
    "in"
    invoked from within
    "puts [in]"
    (file "procproc.tcl" line 9)
    Compilation failed.


    proc "in" only works inside "out."
    That is not my idea of "globally addressable."

    Something is broken in your Tcl interpreter (or you did not actually
    run the same code you posted):

    $ rlwrap tclsh
    proc out {} {
    proc in {} {
    return "deep thoughts"
    }
    return "shallow thoughts"
    }
    % puts [out]
    shallow thoughts
    % puts [in]
    deep thoughts
    %

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Luc@21:1/5 to Ted Nolan on Fri Nov 4 14:20:39 2022
    **************************
    On 4 Nov 2022 17:00:34 GMT, [email protected] (Ted Nolan ) wrote:

    I think he means this:

    Create a file like:

    ============
    #!/usr/local/bin/tclsh8.6

    proc a {} {
    puts "Hello from a!"

    proc b {} {
    puts "hello from b!"
    }

    }
    a
    b
    ============

    and run it. The output will be:

    Hello from a!
    hello from b!


    Yes, because [puts] has a way of piercing through armour.

    Now, if only I could do that with [return]...

    --
    Luc


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Luc@21:1/5 to Rich on Fri Nov 4 14:17:39 2022
    On Fri, 4 Nov 2022 16:48:50 -0000 (UTC), Rich wrote:

    It is not. As defining a proc, inside another proc, is only rarely
    done, and even then, generally for very advanced "dynamic code
    generation" reasons. None of which your example, nor initial question, implied was happening.

    Are you saying I should remove everything from its all-enveloping proc
    and provide the entire idea as a plain page (though still with procs)
    and let people just [source] it instead of running it as a proc?
    I admit I have thought about that.


    By defining a proc, inside another proc, you are repeating the
    creation of that 'inner' proc every time you execute the outer proc
    (which if the outer proc is executed multiple times can result in a
    rather significant performance loss).

    Yes, that's intended. All those procs are necessary every time the big proc
    is run. The big proc won't work without them.

    The big proc will not be executed multiple times. Well, it will, but not
    in rapid sequence. It's a tool that people will launch occasionally.

    I don't believe any of those procs is CPU or memory intensive.

    I believe everything I'm doing is pretty regular except that I wrapped
    the whole package in an all-encompassing proc.

    For example, take /usr/share/tcltk/tk8.6/bgerror.tcl. It has seven procs.
    Now put that entire page inside one parent proc. That's what I did.
    Sort of. That's all.


    That is also not how the procs are organized once defined. Without any namespace qualifiers, they are all created, at the same level, in the
    current namespace.

    That one statement is not accurate. As it turns out, EVERYTHING I'm doing
    has its own namespace so nothing in it will clash with anything else in whatever application that may come to adopt it. It's one big proc inside
    one single namespace. ALL procs and variables reside in that namespace.

    --
    Luc


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robert Heller@21:1/5 to [email protected] on Fri Nov 4 17:35:27 2022
    At Fri, 4 Nov 2022 13:43:34 -0300 Luc <[email protected]> wrote:


    On Fri, 04 Nov 2022 15:45:05 +0000, Robert Heller wrote:

    This sounds like you need to use wait:

    proc proc2 {args} {
    ### create widgets here
    global answer
    set answer 0
    button .foo -command proc3
    }

    proc proc3 {} {
    # this is bound to button
    global answer
    incr answer
    }



    proc proc1 {args} {
    proc2
    global answer
    vwait answer
    return $answer
    }

    ************************

    I suspected for some time that vwait would be the answer. But I don't know how to use it. There are parts of Tcl that I never learned properly.

    Your method with vwait kind of works.

    proc bigproc {} {
    ...
    }
    puts [bigproc]

    The expected output prints, but the... um, application doesn't close.
    That I could have achieved with puts.

    The entire thing is in a proc. If it returns, it should be extinguished immediately after printing output, shouldn't it?

    No. Wish (or package require Tk), does not "exit" upon EOF on the .tcl file. It does not exit until either the exit command is invoked or the main toplevel (.) is destroyed. So, what you really want bound to your "exit" button is:

    proc exitButton {} {
    # print the answer
    puts "This is the answer"
    # then exit
    exit
    }

    Or with a pure GUI environment (with no console screen or shell window):

    proc exitButton {} {
    # put up a message dialog box.
    tk_messageBox -icon info -message "This is the answer" -type ok
    # when the user clicks OK, exit the program.
    exit
    }



    --
    Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
    Deepwoods Software -- Custom Software Services
    http://www.deepsoft.com/ -- Linux Administration Services
    [email protected] -- Webhosting Services

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Luc@21:1/5 to Robert Heller on Fri Nov 4 14:48:26 2022
    On Fri, 04 Nov 2022 17:35:27 +0000, Robert Heller wrote:

    No. Wish (or package require Tk), does not "exit" upon EOF on the .tcl
    file. It does not exit until either the exit command is invoked or the
    main toplevel (.) is destroyed. So, what you really want bound to your "exit" button is:

    proc exitButton {} {
    # print the answer
    puts "This is the answer"
    # then exit
    exit
    }

    Or with a pure GUI environment (with no console screen or shell window):

    proc exitButton {} {
    # put up a message dialog box.
    tk_messageBox -icon info -message "This is the answer" -type ok
    # when the user clicks OK, exit the program.
    exit
    }


    I can't use exit. It's a proc. It's meant to be used inside a parent application. Calling [exit] will kill the parent application.

    --
    Luc


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ralf Fassel@21:1/5 to All on Fri Nov 4 18:47:48 2022
    * Luc <[email protected]>
    | On Fri, 4 Nov 2022 16:48:50 -0000 (UTC), Rich wrote:

    | > It is not. As defining a proc, inside another proc, is only rarely
    | > done, and even then, generally for very advanced "dynamic code
    | > generation" reasons. None of which your example, nor initial question,
    | > implied was happening.

    | Are you saying I should remove everything from its all-enveloping proc
    | and provide the entire idea as a plain page (though still with procs)
    | and let people just [source] it instead of running it as a proc?

    Basically: yes, eventually using a namespace so your code is less likely
    to collide with other code, using procs with the same name.

    The usual way, if your code is not a standalone program but rather a
    library which other programs use, is to build a *package*:

    #------------
    # yourpackage.tcl
    package provide yourpackage 1.0
    namespace eval yourpackage {
    proc proc1 {} {
    puts "this is proc1"
    }
    proc proc2 {} {
    puts "this is proc2, now calling proc1"
    proc1
    }
    proc proc3 {} {
    puts "this is proc3, now calling proc2"
    proc2
    }
    }
    #------------

    #------------
    # pkgIndex.tcl
    package ifneeded yourpackage 1.0 [list source [file join $dir yourpackage.tcl]]
    #------------

    Then the program using that library does

    % lappend auto_path /path/to/yourpackage
    % package require yourpackage
    1.0
    % yourpackage::proc3
    this is proc3, now calling proc2
    this is proc2, now calling proc1
    this is proc1

    etc.

    | I believe everything I'm doing is pretty regular except that I wrapped
    | the whole package in an all-encompassing proc.

    And that exception is not usual. In fact, it would not pass any code
    review by me :-)

    | That one statement is not accurate. As it turns out, EVERYTHING I'm doing
    | has its own namespace so nothing in it will clash with anything else in
    | whatever application that may come to adopt it. It's one big proc inside
    | one single namespace. ALL procs and variables reside in that namespace.

    You did not show that namespace in the code you posted.
    Such things are essential to show.

    By defining a proc2 inside another proc1, you are *not* defining that
    proc2 inside a somehow magically appearing namespace, you define it at
    the same level as proc1 itself.

    R'

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Luc on Fri Nov 4 18:14:16 2022
    Luc <[email protected]> wrote:
    **************************
    On 4 Nov 2022 17:00:34 GMT, [email protected] (Ted Nolan ) wrote:

    I think he means this:

    Create a file like:

    ============
    #!/usr/local/bin/tclsh8.6

    proc a {} {
    puts "Hello from a!"

    proc b {} {
    puts "hello from b!"
    }

    }
    a
    b
    ============

    and run it. The output will be:

    Hello from a!
    hello from b!


    Yes, because [puts] has a way of piercing through armour.

    Puts outputs the string to a file descriptor (stdout by default). That
    results in output being sent to the destination of that file
    descriptor. Strings given to puts simply get sent to the file
    descriptor specified, no matter where they occur.

    Now, if only I could do that with [return]...

    Return provides the value that the invocation of the proc produces at
    the call site. This allows the proc to be used in many ways like a
    Pascal function:

    set returned_result_value [proc_xyz $parm1 $parm2]

    And the value "returned" from invoking "proc_xyz" with those two
    parameters is stored into the returned_result_value variable.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robert Heller@21:1/5 to [email protected] on Fri Nov 4 18:08:26 2022
    At Fri, 4 Nov 2022 14:17:39 -0300 Luc <[email protected]> wrote:


    On Fri, 4 Nov 2022 16:48:50 -0000 (UTC), Rich wrote:

    It is not. As defining a proc, inside another proc, is only rarely
    done, and even then, generally for very advanced "dynamic code
    generation" reasons. None of which your example, nor initial question, implied was happening.

    Are you saying I should remove everything from its all-enveloping proc
    and provide the entire idea as a plain page (though still with procs)
    and let people just [source] it instead of running it as a proc?

    Sure. Or put something like "#!/usr/bin/tclsh" at the version top of the file, call your main proc at the bottm, "chmod +x " it, and then people can just /file.tcl.

    I admit I have thought about that.


    By defining a proc, inside another proc, you are repeating the
    creation of that 'inner' proc every time you execute the outer proc
    (which if the outer proc is executed multiple times can result in a
    rather significant performance loss).

    Yes, that's intended. All those procs are necessary every time the big proc is run. The big proc won't work without them.

    It makes no difference if you have:

    proc p1 {} {
    }

    proc p2 {} {

    }

    proc p3 {} {

    }

    proc p4 {} {

    }

    proc main {} {
    p1
    p2
    p3
    p4
    }


    OR

    proc main {} {
    proc p1 {} {
    }
    proc p2 {} {
    }

    proc p3 {} {

    }

    proc p4 {} {

    }
    p1
    p2
    p3
    p4
    }

    except in the second case p1, p2, p3, and p4 probably won't get byte compiled.




    The big proc will not be executed multiple times. Well, it will, but not
    in rapid sequence. It's a tool that people will launch occasionally.

    I don't believe any of those procs is CPU or memory intensive.

    I believe everything I'm doing is pretty regular except that I wrapped
    the whole package in an all-encompassing proc.

    For example, take /usr/share/tcltk/tk8.6/bgerror.tcl. It has seven procs.
    Now put that entire page inside one parent proc. That's what I did.
    Sort of. That's all.


    That is also not how the procs are organized once defined. Without any namespace qualifiers, they are all created, at the same level, in the current namespace.

    That one statement is not accurate. As it turns out, EVERYTHING I'm doing
    has its own namespace so nothing in it will clash with anything else in whatever application that may come to adopt it. It's one big proc inside
    one single namespace. ALL procs and variables reside in that namespace.


    --
    Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
    Deepwoods Software -- Custom Software Services
    http://www.deepsoft.com/ -- Linux Administration Services
    [email protected] -- Webhosting Services

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ralf Fassel@21:1/5 to All on Fri Nov 4 18:56:42 2022
    * Luc <[email protected]>
    | proc outside {} {
    |
    | proc inside {} {
    | return "deep thoughts"
    | }
    | inside
    | return "shallow thoughts"
    | }

    | puts [outside]
    | --------------------

    | How do I get the outside proc to return "deep thoughts"?

    The simple answer of course is

    proc outside {} {
    return [inside]
    }
    proc inside {} {
    return "deep thoughts"
    }
    outside
    => deep thoughts

    But I suspect this is not what you're after...

    R'

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From saitology9@21:1/5 to Luc on Fri Nov 4 14:18:07 2022
    On 11/4/2022 2:36 AM, Luc wrote:
    Gentlemen, please:

    --------------------
    #!/usr/bin/env tclsh

    proc outside {} {

    proc inside {} {
    return "deep thoughts"
    }
    inside
    return "shallow thoughts"
    }

    puts [outside]
    --------------------

    How do I get the outside proc to return "deep thoughts"?



    First of all, it is important to realize that nesting of proc's, in this particular case, as well as generally in Tcl, is *not* relevant here.

    You may need to define that proc inside of another for whatever reasons.
    That is beside the point.

    So, once you realize this, the question becomes:

    I need to call a proc in my program flow. And then stop right there
    before moving on to the next statement.

    Once you read it like this, the solution is simple. use an "if"
    statement and see if you wish to stop/return or continue on.

    If it doesn't already have it, you need to equip your inner proc's with
    some flag so that it can communicate to you how you need to proceed
    after calling it.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Luc on Fri Nov 4 18:18:20 2022
    Luc <[email protected]> wrote:
    **************************
    On Fri, 4 Nov 2022 17:16:53 -0000 (UTC), Rich wrote:

    Something is broken in your Tcl interpreter (or you did not actually
    run the same code you posted):

    $ rlwrap tclsh
    proc out {} {
    proc in {} {
    return "deep thoughts"
    }
    return "shallow thoughts"
    }
    % puts [out]
    shallow thoughts
    % puts [in]
    deep thoughts
    %


    True.

    I think I ran it the other way around:

    puts [in]
    puts [out]

    Yes, that would generate the error you saw. And not because "in" is
    'hidden' inside out.

    The "in" proc simply does not exist until after "out" has been executed
    once, afterwhich the execution of out will have defined "in" and "in"
    can be called as many times, from anywhere, as you like.

    And, as well, for each subsequent time "out" is executed, the existing
    "in" will be destroyed and a new "in" recreated in its place.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From saitology9@21:1/5 to Ralf Fassel on Fri Nov 4 14:25:46 2022
    On 11/4/2022 1:56 PM, Ralf Fassel wrote:

    The simple answer of course is

    proc outside {} {
    return [inside]
    }
    proc inside {} {
    return "deep thoughts"
    }
    outside
    => deep thoughts

    But I suspect this is not what you're after...

    R'


    I think he's looking for a simple if-statement there. However, [inside]
    does not seem to have any way of letting [outside] know of its decision,
    thus the OP's confusion. OP will need to modify the input/output of its [inside] proc and without any context, no one can help him do this.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robert Heller@21:1/5 to [email protected] on Fri Nov 4 18:24:44 2022
    At Fri, 4 Nov 2022 14:48:26 -0300 Luc <[email protected]> wrote:


    On Fri, 04 Nov 2022 17:35:27 +0000, Robert Heller wrote:

    No. Wish (or package require Tk), does not "exit" upon EOF on the .tcl file. It does not exit until either the exit command is invoked or the
    main toplevel (.) is destroyed. So, what you really want bound to your "exit" button is:

    proc exitButton {} {
    # print the answer
    puts "This is the answer"
    # then exit
    exit
    }

    Or with a pure GUI environment (with no console screen or shell window):

    proc exitButton {} {
    # put up a message dialog box.
    tk_messageBox -icon info -message "This is the answer" -type ok
    # when the user clicks OK, exit the program.
    exit
    }


    I can't use exit. It's a proc. It's meant to be used inside a parent application. Calling [exit] will kill the parent application.

    OK, then you probably want tkwait:


    proc main {} {
    global theanswer
    # build widgets, etc.
    # wait for an answer
    set theanswer {}
    tkwait variable theanswer
    return $theanswer
    }

    and on the Exit button -command option:

    proc exitButton {} {
    global theanswer
    set theanswer "this is the answer"
    }

    [It would really be easier to help you if we could see the code. There is probably something obvious going on that could be solved with a trivial bit of code. It is easy and free to create an account on Github.]

    --
    Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
    Deepwoods Software -- Custom Software Services
    http://www.deepsoft.com/ -- Linux Administration Services
    [email protected] -- Webhosting Services

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gerald Lester@21:1/5 to Luc on Fri Nov 4 13:49:44 2022
    On 11/4/22 11:54, Luc wrote:
    On Fri, 4 Nov 2022 10:17:17 -0500, Gerald Lester wrote:

    Ah, you do realize that all procs are globally addressable -- there is
    no such thing as a sub function in Tcl.

    I don't understand what you mean.

    proc out {} {
    proc in {} {
    return "deep thoughts"
    }
    return "shallow thoughts"
    }

    % puts [out]
    shallow thoughts

    % puts [in]
    invalid command name "in"
    while executing
    "in"
    invoked from within
    "puts [in]"
    (file "procproc.tcl" line 9)
    Compilation failed.

    Ok, you must not be using Tcl but Tcl inside of something else that is
    doing magic!

    Here is what happens in Tcl:
    gerald@gerald-laptop:~$ cat temp.tcl

    proc out {} {
    proc in {} {
    return "deep thoughts"
    }
    return "shallow thoughts"
    }

    puts [out]
    puts [in]

    gerald@gerald-laptop:~$ tclsh temp.tcl
    shallow thoughts
    deep thoughts



    --
    +----------------------------------------------------------------------+
    | Gerald W. Lester, President, KNG Consulting LLC |
    | Email: [email protected] | +----------------------------------------------------------------------+

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Luc on Fri Nov 4 18:31:34 2022
    Luc <[email protected]> wrote:
    On Fri, 4 Nov 2022 16:48:50 -0000 (UTC), Rich wrote:

    It is not. As defining a proc, inside another proc, is only rarely
    done, and even then, generally for very advanced "dynamic code
    generation" reasons. None of which your example, nor initial question,
    implied was happening.

    Are you saying I should remove everything from its all-enveloping proc
    and provide the entire idea as a plain page (though still with procs)
    and let people just [source] it instead of running it as a proc?
    I admit I have thought about that.

    Yes, unless you really are trying to do LISP like macro dynamic code
    generation (which it does not sound like you are doing, and even if you
    were, there are already packages [sugar] to do just that).

    By defining a proc, inside another proc, you are repeating the
    creation of that 'inner' proc every time you execute the outer proc
    (which if the outer proc is executed multiple times can result in a
    rather significant performance loss).

    Yes, that's intended. All those procs are necessary every time the big proc is run. The big proc won't work without them.

    The big proc will not be executed multiple times. Well, it will, but not
    in rapid sequence. It's a tool that people will launch occasionally.

    I don't believe any of those procs is CPU or memory intensive.

    I believe everything I'm doing is pretty regular except that I wrapped
    the whole package in an all-encompassing proc.

    That is the part that is 'irregular'. Wrapping proc definitions inside
    another "proc" is *very irregular* except in specific circumstances
    (that being LISP macro like dynamic code generation).

    For example, take /usr/share/tcltk/tk8.6/bgerror.tcl. It has seven procs.
    Now put that entire page inside one parent proc. That's what I did.
    Sort of. That's all.

    Which sounds like you might be looking for namespaces or objects, not
    "procs in procs".

    That is also not how the procs are organized once defined. Without
    any namespace qualifiers, they are all created, at the same level,
    in the current namespace.

    That one statement is not accurate. As it turns out, EVERYTHING I'm doing
    has its own namespace so nothing in it will clash with anything else in whatever application that may come to adopt it. It's one big proc inside
    one single namespace. ALL procs and variables reside in that namespace.

    I do not believe that I have seen you say anywhere in this thread so
    far that you were doing all this inside a namespace.

    My statement was perfectly accurate when not in a namespace, which is
    what the "without any namespace qualifiers" was getting at.

    If you are looking to isolate this set of "sub-procs" from the rest of
    your "application" then create them inside a unique namespace (it can
    even be a sub namespace of this "one single namespace").

    I.e.:

    namespace eval ::luc {

    # stuff in your existing "one single namespace"

    }

    later in the same source file, or in a separate file that is itself
    sourced:

    namespace eval ::luc::sub-module {

    # the "inner procs" which you wrapped in an outer proc go here

    }

    All those 'procs' will be inside the sub-module namespace, which is
    itself inside the luc namespace. If you don't want them there, you can
    also put them into ::sub-module1 if you like.

    Or, look into 'objects', which also allow you to "put procs inside
    containers" (the 'procs' inside objects are called 'methods'). One
    advantage of objects is you can then create more than one 'object' in
    your outer code, and each 'object' will have its own set of inner
    'procs' (methods), isolated from the 'procs' of the other objects of
    the same type.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gerald Lester@21:1/5 to Robert Heller on Fri Nov 4 13:45:16 2022
    On 11/4/22 11:00, Robert Heller wrote:
    At Fri, 4 Nov 2022 10:17:17 -0500 Gerald Lester <[email protected]> wrote:


    On 11/4/22 09:34, Luc wrote:
    **************************
    On Fri, 4 Nov 2022 13:36:14 -0000 (UTC), Rich wrote:

    Ralf Fassel <[email protected]> wrote:
    Why is proc2 *inside* proc1?

    Indeed, an answer to this question is important.

    ************************

    I believe the answer is pretty obvious.

    It's a large proc. I need to organize everything in sub functions
    inside the function.

    Ah, you do realize that all procs are globally addressable -- there is
    no such thing as a sub function in Tcl.

    You can sort of get that with OOP with member functions (eg SNIT, incrTcl, BWidget). You can also use namespaces to "protect" things and avoid problems with name clashes.

    I know.

    Procs in namespaces still can be called from anywhere -- you can even
    call "private" OO methods if you know what you are doing.


    A Tcl proc, can have another proc declared inside of it -- but that just
    causes it to be defined/redefined at runtime and it can be called by anyone. >>
    Now a Tcl proc can *call* another function, but that does not make it
    "inside" nor does it make it a aub function.

    It sounds like that OP wants to create a class with "private" members (or something like that). Tcl has OOP extensions, but I don't think any implement strickly private (or protected) members or methods (AFAIK). (SNIT doesn't.)

    I think he was local procedures like some of the Algol languages give
    you -- the "inside" procedure is only visible in the scope of the
    procedure it is declared in -- but it really could be anything due to
    his very imprecise language.



    ...
    The return -code return "deep thoughts" idea doesn't work either.
    The "deep thoughts" example I posted previously is too simple to reflect >>> what I have here. I basically need a command that says
    STOP EVERYTHING RIGHT NOW, RETURN THIS STRING AND DISAPPEAR

    You need to combine [info level] with [return] -- please read both
    man/help pages in detail and pay close attention to the level option on
    the return.

    I suspect that this won't help either. He wants to exit a proc on a button click. The button -command is running at level 0 and the proc is somewhere else (or maybe already exited).

    Oh, that was not my read -- so either the proc would have to be a a vwait/update or it would have to be an a different interp.


    I suspect he really wants tkwait:

    proc main {} {
    global theanswer
    ## build widgets and start processing
    set theanswer {}
    tkwait variable theanswer
    return $theanswer
    }

    And somewhere there is a button with a -command bound to a proc like:

    proc buttonpress {} {
    global theanswer
    set theanswer "This is the answer"
    }







    --
    +----------------------------------------------------------------------+
    | Gerald W. Lester, President, KNG Consulting LLC |
    | Email: [email protected] | +----------------------------------------------------------------------+

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)