lilypond-devel
[Top][All Lists]
Advanced

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

Re: Markup module patch (Issue 2026)


From: David Kastrup
Subject: Re: Markup module patch (Issue 2026)
Date: Wed, 14 Dec 2011 10:04:05 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.92 (gnu/linux)

Ian Hulin <address@hidden> writes:

> Hi David,
> On 13/12/11 22:40, David Kastrup wrote:
>> Ian Hulin <address@hidden> writes:
>> 
>>> Hi all, ..snip..
>> 
>> 
>>> I'd like to deprecate this as I think it's nasty, smelly, evil
>>> and kludgy
>> 
>> Care to explain why being able to use the same syntax as one uses
>> in the main document is nasty, smelly, evil and kludgy?  Should we
>> disallow \markup syntax in the main document as well?
>> 
> What is nasty is going back and forth between Lily and Scheme parsing
> unnecessarily.

It isn't unnecessary.  It makes things simpler for the user.  That's the
reason for being for macros (why would you want to have another layer
munging your input when you can just write it correctly yourself?), and
it is the reason for the existence of this construct.

>>> #(define-markup-command (double-box layout props text) (markup?) 
>>> "Draw a double box around text." (interpret-markup layout props 
>>> #{\markup \override #'(box-padding . 0.4) \box \override
>>> #'(box-padding . 0.6) \box { $text }#}))
>                                                         ^^^
> The $text above LilyPond called from within Scheme called from within
> LilyPond referencing a variable declared in the Scheme layer.

Yes.  Why should that be allowed to cease working?

> I'm not criticising the #{...#} stuff in itself, especially after
> you've been working hard to clean this stuff up,

It's not been "cleaned up" but rather extended from creating only
sequential music lists with dubious lexical implications into a
universal, powerful and predictable part of Lilypond's toolkit.

> but *here* it's adding another layer of complexity to access the
> Scheme text variable.

If your code breaks when adding a layer of complexity that works fine
elsewhere, we need to fix your code.

> Also the editorial thrust of the narrative in /extending/ seems to be
> to use the Scheme macros.

I changed that exactly because the important thing is giving the users
power first, complications later.

> You called me an expert, I didn't.  I'm just a stubborn sucker that
> would like to see LilyPond working with a supported version of Guile.

Your changes make it stop working with Guile 1.8 when using previously
working code.

> In order to get the markup stuff to compile or be interpreted
> correctly with Guile V2, I had to get the procedures validating the
> markup commands to look in a single module at the list where they were
> held.

I don't understand why that would be needed or help.

> So I chose the base (lily) module. To keep it consistent, I got
> the define-markup-command and define-markup-list-command macros to
> push and pop the current Scheme module by doing
> (let (prevmod (current-module))
>      (existing declaration)
>       ...
>      (existing declaration))
>   (set-current-module (resolve-module '(lily)))
>   (existing code)
>   ( ... )
>   (set-current-module (prevmod))

There are so many things wrong with this code that it is hard to know
where to start.  For one thing, it can't deal with exceptions or
continuations.  So we'd best start shaking it out from here.

How does this help?  Please explain, and we might find a better
solution.  _Changing_ modules in code related to _macros_ is totally a
recipe for disaster.

And please don't fix snippets or even regtests instead of the things
that they show as being broken, unless there is agreement that it is
reasonable to consider them broken and require users to do something
else.  And _document_ why they are broken, and what the user should do
to avoid writing broken code.

>> It is _exactly_ what the parser will deliver for this particular
>> markup also in the main document, so if it breaks in #{ ... #}, it
>> very likely also breaks in the main document.  Should we only be
>> allowed to specify markups in Scheme macro syntax in future?
>> 
> The implication in the way /extending/ is written is that using the
> macros is preferable in (define-markup-command) and
> (define-markup-list-command).

If that is your impression, than I need to reedit.  If you want to hear
my opinion, define-*markup-command are a steaming heap of unnecessarily
macro-tied crap that has no place in a sensible user programming
environment and sticks out like a sore thumb.  My earliest work on
Lilypond, IIRC, has been in that area, and it was not fun.  Macro
programming is bad enough in Emacs Lisp, but in _lexical_ environments,
you get another quality of surprises from evaluation order.

You are working on this code, and it breaks in ways that spoil your
plans.  I suppose everyone (including myself) working on that code has
had plenty of those experiences.  Lashing out at the world in general
because it is more complex than your code can deal with will not help.

If you don't want to debug this, it might be a good idea to check out
the _unrelated_ snippet that breaks under your changes instead of
"fixing" it.  Its breakage might be related, and it might be easier to
analyze.

> What breaks is #{...#} within a #(define-markup-command ...) with the
> patch.  I get this scheme traceback:

> /home/ian/src/lilypond/build/out/share/lilypond/current/scm/parser-ly-from-scheme.scm:67:21:
> In procedure ly:parser-clone in expression (ly:parser-clone parser
> closures):
> /home/ian/src/lilypond/build/out/share/lilypond/current/scm/parser-ly-from-scheme.scm:67:21:
> Wrong type argument in position 1 (expecting Lily_parser): #f
>
> Why would temporarily changing the current module upset the LilyPond
> parser?
>
> I accept that it's best if I can fettle this patch so that we don't
> need to deprecate anything.

That one's easy to answer.  #{ ... #} expands into code referencing a
free variable "parser".  This variable will typically be defined in your
lexical environment, but if it isn't, the default LilyPond module
provides the startup parser under this name.  So putting
(let ((parser parser))
before switching environments might be enough to paste over this problem.

-- 
David Kastrup




reply via email to

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