Re: `ly:context-property` and empty alist

2022-07-10 Thread Jean Abou Samra




Le 10/07/2022 à 14:32, Valentin Petzel a écrit :

Hello Werner,

the problem here is not really ly:context-property, but the C-implementation
Context::internal_get_property, which uses SCM_EOL as default value. So
Lilypond’s guile interface cannot know if a NULL is actually set or if the
context property is not set. It would be possible to check before whether the
context in question has this property set. Sadly we do not have a scheme
handle on the here_defined macro, but only on the where defined macro.

Still we can use something like
(eq? (ly:context-property-where-defined context sym) context)
to check if a symbol is defined in a specific context. So we could use something
like:

#(define (context-has-defined? context sym)
(eq? (ly:context-property-where-defined context sym) context))



That differs in semantics from ly:context-property not just with the 
handling of '(). Normally, context properties are inherited. If the 
property is not defined in the context, it is read from its parent, or 
the parent of the parent, etc. How about this instead:


#(define* (context-strict-property context property #:optional (default 
'()))

   (if (null? (ly:context-property-where-defined context property))
   default
   (ly:context-property context property)))

Best,
Jean





Re: `ly:context-property` and empty alist

2022-07-10 Thread Werner LEMBERG

>> I have a use case where I want to say
>>
>> ```
>> \set SYM = #'()
>> ```
>>
>> i.e., I explicitly want to override the default DEF with an empty
>> list.  How can I do that?
>
> As a user, if the code is written that way, you have no proper
> solution.  Yes, that’s a bit sad.  (If the property is an alist,
> though, you can use a dummy alist with a key that is not in the set
> of keys the code looks for, e.g. a string if the alist is supposed
> to map numbers to something.)

Thanks, I came to the same conclusion.

> As a developer, you should not write the code that way.

:-)

> I suspect you
> ask this in the context of your figured bass code, right?

Yes, I will continue the discussion on lilypond-devel.


 Werner


Re: `ly:context-property` and empty alist,Re: `ly:context-property` and empty alist

2022-07-10 Thread Werner LEMBERG


> the problem here is not really ly:context-property, but the
> C-implementation Context::internal_get_property, which uses SCM_EOL
> as default value. [...]

Thanks for the explanation!

> #(define (context-has-defined? context sym)
>(eq? (ly:context-property-where-defined context sym) context))
> 
> #(define* (context-strict-get-property context sym #:optional (def '()))
>(if (context-has-defined? context sym)
>(ly:context-property context sym)
>def))

Good to know that this possibility exists.


Werner



Re: `ly:context-property` and empty alist

2022-07-10 Thread Valentin Petzel
Hello Werner,

the problem here is not really ly:context-property, but the C-implementation 
Context::internal_get_property, which uses SCM_EOL as default value. So 
Lilypond’s guile interface cannot know if a NULL is actually set or if the 
context property is not set. It would be possible to check before whether the 
context in question has this property set. Sadly we do not have a scheme 
handle on the here_defined macro, but only on the where defined macro.

Still we can use something like
(eq? (ly:context-property-where-defined context sym) context)
to check if a symbol is defined in a specific context. So we could use 
something 
like:

#(define (context-has-defined? context sym)
   (eq? (ly:context-property-where-defined context sym) context))

#(define* (context-strict-get-property context sym #:optional (def '()))
   (if (context-has-defined? context sym)
   (ly:context-property context sym)
   def))

Cheers,
Valentin

Am Sonntag, 10. Juli 2022, 13:46:58 CEST schrieb Werner LEMBERG:
> The documentation of `ly:context-property` is as follows.
> 
>   -- Function: ly:context-property context sym def
> 
>  Return the value for property SYM in CONTEXT.  If DEF is given,
>  and property value is ‘'()’, return DEF.
> 
> I have a use case where I want to say
> 
> ```
> \set SYM = #'()
> ```
> 
> i.e., I explicitly want to override the default DEF with an empty
> list.  How can I do that?
> 
> 
> Werner



signature.asc
Description: This is a digitally signed message part.


Re: `ly:context-property` and empty alist

2022-07-10 Thread Jean Abou Samra



> Le 10 juil. 2022 à 13:47, Werner LEMBERG  a écrit :
> 
> 
> The documentation of `ly:context-property` is as follows.
> 
>  -- Function: ly:context-property context sym def
> 
> Return the value for property SYM in CONTEXT.  If DEF is given,
> and property value is ‘'()’, return DEF.
> 
> I have a use case where I want to say
> 
> ```
> \set SYM = #'()
> ```
> 
> i.e., I explicitly want to override the default DEF with an empty
> list.  How can I do that?



As a user, if the code is written that way, you have no proper solution. Yes, 
that’s a bit sad. (If the property is an alist, though, you can use a dummy 
alist with a key that is not in the set of keys the code looks for, e.g. a 
string if the alist is supposed to map numbers to something.)

As a developer, you should not write the code that way. I suspect you ask this 
in the context of your figured bass code, right? You need to put the default in 
the definition of the context in ly/engraver-init.ly so that you don’t need to 
use the third argument of ly:context-property. That also makes the default 
appear in the IR.

Jean