lilypond-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: define-grobs.scm properties not alphabetical


From: Carl D. Sorensen
Subject: Re: define-grobs.scm properties not alphabetical
Date: Thu, 25 Jun 2009 13:40:33 -0600



On 6/25/09 1:23 PM, "Mark Polesky" <address@hidden> wrote:

> 
> 
> Carl D. Sorensen wrote:
>> I like this, because it makes the out-of-order stuff be only a
>> programmer's problem, and programmers can use searches to find
>> the code they're looking for.
> 
> To an extent, I would say. There's obvious value to well-organized
> code. The more searches a programmer needs to make, the more time
> is wasted.
> 
> By the way, thanks for taking the time to study this.
> Now some new questions:
> 
> So whenever I create a function with "define-public", do I have to
> make sure that its containing file is listed in the
> init-scheme-files definition in lily.scm?
> 
> And is the order of the init-scheme-files list relevant? So for
> example, if files "a" and "b" are listed in that order in the
> init-scheme-files list, can "a" refer to a function from "b" that
> was created with define-public? If not, how are circular
> references resolved (or do they just need to be avoided)?
> 
>> (define (mismatch str0 str1 ci)
>>   "Return a pair containing the first character from str0 and str1 where
>> the two strings differ.  If one of the strings is a substring of the other,
>> the entry for that string will be #f."
>>   (define (helper list0 list1 ci)
>>             (cond ((and (null? list0) (null? list1))
>>                     #f)
>>                   ((null? list0)
>>                     (cons #f (car list1)))
>>                   ((null? list1)
>>                     (cons (car list0) #f))
>>                   ((not (if ci char-ci=? char=?) (car list0) (car list1)))
>>                     (cons (car list0) (car list1))
>>                   (else
>>                     (helper (cdr list0) (cdr list1)))))
>> 
>>   (helper (string->list str0) (string->list str1) ci))
>> 
>> I like the recursion rather than the loop because the
>> termination point is uncertain, so I think the loop structure is
>> less idiomatic.
> 
> Well, IIUC the "named let" syntax is basically shorthand for this,
> which allows you to do this without having to explicitly call
> "helper" at the bottom. So your function would translate (without
> *any* change to the functionality) like so (I added the missing
> parens in the 3rd clause and removed the redundant "ci" in the
> bindings):
> 
> (define (mismatch str0 str1 ci)
>   (let helper ((list0 (string->list str0))
>                (list1 (string->list str1)))
>     (cond ((and (null? list0) (null? list1))
>              #f)
>           ((null? list0)
>              (cons #f (car list1)))
>           ((null? list1)
>              (cons (car list0) #f))
>           ((not ((if ci char-ci=? char=?) (car list0) (car list1)))
>              (cons (car list0) (car list1)))
>           (else
>              (helper (cdr list0) (cdr list1)))))
> 
> So you see, the loop construct is a more compact structure for
> doing the same thing.

Yes, I see that.  But I don't like the name "loop" for a recursive call that
may not cover all of the elements of the list.  It's a semantic thing, I
guess.

A named let called "check-mismatch" instead of "loop" would be more
attractive to me, personally.

But also, for me personally, I don't like to use the named let construct,
because it's hard for me to remember the syntax.

Obvioiusly, these issues are so far down in the personal preferences list
that there should be no problem accepting the code, whatever you finally
decide.

> 
>> I've used the (not ....) on the next-to-last cond clause because
>> I want the recursive call to show up last in the structure.
> 
> I think I see the value in that approach, but I do like a and b
> better than list0 and list1 (it's easier for me to read). So do
> you approve of this (or do you prefer <test> and <expression> on
> separate lines?
> 
> (define (mismatch str0 str1 ci?)
>   (let loop ((a (string->list str0)) (b (string->list str1)))
>     (cond ((and (null? a) (null? b)) #f)
>           ((null? a) (cons #f (car b)))
>           ((null? b) (cons (car a) #f))
>           ((not ((if ci? char-ci=? char=?) (car a) (car b)))
>               (cons (car a) (car b)))
>           (else (loop (cdr a) (cdr b))))))

No, this is fine.   The only reason I put <test> and <expression> on
different lines was that I needed it for a couple of lines, and I though it
made it clearer to be completely parallel.
> 
> 
>> Also, I think that mismatch needs a doc string because its
>> function isn't transparent.
>> ....
>> Although it works to have both a globally-defined and
>> locally-defined mismatch in ly:string-*> developers, so I'd
>> recommend using different names.
> 
> Okay, I've knocked both pins down with one bowling ball by
> changing "mismatch" (the function-name) to "first-diff-chars".
> 
> And one more question: what do you think of the debugger? Is it a
> waste of source-code space?

Source-code space is pretty cheap.  But it seems to me that the best place
for the "debugger" (I'd call it an analyzer, not a debugger) is somewhere
were it gets called by a script.

What if the debugger were put in as a regression test?  Then it would be
automatically run during LilyPond checking, and the differences in sorting
would show up in the regtest results?  I think that's a better place than in
the source code.

Thanks again,

Carl





reply via email to

[Prev in Thread] Current Thread [Next in Thread]