• Tcl 9 and string is interger -strict

    From meshparts@[email protected] to comp.lang.tcl on Mon Sep 1 21:51:49 2025
    From Newsgroup: comp.lang.tcl

    I'm testing for the first time Tcl 9 with my applications (migrating
    from tcl 8).

    The first issue I see is the changed behavior "string is double -strict"
    to return 1 even if the number contains unterscores.

    My code uses this command a lot and I wonder what would be the easiest
    way to make it compatible and actually return 0 if the number contains underscores.

    I also wonder if there is a chance, make this new behavior only active
    when a specific option is set? And without that option, the old behavior
    would be active.

    Is there a way to customize my Tcl 9 so that the old behavior is back?

    Currently I only see the way out by replacing all calls to "string is
    integer" by a self written procedure

    proc ::StringIsIntegerStrict {args} {
    # Check if _ is present in the string
    set s [lindex $args end]
    set idx [string first {_} $s]
    # If _ is present
    if {$idx>=0} {
    # this is no integer
    return 0
    }
    return [string is integer -strict {*}$args]
    }
    puts [string is integer -strict 1_2]
    puts [::StringIsIntegerStrict 1_2]

    Any better ideas?

    P.S.: Why adding this new logic to "string" command in the first place?
    What is the logic of that?

    Many thanks
    Alexandru
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From meshparts@[email protected] to comp.lang.tcl on Mon Sep 1 21:53:48 2025
    From Newsgroup: comp.lang.tcl

    Am 01.09.2025 um 21:51 schrieb meshparts:
    I'm testing for the first time Tcl 9 with my applications (migrating
    from tcl 8).

    The first issue I see is the changed behavior "string is double -strict"
    to return 1 even if the number contains unterscores.

    My code uses this command a lot and I wonder what would be the easiest
    way to make it compatible and actually return 0 if the number contains underscores.

    I also wonder if there is a chance, make this new behavior only active
    when a specific option is set? And without that option, the old behavior would be active.

    Is there a way to customize my Tcl 9 so that the old behavior is back?

    Currently I only see the way out by replacing all calls to "string is integer" by a self written procedure

    proc ::StringIsIntegerStrict {args} {
      # Check if _ is present in the string
      set s [lindex $args end]
      set idx [string first {_} $s]
      # If _ is present
      if {$idx>=0} {
        # this is no integer
        return 0
      }
      return [string is integer -strict {*}$args]
    }
    puts [string is integer -strict 1_2]
    puts [::StringIsIntegerStrict 1_2]

    Any better ideas?

    P.S.: Why adding this new logic to "string" command in the first place?
    What is the logic of that?

    Many thanks
    Alexandru


    BTW: I don't like replacing the original "string is integer" calls by a procedure, since this could negatively affect the performance of my code.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From et99@[email protected] to comp.lang.tcl on Mon Sep 1 14:12:47 2025
    From Newsgroup: comp.lang.tcl

    On 9/1/2025 12:51 PM, meshparts wrote:
    I'm testing for the first time Tcl 9 with my applications (migrating from tcl 8).

    The first issue I see is the changed behavior "string is double -strict" to return 1 even if the number contains unterscores.

    My code uses this command a lot and I wonder what would be the easiest way to make it compatible and actually return 0 if the number contains underscores.

    I also wonder if there is a chance, make this new behavior only active when a specific option is set? And without that option, the old behavior would be active.

    Is there a way to customize my Tcl 9 so that the old behavior is back?

    Currently I only see the way out by replacing all calls to "string is integer" by a self written procedure

    proc ::StringIsIntegerStrict {args} {
      # Check if _ is present in the string
      set s [lindex $args end]
      set idx [string first {_} $s]
      # If _ is present
      if {$idx>=0} {
        # this is no integer
        return 0
      }
      return [string is integer -strict {*}$args]
    }
    puts [string is integer -strict 1_2]
    puts [::StringIsIntegerStrict 1_2]

    Any better ideas?

    P.S.: Why adding this new logic to "string" command in the first place? What is the logic of that?

    Many thanks
    Alexandru

    The string is integer command returns true if the string would be accepted as an integer in tcl8/9 source code. It is not, (as I read the manual) intended to be used to verify the character class of a string for "integer-ness".

    So, for example, in tcl9 we now can also have a string such as 0d123 that is an integer, whereas in tcl8 that would be false. Since integers in tcl9 now allow the underscore, that is why it now returns 1 for 1_2. Note, radix'd integers are also checked for validity, so 0b123 or 0x123fg would be false. In addition, tcl9 integers can now be bignum's whereas in tcl8 the size was limited. Also, in tcl9 0888 is 888 and a valid integer, since a leading 0 is no longer octal (need to use 0o777 etc.)

    If you don't want to use a procedure, then perhaps a regexp of say,

    regexp {^\d+$} 1_2

    might work for you if you only want an integer with purely digits.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From meshparts@[email protected] to comp.lang.tcl on Mon Sep 1 23:23:49 2025
    From Newsgroup: comp.lang.tcl

    Am 01.09.2025 um 23:12 schrieb et99:
    On 9/1/2025 12:51 PM, meshparts wrote:
    I'm testing for the first time Tcl 9 with my applications (migrating
    from tcl 8).

    The first issue I see is the changed behavior "string is double -
    strict" to return 1 even if the number contains unterscores.

    My code uses this command a lot and I wonder what would be the easiest
    way to make it compatible and actually return 0 if the number contains
    underscores.

    I also wonder if there is a chance, make this new behavior only active
    when a specific option is set? And without that option, the old
    behavior would be active.

    Is there a way to customize my Tcl 9 so that the old behavior is back?

    Currently I only see the way out by replacing all calls to "string is
    integer" by a self written procedure

    proc ::StringIsIntegerStrict {args} {
       # Check if _ is present in the string
       set s [lindex $args end]
       set idx [string first {_} $s]
       # If _ is present
       if {$idx>=0} {
         # this is no integer
         return 0
       }
       return [string is integer -strict {*}$args]
    }
    puts [string is integer -strict 1_2]
    puts [::StringIsIntegerStrict 1_2]

    Any better ideas?

    P.S.: Why adding this new logic to "string" command in the first
    place? What is the logic of that?

    Many thanks
    Alexandru

    The string is integer command returns true if the string would be
    accepted as an integer in tcl8/9 source code. It is not, (as I read the manual) intended to be used to verify the character class of a string
    for "integer-ness".

    So, for example, in tcl9 we now can also have a string such as 0d123
    that is an integer, whereas in tcl8 that would be false. Since integers
    in tcl9 now allow the underscore, that is why it now returns 1 for 1_2. Note, radix'd integers are also checked for validity, so 0b123 or
    0x123fg would be false. In addition, tcl9 integers can now be bignum's whereas in tcl8 the size was limited. Also, in tcl9 0888 is 888  and a valid integer, since a leading 0 is no longer octal (need to use 0o777
    etc.)

    If you don't want to use a procedure, then perhaps a regexp of say,

    regexp {^\d+$} 1_2

    might work for you if you only want an integer with purely digits.

    Thank you for the explanations.
    Regards
    Alexandru
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Harald Oehlmann@[email protected] to comp.lang.tcl on Tue Sep 2 08:08:22 2025
    From Newsgroup: comp.lang.tcl

    If you don't want to use a procedure, then perhaps a regexp of say,

    regexp {^\d+$} 1_2

    might work for you if you only want an integer with purely digits.


    You may also use "string is digit -strict". As the octal interpretation
    of "08" is gone, this is now safe for integer input.
    I use:
    - in tcl 8.6:
    if {1 == [scan $data %d data]} {...}
    Remark that in 8.6,
    [string is integer -exact $data]
    was not ok for me, as the input "077" resulted in the decimal number 73
    - in tcl 9.0
    if {[string is digit -strict $data]} {...}
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From meshparts@[email protected] to comp.lang.tcl on Tue Sep 2 09:44:09 2025
    From Newsgroup: comp.lang.tcl

    Am 02.09.2025 um 08:08 schrieb Harald Oehlmann:
    If you don't want to use a procedure, then perhaps a regexp of say,

    regexp {^\d+$} 1_2

    might work for you if you only want an integer with purely digits.


    You may also use "string is digit -strict". As the octal interpretation
    of "08" is gone, this is now safe for integer input.
    I use:
    - in tcl 8.6:
    if {1 == [scan $data %d data]} {...}
    Remark that in 8.6,
    [string is integer -exact $data]
    was not ok for me, as the input "077" resulted in the decimal number 73
    - in tcl 9.0
    if {[string is digit -strict $data]} {...}
    Thanks.
    According to the manual to digit: Any Unicode digit character. Note that
    this includes characters outside of the [0-9] range.
    How is this safe if I only want to know, if the interger is composed of 0-9? --- Synchronet 3.21a-Linux NewsLink 1.2
  • From meshparts@[email protected] to comp.lang.tcl on Tue Sep 2 15:57:15 2025
    From Newsgroup: comp.lang.tcl

    Am 01.09.2025 um 21:51 schrieb meshparts:
    I'm testing for the first time Tcl 9 with my applications (migrating
    from tcl 8).

    The first issue I see is the changed behavior "string is double -strict"
    to return 1 even if the number contains unterscores.

    My code uses this command a lot and I wonder what would be the easiest
    way to make it compatible and actually return 0 if the number contains underscores.

    I also wonder if there is a chance, make this new behavior only active
    when a specific option is set? And without that option, the old behavior would be active.

    Is there a way to customize my Tcl 9 so that the old behavior is back?

    Currently I only see the way out by replacing all calls to "string is integer" by a self written procedure

    proc ::StringIsIntegerStrict {args} {
      # Check if _ is present in the string
      set s [lindex $args end]
      set idx [string first {_} $s]
      # If _ is present
      if {$idx>=0} {
        # this is no integer
        return 0
      }
      return [string is integer -strict {*}$args]
    }
    puts [string is integer -strict 1_2]
    puts [::StringIsIntegerStrict 1_2]

    Any better ideas?

    P.S.: Why adding this new logic to "string" command in the first place?
    What is the logic of that?

    Many thanks
    Alexandru
    Spining this further: What would be the most efficient solution to
    finding out if a string is a double in Tcl 9?
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Harald Oehlmann@[email protected] to comp.lang.tcl on Tue Sep 2 16:11:01 2025
    From Newsgroup: comp.lang.tcl

    Am 02.09.2025 um 15:57 schrieb meshparts:
    Am 01.09.2025 um 21:51 schrieb meshparts:
    I'm testing for the first time Tcl 9 with my applications (migrating
    from tcl 8).

    The first issue I see is the changed behavior "string is double -
    strict" to return 1 even if the number contains unterscores.

    My code uses this command a lot and I wonder what would be the easiest
    way to make it compatible and actually return 0 if the number contains
    underscores.

    I also wonder if there is a chance, make this new behavior only active
    when a specific option is set? And without that option, the old
    behavior would be active.

    Is there a way to customize my Tcl 9 so that the old behavior is back?

    Currently I only see the way out by replacing all calls to "string is
    integer" by a self written procedure

    proc ::StringIsIntegerStrict {args} {
       # Check if _ is present in the string
       set s [lindex $args end]
       set idx [string first {_} $s]
       # If _ is present
       if {$idx>=0} {
         # this is no integer
         return 0
       }
       return [string is integer -strict {*}$args]
    }
    puts [string is integer -strict 1_2]
    puts [::StringIsIntegerStrict 1_2]

    Any better ideas?

    P.S.: Why adding this new logic to "string" command in the first
    place? What is the logic of that?

    Many thanks
    Alexandru
    Spining this further: What would be the most efficient solution to
    finding out if a string is a double in Tcl 9?

    Do you want to filter string representations of doubles or differentiate double and entier ?

    As most "string is" commands are nowdays effective, when not applied to strings, you may use:

    - string is double
    - string is entier

    But if you want to filter an input mask on number "." number, I would
    use a regexp. Eventually also with German separator ",".

    regexp {^\d+\.\d+$}
    If you want double and integers (e.g. ". number is optional):
    regexp {^\d+(\.\d+)?$}

    The German version is:
    regexp {^\d+(,\d+)?$} $data
    set data [string map {, .} $data]

    Harald

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From meshparts@[email protected] to comp.lang.tcl on Tue Sep 2 16:27:15 2025
    From Newsgroup: comp.lang.tcl

    Am 02.09.2025 um 16:11 schrieb Harald Oehlmann:
    Am 02.09.2025 um 15:57 schrieb meshparts:
    Am 01.09.2025 um 21:51 schrieb meshparts:
    I'm testing for the first time Tcl 9 with my applications (migrating
    from tcl 8).

    The first issue I see is the changed behavior "string is double -
    strict" to return 1 even if the number contains unterscores.

    My code uses this command a lot and I wonder what would be the
    easiest way to make it compatible and actually return 0 if the number
    contains underscores.

    I also wonder if there is a chance, make this new behavior only
    active when a specific option is set? And without that option, the
    old behavior would be active.

    Is there a way to customize my Tcl 9 so that the old behavior is back?

    Currently I only see the way out by replacing all calls to "string is
    integer" by a self written procedure

    proc ::StringIsIntegerStrict {args} {
       # Check if _ is present in the string
       set s [lindex $args end]
       set idx [string first {_} $s]
       # If _ is present
       if {$idx>=0} {
         # this is no integer
         return 0
       }
       return [string is integer -strict {*}$args]
    }
    puts [string is integer -strict 1_2]
    puts [::StringIsIntegerStrict 1_2]

    Any better ideas?

    P.S.: Why adding this new logic to "string" command in the first
    place? What is the logic of that?

    Many thanks
    Alexandru
    Spining this further: What would be the most efficient solution to
    finding out if a string is a double in Tcl 9?

    Do you want to filter string representations of doubles or differentiate double and entier ?

    As most "string is" commands are nowdays effective, when not applied to strings, you may use:

    - string is double
    - string is entier

    But if you want to filter an input mask on number "." number, I would
    use a regexp. Eventually also with German separator ",".

    regexp {^\d+\.\d+$}
    If you want double and integers (e.g. ". number is optional):
    regexp {^\d+(\.\d+)?$}

    The German version is:
    regexp {^\d+(,\d+)?$} $data
    set data [string map {, .} $data]

    Harald


    I should have specified more exactly: I want to identify strings that
    are usual numbers (e.g. 10, 10.5, 1e4). That is, string on which I can
    apply math operations. But numbers as 10_5 or other exotic represations
    of numbers should not be recognized as numbers.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Harald Oehlmann@[email protected] to comp.lang.tcl on Tue Sep 2 16:37:04 2025
    From Newsgroup: comp.lang.tcl

    Am 02.09.2025 um 16:27 schrieb meshparts:
    Am 02.09.2025 um 16:11 schrieb Harald Oehlmann:
    Am 02.09.2025 um 15:57 schrieb meshparts:
    Am 01.09.2025 um 21:51 schrieb meshparts:
    I'm testing for the first time Tcl 9 with my applications (migrating
    from tcl 8).

    The first issue I see is the changed behavior "string is double -
    strict" to return 1 even if the number contains unterscores.

    My code uses this command a lot and I wonder what would be the
    easiest way to make it compatible and actually return 0 if the
    number contains underscores.

    I also wonder if there is a chance, make this new behavior only
    active when a specific option is set? And without that option, the
    old behavior would be active.

    Is there a way to customize my Tcl 9 so that the old behavior is back? >>>>
    Currently I only see the way out by replacing all calls to "string
    is integer" by a self written procedure

    proc ::StringIsIntegerStrict {args} {
       # Check if _ is present in the string
       set s [lindex $args end]
       set idx [string first {_} $s]
       # If _ is present
       if {$idx>=0} {
         # this is no integer
         return 0
       }
       return [string is integer -strict {*}$args]
    }
    puts [string is integer -strict 1_2]
    puts [::StringIsIntegerStrict 1_2]

    Any better ideas?

    P.S.: Why adding this new logic to "string" command in the first
    place? What is the logic of that?

    Many thanks
    Alexandru
    Spining this further: What would be the most efficient solution to
    finding out if a string is a double in Tcl 9?

    Do you want to filter string representations of doubles or
    differentiate double and entier ?

    As most "string is" commands are nowdays effective, when not applied
    to strings, you may use:

    - string is double
    - string is entier

    But if you want to filter an input mask on number "." number, I would
    use a regexp. Eventually also with German separator ",".

    regexp {^\d+\.\d+$}
    If you want double and integers (e.g. ". number is optional):
    regexp {^\d+(\.\d+)?$}

    The German version is:
    regexp {^\d+(,\d+)?$} $data
    set data [string map {, .} $data]

    Harald


    I should have specified more exactly: I want to identify strings that
    are usual numbers (e.g. 10, 10.5, 1e4). That is, string on which I can
    apply math operations. But numbers as 10_5 or other exotic represations
    of numbers should not be recognized as numbers.

    Well, "exotic" is a matter of taste ;-).

    The reason for the "_" is to represent big numbers with a visual
    separator: "1_000_000_000" for 1 Billion. Other programming languages do
    it the same way. For me "1e4" is more exotic than that.

    But anyway. You can express a regexp or use "string is double -strict",
    which allows the exotic parts.
    Harald
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From meshparts@[email protected] to comp.lang.tcl on Tue Sep 2 19:56:42 2025
    From Newsgroup: comp.lang.tcl

    Am 02.09.2025 um 16:37 schrieb Harald Oehlmann:
    Am 02.09.2025 um 16:27 schrieb meshparts:
    Am 02.09.2025 um 16:11 schrieb Harald Oehlmann:
    Am 02.09.2025 um 15:57 schrieb meshparts:
    Am 01.09.2025 um 21:51 schrieb meshparts:
    I'm testing for the first time Tcl 9 with my applications
    (migrating from tcl 8).

    The first issue I see is the changed behavior "string is double -
    strict" to return 1 even if the number contains unterscores.

    My code uses this command a lot and I wonder what would be the
    easiest way to make it compatible and actually return 0 if the
    number contains underscores.

    I also wonder if there is a chance, make this new behavior only
    active when a specific option is set? And without that option, the
    old behavior would be active.

    Is there a way to customize my Tcl 9 so that the old behavior is back? >>>>>
    Currently I only see the way out by replacing all calls to "string
    is integer" by a self written procedure

    proc ::StringIsIntegerStrict {args} {
       # Check if _ is present in the string
       set s [lindex $args end]
       set idx [string first {_} $s]
       # If _ is present
       if {$idx>=0} {
         # this is no integer
         return 0
       }
       return [string is integer -strict {*}$args]
    }
    puts [string is integer -strict 1_2]
    puts [::StringIsIntegerStrict 1_2]

    Any better ideas?

    P.S.: Why adding this new logic to "string" command in the first
    place? What is the logic of that?

    Many thanks
    Alexandru
    Spining this further: What would be the most efficient solution to
    finding out if a string is a double in Tcl 9?

    Do you want to filter string representations of doubles or
    differentiate double and entier ?

    As most "string is" commands are nowdays effective, when not applied
    to strings, you may use:

    - string is double
    - string is entier

    But if you want to filter an input mask on number "." number, I would
    use a regexp. Eventually also with German separator ",".

    regexp {^\d+\.\d+$}
    If you want double and integers (e.g. ". number is optional):
    regexp {^\d+(\.\d+)?$}

    The German version is:
    regexp {^\d+(,\d+)?$} $data
    set data [string map {, .} $data]

    Harald


    I should have specified more exactly: I want to identify strings that
    are usual numbers (e.g. 10, 10.5, 1e4). That is, string on which I can
    apply math operations. But numbers as 10_5 or other exotic
    represations of numbers should not be recognized as numbers.

    Well, "exotic" is a matter of taste ;-).

    The reason for the "_" is to represent big numbers with a visual
    separator: "1_000_000_000" for 1 Billion. Other programming languages do
    it the same way. For me "1e4" is more exotic than that.

    But anyway. You can express a regexp or use "string is double -strict", which allows the exotic parts.
    Harald
    Well, that regexp (regexp {^\d+(\.\d+)?$}) would not identify a number,
    since it skips the scientific notation.

    It's really annoying there is no inbuild function for this in Tcl.
    And Tcl 9 makes it (at least for me) even harder than Tcl 8.
    What I can do is at least bring back the old behavior of Tcl 8, where underscores were not a number. So I would replace all "string is double -strict" by this procedure:

    proc ::StringIsDoubleStrict {args} {
    # Check if _ is present in the string
    set s [lindex $args end]
    set idx [string first {_} $s]
    # If _ is present
    if {$idx>=0} {
    # this is no integer
    return 0
    }
    return [string is double -strict {*}$args]
    }

    Testing shows that the procedure is 7x slower than "string is double
    -strict" though...
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From et99@[email protected] to comp.lang.tcl on Tue Sep 2 13:18:49 2025
    From Newsgroup: comp.lang.tcl

    On 9/2/2025 10:56 AM, meshparts wrote:
    proc ::StringIsDoubleStrict {args} {
       # Check if _ is present in the string
       set s [lindex $args end]
       set idx [string first {_} $s]
       # If _ is present
       if {$idx>=0} {
         # this is no integer
         return 0
       }
       return [string is double -strict {*}$args]
    }

    AFAIK [string is double -strict] does not accept a list of numbers, so there's no need to use args, lindex, and {*}.

    Also, you can reduce this to just an expr command, (to replace your current code w/o a proc) like so:

    expr {[string is double -strict $input] && [string first {_} $input]<0}

    which my timings show, depending on input, is 2-3x faster than using a proc. If the value fails the first test, the check for underscores need not be done at all.





    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From meshparts@[email protected] to comp.lang.tcl on Wed Sep 3 08:13:27 2025
    From Newsgroup: comp.lang.tcl

    Am 02.09.2025 um 22:18 schrieb et99:
    string is double
    That should be faster indeed. Thanks.

    BTW: The args are there for the options that could be added to the
    string command.

    But if I leave those options out, this procedure is only 3x slower:

    proc ::StringIsDoubleStrict {s} {
    return [expr {[string is double -strict $s] && [string first {_} $s]<0}]
    }

    Of course, I could call the command directly, but then the code is ugly
    and it's hard to remember it.
    --- Synchronet 3.21a-Linux NewsLink 1.2