• Sending empty optional parameter

    From [email protected]@21:1/5 to All on Sun Jul 2 21:54:57 2023
    Having

    #--------------
    proc uno { {param1 x} {param2 y} } {
    dos $param1 $param2
    }


    proc dos { { param1 {} } {param2 {} } } {
    puts "dos (1 $param1) (2 $param2)"
    }
    #----------------------
    if we run

    uno w z
    uno
    uno w
    uno {} z

    we get

    dos (1 w) (2 z)
    dos (1 x) (2 y)
    dos (1 w) (2 y)
    dos (1 ) (2 z)

    Then, how, in the last case, we get "x" in the first parameter if the parameter sent is "empty"?

    Alejandro

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Harald Oehlmann@21:1/5 to All on Mon Jul 3 08:29:28 2023
    Am 03.07.2023 um 06:54 schrieb [email protected]:
    Having

    #--------------
    proc uno { {param1 x} {param2 y} } {
    dos $param1 $param2
    }


    proc dos { { param1 {} } {param2 {} } } {
    puts "dos (1 $param1) (2 $param2)"
    }
    #----------------------
    if we run

    uno w z
    uno
    uno w
    uno {} z

    we get

    dos (1 w) (2 z)
    dos (1 x) (2 y)
    dos (1 w) (2 y)
    dos (1 ) (2 z)

    Then, how, in the last case, we get "x" in the first parameter if the parameter sent is "empty"?

    Alejandro


    Parameters are always from left to right.
    You may use flags to choose what is optional and what is mandatory

    proc uno {args} {
    dos {*}$args
    }

    proc dos {args} {
    set default [-param1 x -param2 y]
    set param [dict merge $default [dict create $args]]
    puts "dos (1 [dict get $param -param1]) (2 [dict get $param -param1])" }

    Or use package cmdline from tcllib for optional arguments.

    Harald

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Harald Oehlmann@21:1/5 to All on Mon Jul 3 09:05:53 2023
    Am 03.07.2023 um 08:29 schrieb Harald Oehlmann:
    Am 03.07.2023 um 06:54 schrieb [email protected]:
    Having

    #--------------
    proc uno { {param1 x} {param2 y}  }  {
        dos $param1 $param2
    }


    proc dos { { param1 {} } {param2 {} } } {
          puts "dos (1 $param1) (2 $param2)"
    }
    #----------------------
    if we run

    uno w z
    uno
    uno w
    uno {} z

    we get

    dos (1 w) (2 z)
    dos (1 x) (2 y)
    dos (1 w) (2 y)
    dos (1 ) (2 z)

    Then, how, in the last case, we get "x" in the first parameter if the
    parameter sent is "empty"?

    Alejandro


    Parameters are always from left to right.
    You may use flags to choose what is optional and what is mandatory

    proc uno {args} {
        dos {*}$args
    }

    proc dos {args} {
        set default [-param1 x -param2 y]
        set param [dict merge $default [dict create $args]]
        puts "dos (1 [dict get $param -param1]) (2 [dict get $param -param1])"
    }

    Or use package cmdline from tcllib for optional arguments.

    Harald

    Sorry, my untested snipped was incomplete:

    uno -param1 w -param2 z
    uno -param2 x

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ralf Fassel@21:1/5 to All on Mon Jul 3 10:31:47 2023
    * "[email protected]" <[email protected]>
    | #--------------
    | proc uno { {param1 x} {param2 y} } {
    | dos $param1 $param2
    | }

    | proc dos { { param1 {} } {param2 {} } } {
    | puts "dos (1 $param1) (2 $param2)"
    | }
    | #----------------------
    | if we run

    | uno w z
    | uno
    | uno w
    | uno {} z

    | we get

    | dos (1 w) (2 z)
    | dos (1 x) (2 y)
    | dos (1 w) (2 y)
    | dos (1 ) (2 z)

    | Then, how, in the last case, we get "x" in the first parameter if the
    | parameter sent is "empty"?

    By explicit checking in 'uno' whether the first parameter is "" and
    re-setting it to x if it is.

    proc uno { {param1 x} {param2 y} } {
    if {$param1 eq ""} {
    # param1 never ""
    set param1 x
    }
    dos $param1 $param2
    }

    Drawback: you can't set the first arg to "" (empty) then.

    R'

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to [email protected] on Mon Jul 3 14:08:35 2023
    [email protected] <[email protected]> wrote:
    Having

    #--------------
    proc uno { {param1 x} {param2 y} } {
    dos $param1 $param2
    }


    proc dos { { param1 {} } {param2 {} } } {
    puts "dos (1 $param1) (2 $param2)"
    }
    #----------------------
    if we run

    uno w z
    uno
    uno w
    uno {} z

    we get

    dos (1 w) (2 z)
    dos (1 x) (2 y)
    dos (1 w) (2 y)
    dos (1 ) (2 z)

    Then, how, in the last case, we get "x" in the first parameter if the parameter sent is "empty"?

    Empty string is not "missing entirely". The "use default" mechanism
    for procs works by assiging all actual proc parameters (and {} is an
    actual parameter in your case above) first, then using the default
    values for any parameters which do not have an actual value given them
    in the command invocation.

    I.e., this: "uno {} z" is a call to uno with two parameters, {} and z,
    so the defaults for 'uno' never trigger (two actual parameters, two
    slots in the proc definition).

    Only your second and third uno call trigger usage of uno's default
    values, because there are zero actual parameters (second call) or only
    one actual parameter (third call, which then uses the default for only
    param2).

    This exact outcome is what is being described in the proc man page by
    this sentence:

    Arguments with default values that are followed by non-defaulted
    arguments become de-facto required arguments, though this may
    change in a future version of Tcl; portable code should ensure
    that all optional arguments come after all required arguments.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From saitology9@21:1/5 to [email protected] on Mon Jul 3 10:37:35 2023
    On 7/3/2023 12:54 AM, [email protected] wrote:


    uno w z
    uno
    uno w
    uno {} z


    In the above calls, you make calls with different number of parameters
    and thus trigger the use of the default values for your parameters for
    some of those calls.

    However, from uno, you make this call:


    dos $param1 $param2

    Which *always* uses two arguments to call dos (even if one of them turns
    out to be an empty string). So, no reason or opportunity for the
    default values to kick in.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Andreas Leitgeb@21:1/5 to [email protected] on Mon Jul 3 21:23:33 2023
    [email protected] <[email protected]> wrote:
    Having
    proc uno { {param1 x} {param2 y} } {
    uno {} z

    If you need that bit of extra flexibility for calling
    certain procedures with specific parameters while
    leaving others at a default, then have a look at

    https://wiki.tcl-lang.org/page/TclImplForNamedArguments

    ... at least in cases where speed is not most important.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From [email protected]@21:1/5 to All on Mon Jul 3 19:26:37 2023
    Thanks all for your comments.
    So , if we have various parameters (all optional) is not possible to call the procedure leaving one empty followed by another non-empty parameter.
    But , i'm curious, why not ?( i mean, could be possible, for example; have an special value to indicate an empty parameter...).
    There are technical reasons, of good practices, of use, etc. ?

    Alejandro

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to [email protected] on Tue Jul 4 03:14:06 2023
    [email protected] <[email protected]> wrote:
    Thanks all for your comments.

    So , if we have various parameters (all optional) is not possible to
    call the procedure leaving one empty followed by another non-empty parameter.

    No, Tcl is not designed to operate that way. Empty parameters must
    always also be the last parameters.

    But , i'm curious, why not ?( i mean, could be possible, for example;
    have an special value to indicate an empty parameter...).

    Not that this helps, but: because that was the way Tcl was designed.

    There are technical reasons, of good practices, of use, etc. ?

    Think about how you would indicate a missing argument that is followed
    by a non-missing argument, without using any special value to indicate
    'empty'.

    When you have reached enlightenment on that puzzle, you will see that
    there is no way to indicate "nothing here" before the end of the given parameter list.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et99@21:1/5 to [email protected] on Mon Jul 3 20:48:18 2023
    On 7/3/2023 7:26 PM, [email protected] wrote:
    Thanks all for your comments.
    So , if we have various parameters (all optional) is not possible to call the procedure leaving one empty followed by another non-empty parameter.
    But , i'm curious, why not ?( i mean, could be possible, for example; have an special value to indicate an empty parameter...).
    There are technical reasons, of good practices, of use, etc. ?

    Alejandro


    If you wish to customize further, you would likely want to use the special argument: args

    Then you can do more things, such as [llength $args] or [lassign $args ...] (see the shift example in the lassign manual entry). It also lends itself to the {*} expansion.


    Some commands, such as [puts], do have optional arguments on the left. That command even can have an optional flag -nonewline in the beginning, which incidentally must be spelled exactly.

    puts ?-nonewline? ?channelId? string


    But notice that the following

    puts -nonewline

    outputs the text "-nonewline" to stdout. And,

    puts -nonewline stderr

    outputs "stderr" with no newline, and

    puts -nonewline stderr "text"

    outputs "text" to channel stderr w/o a newline.

    These cases indicate that the code must be using the argcount. In tcl one
    might code it as:

    proc puts {args} {
    ...
    }

    and use the [llength $args] to decide which arguments are defaulted. They
    also must be checking for the exact text "-nonewline" as well, since they don't treat it as an io channel, whereas this occurs if abbreviated:

    % puts -nonewlin stderr
    can not find channel named "-nonewlin"

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