[racket] Fwd: Performance help

From: Jens Axel Søgaard (jensaxel at soegaard.net)
Date: Fri Jan 2 08:42:38 EST 2015

2015-01-02 13:23 GMT+01:00 Daniel Prager <daniel.a.prager at gmail.com>:
> Slightly off-topic:
>
> Norvig's code is both concise and -- to my eye -- highly readable. E.g.
>
> def edits1(word):
>    splits     = [(word[:i], word[i:]) for i in range(len(word) + 1)]
>    deletes    = [a + b[1:] for a, b in splits if b]
>    transposes = [a + b[1] + b[0] + b[2:] for a, b in splits if len(b)>1]
>    replaces   = [a + c + b[1:] for a, b in splits for c in alphabet if b]
>    inserts    = [a + c + b     for a, b in splits for c in alphabet]
>    return set(deletes + transposes + replaces + inserts)
>
> Python's concise list comprehensions, destructuring, string slice operators,
> and operator overloading slot together nicely to make this kind of thing
> easy to knock out.
>
> I was able to achieve the following in Racket, but it's a fair bit of extra
> for a lesser result:
>
>> (define (edits1 word)
>>   (define sub substring)
>>   (define nth string-ref)
>>   (define splits (for/list ([i (range (add1 (string-length word)))])
>>                    (cons (sub word 0 i) (sub word i))))
>>
>>   (define (map-splits min-b f [chars '(dummy)])
>>     (for*/list ([split splits]
>>                 [a (in-value (car split))]
>>                 [b (in-value (cdr split))]
>>                 #:when (>= (string-length b) min-b)
>>                 [ch chars])
>>       (f a b ch)))
>>
>>   (let ([deletes    (map-splits 1 (λ (a b _)  (~a a (sub b 1))))]
>>         [transposes (map-splits 2 (λ (a b _)  (~a a (nth b 1) (nth b 0)
>> (sub b 2))))]
>>         [replaces   (map-splits 1 (λ (a b ch) (~a a ch (sub b 1)))
>> alphabet)]
>>         [inserts    (map-splits 0 (λ (a b ch) (~a a ch b)) alphabet)])
>>     (append deletes transposes replaces inserts)))
>
>
> Comments? Suggestions?

A DSL to make string manipulations more concise would be nice to have.
An ad hoc attempt can be seen here (the concat macro):

http://scheme.dk/blog/2007/04/writing-spelling-corrector-in-plt.html

The blog post was written before  for  and friends arrived in Racket,
so the code uses srfi 42 instead.

--
Jens Axel Søgaard


Posted on the users mailing list.