[squeak-dev] Anybody got an elegent construct for this functional monstrosity?

Eliot Miranda eliot.miranda at gmail.com
Sat Nov 27 17:47:40 UTC 2021


On Sat, Nov 27, 2021 at 8:36 AM Thiede, Christoph <
Christoph.Thiede at student.hpi.uni-potsdam.de> wrote:

> What about
>
>
> { '{|'  . '|-' . '|}' . '{{' . '}}' .  '[[' . ']]' . '__' . '==' . '::' .
> '**' . '##' . '''' } anySatisfy: [:pattern | self match: pattern]
>
>
> ?
>
>
> Maybe also this one if the identity of the matching pattern is of interest:
>
>
> { '{|'  . '|-' . '|}' . '{{' . '}}' .  '[[' . ']]' . '__' . '==' . '::' .
> '**' . '##' . '''' }
>
>     detect: [:pattern | self match: pattern]
>
>     ifFound: [:pattern | self inform: 'Matched pattern: ' , pattern]
>
>     ifNone: [self inform: 'no match']
>
>
> Best,
>
> Christoph
>
>
> PS: Don't use #| unless you explicitly want every method to be invoked
> always. Use #or:... instead, this is faster.
>

And just as importantly, never use a brace construct when a literal array
will do.  { '{|'  . '|-' . '|}' . '{{' . '}}' .  '[[' . ']]' . '__' . '=='
. '::' . '**' . '##' . '''' } is created at run-time.  The equivalent #('{|'
'|-' '|}' '{{' '}}' '[[' ']]' '__' '==' '::' '**' '##' '''')  is created at
compile-time.  Inspect the method in the browser or the debugger and have a
look at the bytecode.

If performancer is important you'll construct a parser of some form.  For
example, the simplest optimization here is to check if the first character
is a candidate and then if the second character is a candidate.  In a
parser you'd have different code executed for each first character
candidate.  But the below avoids doing a match until we know both
characters are in the set.  I've written it as a doit bit I'm imagining
Firsts and Seconds are class or instance variables (the issue here is
provided the matcher is called often we want Firsts and Seconds to be
computed precisely once).

| patterns first second Firsts Seconds |
patterns :=  #('{|' '|-' '|}' '{{' '}}' '[[' ']]' '__' '==' '::' '**' '##'
'''').
Firsts ifNil:
   [Firsts := (patterns collect: #first) as: String.
    Seconds  := (patterns collect: #second) as: String].
self size >= 2
and: [(Firsts includes: (first := self first))
and: [(Seconds includes: (second := sef second)
and: [patterns includes: (ByteString with: first with: second)]]]

------------------------------
> *Von:* Squeak-dev <squeak-dev-bounces at lists.squeakfoundation.org> im
> Auftrag von gettimothy via Squeak-dev <
> squeak-dev at lists.squeakfoundation.org>
> *Gesendet:* Samstag, 27. November 2021 17:30:38
> *An:* squeak-dev
> *Betreff:* [squeak-dev] Anybody got an elegent construct for this
> functional monstrosity?
>
> I have a ReadStream and I want to detect some substrings in it.
>
> This works, but it is ugly.
>
>
> ((self match:'{|') |
> (self match:'|-') |
> (self match:'|}') |
> (self match:'{{') |
> (self match:'}}') |
> (self match:'[[') |
> (self match:']]') |
> (self match:'__') |
> (self match:'==') |
> (self match:'::') |
> (self match:'**') |
> (self match:'##') |
> (self match:'''') )
>
>
> Is anybody aware of an elegant approach to this?
>
>
> Something along the lines of
>
>
> self matchAny: { '{|'  . '|-' . '|}' . '{{' . '}}' .  '[[' . ']]' . '__' .
> '==' . '::' . '**' . '##' . '''' }
>
>
>
> thx in advance
>
>
>

-- 
_,,,^..^,,,_
best, Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20211127/b57a5e89/attachment.html>


More information about the Squeak-dev mailing list