Pharo-dev
By thread
pharo-dev@lists.pharo.org
By month
Messages by month
- ----- 2026 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
February 2026
- 24 messages
LLM which coder is best?
by John M McIntosh
Updated our release of ClaudeSmalltalk today to better support the OpenAI codex models, and added xAI support.
Any Pharo developer who would like to assist in altering the code base to support Pharo?
In asking the various LLM models to explain for example the class 'FMSound' I found that xAI Grok 4.1 Fast gave the best answer as compared to OpenAI, Anthropic, and Qwen. It is significantly cheap too.
https://github.com/CorporateSmalltalkConsultingLtd/ClaudeSmalltalk/releases…
....
John M. McIntosh. Corporate Smalltalk Consulting Ltd https://www.linkedin.com/in/smalltalk
Feb. 12, 2026
"Identifying Spec Presenters in Hera" â New blog post on all: objects all: theTime
by Koen De Hondt
Dear Pharo users and developers,
I posted a second article in the series about describing Spec application behaviour with Hera. The first post explained how Hera manages open Spec windows. The new post explains how Hera identifies presenters so they can be referenced in Gherkin scenarios.
https://all-objects-all-the-time.st/#/blog/posts/20
As always, all feedback is welcome.
Happy reading!
Ciao,
Koen
Feb. 10, 2026
Re: [Pharo-users] [Ann] BPatterns: The rewrite engine at your fingertips
by Denis Kudriashov
Hi Eliot.
Yes, the recursive mode is default in BPatterns.
I wonder when we do not need it
пн, 9 ÑевÑ. 2026â¯Ð³., 13:45 Eliot Miranda <eliot.miranda(a)gmail.com>:
>
>
> On Feb 9, 2026, at 2:03â¯AM, Denis Kudriashov <dionisiydk(a)gmail.com> wrote:
>
> 
> Hi Eliot.
>
> The recursive mode is per pattern variable. It can be done globally of
> course in a way you suggested. But I do not see much value from this.
>
> Do you have an example where we don't want the non recursive search?
>
>
> Yes. When I refactored the VM to make the object memory/garbage collector
> an instance variable of the interpreter, rather than the superclass of the
> interpreter, this major refactoring needed to be recursive.
>
>
> ÑÑ, 4 ÑевÑ. 2026â¯Ð³., 01:16 Eliot Miranda <eliot.miranda(a)gmail.com>:
>
>> Hi Denis,
>>
>> could you support single & double ticks/non-recursive & recursive
>> modes by providing eg shallowBpattern and bpattern?
>>
>>
>>
> P.S.
>
> Also why bpattern and not bPattern or rewritePattern?
>>
>
>
> _,,,^..^,,,_ (phone)
>>
>> On Feb 3, 2026, at 10:41â¯AM, Denis Kudriashov <dionisiydk(a)gmail.com>
>> wrote:
>>
>> 
>> Hi Richard.
>>
>> I checked the code and the double backticks are for the recursion mode.
>> It forces the search to dive into the current matching node to find more
>> cases inside it.
>> For example:
>>
>> (instVar isNil ifTrue: [ 'inside recursion' ]) isNil ifTrue: [ 'outer
>> node' ]
>>
>> The syntax with single backtick will not find the internal "instVar
>> isNil" expression.
>>
>> In BPatterns the recursion mode is enabled by default for the pattern
>> variables. So the default mode covers the maximum scope for a search.
>> Currently you can't not disable the #recurseInto flag as there is not
>> suitable accessor for this. But if it would be there the pattern would like:
>>
>> [ anyVar isNil ifTrue: anyBlock ] bpattern with: [ anyVar ] -> [:pattern
>> | pattern recurseInto: false ]
>>
>>
>> Anyway I adjusted my blog accordingly. Thanks for the attention.
>>
>> вÑ, 3 ÑевÑ. 2026â¯Ð³. в 10:47, Richard O'Keefe <raoknz(a)gmail.com>:
>>
>>> Thank you. One of the reasons given for introducing BPatterns is a
>>> subtle difference between
>>> single backticks and double backticks, which is mentioned but not
>>> explained in the BPatterns
>>> blog entry. The help screen you directed me to does not explain that.
>>>
>>> Is there any documentation which is *complete* and *proofread*?
>>>
>>> On Tue, 3 Feb 2026 at 23:16, Denis Kudriashov <dionisiydk(a)gmail.com>
>>> wrote:
>>>
>>>> Yes. There is nice help presenter in the Pharo:
>>>>
>>>> StRewriterHelpBrowserPresenter new open
>>>>
>>>>
>>>> <Screenshot 2026-02-03 at 10.15.45.png>
>>>>
>>>>
>>>>
>>>> вÑ, 3 ÑевÑ. 2026â¯Ð³. в 01:36, Richard O'Keefe <raoknz(a)gmail.com>:
>>>>
>>>>> Is the "classic" rewriting syntax documented anywhere?
>>>>>
>>>>> On Mon, 2 Feb 2026 at 22:52, Denis Kudriashov via Pharo-users <
>>>>> pharo-users(a)lists.pharo.org> wrote:
>>>>>
>>>>>> Hi all.
>>>>>>
>>>>>> This is the release of *BPatterns* project, one of my old ideas on
>>>>>> how to make the rewrite engine usable for scripting.
>>>>>>
>>>>>> As a quick reminder, here is an example of the classic rewrite-engine
>>>>>> matching syntax:
>>>>>>
>>>>>> *``@receiver isNil ifTrue: ``@nilBlock*
>>>>>>
>>>>>>
>>>>>> In practice, patterns like this usually live inside string
>>>>>> literalsâhidden away in lint rules, deprecations, or refactorings.
>>>>>> To use them for *manual* code search or rewriting, you typically
>>>>>> need a dedicated tool.
>>>>>>
>>>>>> Now compare that with the same pattern expressed as a *BPattern*:
>>>>>>
>>>>>> *[ any isNil ifTrue: anyBlock ] bpattern*
>>>>>>
>>>>>> No special syntax.
>>>>>> No magical tools.
>>>>>> Just pure Smalltalk.
>>>>>>
>>>>>> You write a block.
>>>>>> You send #bpattern.
>>>>>> Youâre done.
>>>>>>
>>>>>> Every editor understands it.
>>>>>> Every tool respects it.
>>>>>>
>>>>>> Want to see where this pattern appears?
>>>>>>
>>>>>> * [ any isNil ifTrue: anyBlock ] bpattern browseUsers*
>>>>>>
>>>>>>
>>>>>> <Screenshot 2026-01-31 at 12.16.19.png>
>>>>>>
>>>>>>
>>>>>> Want to rewrite all of them?
>>>>>>
>>>>>> *[[ any isNil ifTrue: anyBlock ] -> [ any ifNil: anyBlock ]] brewrite
>>>>>> preview*
>>>>>>
>>>>>>
>>>>>> <Screenshot 2026-01-31 at 12.17.57.png>
>>>>>>
>>>>>> Because *BPatterns are real Smalltalk code*, all development tools
>>>>>> work out of the box:
>>>>>> syntax highlighting, completion, navigation, refactorings.
>>>>>>
>>>>>> This is the rewrite engine treated as a *first-class citizen*.
>>>>>>
>>>>>> Not strings.
>>>>>> Not tooling sidecars.
>>>>>> Not just for advanced users.
>>>>>>
>>>>>> *A rewrite engine you can actually use.*
>>>>>> * A rewrite engine at your fingertips.*
>>>>>> More details are in the blog post:
>>>>>>
>>>>>> -
>>>>>> https://dionisiydk.blogspot.com/2026/02/bpatterns-rewrite-engine-with-small…
>>>>>>
>>>>>> And follow the project on GitHub:
>>>>>>
>>>>>> - https://github.com/dionisiydk/BPatterns
>>>>>>
>>>>>>
>>>>>> -
>>>>>>
>>>>>>
Feb. 10, 2026
Feb. 9, 2026
Re: [Pharo-users] [Ann] BPatterns: The rewrite engine at your fingertips
by Denis Kudriashov
Hi Eliot.
The recursive mode is per pattern variable. It can be done globally of
course in a way you suggested. But I do not see much value from this.
Do you have an example where we don't want the non recursive search?
ÑÑ, 4 ÑевÑ. 2026â¯Ð³., 01:16 Eliot Miranda <eliot.miranda(a)gmail.com>:
> Hi Denis,
>
> could you support single & double ticks/non-recursive & recursive
> modes by providing eg shallowBpattern and bpattern?
>
>
> Also why bpattern and not bPattern or rewritePattern?
> _,,,^..^,,,_ (phone)
>
> On Feb 3, 2026, at 10:41â¯AM, Denis Kudriashov <dionisiydk(a)gmail.com>
> wrote:
>
> 
> Hi Richard.
>
> I checked the code and the double backticks are for the recursion mode. It
> forces the search to dive into the current matching node to find more cases
> inside it.
> For example:
>
> (instVar isNil ifTrue: [ 'inside recursion' ]) isNil ifTrue: [ 'outer
> node' ]
>
> The syntax with single backtick will not find the internal "instVar isNil"
> expression.
>
> In BPatterns the recursion mode is enabled by default for the pattern
> variables. So the default mode covers the maximum scope for a search.
> Currently you can't not disable the #recurseInto flag as there is not
> suitable accessor for this. But if it would be there the pattern would like:
>
> [ anyVar isNil ifTrue: anyBlock ] bpattern with: [ anyVar ] -> [:pattern |
> pattern recurseInto: false ]
>
>
> Anyway I adjusted my blog accordingly. Thanks for the attention.
>
> вÑ, 3 ÑевÑ. 2026â¯Ð³. в 10:47, Richard O'Keefe <raoknz(a)gmail.com>:
>
>> Thank you. One of the reasons given for introducing BPatterns is a
>> subtle difference between
>> single backticks and double backticks, which is mentioned but not
>> explained in the BPatterns
>> blog entry. The help screen you directed me to does not explain that.
>>
>> Is there any documentation which is *complete* and *proofread*?
>>
>> On Tue, 3 Feb 2026 at 23:16, Denis Kudriashov <dionisiydk(a)gmail.com>
>> wrote:
>>
>>> Yes. There is nice help presenter in the Pharo:
>>>
>>> StRewriterHelpBrowserPresenter new open
>>>
>>>
>>> <Screenshot 2026-02-03 at 10.15.45.png>
>>>
>>>
>>>
>>> вÑ, 3 ÑевÑ. 2026â¯Ð³. в 01:36, Richard O'Keefe <raoknz(a)gmail.com>:
>>>
>>>> Is the "classic" rewriting syntax documented anywhere?
>>>>
>>>> On Mon, 2 Feb 2026 at 22:52, Denis Kudriashov via Pharo-users <
>>>> pharo-users(a)lists.pharo.org> wrote:
>>>>
>>>>> Hi all.
>>>>>
>>>>> This is the release of *BPatterns* project, one of my old ideas on
>>>>> how to make the rewrite engine usable for scripting.
>>>>>
>>>>> As a quick reminder, here is an example of the classic rewrite-engine
>>>>> matching syntax:
>>>>>
>>>>> *``@receiver isNil ifTrue: ``@nilBlock*
>>>>>
>>>>>
>>>>> In practice, patterns like this usually live inside string
>>>>> literalsâhidden away in lint rules, deprecations, or refactorings.
>>>>> To use them for *manual* code search or rewriting, you typically need
>>>>> a dedicated tool.
>>>>>
>>>>> Now compare that with the same pattern expressed as a *BPattern*:
>>>>>
>>>>> *[ any isNil ifTrue: anyBlock ] bpattern*
>>>>>
>>>>> No special syntax.
>>>>> No magical tools.
>>>>> Just pure Smalltalk.
>>>>>
>>>>> You write a block.
>>>>> You send #bpattern.
>>>>> Youâre done.
>>>>>
>>>>> Every editor understands it.
>>>>> Every tool respects it.
>>>>>
>>>>> Want to see where this pattern appears?
>>>>>
>>>>> * [ any isNil ifTrue: anyBlock ] bpattern browseUsers*
>>>>>
>>>>>
>>>>> <Screenshot 2026-01-31 at 12.16.19.png>
>>>>>
>>>>>
>>>>> Want to rewrite all of them?
>>>>>
>>>>> *[[ any isNil ifTrue: anyBlock ] -> [ any ifNil: anyBlock ]] brewrite
>>>>> preview*
>>>>>
>>>>>
>>>>> <Screenshot 2026-01-31 at 12.17.57.png>
>>>>>
>>>>> Because *BPatterns are real Smalltalk code*, all development tools
>>>>> work out of the box:
>>>>> syntax highlighting, completion, navigation, refactorings.
>>>>>
>>>>> This is the rewrite engine treated as a *first-class citizen*.
>>>>>
>>>>> Not strings.
>>>>> Not tooling sidecars.
>>>>> Not just for advanced users.
>>>>>
>>>>> *A rewrite engine you can actually use.*
>>>>> * A rewrite engine at your fingertips.*
>>>>> More details are in the blog post:
>>>>>
>>>>> -
>>>>> https://dionisiydk.blogspot.com/2026/02/bpatterns-rewrite-engine-with-small…
>>>>>
>>>>> And follow the project on GitHub:
>>>>>
>>>>> - https://github.com/dionisiydk/BPatterns
>>>>>
>>>>>
>>>>> -
>>>>>
>>>>>
Feb. 9, 2026
Re: [Pharo-users] [Ann] BPatterns: The rewrite engine at your fingertips
by Denis Kudriashov
Hi Daniel.
Quick question: Does this use the same underlying parse nodes, and helper
> classes like ParseTreeRewriter, as the old system, just generating them a
> different way? If so, I think the value here is as much in the convenience
> methods for performing searches and rewrites as the pattern syntaxâso thank
> you for that, regardless!
Yes, underhood BPatterns is based on the pattern AST nodes and the
matching/rewrite machinery. It's just a different DSL to the original
engine.
There are some changes to better follow my idea but it is not significant.
While we're on the subject of rewrite tools, a while back I noticed that I
> often wanted to rewrite sequences of statements to a single method call,
> where that sequence might recur several times in the same method. This
> especially comes up in testsâperhaps I notice that the pattern:
self assert: obj foo equals: `#expectedFoo.
> self assert: obj bar equals: `#expectedBar.
> self assert: obj baz equals: `#expectedBaz.
Agree, I have the same feeling about the sequences. And it can be quite
confusing when you do not know the internal details.
I don't think I will have any time to change this.
вÑ, 3 ÑевÑ. 2026â¯Ð³. в 23:51, Daniel Slomovits <daniels220(a)gmail.com>:
> I love the basic idea, but at a glance, it seems like the syntax rapidly
> becomes *much* more verbose than the equivalent using the special pattern
> syntax. For simple examples it's more-or-less equivalent, but the with: [
> anyVar ] -> [:pattern | ...] syntax is *very* clunky.
>
> What I would *really* love to see is an extension to the Compiler, that
> allows for mixing the actual pattern syntax directly into code. Perhaps
> initiated by a backtick-parenthesis, so you could write:
>
> (`(``@receiver isNil ifTrue: ``@nilBlock) -> `(``@receiver ifNil:
> ``@nilBlock)) rewrite preview
>
> I'm not even sure this would be all that hardâit would mean adding one new
> type of parse node, call it a "pattern literal", delimited by `(), whose
> implementation would be very straightforward for the most part, with the
> only complication being that pattern blocks (`{}) would have to be
> compiled properly in the outer scope. As additional niceties, individual
> pattern nodes should ideally be able to appear bare, rather than needing to
> be wrapped in `(), and we would want a syntax for "this is a whole-method
> pattern"
>
> On another note, I want to call attention to one thing that BPattern has
> going for it that string-literal-based patterns can't (easily) do: modifier
> blocks are closures in the method that generated them, so you can do things
> like have methods that return a pattern which closes over the arguments of
> the method...having trouble coming up with an example off the top of my
> head, but this is very powerful. (Well. Actually you *can* do this with
> string-based patterns, by reaching in after the pattern is parsed and
> editing the modifier block. I've written methods to support the following
> syntax: '`@exp' withPatternBlock: [:exp | "this is a real block, although
> the expression it wraps was still parsed from a string literal"].)
>
> Quick question: Does this use the same underlying parse nodes, and helper
> classes like ParseTreeRewriter, as the old system, just generating them a
> different way? If so, I think the value here is as much in the convenience
> methods for performing searches and rewrites as the pattern syntaxâso thank
> you for that, regardless!
>
> While we're on the subject of rewrite tools, a while back I noticed that I
> often wanted to rewrite sequences of statements to a single method call,
> where that sequence might recur several times in the same method. This
> especially comes up in testsâperhaps I notice that the pattern:
>
> self assert: obj foo equals: `#expectedFoo.
> self assert: obj bar equals: `#expectedBar.
> self assert: obj baz equals: `#expectedBaz.
>
> occurs a lot, and those properties are related enough that it makes more
> sense to say self verifyFooBarBaz: obj equal: {`#expectedFoo.
> `#expectedBar. `#expectedBaz}. (This is a poor example, in truth, but there
> are cases where it's much more clearly justified.) By default you can only
> get one of these occurrences per run of the rewrite tool, because any
> pattern you write has to match the *entire sequence*, and once it has
> matched, the entire sequence is disqualified from further matching. I was
> able to extend the matching semantics so that a
> recurse-into-list-of-statements pattern (i.e. ``@.stmts,
> double-backtick-at-period) effectively builds a *new* sequence containing
> only the statements it matched, and retries the rule against *that*. It
> could definitely stand to be more elegant, but for me it filled an
> important hole in the existing capabilities. Is that something anyone would
> be interested in helping me dust off and contribute?
>
> On Tue, Feb 3, 2026 at 1:41â¯PM Denis Kudriashov <dionisiydk(a)gmail.com>
> wrote:
>
>> Hi Richard.
>>
>> I checked the code and the double backticks are for the recursion mode.
>> It forces the search to dive into the current matching node to find more
>> cases inside it.
>> For example:
>>
>> (instVar isNil ifTrue: [ 'inside recursion' ]) isNil ifTrue: [ 'outer
>> node' ]
>>
>> The syntax with single backtick will not find the internal "instVar
>> isNil" expression.
>>
>> In BPatterns the recursion mode is enabled by default for the pattern
>> variables. So the default mode covers the maximum scope for a search.
>> Currently you can't not disable the #recurseInto flag as there is not
>> suitable accessor for this. But if it would be there the pattern would like:
>>
>> [ anyVar isNil ifTrue: anyBlock ] bpattern with: [ anyVar ] -> [:pattern
>> | pattern recurseInto: false ]
>>
>>
>> Anyway I adjusted my blog accordingly. Thanks for the attention.
>>
>> вÑ, 3 ÑевÑ. 2026â¯Ð³. в 10:47, Richard O'Keefe <raoknz(a)gmail.com>:
>>
>>> Thank you. One of the reasons given for introducing BPatterns is a
>>> subtle difference between
>>> single backticks and double backticks, which is mentioned but not
>>> explained in the BPatterns
>>> blog entry. The help screen you directed me to does not explain that.
>>>
>>> Is there any documentation which is *complete* and *proofread*?
>>>
>>> On Tue, 3 Feb 2026 at 23:16, Denis Kudriashov <dionisiydk(a)gmail.com>
>>> wrote:
>>>
>>>> Yes. There is nice help presenter in the Pharo:
>>>>
>>>> StRewriterHelpBrowserPresenter new open
>>>>
>>>>
>>>> [image: Screenshot 2026-02-03 at 10.15.45.png]
>>>>
>>>>
>>>> вÑ, 3 ÑевÑ. 2026â¯Ð³. в 01:36, Richard O'Keefe <raoknz(a)gmail.com>:
>>>>
>>>>> Is the "classic" rewriting syntax documented anywhere?
>>>>>
>>>>> On Mon, 2 Feb 2026 at 22:52, Denis Kudriashov via Pharo-users <
>>>>> pharo-users(a)lists.pharo.org> wrote:
>>>>>
>>>>>> Hi all.
>>>>>>
>>>>>> This is the release of *BPatterns* project, one of my old ideas on
>>>>>> how to make the rewrite engine usable for scripting.
>>>>>>
>>>>>> As a quick reminder, here is an example of the classic rewrite-engine
>>>>>> matching syntax:
>>>>>>
>>>>>> *``@receiver isNil ifTrue: ``@nilBlock*
>>>>>>
>>>>>>
>>>>>> In practice, patterns like this usually live inside string
>>>>>> literalsâhidden away in lint rules, deprecations, or refactorings.
>>>>>> To use them for *manual* code search or rewriting, you typically
>>>>>> need a dedicated tool.
>>>>>>
>>>>>> Now compare that with the same pattern expressed as a *BPattern*:
>>>>>>
>>>>>> *[ any isNil ifTrue: anyBlock ] bpattern*
>>>>>>
>>>>>> No special syntax.
>>>>>> No magical tools.
>>>>>> Just pure Smalltalk.
>>>>>>
>>>>>> You write a block.
>>>>>> You send #bpattern.
>>>>>> Youâre done.
>>>>>>
>>>>>> Every editor understands it.
>>>>>> Every tool respects it.
>>>>>>
>>>>>> Want to see where this pattern appears?
>>>>>>
>>>>>> * [ any isNil ifTrue: anyBlock ] bpattern browseUsers*
>>>>>>
>>>>>>
>>>>>> [image: Screenshot 2026-01-31 at 12.16.19.png]
>>>>>>
>>>>>> Want to rewrite all of them?
>>>>>>
>>>>>> *[[ any isNil ifTrue: anyBlock ] -> [ any ifNil: anyBlock ]] brewrite
>>>>>> preview*
>>>>>>
>>>>>>
>>>>>> [image: Screenshot 2026-01-31 at 12.17.57.png]
>>>>>>
>>>>>> Because *BPatterns are real Smalltalk code*, all development tools
>>>>>> work out of the box:
>>>>>> syntax highlighting, completion, navigation, refactorings.
>>>>>>
>>>>>> This is the rewrite engine treated as a *first-class citizen*.
>>>>>>
>>>>>> Not strings.
>>>>>> Not tooling sidecars.
>>>>>> Not just for advanced users.
>>>>>>
>>>>>> *A rewrite engine you can actually use.*
>>>>>> * A rewrite engine at your fingertips.*
>>>>>> More details are in the blog post:
>>>>>>
>>>>>> -
>>>>>> https://dionisiydk.blogspot.com/2026/02/bpatterns-rewrite-engine-with-small…
>>>>>>
>>>>>> And follow the project on GitHub:
>>>>>>
>>>>>> - https://github.com/dionisiydk/BPatterns
>>>>>>
>>>>>>
>>>>>> -
>>>>>>
>>>>>>
Feb. 7, 2026
Feb. 4, 2026
Re: [Pharo-users] [Ann] BPatterns: The rewrite engine at your fingertips
by Daniel Slomovits
I love the basic idea, but at a glance, it seems like the syntax rapidly
becomes *much* more verbose than the equivalent using the special pattern
syntax. For simple examples it's more-or-less equivalent, but the with: [
anyVar ] -> [:pattern | ...] syntax is *very* clunky.
What I would *really* love to see is an extension to the Compiler, that
allows for mixing the actual pattern syntax directly into code. Perhaps
initiated by a backtick-parenthesis, so you could write:
(`(``@receiver isNil ifTrue: ``@nilBlock) -> `(``@receiver ifNil:
``@nilBlock)) rewrite preview
I'm not even sure this would be all that hardâit would mean adding one new
type of parse node, call it a "pattern literal", delimited by `(), whose
implementation would be very straightforward for the most part, with the
only complication being that pattern blocks (`{}) would have to be compiled
properly in the outer scope. As additional niceties, individual pattern
nodes should ideally be able to appear bare, rather than needing to be
wrapped in `(), and we would want a syntax for "this is a whole-method
pattern"
On another note, I want to call attention to one thing that BPattern has
going for it that string-literal-based patterns can't (easily) do: modifier
blocks are closures in the method that generated them, so you can do things
like have methods that return a pattern which closes over the arguments of
the method...having trouble coming up with an example off the top of my
head, but this is very powerful. (Well. Actually you *can* do this with
string-based patterns, by reaching in after the pattern is parsed and
editing the modifier block. I've written methods to support the following
syntax: '`@exp' withPatternBlock: [:exp | "this is a real block, although
the expression it wraps was still parsed from a string literal"].)
Quick question: Does this use the same underlying parse nodes, and helper
classes like ParseTreeRewriter, as the old system, just generating them a
different way? If so, I think the value here is as much in the convenience
methods for performing searches and rewrites as the pattern syntaxâso thank
you for that, regardless!
While we're on the subject of rewrite tools, a while back I noticed that I
often wanted to rewrite sequences of statements to a single method call,
where that sequence might recur several times in the same method. This
especially comes up in testsâperhaps I notice that the pattern:
self assert: obj foo equals: `#expectedFoo.
self assert: obj bar equals: `#expectedBar.
self assert: obj baz equals: `#expectedBaz.
occurs a lot, and those properties are related enough that it makes more
sense to say self verifyFooBarBaz: obj equal: {`#expectedFoo.
`#expectedBar. `#expectedBaz}. (This is a poor example, in truth, but there
are cases where it's much more clearly justified.) By default you can only
get one of these occurrences per run of the rewrite tool, because any
pattern you write has to match the *entire sequence*, and once it has
matched, the entire sequence is disqualified from further matching. I was
able to extend the matching semantics so that a
recurse-into-list-of-statements pattern (i.e. ``@.stmts,
double-backtick-at-period) effectively builds a *new* sequence containing
only the statements it matched, and retries the rule against *that*. It
could definitely stand to be more elegant, but for me it filled an
important hole in the existing capabilities. Is that something anyone would
be interested in helping me dust off and contribute?
On Tue, Feb 3, 2026 at 1:41â¯PM Denis Kudriashov <dionisiydk(a)gmail.com>
wrote:
> Hi Richard.
>
> I checked the code and the double backticks are for the recursion mode. It
> forces the search to dive into the current matching node to find more cases
> inside it.
> For example:
>
> (instVar isNil ifTrue: [ 'inside recursion' ]) isNil ifTrue: [ 'outer
> node' ]
>
> The syntax with single backtick will not find the internal "instVar isNil"
> expression.
>
> In BPatterns the recursion mode is enabled by default for the pattern
> variables. So the default mode covers the maximum scope for a search.
> Currently you can't not disable the #recurseInto flag as there is not
> suitable accessor for this. But if it would be there the pattern would like:
>
> [ anyVar isNil ifTrue: anyBlock ] bpattern with: [ anyVar ] -> [:pattern |
> pattern recurseInto: false ]
>
>
> Anyway I adjusted my blog accordingly. Thanks for the attention.
>
> вÑ, 3 ÑевÑ. 2026â¯Ð³. в 10:47, Richard O'Keefe <raoknz(a)gmail.com>:
>
>> Thank you. One of the reasons given for introducing BPatterns is a
>> subtle difference between
>> single backticks and double backticks, which is mentioned but not
>> explained in the BPatterns
>> blog entry. The help screen you directed me to does not explain that.
>>
>> Is there any documentation which is *complete* and *proofread*?
>>
>> On Tue, 3 Feb 2026 at 23:16, Denis Kudriashov <dionisiydk(a)gmail.com>
>> wrote:
>>
>>> Yes. There is nice help presenter in the Pharo:
>>>
>>> StRewriterHelpBrowserPresenter new open
>>>
>>>
>>> [image: Screenshot 2026-02-03 at 10.15.45.png]
>>>
>>>
>>> вÑ, 3 ÑевÑ. 2026â¯Ð³. в 01:36, Richard O'Keefe <raoknz(a)gmail.com>:
>>>
>>>> Is the "classic" rewriting syntax documented anywhere?
>>>>
>>>> On Mon, 2 Feb 2026 at 22:52, Denis Kudriashov via Pharo-users <
>>>> pharo-users(a)lists.pharo.org> wrote:
>>>>
>>>>> Hi all.
>>>>>
>>>>> This is the release of *BPatterns* project, one of my old ideas on
>>>>> how to make the rewrite engine usable for scripting.
>>>>>
>>>>> As a quick reminder, here is an example of the classic rewrite-engine
>>>>> matching syntax:
>>>>>
>>>>> *``@receiver isNil ifTrue: ``@nilBlock*
>>>>>
>>>>>
>>>>> In practice, patterns like this usually live inside string
>>>>> literalsâhidden away in lint rules, deprecations, or refactorings.
>>>>> To use them for *manual* code search or rewriting, you typically need
>>>>> a dedicated tool.
>>>>>
>>>>> Now compare that with the same pattern expressed as a *BPattern*:
>>>>>
>>>>> *[ any isNil ifTrue: anyBlock ] bpattern*
>>>>>
>>>>> No special syntax.
>>>>> No magical tools.
>>>>> Just pure Smalltalk.
>>>>>
>>>>> You write a block.
>>>>> You send #bpattern.
>>>>> Youâre done.
>>>>>
>>>>> Every editor understands it.
>>>>> Every tool respects it.
>>>>>
>>>>> Want to see where this pattern appears?
>>>>>
>>>>> * [ any isNil ifTrue: anyBlock ] bpattern browseUsers*
>>>>>
>>>>>
>>>>> [image: Screenshot 2026-01-31 at 12.16.19.png]
>>>>>
>>>>> Want to rewrite all of them?
>>>>>
>>>>> *[[ any isNil ifTrue: anyBlock ] -> [ any ifNil: anyBlock ]] brewrite
>>>>> preview*
>>>>>
>>>>>
>>>>> [image: Screenshot 2026-01-31 at 12.17.57.png]
>>>>>
>>>>> Because *BPatterns are real Smalltalk code*, all development tools
>>>>> work out of the box:
>>>>> syntax highlighting, completion, navigation, refactorings.
>>>>>
>>>>> This is the rewrite engine treated as a *first-class citizen*.
>>>>>
>>>>> Not strings.
>>>>> Not tooling sidecars.
>>>>> Not just for advanced users.
>>>>>
>>>>> *A rewrite engine you can actually use.*
>>>>> * A rewrite engine at your fingertips.*
>>>>> More details are in the blog post:
>>>>>
>>>>> -
>>>>> https://dionisiydk.blogspot.com/2026/02/bpatterns-rewrite-engine-with-small…
>>>>>
>>>>> And follow the project on GitHub:
>>>>>
>>>>> - https://github.com/dionisiydk/BPatterns
>>>>>
>>>>>
>>>>> -
>>>>>
>>>>>
Feb. 3, 2026
Re: [Pharo-users] [Ann] BPatterns: The rewrite engine at your fingertips
by Denis Kudriashov
Hi Richard.
I checked the code and the double backticks are for the recursion mode. It
forces the search to dive into the current matching node to find more cases
inside it.
For example:
(instVar isNil ifTrue: [ 'inside recursion' ]) isNil ifTrue: [ 'outer node'
]
The syntax with single backtick will not find the internal "instVar isNil"
expression.
In BPatterns the recursion mode is enabled by default for the pattern
variables. So the default mode covers the maximum scope for a search.
Currently you can't not disable the #recurseInto flag as there is not
suitable accessor for this. But if it would be there the pattern would like:
[ anyVar isNil ifTrue: anyBlock ] bpattern with: [ anyVar ] -> [:pattern |
pattern recurseInto: false ]
Anyway I adjusted my blog accordingly. Thanks for the attention.
вÑ, 3 ÑевÑ. 2026â¯Ð³. в 10:47, Richard O'Keefe <raoknz(a)gmail.com>:
> Thank you. One of the reasons given for introducing BPatterns is a subtle
> difference between
> single backticks and double backticks, which is mentioned but not
> explained in the BPatterns
> blog entry. The help screen you directed me to does not explain that.
>
> Is there any documentation which is *complete* and *proofread*?
>
> On Tue, 3 Feb 2026 at 23:16, Denis Kudriashov <dionisiydk(a)gmail.com>
> wrote:
>
>> Yes. There is nice help presenter in the Pharo:
>>
>> StRewriterHelpBrowserPresenter new open
>>
>>
>> [image: Screenshot 2026-02-03 at 10.15.45.png]
>>
>>
>> вÑ, 3 ÑевÑ. 2026â¯Ð³. в 01:36, Richard O'Keefe <raoknz(a)gmail.com>:
>>
>>> Is the "classic" rewriting syntax documented anywhere?
>>>
>>> On Mon, 2 Feb 2026 at 22:52, Denis Kudriashov via Pharo-users <
>>> pharo-users(a)lists.pharo.org> wrote:
>>>
>>>> Hi all.
>>>>
>>>> This is the release of *BPatterns* project, one of my old ideas on how
>>>> to make the rewrite engine usable for scripting.
>>>>
>>>> As a quick reminder, here is an example of the classic rewrite-engine
>>>> matching syntax:
>>>>
>>>> *``@receiver isNil ifTrue: ``@nilBlock*
>>>>
>>>>
>>>> In practice, patterns like this usually live inside string
>>>> literalsâhidden away in lint rules, deprecations, or refactorings.
>>>> To use them for *manual* code search or rewriting, you typically need
>>>> a dedicated tool.
>>>>
>>>> Now compare that with the same pattern expressed as a *BPattern*:
>>>>
>>>> *[ any isNil ifTrue: anyBlock ] bpattern*
>>>>
>>>> No special syntax.
>>>> No magical tools.
>>>> Just pure Smalltalk.
>>>>
>>>> You write a block.
>>>> You send #bpattern.
>>>> Youâre done.
>>>>
>>>> Every editor understands it.
>>>> Every tool respects it.
>>>>
>>>> Want to see where this pattern appears?
>>>>
>>>> * [ any isNil ifTrue: anyBlock ] bpattern browseUsers*
>>>>
>>>>
>>>> [image: Screenshot 2026-01-31 at 12.16.19.png]
>>>>
>>>> Want to rewrite all of them?
>>>>
>>>> *[[ any isNil ifTrue: anyBlock ] -> [ any ifNil: anyBlock ]] brewrite
>>>> preview*
>>>>
>>>>
>>>> [image: Screenshot 2026-01-31 at 12.17.57.png]
>>>>
>>>> Because *BPatterns are real Smalltalk code*, all development tools
>>>> work out of the box:
>>>> syntax highlighting, completion, navigation, refactorings.
>>>>
>>>> This is the rewrite engine treated as a *first-class citizen*.
>>>>
>>>> Not strings.
>>>> Not tooling sidecars.
>>>> Not just for advanced users.
>>>>
>>>> *A rewrite engine you can actually use.*
>>>> * A rewrite engine at your fingertips.*
>>>> More details are in the blog post:
>>>>
>>>> -
>>>> https://dionisiydk.blogspot.com/2026/02/bpatterns-rewrite-engine-with-small…
>>>>
>>>> And follow the project on GitHub:
>>>>
>>>> - https://github.com/dionisiydk/BPatterns
>>>>
>>>>
>>>> -
>>>>
>>>>
Feb. 3, 2026
Re: [Pharo-users] [Ann] BPatterns: The rewrite engine at your fingertips
by Denis Kudriashov
Yes. There is nice help presenter in the Pharo:
StRewriterHelpBrowserPresenter new open
[image: Screenshot 2026-02-03 at 10.15.45.png]
вÑ, 3 ÑевÑ. 2026â¯Ð³. в 01:36, Richard O'Keefe <raoknz(a)gmail.com>:
> Is the "classic" rewriting syntax documented anywhere?
>
> On Mon, 2 Feb 2026 at 22:52, Denis Kudriashov via Pharo-users <
> pharo-users(a)lists.pharo.org> wrote:
>
>> Hi all.
>>
>> This is the release of *BPatterns* project, one of my old ideas on how
>> to make the rewrite engine usable for scripting.
>>
>> As a quick reminder, here is an example of the classic rewrite-engine
>> matching syntax:
>>
>> *``@receiver isNil ifTrue: ``@nilBlock*
>>
>>
>> In practice, patterns like this usually live inside string
>> literalsâhidden away in lint rules, deprecations, or refactorings.
>> To use them for *manual* code search or rewriting, you typically need a
>> dedicated tool.
>>
>> Now compare that with the same pattern expressed as a *BPattern*:
>>
>> *[ any isNil ifTrue: anyBlock ] bpattern*
>>
>> No special syntax.
>> No magical tools.
>> Just pure Smalltalk.
>>
>> You write a block.
>> You send #bpattern.
>> Youâre done.
>>
>> Every editor understands it.
>> Every tool respects it.
>>
>> Want to see where this pattern appears?
>>
>> * [ any isNil ifTrue: anyBlock ] bpattern browseUsers*
>>
>>
>> [image: Screenshot 2026-01-31 at 12.16.19.png]
>>
>> Want to rewrite all of them?
>>
>> *[[ any isNil ifTrue: anyBlock ] -> [ any ifNil: anyBlock ]] brewrite
>> preview*
>>
>>
>> [image: Screenshot 2026-01-31 at 12.17.57.png]
>>
>> Because *BPatterns are real Smalltalk code*, all development tools work
>> out of the box:
>> syntax highlighting, completion, navigation, refactorings.
>>
>> This is the rewrite engine treated as a *first-class citizen*.
>>
>> Not strings.
>> Not tooling sidecars.
>> Not just for advanced users.
>>
>> *A rewrite engine you can actually use.*
>> * A rewrite engine at your fingertips.*
>> More details are in the blog post:
>>
>> -
>> https://dionisiydk.blogspot.com/2026/02/bpatterns-rewrite-engine-with-small…
>>
>> And follow the project on GitHub:
>>
>> - https://github.com/dionisiydk/BPatterns
>>
>>
>> -
>>
>>
Feb. 3, 2026