You can subscribe to this list here.
| 2000 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(19) |
Jul
(96) |
Aug
(144) |
Sep
(222) |
Oct
(496) |
Nov
(171) |
Dec
(6) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2001 |
Jan
(4) |
Feb
(4) |
Mar
(9) |
Apr
(4) |
May
(12) |
Jun
(6) |
Jul
|
Aug
|
Sep
(1) |
Oct
(2) |
Nov
|
Dec
|
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
(52) |
Aug
(47) |
Sep
(47) |
Oct
(95) |
Nov
(56) |
Dec
(34) |
| 2003 |
Jan
(99) |
Feb
(116) |
Mar
(125) |
Apr
(99) |
May
(123) |
Jun
(69) |
Jul
(110) |
Aug
(130) |
Sep
(289) |
Oct
(211) |
Nov
(98) |
Dec
(140) |
| 2004 |
Jan
(85) |
Feb
(87) |
Mar
(342) |
Apr
(125) |
May
(101) |
Jun
(60) |
Jul
(151) |
Aug
(118) |
Sep
(162) |
Oct
(117) |
Nov
(125) |
Dec
(95) |
| 2005 |
Jan
(141) |
Feb
(54) |
Mar
(79) |
Apr
(83) |
May
(74) |
Jun
(125) |
Jul
(63) |
Aug
(89) |
Sep
(130) |
Oct
(89) |
Nov
(34) |
Dec
(39) |
| 2006 |
Jan
(98) |
Feb
(62) |
Mar
(56) |
Apr
(94) |
May
(169) |
Jun
(41) |
Jul
(34) |
Aug
(35) |
Sep
(132) |
Oct
(722) |
Nov
(381) |
Dec
(36) |
| 2007 |
Jan
(34) |
Feb
(174) |
Mar
(15) |
Apr
(35) |
May
(74) |
Jun
(15) |
Jul
(8) |
Aug
(18) |
Sep
(39) |
Oct
(125) |
Nov
(89) |
Dec
(129) |
| 2008 |
Jan
(176) |
Feb
(91) |
Mar
(69) |
Apr
(178) |
May
(310) |
Jun
(434) |
Jul
(171) |
Aug
(73) |
Sep
(187) |
Oct
(132) |
Nov
(259) |
Dec
(292) |
| 2009 |
Jan
(27) |
Feb
(54) |
Mar
(35) |
Apr
(54) |
May
(93) |
Jun
(10) |
Jul
(36) |
Aug
(36) |
Sep
(93) |
Oct
(52) |
Nov
(45) |
Dec
(74) |
| 2010 |
Jan
(20) |
Feb
(120) |
Mar
(165) |
Apr
(101) |
May
(56) |
Jun
(12) |
Jul
(73) |
Aug
(306) |
Sep
(154) |
Oct
(82) |
Nov
(63) |
Dec
(42) |
| 2011 |
Jan
(176) |
Feb
(86) |
Mar
(199) |
Apr
(86) |
May
(237) |
Jun
(50) |
Jul
(26) |
Aug
(56) |
Sep
(42) |
Oct
(62) |
Nov
(62) |
Dec
(52) |
| 2012 |
Jan
(35) |
Feb
(33) |
Mar
(128) |
Apr
(152) |
May
(133) |
Jun
(21) |
Jul
(74) |
Aug
(423) |
Sep
(165) |
Oct
(129) |
Nov
(387) |
Dec
(276) |
| 2013 |
Jan
(105) |
Feb
(30) |
Mar
(130) |
Apr
(42) |
May
(60) |
Jun
(79) |
Jul
(101) |
Aug
(46) |
Sep
(81) |
Oct
(14) |
Nov
(43) |
Dec
(4) |
| 2014 |
Jan
(25) |
Feb
(32) |
Mar
(30) |
Apr
(80) |
May
(42) |
Jun
(23) |
Jul
(68) |
Aug
(127) |
Sep
(112) |
Oct
(72) |
Nov
(29) |
Dec
(69) |
| 2015 |
Jan
(35) |
Feb
(49) |
Mar
(95) |
Apr
(10) |
May
(70) |
Jun
(64) |
Jul
(93) |
Aug
(85) |
Sep
(43) |
Oct
(38) |
Nov
(124) |
Dec
(29) |
| 2016 |
Jan
(253) |
Feb
(181) |
Mar
(132) |
Apr
(419) |
May
(68) |
Jun
(90) |
Jul
(52) |
Aug
(142) |
Sep
(131) |
Oct
(80) |
Nov
(84) |
Dec
(192) |
| 2017 |
Jan
(329) |
Feb
(842) |
Mar
(248) |
Apr
(85) |
May
(247) |
Jun
(186) |
Jul
(37) |
Aug
(73) |
Sep
(98) |
Oct
(108) |
Nov
(143) |
Dec
(143) |
| 2018 |
Jan
(155) |
Feb
(139) |
Mar
(72) |
Apr
(112) |
May
(82) |
Jun
(119) |
Jul
(24) |
Aug
(33) |
Sep
(179) |
Oct
(295) |
Nov
(111) |
Dec
(34) |
| 2019 |
Jan
(20) |
Feb
(29) |
Mar
(49) |
Apr
(89) |
May
(185) |
Jun
(131) |
Jul
(9) |
Aug
(59) |
Sep
(30) |
Oct
(44) |
Nov
(118) |
Dec
(53) |
| 2020 |
Jan
(70) |
Feb
(108) |
Mar
(50) |
Apr
(9) |
May
(70) |
Jun
(24) |
Jul
(103) |
Aug
(82) |
Sep
(132) |
Oct
(119) |
Nov
(174) |
Dec
(169) |
| 2021 |
Jan
(75) |
Feb
(51) |
Mar
(76) |
Apr
(73) |
May
(53) |
Jun
(120) |
Jul
(114) |
Aug
(73) |
Sep
(70) |
Oct
(18) |
Nov
(26) |
Dec
|
| 2022 |
Jan
(26) |
Feb
(63) |
Mar
(64) |
Apr
(64) |
May
(48) |
Jun
(74) |
Jul
(129) |
Aug
(106) |
Sep
(238) |
Oct
(169) |
Nov
(149) |
Dec
(111) |
| 2023 |
Jan
(110) |
Feb
(47) |
Mar
(82) |
Apr
(106) |
May
(168) |
Jun
(101) |
Jul
(155) |
Aug
(35) |
Sep
(51) |
Oct
(55) |
Nov
(134) |
Dec
(202) |
| 2024 |
Jan
(103) |
Feb
(129) |
Mar
(154) |
Apr
(89) |
May
(60) |
Jun
(162) |
Jul
(201) |
Aug
(61) |
Sep
(167) |
Oct
(111) |
Nov
(133) |
Dec
(141) |
| 2025 |
Jan
(122) |
Feb
(88) |
Mar
(106) |
Apr
(113) |
May
(203) |
Jun
(185) |
Jul
(124) |
Aug
(202) |
Sep
(176) |
Oct
(206) |
Nov
(259) |
Dec
(276) |
| 2026 |
Jan
(207) |
Feb
(180) |
Mar
(303) |
Apr
(340) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: Florent M. <flo...@gm...> - 2026-04-28 05:42:38
|
Hi Mason, hi Donal,
Compared to lmap, there is a need for a test, to know if the result must
be collected,
but there is also a need of a body : we may not just want to return the
first var.
So the interface would be more generic like this :
lfilter var List test body
The "test" script indicating if we must collect or not, the body the
transformation to apply.
But it could even be more general, because we may want to make many
tests, and apply a different transformation for each.
Then it would look more like a switch :
lfilter var List {
{test1} { body1}
{test 2} { body 2}
default {}
}
An empty body would means : don't collect.
a filled body would apply a transform before appending.
lfilter x [lseq 100] {
{(round($x*0.5)*2 == $x)} ($x)
}
Regards
Le 27/04/2026 à 21:28, Mason McParlane a écrit :
> Florent,
>
> Please don’t spam the thread this should stay focused on simple list
> filtering and not other requested features. That is a lot to read
> through and frankly unrelated to the proposed change.
>
>
> Thanks,
> Mason
>
> On Mon, Apr 27, 2026, at 4:01 PM, Florent Merlet wrote:
>> Hi Donal,
>>
>> Le 26/04/2026 à 13:02, Donal Fellows a écrit :
>>>
>>> TIP 735: Simpler List Filtering
>>> <https://core.tcl-lang.org/tips/doc/trunk/tip/735.md>
>>> This adds a global *lfilter *command, because the current idiom for
>>> filtering out items of a list (when *lsearch -inline -all
>>> -not* can't do it) is weird. /I've tried using an expression for the
>>> filter/ (that was the initial version of the TIP /but not the
>>> current one/), which works but feels more annoying to me than using
>>> a script (with expressions available by calling *expr*). I can be
>>> talked round to doing this the other way, but the current way is
>>> marginally simpler to implement (on the interpreted side; the
>>> compiled version is pretty much identically complex).
>>
>> With my proposal
>> <https://github.com/florentis/tcl90-exprSH/tree/core-9-0-branch/install_SH>,
>> you wouldn't have to worry about this existential question :
>> /expression or not expression/ ?
>>
>> Just use {( ... )} to parse any body as an expression.
>> |% lfilter x [lseq 100] {( # Is this value a square number?
>> round($x**0.5)**2 == $x )} 0 1 4 9 16 25 36 49 64 81|
>>
>> Command interface has a prefix notation, while expression interface
>> has infix notation. Both interfaces are producing the same bytecode,
>> which has globally a postfix notation.
>>
>> Command interface is more convenient for strings and list. Expression
>> interface is more convenient for numbers and arithmetic. That's why
>> we may want to choose between the two interfaces, depending on what
>> we like to do.
>>
>> Hence this idea to introduce a syntactical mark, like enclosing a
>> body into parentheses, to quickly access to the expression interface
>> when it is more convenient.
>>
>> This works fine in my prototype :
>>
>> |% lmap x [lseq 100] {( round($x**0.5)**2 == $x ? $x : [continue])}
>> 0 1 4 9 16 25 36 49 64 81
>>
>> % lmap ||s|{abc foo dad} {( [|string equal $s [string reverse $s]|] ?
>> $s : [continue] )}
>> |dad
>>
>> |A lfilter script is :
>>
>> proc lfilter {args} {
>> set body [lindex $args end]
>> set var [lindex $args 0 0]
>> uplevel [list lmap {*}[lrange $args 0 end-1] [format {( [%s] ?
>> "${%s}" : [continue] )} $body $var]]
>> }
>>
>> (bin) 2 % lfilter x [lseq 100] {(
>> # Is this value a square number?
>> round($x**0.5)**2 == $x
>> )}
>> 0 1 4 9 16 25 36 49 64 81
>> |(bin) 3 % lfilter s {abc foo dad} { # Is the string exactly equal to
>> itself when reversed string equal $s [string reverse $s] } dad|
>> Measurements :
>> 1° expr :
>> % timerate {lfilter x [lseq 100] {(
>> # Is this value a square number?
>> round($x**0.5)**2 == $x
>> )}}
>> 246.161 µs/# 4062 # 4062.4 #/sec 999.906 net-ms
>>
>> timerate {
>> lmap x [lseq 100] {(
>> round($x**0.5)**2 == $x ? $x : [continue]
>> )}
>> }
>> 243.434 µs/# 4107 # 4107.9 #/sec 999.782 net-ms
>>
>> timerate {
>> lmap x [lseq 100] {
>> expr {round($x**0.5)**2 == $x ? $x : [continue]}
>> }
>> }
>> 244.795 µs/# 4085 # 4085.1 #/sec 999.987 net-ms
>> |(bin) 3 % lfilter s {abc foo dad} { # Is the string exactly equal to
>> itself when reversed string equal $s [string reverse $s] } dad|
>> 2° String :
>> timerate {lfilter s {abc foo dad} { string equal $s [string reverse
>> $s] }}
>> 31.9969 µs/# 31253 # 31253.0 #/sec 999.999 net-ms
>>
>> timerate {
>> lmap s {abc foo dad} {(
>> [string equal $s [string reverse $s]] ? $s : [continue]
>> )}
>> }
>> 9.166193 µs/# 109096 # 109096 #/sec 999.995 net-ms
>>
>> timerate {lmap s {abc foo dad} {
>> if {[string equal $s [string reverse $s]]} {
>> set s
>> } else continue
>> }}
>> 9.574369 µs/# 104445 # 104445 #/sec 999.995 net-ms
>>
>>
>> About the discussion with Pietro :
>> > while it's neat that we can filter lists with [lmap], the _how_ of
>> it isn't
>> > so nice and _many_ other languages have some sort of filter()
>> > operation, so this felt like a neglected corner.
>> First : the script expr shorthand by itself would imporve the situation.
>>
>> |lmap x [lseq 100] {( round($x**0.5)**2 == $x ? $x : [continue])}
>> is quite clear.
>> ||
>> Second. What is the intend ? It is to build a list thanks to a
>> predicate <https://en.wikipedia.org/wiki/Predicate_(logic)>
>> ||
>> round($x**0.5)**2 == $x
>> |[string equal $s [string reverse $s]]
>> are predicates
>>
>> Third : what is annoying here ? The need to add "[continue]".
>>
>> Historically, Before lmap, we would have used foreach for this|,
>> building a new list piece by piece.
>> When ||the predicate is true, then append|, else nothing
>>
>> set L {}
>> foreach |x [lseq 100] {(
>> ||round($x**0.5)**2 == $x ? [lappend L $x] :;|
>> |)}
>> ||set L
>> 0 1 4 9 16 25 36 49 64 81
>>
>> lmap is build on foreach, it's a collecting foreach.
>>
>> |lmap |x [lseq 100] {(
>> ||round($x**0.5)**2 == $x ? $x : ""|
>> |)}
>> |||0 1 {} {} 4 {} {} {} {} 9 {} {} {} {} {} {} 16 {} {} {} {} {} {}
>> {} {} 25 {} {} {} {} {} {} {} {} {} {} 36 {} {} {} {} {} {} {} {} {}
>> {} {} {} 49 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 64 {} {} {} {}
>> {} {} {} {} {} {} {} {} {} {} {} {} 81 {} {} {} {} {} {} {} {} {} {}
>> {} {} {} {} {} {} {} {} 100
>>
>> lmap collect every value, it doesn't select it.
>> We have to explicitly use the continue command skip what is not wanted.
>>
>> What you seem to expect is a projection (in database language)
>>
>> select $L {(|round($x**0.5)**2)}
>>
>> lmap is more done to "transform" the data, so naturally, the arity
>> remains the same. With this We can lmap Test to get the trace of the
>> predicate on the list.
>>
>> set L [lmap x [lseq 0 100] {(
>> round($x**0.5)**2 == $x
>> )}]
>> 1 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
>> 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
>> 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
>>
>> To select elements from a list, there is allready a command :
>>
>> lsearch -all $L 1
>> 0 1 4 9 16 25 36 49 64 81 100
>>
>> So maybe it is in this command the interface should be more obvious :
>>
>> lsearch -all -command {{x} {(||round($x**0.5)**2 == $x)}} ||$L
>> ||lsearch -all -command {|{s} {string equal $s [string reverse
>> $s]}|}||||$L|
>> |
>> Regards
>>
>> Florent
>> |
>> |
>> |
>>
>>
>> _______________________________________________
>> Tcl-Core mailing list
>> Tcl...@li...
>> https://lists.sourceforge.net/lists/listinfo/tcl-core
>>
>
>
>
> _______________________________________________
> Tcl-Core mailing list
> Tcl...@li...
> https://lists.sourceforge.net/lists/listinfo/tcl-core |
|
From: Emiliano <emi...@gm...> - 2026-04-27 21:51:49
|
On Fri, 24 Apr 2026 12:28:30 -0700 B Harder <bra...@gm...> wrote: Tk image types are visible at thread level; calling Tk_CreateImageType makes the registerd type to be visible on all intepreters in that thread. If an application needs to maintain a data structure associated with an image type, it can use Tcl_GetThreadData and associated functions without having to resort to using spare fields in a structure. Regards > Hello Tclers. > > I've been working in Tk, specifically w image, and would like run a proposal passed Core. > > In struct Tk_ImageType, generic/tk.h L1257 there is a "char *reserved", which was last updated by Brent Welch nearly 30 (c. 1998) years ago, is semantically marked as a placeholder for some future expansion, and as far as i can tell, not actually referenced anywhere. > > Proposal: can we take this and formally give it to developers as a ClientData clientData entry in the struct? As far as i can tell, it would functionally be a documentation update, not breaking any public APIs or ABIs. > > Best, > -bch -- Emiliano <emi...@gm...> |
|
From: Pietro C. <ga...@ga...> - 2026-04-27 20:00:33
|
On Apr 27 2026, 15:32 +0000, Donal Fellows <don...@ma...> wrote: [-- Type: text/html; charset=iso-8859-1, Encoding: quoted-printable, Size: 11K --] >I tend to feel that operations shouldn't just be justified by a grand plan. A >wall is not just built by imagining it's totality, but also by the placing of >each brick where it belongs. >But this is a huge scope-creep relative to my TIP, so others may pursue >it, but I'll not do so here. I believe that lfilter is useful in >itself. Thanks for taking the time to address my comments, Donal. This is a fair enough conclusion. I might have different preferences and opinions on how to build a consistent and cohesive experience, and we might not even be in agreement that those properties are something worth pursuing at all, but ultimately you're the one doing the job here :) -- Pietro Cerutti I have pledged to give 10% of income to effective charities and invite you to join me - https://givingwhatwecan.org |
|
From: Mason M. <ma...@ba...> - 2026-04-27 19:28:34
|
Florent, Please don’t spam the thread this should stay focused on simple list filtering and not other requested features. That is a lot to read through and frankly unrelated to the proposed change. Thanks, Mason On Mon, Apr 27, 2026, at 4:01 PM, Florent Merlet wrote: > Hi Donal, > > Le 26/04/2026 à 13:02, Donal Fellows a écrit : >> >> TIP 735: Simpler List Filtering <https://core.tcl-lang.org/tips/doc/trunk/tip/735.md> >> This adds a global *lfilter *command, because the current idiom for filtering out items of a list (when *lsearch -inline -all -not* can't do it) is weird. *I've tried using an expression for the filter* (that was the initial version of the TIP *but not the current one*), which works but feels more annoying to me than using a script (with expressions available by calling *expr*). I can be talked round to doing this the other way, but the current way is marginally simpler to implement (on the interpreted side; the compiled version is pretty much identically complex). > > With my proposal <https://github.com/florentis/tcl90-exprSH/tree/core-9-0-branch/install_SH>, > you wouldn't have to worry about this existential question : *expression or not expression* ? > > Just use {( ... )} to parse any body as an expression. > `% lfilter x [lseq 100] {( > # Is this value a square number? > round($x**0.5)**2 == $x > )} > 0 1 4 9 16 25 36 49 64 81` > Command interface has a prefix notation, while expression interface has infix notation. Both interfaces are producing the same bytecode, which has globally a postfix notation. > > Command interface is more convenient for strings and list. Expression interface is more convenient for numbers and arithmetic. That's why we may want to choose between the two interfaces, depending on what we like to do. > > Hence this idea to introduce a syntactical mark, like enclosing a body into parentheses, to quickly access to the expression interface when it is more convenient. > > This works fine in my prototype : > > `% lmap x [lseq 100] {( round($x**0.5)**2 == $x ? $x : [continue])} > 0 1 4 9 16 25 36 49 64 81 > > % lmap ``s` {abc foo dad} {( [`string equal $s [string reverse $s]`] ? $s : [continue] )} > `dad > `A lfilter script is : > > proc lfilter {args} { > set body [lindex $args end] > set var [lindex $args 0 0] > uplevel [list lmap {*}[lrange $args 0 end-1] [format {( [%s] ? "${%s}" : [continue] )} $body $var]] > } > > (bin) 2 % lfilter x [lseq 100] {( > # Is this value a square number? > round($x**0.5)**2 == $x > )} > 0 1 4 9 16 25 36 49 64 81 > `(bin) 3 % lfilter s {abc foo dad} { > # Is the string exactly equal to itself when reversed > string equal $s [string reverse $s] > } > dad` > Measurements : > 1° expr : > % timerate {lfilter x [lseq 100] {( > # Is this value a square number? > round($x**0.5)**2 == $x > )}} > 246.161 µs/# 4062 # 4062.4 #/sec 999.906 net-ms > > timerate { > lmap x [lseq 100] {( > round($x**0.5)**2 == $x ? $x : [continue] > )} > } > 243.434 µs/# 4107 # 4107.9 #/sec 999.782 net-ms > > timerate { > lmap x [lseq 100] { > expr {round($x**0.5)**2 == $x ? $x : [continue]} > } > } > 244.795 µs/# 4085 # 4085.1 #/sec 999.987 net-ms > ` > (bin) 3 % lfilter s {abc foo dad} { > # Is the string exactly equal to itself when reversed > string equal $s [string reverse $s] > } > dad` > 2° String : > timerate {lfilter s {abc foo dad} { string equal $s [string reverse $s] }} > 31.9969 µs/# 31253 # 31253.0 #/sec 999.999 net-ms > > timerate { > lmap s {abc foo dad} {( > [string equal $s [string reverse $s]] ? $s : [continue] > )} > } > 9.166193 µs/# 109096 # 109096 #/sec 999.995 net-ms > > timerate {lmap s {abc foo dad} { > if {[string equal $s [string reverse $s]]} { > set s > } else continue > }} > 9.574369 µs/# 104445 # 104445 #/sec 999.995 net-ms > > > About the discussion with Pietro : > > while it's neat that we can filter lists with [lmap], the _how_ of it isn't > > so nice and _many_ other languages have some sort of filter() > > operation, so this felt like a neglected corner. > First : the script expr shorthand by itself would imporve the situation. > > `lmap x [lseq 100] {( round($x**0.5)**2 == $x ? $x : [continue])} > is quite clear. `` > Second. What is the intend ? It is to build a list thanks to a predicate <https://en.wikipedia.org/wiki/Predicate_(logic)> `` > round($x**0.5)**2 == $x `[string equal $s [string reverse $s]] > are predicates > > Third : what is annoying here ? The need to add "[continue]". > > Historically, Before lmap, we would have used foreach for this`, building a new list piece by piece. > When ``the predicate is true, then append`, else nothing > > set L {} > foreach `x [lseq 100] {( > ``round($x**0.5)**2 == $x ? [lappend L $x] :;` > `)} ``set L > 0 1 4 9 16 25 36 49 64 81 > > lmap is build on foreach, it's a collecting foreach. > `lmap `x [lseq 100] {( > ``round($x**0.5)**2 == $x ? $x : ""` > `)} ```0 1 {} {} 4 {} {} {} {} 9 {} {} {} {} {} {} 16 {} {} {} {} {} {} {} {} 25 {} {} {} {} {} {} {} {} {} {} 36 {} {} {} {} {} {} {} {} {} {} {} {} 49 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 64 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 81 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 100 > > lmap collect every value, it doesn't select it. > We have to explicitly use the continue command skip what is not wanted. > > What you seem to expect is a projection (in database language) > > select $L {(`round($x**0.5)**2)} > > lmap is more done to "transform" the data, so naturally, the arity remains the same. With this We can lmap Test to get the trace of the predicate on the list. > > set L [lmap x [lseq 0 100] {( > round($x**0.5)**2 == $x > )}] > 1 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 > > To select elements from a list, there is allready a command : > > lsearch -all $L 1 > 0 1 4 9 16 25 36 49 64 81 100 > > So maybe it is in this command the interface should be more obvious : > > lsearch -all -command {{x} {(``round($x**0.5)**2 == $x)}} ``$L ``lsearch -all -command {`{s} {string equal $s [string reverse $s]}`}`` ``$L` > ` > Regards > > Florent ` > ` ` > > > _______________________________________________ > Tcl-Core mailing list > Tcl...@li... > https://lists.sourceforge.net/lists/listinfo/tcl-core > |
|
From: Florent M. <flo...@gm...> - 2026-04-27 19:02:09
|
Hi Donal, Le 26/04/2026 à 13:02, Donal Fellows a écrit : > > TIP 735: Simpler List Filtering > <https://core.tcl-lang.org/tips/doc/trunk/tip/735.md> > This adds a global *lfilter *command, because the current idiom for > filtering out items of a list (when *lsearch -inline -all -not* can't > do it) is weird. /I've tried using an expression for the filter/ (that > was the initial version of the TIP /but not the current one/), which > works but feels more annoying to me than using a script (with > expressions available by calling *expr*). I can be talked round to > doing this the other way, but the current way is marginally simpler to > implement (on the interpreted side; the compiled version is pretty > much identically complex). With my proposal <https://github.com/florentis/tcl90-exprSH/tree/core-9-0-branch/install_SH>, you wouldn't have to worry about this existential question : /expression or not expression/ ? Just use {( ... )} to parse any body as an expression. |% lfilter x [lseq 100] {( # Is this value a square number? round($x**0.5)**2 == $x )} 0 1 4 9 16 25 36 49 64 81| Command interface has a prefix notation, while expression interface has infix notation. Both interfaces are producing the same bytecode, which has globally a postfix notation. Command interface is more convenient for strings and list. Expression interface is more convenient for numbers and arithmetic. That's why we may want to choose between the two interfaces, depending on what we like to do. Hence this idea to introduce a syntactical mark, like enclosing a body into parentheses, to quickly access to the expression interface when it is more convenient. This works fine in my prototype : |% lmap x [lseq 100] {( round($x**0.5)**2 == $x ? $x : [continue])} 0 1 4 9 16 25 36 49 64 81 % lmap ||s|{abc foo dad} {( [|string equal $s [string reverse $s]|] ? $s : [continue] )} |dad |A lfilter script is : proc lfilter {args} { set body [lindex $args end] set var [lindex $args 0 0] uplevel [list lmap {*}[lrange $args 0 end-1] [format {( [%s] ? "${%s}" : [continue] )} $body $var]] } (bin) 2 % lfilter x [lseq 100] {( # Is this value a square number? round($x**0.5)**2 == $x )} 0 1 4 9 16 25 36 49 64 81 |(bin) 3 % lfilter s {abc foo dad} { # Is the string exactly equal to itself when reversed string equal $s [string reverse $s] } dad| Measurements : 1° expr : % timerate {lfilter x [lseq 100] {( # Is this value a square number? round($x**0.5)**2 == $x )}} 246.161 µs/# 4062 # 4062.4 #/sec 999.906 net-ms timerate { lmap x [lseq 100] {( round($x**0.5)**2 == $x ? $x : [continue] )} } 243.434 µs/# 4107 # 4107.9 #/sec 999.782 net-ms timerate { lmap x [lseq 100] { expr {round($x**0.5)**2 == $x ? $x : [continue]} } } 244.795 µs/# 4085 # 4085.1 #/sec 999.987 net-ms |(bin) 3 % lfilter s {abc foo dad} { # Is the string exactly equal to itself when reversed string equal $s [string reverse $s] } dad| 2° String : timerate {lfilter s {abc foo dad} { string equal $s [string reverse $s] }} 31.9969 µs/# 31253 # 31253.0 #/sec 999.999 net-ms timerate { lmap s {abc foo dad} {( [string equal $s [string reverse $s]] ? $s : [continue] )} } 9.166193 µs/# 109096 # 109096 #/sec 999.995 net-ms timerate {lmap s {abc foo dad} { if {[string equal $s [string reverse $s]]} { set s } else continue }} 9.574369 µs/# 104445 # 104445 #/sec 999.995 net-ms About the discussion with Pietro : > while it's neat that we can filter lists with [lmap], the _how_ of it isn't > so nice and _many_ other languages have some sort of filter() > operation, so this felt like a neglected corner. First : the script expr shorthand by itself would imporve the situation. |lmap x [lseq 100] {( round($x**0.5)**2 == $x ? $x : [continue])} is quite clear. || Second. What is the intend ? It is to build a list thanks to a predicate <https://en.wikipedia.org/wiki/Predicate_(logic)> || round($x**0.5)**2 == $x |[string equal $s [string reverse $s]] are predicates Third : what is annoying here ? The need to add "[continue]". Historically, Before lmap, we would have used foreach for this|, building a new list piece by piece. When ||the predicate is true, then append|, else nothing set L {} foreach |x [lseq 100] {( ||round($x**0.5)**2 == $x ? [lappend L $x] :;| |)} ||set L 0 1 4 9 16 25 36 49 64 81 lmap is build on foreach, it's a collecting foreach. |lmap |x [lseq 100] {( ||round($x**0.5)**2 == $x ? $x : ""| |)} |||0 1 {} {} 4 {} {} {} {} 9 {} {} {} {} {} {} 16 {} {} {} {} {} {} {} {} 25 {} {} {} {} {} {} {} {} {} {} 36 {} {} {} {} {} {} {} {} {} {} {} {} 49 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 64 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 81 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 100 lmap collect every value, it doesn't select it. We have to explicitly use the continue command skip what is not wanted. What you seem to expect is a projection (in database language) select $L {(|round($x**0.5)**2)} lmap is more done to "transform" the data, so naturally, the arity remains the same. With this We can lmap Test to get the trace of the predicate on the list. set L [lmap x [lseq 0 100] {( round($x**0.5)**2 == $x )}] 1 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 To select elements from a list, there is allready a command : lsearch -all $L 1 0 1 4 9 16 25 36 49 64 81 100 So maybe it is in this command the interface should be more obvious : lsearch -all -command {{x} {(||round($x**0.5)**2 == $x)}} ||$L ||lsearch -all -command {|{s} {string equal $s [string reverse $s]}|}||||$L| | Regards Florent | | | |
|
From: Donal F. <don...@ma...> - 2026-04-27 15:33:07
|
I tend to feel that operations shouldn't just be justified by a grand plan. A wall is not just built by imagining it's totality, but also by the placing of each brick where it belongs. For the operations you list: * Fold is obviated by variadic operators; we just do an expanded application. It's a slightly different generalisation. * Take and Drop are just simple applications of lrange. * Nth is exactly within what lindex does. * Iota is lseq. Thinking about the other common operations in Python: * We could perhaps do with enumerate<https://docs.python.org/3/library/functions.html#enumerate>(), all<https://docs.python.org/3/library/functions.html#all>() and any<https://docs.python.org/3/library/functions.html#any>() sometime; they can be useful. * We don't have zip<https://docs.python.org/3/library/functions.html#zip>(), but don't need it so much either (again, that variadicity). * We don't agonise over the difference between tuples and lists, and don't have user-defined generators for various reasons at the moment. * Sorting and searching by a collation key are annoying operations right now, nor do we support min() or max() with a measure function. Thinking about operations from Java's List and ArrayList (similarly for C# but with different names): * We've nothing like containsAll<https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/List.html#containsAll(java.util.Collection)>() or removeAll<https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/List.html#removeAll(java.util.Collection)>()/retainAll(). We could perhaps do with something like partition<https://smlfamily.github.io/Basis/list.html#SIG:LIST.partition:VAL> <https://smlfamily.github.io/Basis/list.html#SIG:LIST.partition:VAL> from SML, though it might be low priority. You can probably list other things from other languages, but I believe the above cover all the common cases that we don't already have. We could also perhaps do with some operations more like those for (insertion-time ordered, much as dicts are insertion-time ordered) sets. They're reasonably useful. Linked lists and actual balanced trees... not so useful except in special circumstances. I've never missed having them! But this is a huge scope-creep relative to my TIP, so others may pursue it, but I'll not do so here. I believe that lfilter is useful in itself. Donal. ________________________________ From: Pietro Cerutti Sent: Monday, April 27, 2026 09:54 To: Donal Fellows Cc: Tcl Core Subject: Re: [TCLCORE] CFV: TIP 735 "Simpler List Filtering", TIP 745 "Functions from C99" wouldn't it be better if we drafted a TIP for a complete set of list operations? Some of the functions of tcllib's struct::list such as reverse and map are already part of core (lreverse, lmap). How about we draft a set of function that we recognize being generally useful for lists and provide a complete set. I can think of, e.g., fold, take, drop, nth, iota. |
|
From: Kevin W. <kw...@co...> - 2026-04-27 11:54:43
|
💯
—
Kevin Walzer kw...@co...
> On Apr 27, 2026, at 5:34 AM, Steve Landers <st...@di...> wrote:
>
>
> Zipkits are the modern starkits. Why oh why can't we just call them that?
>
> As for core vs package, my personal view is the functionality to create a star/zipkit should be in every Tcl build. Put the compatibility stuff in a separate package if we must but why do we constantly look for ways to make it harder to use Tcl?
>
> -- Steve
>> On 27 Apr 2026 at 4:43 PM +0800, Harald Oehlmann <har...@el...>, wrote:
>> Dear Keith,
>> thanks for your great work!
>> Here is my personal opinion:
>> I am not to much in favour of having starkit functionality in the core.
>> We have zipkits now and look foreward.
>> zipkits and starkits are quite similar.
>> I personally use something like this for my own compatibility in main.tcl:
>>
>> if {[string equal -length 8 "//zipfs:" [info script]]} {
>> namespace eval starkit [list variable topdir [file dirname [info script]]]
>> } else {
>> package require starkit
>> starkit::startup
>> }
>>
>> The other differences (zip wrap does not exclude .csv, no windows icon
>> replacement) are handled outside.
>>
>> WouldnÄt it be ok to have this in a package?
>>
>> Thanks for all,
>> Harald
>>
>>
>>> Am 26.04.2026 um 11:15 schrieb KEITH NASH:
>>> Hi All,
>>>
>>> Version 2.1.0 of package starkit is available, including documentation and
>>> tests.
>>>
>>> https://chiselapp.com/user/kjnash/repository/Starkit/home
>>>
>>> The package goals are to:
>>>
>>> 1. enable zip-based starkits that can be executed by a Tcl 9 installation or
>>> by a "tclkit" (zipkit)
>>> 2. provide the same facilities for zip-based starkits that version 1.3.3 of
>>> starkit package provides for mk4 (Metakit) starkits
>>> 3. make porting from mk4 starkits as easy as possible
>>> * if its code is Tcl-9-compatible, unwrapping the mk4 starkit and
>>> rewrapping it in zip format will suffice
>>> 4. run mk4 starkits without modification if their code is Tcl-9-compatible
>>> * EITHER the Tcl 9 installation or Tclkit must provide dynamic libraries
>>> for vlerq and vfs
>>> * OR starkit will use the included package readkit (which still has bugs)
>>> to unwrap the mk4 archive
>>> 5. preserve the tclkit + starkit format as a distribution mechanism for Tcl
>>> applications
>>>
>>> All that is needed to make Tcl 9 compatible with zip-based starkits is to
>>> provide the starkit library (29kB source, 17kB if comments stripped, plus 20kB
>>> if readkit is needed for mk4 packages).
>>>
>>> The starkit package could be included in the tcl_library.
>>>
>>> I would be willing to write a TIP for this if it is wanted. A few issues to
>>> discuss first:
>>> * Are starkit facilities still wanted? I use them in my own work, but they
>>> seem to have lost popularity over the last 20 years.
>>> * Are the goals/features listed above suitable? For example, the package
>>> could be smaller and simpler if mk4 compatibility is not required.
>>> * The library is derived from starkit package version 1.3.3 by JCW, which did
>>> not have a license statement. Will this matter?
>>> * Version 2 of the starkit package is compatible with Tcl 9.0 upwards, because
>>> it uses Tcl's zipfs facilities. Which version of Tcl should the TIP target?
>>>
>>> Keith.
>>>
>>>
>>>
>>> _______________________________________________
>>> Tcl-Core mailing list
>>> Tcl...@li...
>>> https://lists.sourceforge.net/lists/listinfo/tcl-core
>>
>>
>> --
>> ELMICRON Dr. Harald Oehlmann GmbH
>> Koesener Str. 85
>> 06618 NAUMBURG - Germany
>> Phone: +49 3445 781120
>> Direct: +49 3445 781127
>> www.Elmicron.de
>> German legal references:
>> Geschaeftsfuehrer: Dr. Harald Oehlmann
>> UST Nr. / VAT ID No.: DE206105272
>> HRB 212803 Stendal
>>
>>
>> _______________________________________________
>> Tcl-Core mailing list
>> Tcl...@li...
>> https://lists.sourceforge.net/lists/listinfo/tcl-core
> _______________________________________________
> Tcl-Core mailing list
> Tcl...@li...
> https://lists.sourceforge.net/lists/listinfo/tcl-core
|
|
From: Steve L. <st...@di...> - 2026-04-27 09:33:37
|
Zipkits are the modern starkits. Why oh why can't we just call them that?
As for core vs package, my personal view is the functionality to create a star/zipkit should be in every Tcl build. Put the compatibility stuff in a separate package if we must but why do we constantly look for ways to make it harder to use Tcl?
-- Steve
On 27 Apr 2026 at 4:43 PM +0800, Harald Oehlmann <har...@el...>, wrote:
> Dear Keith,
> thanks for your great work!
> Here is my personal opinion:
> I am not to much in favour of having starkit functionality in the core.
> We have zipkits now and look foreward.
> zipkits and starkits are quite similar.
> I personally use something like this for my own compatibility in main.tcl:
>
> if {[string equal -length 8 "//zipfs:" [info script]]} {
> namespace eval starkit [list variable topdir [file dirname [info script]]]
> } else {
> package require starkit
> starkit::startup
> }
>
> The other differences (zip wrap does not exclude .csv, no windows icon
> replacement) are handled outside.
>
> WouldnÄt it be ok to have this in a package?
>
> Thanks for all,
> Harald
>
>
> Am 26.04.2026 um 11:15 schrieb KEITH NASH:
> > Hi All,
> >
> > Version 2.1.0 of package starkit is available, including documentation and
> > tests.
> >
> > https://chiselapp.com/user/kjnash/repository/Starkit/home
> >
> > The package goals are to:
> >
> > 1. enable zip-based starkits that can be executed by a Tcl 9 installation or
> > by a "tclkit" (zipkit)
> > 2. provide the same facilities for zip-based starkits that version 1.3.3 of
> > starkit package provides for mk4 (Metakit) starkits
> > 3. make porting from mk4 starkits as easy as possible
> > * if its code is Tcl-9-compatible, unwrapping the mk4 starkit and
> > rewrapping it in zip format will suffice
> > 4. run mk4 starkits without modification if their code is Tcl-9-compatible
> > * EITHER the Tcl 9 installation or Tclkit must provide dynamic libraries
> > for vlerq and vfs
> > * OR starkit will use the included package readkit (which still has bugs)
> > to unwrap the mk4 archive
> > 5. preserve the tclkit + starkit format as a distribution mechanism for Tcl
> > applications
> >
> > All that is needed to make Tcl 9 compatible with zip-based starkits is to
> > provide the starkit library (29kB source, 17kB if comments stripped, plus 20kB
> > if readkit is needed for mk4 packages).
> >
> > The starkit package could be included in the tcl_library.
> >
> > I would be willing to write a TIP for this if it is wanted. A few issues to
> > discuss first:
> > * Are starkit facilities still wanted? I use them in my own work, but they
> > seem to have lost popularity over the last 20 years.
> > * Are the goals/features listed above suitable? For example, the package
> > could be smaller and simpler if mk4 compatibility is not required.
> > * The library is derived from starkit package version 1.3.3 by JCW, which did
> > not have a license statement. Will this matter?
> > * Version 2 of the starkit package is compatible with Tcl 9.0 upwards, because
> > it uses Tcl's zipfs facilities. Which version of Tcl should the TIP target?
> >
> > Keith.
> >
> >
> >
> > _______________________________________________
> > Tcl-Core mailing list
> > Tcl...@li...
> > https://lists.sourceforge.net/lists/listinfo/tcl-core
>
>
> --
> ELMICRON Dr. Harald Oehlmann GmbH
> Koesener Str. 85
> 06618 NAUMBURG - Germany
> Phone: +49 3445 781120
> Direct: +49 3445 781127
> www.Elmicron.de
> German legal references:
> Geschaeftsfuehrer: Dr. Harald Oehlmann
> UST Nr. / VAT ID No.: DE206105272
> HRB 212803 Stendal
>
>
> _______________________________________________
> Tcl-Core mailing list
> Tcl...@li...
> https://lists.sourceforge.net/lists/listinfo/tcl-core
|
|
From: Pietro C. <ga...@ga...> - 2026-04-27 08:54:18
|
On Apr 27 2026, 08:41 +0000, Donal Fellows <don...@ma...> wrote: >To be honest, I don't agonise too much about such matters. I look for >places where the idioms we build ourselves are messy, and my >expectations based on what other languages do are higher. Thus, while >it's neat that we can filter lists with [lmap], the _how_ of it isn't >so nice and _many_ other languages have some sort of filter() >operation, so this felt like a neglected corner. > >I remain on the lookout for such ideas. (For example, I've looked at >pipeline syntaxes for connecting commands together, but they're >messy/restricted because so many of our commands are strongly variadic, >and we parse things differently. Can't win them all...) In my opinion, doing it on a case-by-case basis and based on one's personal pain points and willingness to draft a TIP will result in an incoherent / incomplete API. If we think that more utility commands belong to core, wouldn't it be better if we drafted a TIP for a complete set of list operations? Some of the functions of tcllib's struct::list such as reverse and map are already part of core (lreverse, lmap). How about we draft a set of function that we recognize being generally useful for lists and provide a complete set. I can think of, e.g., fold, take, drop, nth, iota. -- Pietro Cerutti I have pledged to give 10% of income to effective charities and invite you to join me - https://givingwhatwecan.org |
|
From: Harald O. <har...@el...> - 2026-04-27 08:42:31
|
Dear Keith,
thanks for your great work!
Here is my personal opinion:
I am not to much in favour of having starkit functionality in the core.
We have zipkits now and look foreward.
zipkits and starkits are quite similar.
I personally use something like this for my own compatibility in main.tcl:
if {[string equal -length 8 "//zipfs:" [info script]]} {
namespace eval starkit [list variable topdir [file dirname [info script]]]
} else {
package require starkit
starkit::startup
}
The other differences (zip wrap does not exclude .csv, no windows icon
replacement) are handled outside.
WouldnÄt it be ok to have this in a package?
Thanks for all,
Harald
Am 26.04.2026 um 11:15 schrieb KEITH NASH:
> Hi All,
>
> Version 2.1.0 of package starkit is available, including documentation and
> tests.
>
> https://chiselapp.com/user/kjnash/repository/Starkit/home
>
> The package goals are to:
>
> 1. enable zip-based starkits that can be executed by a Tcl 9 installation or
> by a "tclkit" (zipkit)
> 2. provide the same facilities for zip-based starkits that version 1.3.3 of
> starkit package provides for mk4 (Metakit) starkits
> 3. make porting from mk4 starkits as easy as possible
> * if its code is Tcl-9-compatible, unwrapping the mk4 starkit and
> rewrapping it in zip format will suffice
> 4. run mk4 starkits without modification if their code is Tcl-9-compatible
> * EITHER the Tcl 9 installation or Tclkit must provide dynamic libraries
> for vlerq and vfs
> * OR starkit will use the included package readkit (which still has bugs)
> to unwrap the mk4 archive
> 5. preserve the tclkit + starkit format as a distribution mechanism for Tcl
> applications
>
> All that is needed to make Tcl 9 compatible with zip-based starkits is to
> provide the starkit library (29kB source, 17kB if comments stripped, plus 20kB
> if readkit is needed for mk4 packages).
>
> The starkit package could be included in the tcl_library.
>
> I would be willing to write a TIP for this if it is wanted. A few issues to
> discuss first:
> * Are starkit facilities still wanted? I use them in my own work, but they
> seem to have lost popularity over the last 20 years.
> * Are the goals/features listed above suitable? For example, the package
> could be smaller and simpler if mk4 compatibility is not required.
> * The library is derived from starkit package version 1.3.3 by JCW, which did
> not have a license statement. Will this matter?
> * Version 2 of the starkit package is compatible with Tcl 9.0 upwards, because
> it uses Tcl's zipfs facilities. Which version of Tcl should the TIP target?
>
> Keith.
>
>
>
> _______________________________________________
> Tcl-Core mailing list
> Tcl...@li...
> https://lists.sourceforge.net/lists/listinfo/tcl-core
--
ELMICRON Dr. Harald Oehlmann GmbH
Koesener Str. 85
06618 NAUMBURG - Germany
Phone: +49 3445 781120
Direct: +49 3445 781127
www.Elmicron.de
German legal references:
Geschaeftsfuehrer: Dr. Harald Oehlmann
UST Nr. / VAT ID No.: DE206105272
HRB 212803 Stendal
|
|
From: Donal F. <don...@ma...> - 2026-04-27 08:42:09
|
To be honest, I don't agonise too much about such matters. I look for places where the idioms we build ourselves are messy, and my expectations based on what other languages do are higher. Thus, while it's neat that we can filter lists with [lmap], the _how_ of it isn't so nice and _many_ other languages have some sort of filter() operation, so this felt like a neglected corner. I remain on the lookout for such ideas. (For example, I've looked at pipeline syntaxes for connecting commands together, but they're messy/restricted because so many of our commands are strongly variadic, and we parse things differently. Can't win them all...) Donal. ________________________________________ From: Pietro Cerutti Sent: Monday, April 27, 2026 07:53 To: Donal Fellows Cc: Tcl Core Subject: Re: [TCLCORE] CFV: TIP 735 "Simpler List Filtering", TIP 745 "Functions from C99" What's the boundary, in your opinion, and what's the direction? |
|
From: Harald O. <har...@el...> - 2026-04-27 08:24:14
|
Hi Donal, TIP 735: yes TIP 745: yes Thanks for the work, Harald Am 26.04.2026 um 13:02 schrieb Donal Fellows: > Hi everyone > > This is a call for votes on two self-contained TIPs that I've been > sitting on for far too long. > > TIP 735: Simpler List Filtering <https://core.tcl-lang.org/tips/doc/ > trunk/tip/735.md> > This adds a global *lfilter *command, because the current idiom for > filtering out items of a list (when *lsearch -inline -all -not* can't do > it) is weird. I've tried using an expression for the filter (that was > the initial version of the TIP /but not the current one/), which works > but feels more annoying to me than using a script (with expressions > available by calling *expr*). I can be talked round to doing this the > other way, but the current way is marginally simpler to implement (on > the interpreted side; the compiled version is pretty much identically > complex). > > TIP 745: Functions from C99 <https://core.tcl-lang.org/tips/doc/trunk/ > tip/745.md> > This imports virtually all the remaining math functions from C99 > <https://en.cppreference.com/w/c/numeric/math.html> into Tcl, pretty > much as-is (bearing in mind that some "return" multiple values, which > maps differently in Tcl; see below) with most just going into the > *::tcl::mathfunc* namespace and so having limited global impact. > Implementation bugs in the functions' C implementations are exactly bugs > in the corresponding Tcl functions; I do not propose we reimplement them > (except for *signbit*, which is extended to directly cover all Tcl > numeric values). > /NB:/ Introduces four new global commands for the multiple-value- > returners: *divmod*, *frexp*, *modf*, *remquo*. They don't sit nicely as > standard functions. > > Implementation branches exist for both TIPs (tip-735 <https://core.tcl- > lang.org/tcl/timeline?r=tip-735>, c11-functions <https://core.tcl- > lang.org/tcl/timeline?r=c11-functions>). > > Votes in the standard form to this mailing list. Vote closes at 12:00 my > time, 4 May 2026, *[clock format 1777892400]*. My votes follow: > > TIP 735: YES > TIP 745: YES > > Donal. |
|
From: Harald O. <har...@el...> - 2026-04-27 08:10:36
|
Hi Brad, thanks for the message. Generally, anything is possible. It would nevertheless be great, to author a TIP. Even, if only the documentation is changed. If it is not a breaking change, we can do it for Tk 9.1/9.2... I tried to author TIP 714 and implementation was ready. Unfortunately, it was told, that the image framework has multi-interpreter and multi-thread issues. As I don't understand those issues, I have stopped. But if you want to put a CLientData into the structure -> this is a threading issue, right? So, the multi-interpreter and threading issues of the image command may be attacked? Thanks for all and take care, Harald Am 24.04.2026 um 21:28 schrieb B Harder: > Hello Tclers. > > I've been working in Tk, specifically w image, and would like run a proposal passed Core. > > In struct Tk_ImageType, generic/tk.h L1257 there is a "char *reserved", which was last updated by Brent Welch nearly 30 (c. 1998) years ago, is semantically marked as a placeholder for some future expansion, and as far as i can tell, not actually referenced anywhere. > > Proposal: can we take this and formally give it to developers as a ClientData clientData entry in the struct? As far as i can tell, it would functionally be a documentation update, not breaking any public APIs or ABIs. > > Best, > -bch |
|
From: Pietro C. <ga...@ga...> - 2026-04-27 06:53:41
|
On Apr 26 2026, 11:02 +0000, Donal Fellows <don...@ma...> wrote:
[-- Type: text/html; charset=iso-8859-1, Encoding: quoted-printable, Size: 6.5K --]
>Hi everyone
>
>This is a call for votes on two self-contained TIPs that I've been sitting on
>for far too long.
>
>[1]TIP 735: Simpler List Filtering
>This adds a global lfilter command, because the current idiom for filtering out
>items of a list (when lsearch -inline -all -not can't do it) is weird. I've
>tried using an expression for the filter (that was the initial version of the
>TIP but not the current one), which works but feels more annoying to me than
>using a script (with expressions available by calling expr). I can be talked
>round to doing this the other way, but the current way is marginally simpler to
>implement (on the interpreted side; the compiled version is pretty much
>identically complex).
The lmap documentation has this example
set values {1 2 3 4 5 6 7 8}
proc isEven {n} {expr {($n % 2) == 0}}
set goodOnes [lmap x $values {expr { [isEven $x] ? $x : [continue] }}]
With your TIP, the last line would be
set goodOnes [lfilter x $values {isEven $x}]
It is indeed slightly clearer, but I am left wondering if we really need
to add core function for all small things, especially those which are in
tcllib already:
https://core.tcl-lang.org/tcllib/doc/trunk/embedded/md/tcllib/files/modules/struct/struct_list.md#13
I already had this impression when you proposed TIP670
https://core.tcl-lang.org/tips/doc/trunk/tip/670.md, but I didn't speak
up at the time.
What's the boundary, in your opinion, and what's the direction? Core
getting more and more batteries, or tcllib being intended as an almost
mandatory companion to do anything useful?
Thanks,
Pietro
--
Pietro Cerutti
I have pledged to give 10% of income to effective charities
and invite you to join me - https://givingwhatwecan.org
|
|
From: Alan <ala...@gm...> - 2026-04-26 23:29:52
|
Hi, New release v1.0.1 available: https://github.com/AlaoPrado/voo/releases/tag/v1.0.1! There is now a migration guide in https://github.com/AlaoPrado/voo/blob/main/MIGRATION.md. Furthermore, the README.md file was updated to provide new guidelines along the sections, and general coding guidelines for VOO in https://github.com/AlaoPrado/voo/blob/main/MIGRATION.md <https://github.com/AlaoPrado/voo/blob/main/MIGRATION.md>. Kind Regards, Alan On Thu, Apr 16, 2026 at 9:00 PM Alan <ala...@gm...> wrote: > Hi Rene, > > Ok. Thanks for the feedback. I'm going to review the documentation for the > suggested points of improvement. It might be worth to have a side-by-side > equivalent table between different patterns of existing frameworks (e.g.: > TclOO, Tk). > > Few comments below: > - The "next" command alone without any parameter might require some > additional instrospection for recovering the method name and parameter. > This can be possible, but I need to review the performance bottleneck. It > might be more eficient to call `[class.parent]::<method_name> <args>` > instead. > - Instead o cget a config, voo has get.<field>, set.<field>, and > update.<name> for managing field. > - The default value for each field is defined when declaring de field with > <type>_t commands. > > Kind Regards, > Alan > > Em qui., 16 de abr. de 2026 08:46, Zaumseil René <RZa...@kk...> > escreveu: > >> Hi Alan >> >> >> >> I have to figure out the github fork thing. >> >> I'm currently also in adding/changing parts of ruff! and adopting my >> documentation style. >> >> So I'm not experimenting with your VOO in the next time. >> >> >> >> A special "next" method would be fine. Alternatively you could mention >> the calling of <parent_class_ns>::<method_name> in the docs. >> >> >> >> For object configuration a cget/configure out of the box would be fine. >> >> May be with support of "option default" and tk-like "option dbclass >> dbname default". >> >> You could use the option name as method name like in my tko. >> >> >> >> And a compare list of features of tcloo and voo with examples would also >> be nice. >> >> >> >> HTH >> >> rene >> >> >> >> *Von:* Alan <ala...@gm...> >> *Gesendet:* Donnerstag, 16. April 2026 13:30 >> *An:* Zaumseil René <RZa...@kk...> >> *Cc:* Arjen Markus via Tcl-Core <tcl...@li...> >> *Betreff:* Re: [Ext] [TCLCORE] Vanilla Object Orientation (VOO): A >> Value-Semantics Approach to Classes in Tcl >> >> >> >> Hi Zaumseil, >> >> >> >> Thanks! >> >> >> >> In case parent class an method is virtual, you can call >> <parent_class_ns>::base.<method_name> to call orginal method. You can call >> any <parent_class_ns>::<method_name> anyway. There could be a >> [class.parent] to get <parent_class_ns> easily. I'm thinking about the >> perfomance cost of implementing a [class.next] (or a potentially >> non-ambiguous alternative name) for automatially returning >> <parent_class_ns>::<method_name> or the base.<method_name> variant in case >> of virtual... >> >> >> >> What do you think? Would you like to start some experiments on your side? >> Feel free to fork and open a PR on main repository. >> >> >> >> Kind Regards, >> >> Alan. >> >> >> >> Em qui., 16 de abr. de 2026 06:41, Zaumseil René <RZa...@kk...> >> escreveu: >> >> Hi Alan >> >> >> >> This looks impresing. >> >> >> >> I remember another tcl proc oo system at: >> thedev.nhi1.de/theLib/main/index.htm >> >> May be you could some ideas from this one. >> >> >> >> I currently miss the "next" method from tcloo. Is there a workaround for >> this one? >> >> >> >> Regards >> >> Rene >> >> >> >> *Von:* Alan <ala...@gm...> >> *Gesendet:* Mittwoch, 15. April 2026 21:47 >> *An:* Arjen Markus via Tcl-Core <tcl...@li...> >> *Betreff:* [Ext] [TCLCORE] Vanilla Object Orientation (VOO): A >> Value-Semantics Approach to Classes in Tcl >> >> >> >> Hi folks, >> >> >> >> I'm glad to announce VOO, a lightweight, native, and efficient, OO >> framework for Tcl. It follows a Value-Semantics approach instead of the >> traditional reference-by-procedure of other frameworks (TclOO, Itcl, etc). >> This brings interesting advantages w.r.t. both scalability and >> maintainability of Tcl projects. >> >> >> >> I'd like to hear from you all what you think about the implementation and >> results, and if it makes sense to have its package available in the default >> packages shipped with Tcl, or in tcllib. Its source code is fully written >> in Tcl, so it is easy to integrate it into any demo project for local >> experiments. >> >> >> >> Below you can find the abstract, the link for the white paper and the >> link for the code repository. >> >> >> >> *Abstract* >> >> *I present Vanilla Object Orientation (VOO), a framework that composes >> classes from Tcl's native data structures -- lists and dictionaries -- >> rather than introducing additional framework infrastructure. VOO objects >> are plain Tcl lists with automatic memory management through copy-on-write >> semantics, eliminating the destructor burden inherent in TclOO and Itcl. >> Benchmarks on Tcl 8.6.13 and Tcl 9.0 show VOO achieves 7--18x faster object >> creation and 4--6x superior memory efficiency compared to TclOO. A >> companion C++ migration path (VOO C++) further improves field-access speed >> (setter 2.3--2.6x faster) and memory (6.8--9.8x lighter than TclOO), while >> preserving an identical Tcl call-site API. Cross-version analysis confirms >> that VOO's compositional design scales better than framework-based >> approaches as the interpreter evolves.* >> >> >> >> *Lisks* >> >> White Paper: https://arxiv.org/abs/2604.10399 >> >> Code Repository: https://github.com/AlaoPrado/voo >> >> >> >> Thanks, and Kind Regards, >> >> Alan >> >> |
|
From: Donal F. <don...@ma...> - 2026-04-26 11:03:07
|
Hi everyone This is a call for votes on two self-contained TIPs that I've been sitting on for far too long. TIP 735: Simpler List Filtering<https://core.tcl-lang.org/tips/doc/trunk/tip/735.md> This adds a global lfilter command, because the current idiom for filtering out items of a list (when lsearch -inline -all -not can't do it) is weird. I've tried using an expression for the filter (that was the initial version of the TIP but not the current one), which works but feels more annoying to me than using a script (with expressions available by calling expr). I can be talked round to doing this the other way, but the current way is marginally simpler to implement (on the interpreted side; the compiled version is pretty much identically complex). TIP 745: Functions from C99<https://core.tcl-lang.org/tips/doc/trunk/tip/745.md> This imports virtually all the remaining math functions from C99<https://en.cppreference.com/w/c/numeric/math.html> into Tcl, pretty much as-is (bearing in mind that some "return" multiple values, which maps differently in Tcl; see below) with most just going into the ::tcl::mathfunc namespace and so having limited global impact. Implementation bugs in the functions' C implementations are exactly bugs in the corresponding Tcl functions; I do not propose we reimplement them (except for signbit, which is extended to directly cover all Tcl numeric values). NB: Introduces four new global commands for the multiple-value-returners: divmod, frexp, modf, remquo. They don't sit nicely as standard functions. Implementation branches exist for both TIPs (tip-735<https://core.tcl-lang.org/tcl/timeline?r=tip-735>, c11-functions<https://core.tcl-lang.org/tcl/timeline?r=c11-functions>). Votes in the standard form to this mailing list. Vote closes at 12:00 my time, 4 May 2026, [clock format 1777892400]. My votes follow: TIP 735: YES TIP 745: YES Donal. |
|
From: KEITH N. <k.j...@us...> - 2026-04-26 09:16:02
|
Hi All, Version 2.1.0 of package starkit is available, including documentation and tests. https://chiselapp.com/user/kjnash/repository/Starkit/home The package goals are to: 1. enable zip-based starkits that can be executed by a Tcl 9 installation or by a "tclkit" (zipkit) 2. provide the same facilities for zip-based starkits that version 1.3.3 of starkit package provides for mk4 (Metakit) starkits 3. make porting from mk4 starkits as easy as possible * if its code is Tcl-9-compatible, unwrapping the mk4 starkit and rewrapping it in zip format will suffice 4. run mk4 starkits without modification if their code is Tcl-9-compatible * EITHER the Tcl 9 installation or Tclkit must provide dynamic libraries for vlerq and vfs * OR starkit will use the included package readkit (which still has bugs) to unwrap the mk4 archive 5. preserve the tclkit + starkit format as a distribution mechanism for Tcl applications All that is needed to make Tcl 9 compatible with zip-based starkits is to provide the starkit library (29kB source, 17kB if comments stripped, plus 20kB if readkit is needed for mk4 packages). The starkit package could be included in the tcl_library. I would be willing to write a TIP for this if it is wanted. A few issues to discuss first: * Are starkit facilities still wanted? I use them in my own work, but they seem to have lost popularity over the last 20 years. * Are the goals/features listed above suitable? For example, the package could be smaller and simpler if mk4 compatibility is not required. * The library is derived from starkit package version 1.3.3 by JCW, which did not have a license statement. Will this matter? * Version 2 of the starkit package is compatible with Tcl 9.0 upwards, because it uses Tcl's zipfs facilities. Which version of Tcl should the TIP target? Keith. |
|
From: Phillip B. <phi...@um...> - 2026-04-26 05:40:31
|
I have checked into the main branch the Windows makefile changes needed for ARM64 cross compilation and removal of the x86_64-w64-mingw32-nmakehlp.exe binary from the fossil source tree. Let me know if you see any issues. ARM64 cross compilation also now works on x86 machines for the following projects on the main trunk: tcl, tk, itcl, tdbc, tdbcsqlite3, tdbcodbc, tdbcpostgres, tdbcmysql, thread As before, cross compilation requires that a native x86 tclsh shell be identified with the TCLSH_NATIVE environment variable. That value is now also used to identify the location of an nmakehlp.exe executable in the same install tree as TCLSH_NATIVE assuming that if .../bin/tclsh? is the location of the Tcl shell, the .../lib/nmake/nmakehlp.exe is the location of the nmakehlp executable to be used for cross compilation. If that is not the case, then the NMAKEHLP_NATIVE environment variable can be set explicitly for the cross compilation build. The sqlite3 project still needs to be updated, I hope we can get to that in the next few days. I have a question for the release managers - will all of the above projects be released from main for the June Tcl/Tk 9.1 beta build? I want to make sure that I don't have to worry about x86_64-w64-mingw32-nmakehlp.exe binaries in the signed Windows release build project that I am working on for the 9.1 Windows binary release. The checkins for each project have this comment: Remove x86_64-w64-mingw32-nmakehlp.exe. In its place, use the NMAKEHLP_NATIVE variable to find an nmakehlp.exe during cross compilation. If you are aware of any other projects that contain the file x86_64-w64-mingw32-nmakehlp.exe let me know, especially if they would be useful in the Tcl/Tk 9.1 signed release for Windows. Phil |
|
From: Kevin W. <kw...@co...> - 2026-04-26 02:29:11
|
<html class="apple-mail-supports-explicit-dark-mode"><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto">One additional note. There are two remaining bugs with bidi text on Tk X11 that we probably need to document as known issues that cannot be corrected at this time:. <div><br></div><div> 1. Harfbuzz badly renders CJK fonts with spacing that is too tight. Christian Werner has reported this, and I can reproduce it. This appears to be an upstream bug in Harfbuzz that will not be addressed: <a href="https://github.com/harfbuzz/harfbuzz/issues/4651?utm_source=copilot.com">https://github.com/harfbuzz/harfbuzz/issues/4651</a></div><div><br></div><div> 2. RTL text gets subtly darker when I click the cursor through it then gets lighter when the cursor leaves. This is probably an upstream Xft drawing bug involving partial vs. full redraws in the XRender pipeline. I am not aware of a solution. </div><div><br></div><div>-Kevin<br id="lineBreakAtBeginningOfSignature"><div dir="ltr"><div>—</div>Kevin Walzer kw...@co...</div><div dir="ltr"><br><blockquote type="cite">On Apr 25, 2026, at 7:33 PM, Kevin Walzer <kw...@co...> wrote:<br><br></blockquote></div><blockquote type="cite"><div dir="ltr"><span>Quick update:</span><br><span></span><br><span>1. I have modified "configure" to run "--enable-bidi" by default on X11. Bidi support is already the default on macOS and Windows.</span><br><span></span><br><span>2. I've spent a couple of days working on updating the test suite. I've modified six or seven tests to recognize different results because of the internal changes to bidi, set a win32 constraint on one test, and made a few tweaks to C code.</span><br><span></span><br><span>I think this is as good as I can make it, and I'd like to request some testing. I will be AFK next week for work, so this will give everyone some time to review the changes.</span><br><span></span><br><span>-Kevin</span><br><span></span><br><span>On 4/24/26 9:23 AM, Kevin Walzer wrote:</span><br><blockquote type="cite"><span>The test failures may come later IMHO. Of cause, it is important.</span><br></blockquote><blockquote type="cite"><span>But I would prefer first a comment by other experts, if they agree with the proposed change. </span><br></blockquote><span></span><br><span>-- </span><br><span>Kevin Walzer kw...@co...</span><br><span></span><br><span></span><br><span></span><br><span>_______________________________________________</span><br><span>Tcl-Core mailing list</span><br><span>Tcl...@li...</span><br><span>https://lists.sourceforge.net/lists/listinfo/tcl-core</span><br></div></blockquote></div></body></html> |
|
From: Kevin W. <kw...@co...> - 2026-04-25 23:32:51
|
Quick update: 1. I have modified "configure" to run "--enable-bidi" by default on X11. Bidi support is already the default on macOS and Windows. 2. I've spent a couple of days working on updating the test suite. I've modified six or seven tests to recognize different results because of the internal changes to bidi, set a win32 constraint on one test, and made a few tweaks to C code. I think this is as good as I can make it, and I'd like to request some testing. I will be AFK next week for work, so this will give everyone some time to review the changes. -Kevin On 4/24/26 9:23 AM, Kevin Walzer wrote: > The test failures may come later IMHO. Of cause, it is important. > But I would prefer first a comment by other experts, if they agree > with the proposed change. -- Kevin Walzer kw...@co... |
|
From: Marc C. <cul...@gm...> - 2026-04-24 22:16:53
|
I have just pushed a change to the implementation of TIP 750, and I will shortly update the text of the TIP. Those who have already voted need to be aware of this. The change is that the implementation now fully supports the "auto" value for the appearance attribute of a toplevel on Windows. Specifically: 1) The default value of the appearance attribute is now "auto". 2) When a new toplevel is created (with appearance "auto") it will be displayed with the light or dark theme as specified by the AppsUseLightTheme Registry variable, which can be set from the system Settings app. 3) When the value of that setting is changed, all "auto" toplevels will be re-rendered with the new choice of theme. For example, if the user has a tool like "Light Switch" that automatically changes to dark mode at a certain time, all "auto" toplevels will switch to having black title bars when the change occurs. 4} A toplevel with appearance "light" or "dark" has opted to override the system setting, and it will not change color when the Settings variable toggles between light and dark. 5) When an "auto" toplevel changes theme as a result of a change to the value of AppsUseLightTheme, e.g. by choosing "dark" in the Settings, it will receive a virtual event <<AppearanceChanged>> with data string "appearance light" or "appearance dark" as appropriate for the new theme. This should allow a Tk app to support dark mode in its window content by changing the color palette within the binding script for that virtual event. I anticipate that someday more fields will be added to the data string, for example specifying accent colors. But this TIP only relates to the light and dark themes. Emiliano has kindly tested the latest version on Windows 10 and reports that it works. I have tested on Windows 11 with the same report. - Marc |
|
From: <av...@lo...> - 2026-04-24 21:53:06
|
Now at least 11 ;-) See you in ... uhm ... Bologna ... > We are looking forward to meeting you in Bologna. > > Many thanks, > The Organization Committee ... seems like a relict from last year (in the welcome Mail after reg). Not yet sure about doing a short talk, maybe, if slots are still vacant lateron... -- avl Am 2026-04-24 11:42, schrieb Harald Oehlmann: > Dear Tcl/Tk team members, > > The OpenACS/TCL/Tk user meeting in Vienna 16/17th of July 2026 will > take place. We just had the wrap-up call. 10 people registered, mainly > from Tcl/Tk side. So, the critical mass is reached. > > https://openacs.km.at > > It is a community meeting. Each participant is motivated to show its > work in a small presentation. And we will have the panels about > Tcl/Tk/Naviserver/OpenACS. > The location is the same great cosy room at the University of Economics > as in 2024. > Newcomers are also invited. Helpful people and information will be > there! > > So, feel welcomed to the great meeting. > > See you in July in Vienna! > > Gustaf, Stefan and Harald > > _______________________________________________ > Tcl-Core mailing list > Tcl...@li... > https://lists.sourceforge.net/lists/listinfo/tcl-core |
|
From: B H. <bra...@gm...> - 2026-04-24 19:28:53
|
Hello Tclers. I've been working in Tk, specifically w image, and would like run a proposal passed Core. In struct Tk_ImageType, generic/tk.h L1257 there is a "char *reserved", which was last updated by Brent Welch nearly 30 (c. 1998) years ago, is semantically marked as a placeholder for some future expansion, and as far as i can tell, not actually referenced anywhere. Proposal: can we take this and formally give it to developers as a ClientData clientData entry in the struct? As far as i can tell, it would functionally be a documentation update, not breaking any public APIs or ABIs. Best, -bch |
|
From: EricT <tw...@gm...> - 2026-04-24 13:50:41
|
Yes, you are right about the drawback to using tcl::unsupported::assemble.
That is certainly the Achilles heel of my little Calc project. But I'm only
in it for the subs and likes, anyway. However, I do notice I have 0
followers and 0 likes on my github page😭
It will likely be quite difficult to get that assembler made public. On the
other hand, it sure seems like a waste of 4400 lines of great code, not to
mention another 1600 lines or so in the disassembly.
I'm not sure if vecTCL would benefit or not, but that was also mentioned in
the telco.
Now that the frenzy is dying down, how about you. Did you really debug your
code just using printf? You should have plenty of time now getting VS 2026
installed and then you would see how super their debugger for C is. I used
it to find the code that was doing pointer arithmetic across tokens that
caused my $(...) code to crash. I can't imagine finding that with just
printf.
Anyway, good luck with your project.
Eric
On Fri, Apr 24, 2026 at 3:39 AM Florent Merlet <flo...@gm...>
wrote:
> Hi Eric,
> I ve noticed at bytecodes analysis that inst_invoke_stk has a cost while
> building list.
>
> The correction is to create a "LIST" lexeme, to set it instead of FUNC,
> then emit the list bytecodes inst while compiling the tree.
> Then I can remove this list FUNC from table of math FUNC. I was planning
> to do it.
>
> But, this is a question of optimisation, that can be seen later, if ever
> the proposal become a TIP.
>
> Build : I saw a TIP about encoding and wish.exe.manifest.in, from Ashok.
> Surely he can say something about this.
> I must clean tclVar.c. There is no change in this file, since i dismissed
> array index expr shorthand.
>
> You are saying you follow this direction, because you want it to be
> independant from the core. But, finally, you have to ask for a core change,
> because it would be too slow without bytecodes compilation.
>
> So in fact, you can't be independant from the core, also.
>
> Yes, the possibility to generate bytecodes could serve many purposes (and
> my proposal is still on the table) but the core team people said, they want
> to be free to refactor it if they need to.
>
> If you rely on it, you may loose compatibility at any time. That would be
> a problem also.
>
> So, your proposal, done to be "independant from the core" is shown to be
> "dependant on the core", in a contradiction with your initial intention.
>
> Maybe the only solution for you is to produce native code ? Would it be
> possible with critcl ?
>
> Regards,
> Florent.
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> Le ven. 24 avr. 2026, 11:16, EricT <tw...@gm...> a écrit :
>
>> Hi Florent,
>>
>> On your three points:
>>
>> 1. The timerate example -- timerate is a development and benchmarking tool, not production code. And actually the [: ...] inline form does not need to start on its own line at all, so the side by side comparison is straightforward:
>>
>> proc= test {x y} {
>> puts orig:[timerate {list [expr {$x-10}] [expr {$x+20}] [expr {$y-20}] [expr {$y+20}]}]
>> puts colon:[timerate {[: list(x-10,x+20,y-20,y+20)]}]
>> }
>>
>> The : standalone statement form does need to be on its own line, which is a deliberate tradeoff -- no full Tcl parser, no surgery on the existing one, no TIP, no requiring consensus from programmers all over the world. Completely optional -- if one person uses it, everyone else is entirely unaffected.
>>
>> 2. Of course proc= adds a new command -- it is a module, not a core change. Every package ever written adds new commands. The real question is whether those commands require a TIP and core team consensus, and mine do not.
>>
>> But I notice your approach also adds a new command -- list as a mathfunc in BuiltinFuncDef. Unlike proc= which is optional and only affects those who load the module, your list addition is a permanent core modification that affects every Tcl program. And it is slower -- your list(1,2,3) generates:
>>
>> push "tcl::mathfunc::list"
>> invokeStk n
>>
>> whereas my list() generates the direct list bytecode instruction -- no push of a fully qualified name, no command dispatch at all. The core modification buys you worse performance.
>>
>> 3. Your inline flexibility with for, foreach, if, switch, eval is a genuine advantage of your approach. But the transformation cost of proc= is negligible and happens only once at program startup when the procs are defined -- much like sourcing any Tcl file, or namespace eval which evaluates a script in a particular context. Nobody argues that namespace eval is a bad pattern because it requires wrapping code in a block.
>>
>> Also, my module works in 8.6 and 9.x now. I don't have to build tcl from a modified source.
>>
>> BTW, I can't run your static wish/tclsh exe's because I don't have the compiler you use.
>>
>> I was unable to get your tk to build something about a wish.exe.manifest.in. Also, you had an unused variable "len" in TclLookupArrayElement which tripped the warnings are errors on my build. After fixing that I could run your code in tclsh.
>>
>>
>> Best regards,
>> Eric
>>
>>
>>
>> On Fri, Apr 24, 2026 at 12:27 AM Florent Merlet <
>> flo...@gm...> wrote:
>>
>>> Ok.
>>>
>>> Notice that my proposal doesn't need any new command named 'proc='.
>>>
>>> I can just do :
>>> proc test {x y} {
>>> puts orig:[timerate {list [ .... ]}]
>>> puts shorthand:[timerate {( ... )}]
>>> }
>>> to compare two bytecodes.
>>>
>>> can you do this with your proposal ?
>>>
>>> proc test {x y} {
>>> puts orig:[timerate {list [ .... ]}]
>>> puts colon:[timerate {: ... }]
>>> }
>>>
>>>
>>> If i want to compile a whole proc as expression, i can do :
>>>
>>> proc p args {( ... )}
>>>
>>> How will you get this effect with your proposal ?
>>>
>>> proc p args {: { ... }}
>>> proc= p args { ... }
>>>
>>> The last one is 1 char shorther, but need a new command.
>>>
>>> With my proposal, you can do :
>>> eval {( .... )}
>>> for {( .... )} {....} {( .... )} {( .... )}
>>> If { } then {( .... )} else {( .... )}
>>> Switch $a { case {( .... )} default {( .... )} }
>>> Foreach i $L {( .... )}
>>> Lmap j $K {( .... )}
>>> ... Etc
>>> And get it bytecompiled with the expression parser where there is
>>> parenthesis.
>>>
>>> Can your proposal do this ?
>>>
>>> Regards,
>>> Florent
>>>
>>>
>>>
>>> Le ven. 24 avr. 2026, 07:42, EricT <tw...@gm...> a écrit :
>>>
>>>> Hi Florent,
>>>>
>>>> The ugliness of my test case was simply my uncertainty about how timerate works. After Serg's clarification I realized that transform= can handle : inside a timerate block as long as the : command starts on its own line. My transform= is not a full Tcl parser -- it uses 5 or 6 regexps and doesn't count brace nesting levels -- so I accept that compromise. Here is the cleaner test Serg suggested:
>>>>
>>>> % proc= test {x y} {
>>>> timerate {
>>>> : list(x-10,x+20,y-20,y+20)
>>>> }
>>>> }
>>>> % test 5 20
>>>> 0.260845 µs/# 3833681 #/sec 999.997 net-ms
>>>>
>>>> % proc test2 {x y} {
>>>> timerate {
>>>> list [expr {$x-10}] [expr {$x+20}] [expr {$y-20}] [expr {$y+20}]
>>>> }
>>>> }
>>>> % test2 5 10
>>>> 0.253317 µs/# 3947624 #/sec 1000.000 net-ms
>>>>
>>>> Essentially identical -- and the disassembly confirms why: both produce exactly the same bytecode.
>>>>
>>>> As for why I used an infix expression compiler rather than extending expr -- two reasons. First, Colin had already written a beautiful pure Tcl Pratt parser that I could build on immediately. Second, at the time I had no understanding of how bytecode and the assembler worked, so using Colin's compiler as a front end to generate TAL was the obvious path. It turned out to be a fortunate choice since it required no core changes at all.
>>>>
>>>> Regarding your bytecode interface proposal -- I think you may be underestimating the scope of what tclAssembly.c actually does. The parser touch points you list are just the entry points. The 4400 lines handle label resolution, stack depth verification, LVT management, exception range tracking, operand encoding, and error reporting for 130+ opcodes. That infrastructure already exists and works -- which is exactly why I am arguing for a public interface to it rather than new parser syntax on top of it.
>>>>
>>>> Best regards,
>>>> Eric
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> On Thu, Apr 23, 2026 at 9:53 PM Florent Merlet <
>>>> flo...@gm...> wrote:
>>>>
>>>>> Hi Eric,
>>>>>
>>>>> my computer is more than 15 years old...
>>>>> You may try with the tcl there :
>>>>>
>>>>> https://github.com/florentis/tcl90-exprSH/tree/core-9-0-branch/install_SH
>>>>> to check with your own machine.
>>>>>
>>>>> Le 24/04/2026 à 00:11, EricT a écrit :
>>>>>
>>>>> timerate " [Calc::transform= {} {: list(x-10,x+20,y-20,y+20) } 0 0] "
>>>>> ;# 0 0 = non-proc3.
>>>>>
>>>>> Beauty is in the eye of the beholder... This last point should be
>>>>> obvious.
>>>>>
>>>>> For me :
>>>>> % timerate {($x-10, $x+20, $y-20, $y+20)}
>>>>>
>>>>> is obviously more beautifull than :
>>>>>
>>>>> % timerate " [Calc::transform= {} {: list(x-10,x+20,y-20,y+20) } 0 0]
>>>>> "
>>>>>
>>>>> There will never be a consensus on what syntax is best.
>>>>>
>>>>> A syntax is just an apparence, a shape. It's an interface to something
>>>>> deeper (for instance : bytecode).
>>>>> The goal of an interface is to make easy to work with a toolset.
>>>>>
>>>>> Command interface is well suited to work with list of strings. (Tk
>>>>> beauty and concision)
>>>>> But it is not well suited to work with numbers (operators as command
>>>>> are rarely used).
>>>>>
>>>>> For numbers, Tcl propose an expr interface. Why not use it ?
>>>>>
>>>>> I didn't choose the syntax in expr interface. I'm not fond of dollars
>>>>> signs for variable, but I accept it as it is.
>>>>>
>>>>> It is from all Tcl, as well as '[ ]' substitution.
>>>>>
>>>>> So, I don't want espacially to propose a new syntax (even if I must
>>>>> have one to achieve the proposal),
>>>>> I choosed [(y=$x;)], but it could have been also : ≺y=$x;≻ or ⎨ y
>>>>> =$x; ⎬ or ⟦ y = $x⟧ or ⟪ y = $x; ⟫
>>>>>
>>>>> I want to suggest a principle.
>>>>>
>>>>> In Tcl, there is 2 parsing interfaces :
>>>>> * a command parsing interface, more convenient for strings and lists
>>>>> (using *a prefix notation*)
>>>>> * an expression parsing interface, more convenient for numbers and
>>>>> assignement (using *an infix notation*)
>>>>>
>>>>> These 2 interfaces should be of equal right, so we can choose the more
>>>>> convenient for a task to be done.
>>>>>
>>>>> To do so, I needed to achieve two things here :
>>>>> * expression substitution, to get a value from the infix parsing
>>>>> interface
>>>>> * expression script signalisation, to signal when a script must be
>>>>> compiled with the infix parsing interface
>>>>>
>>>>> Then, I can get the better of this two worlds. This, in less than 260
>>>>> lines of code !
>>>>>
>>>>> There is already 4400 lines of C code in generic/tclAssembly.c that as
>>>>> far as I can tell is used only to assist in the debugging of new bytecode.
>>>>>
>>>>> If I'm wrong, please tell me since that would provide another reason
>>>>> to provide a public interface to tcl::unsupported::assemble. I have used
>>>>> the Tcl assemble command to produce performance par with expr without
>>>>> modification to the core. Other's could make use of a public interface as
>>>>> well. Then many design specific languages (DSL) could be built upon Tcl
>>>>> with high performance.
>>>>>
>>>>> Yes, Assemble bytecode is proposing its own interface, in "*postfix
>>>>> notation*".
>>>>>
>>>>> On this matter, we can adopt exactly the same principles I adopted
>>>>> above to resolve it.
>>>>> We need :
>>>>> * Bytecode substitution : e.g. => [! ... !]
>>>>> * Bytecode script signalisation : e.g. => {! ... !}
>>>>>
>>>>> set a [! load x, push 10, sub; load x, push 20, add; load y, push 20,
>>>>> sub; load y, push 20, add; list 4 !]
>>>>>
>>>>> proc A {} {!
>>>>> load x, push 10, sub load x, push 20, add load y, push 20, sub load
>>>>> y, push 20, add list 4
>>>>> !}
>>>>>
>>>>> To achieve this, it should be very similar with as what I did for the
>>>>> expr shorthand, in exactly the same codes location (except the ones
>>>>> specific to expr, of course)
>>>>> * Just need a TCL_TOKEN_BYTECODE in the parser
>>>>> * recognize the syntax :
>>>>> ** in ParseCommand
>>>>> ** in ParseToken
>>>>> * route correctly the compilation int TclCompileScript.
>>>>> * route correctly the compilation int TclSetBytecodefromAny.
>>>>> * Do what it has be done with this TOKEN
>>>>> ** in TclSubstToken
>>>>> ** in TclCompileToken
>>>>> That's all !
>>>>>
>>>>> This proposal is very interesting : We could even get the better of
>>>>> three worlds !
>>>>>
>>>>> That said, this "*postfix notation*" interface is not the more
>>>>> convenient for the Job. As you know, *Infix notation* is better here :
>>>>>
>>>>> set a [($x+20, $x-20, $y+20, $y-20 )]
>>>>> proc A {} {($x+20, $x-20, $y+20, $y-20)}
>>>>>
>>>>> At the end, you will have to create your own code to translate from
>>>>> your new and expr-like interface to this new bytecode interface.
>>>>> That is what you did.
>>>>>
>>>>> Then, this question arise : why not just have used the expr interface
>>>>> from the begining ?
>>>>>
>>>>>
>>>>> Regards,
>>>>> Florent
>>>>> _______________________________________________
>>>>> Tcl-Core mailing list
>>>>> Tcl...@li...
>>>>> https://lists.sourceforge.net/lists/listinfo/tcl-core
>>>>>
>>>> _______________________________________________
>>> Tcl-Core mailing list
>>> Tcl...@li...
>>> https://lists.sourceforge.net/lists/listinfo/tcl-core
>>>
>> _______________________________________________
> Tcl-Core mailing list
> Tcl...@li...
> https://lists.sourceforge.net/lists/listinfo/tcl-core
>
|
|
From: Kevin W. <kw...@co...> - 2026-04-24 13:23:47
|
Hi Harald, On 4/24/26 7:41 AM, Harald Oehlmann wrote: > thanks for all the work, this is highly appreciated. > I suppose, that the branch rtl_text is ready for testing: > > https://core.tcl-lang.org/tk/timeline?r=rtl_text&c=2026-04-23+12%3A05%3A22 > Almost. I am reviewing the test failures to determine what the issues might be. I don't want to cause regressions with bidi text in addressing the test failures - looking into the test suite is part of making sure the bidi changes are as stable as I can make them. One known bug that I can't fix - CJK text spacing is still too tight in the text widget when mixed with other encodings (Latin/RTL). > > It is only about the text widget, right? Correct. > > It would be great to give other experts a week of time to digest. > Christian and Csaba understand the internals, Jan and Emiliano are > also in. Maybe, they may comment. Agree - when I am satisfied it is as stable as I can make it, I want as much input as possible. > > The test failures may come later IMHO. Of cause, it is important. > But I would prefer first a comment by other experts, if they agree > with the proposed change. See above. > > I would really love to have this feature in 9.1. We don't need a TIP. > But it is for sure a breaking feature which solves a long standing > miss-functioning. As I have recently observed with font and rotation, > bug fixes may create new bugs found years after... > > If it may be the default on Linux: "yes of cause", says the Windows > guy. AFAI understood, there are new dependencies to the "harfbuzz" > library. So, the question is, if this dependency is ok. > Con't we test by the configure script, if this dependency is ok? > Some distribution people? Reinhard? As part of testing, I will set up configure to make bidi the default on X11 - so simply running "configure" will activate both bidi and Xft. Harfbuzz is not a niche library, it is as widely installed as dbus or Xlib, so I don't believe it will present an issue. But let's see what others think. I'll send out a formal invitation for testing soon. > > Thanks for all and take care, > Harald > Thank you, Kevin -- Kevin Walzer kw...@co... |