Re: Procedure for set-paper-size in \paper ?

2018-05-19 Thread David Kastrup
Thomas Morley  writes:

> 2018-05-19 9:45 GMT+02:00 David Kastrup :
>> Thomas Morley  writes:
>
> Uh, oh, another typo/oversight.
> Note to self: Don't post anything while being overtired...
>
>>
>> Now if you want to execute only conditionally, you either need to wrap
>> in lambdas or use a macro rather than a procedure:
>>
>> #(define-macro (proc bool x y)
>>(if bool x y))
>>
>> \paper {
>>   #(if #t (set-paper-size "a8" 'landscape) (set-paper-size "a8"))
>> }

Talk about type/oversight: I don't even use the proc macro here.  You
need to write it instead of "if" in the paper block, or the example does
not make a whole lot of sense.

>> Note that this will only work with a _literal_ #f or #t as argument:
>> you'll likely want to have some actual condition evaluated at runtime,
>> like some variable name.  Then you'll need to write
>>
>> #(define-macro (proc bool x y)
>>   `(if ,bool ,x ,y))
>
> Thanks for the insights,

The last bit is a whole lot of quasiquote obviously equivalent to

(list 'if bool x y)

But in the context of macro expansions, using quasiquotes is sort of
customary for emphasizing the structure of what gets returned rather
than how it is getting built.

-- 
David Kastrup

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Procedure for set-paper-size in \paper ?

2018-05-19 Thread Thomas Morley
2018-05-19 9:45 GMT+02:00 David Kastrup :
> Thomas Morley  writes:
>
>> Hi all,
>>
>> (1)
>> consider the following code (working as expected):
>>
>> \paper {
>>   #(if #t (set-paper-size "a8" 'landscape) #(set-paper-size "a8"))
>> }
>>
>> \score { { R1 } \layout { ragged-right = ##f } }
>>
>> Switching from #t to #f results in different paper-size, as desired.
>
> Unlikely as you write #(set-paper-size ...) here, see below.
>
>>
>> (2)
>> But trying to put it in a procedure, it always returns the true-case:
>>
>> #(define (proc bool x y)
>>   (if bool x y))
>>
>> \paper {
>>   #(proc #f (set-paper-size "a8" 'landscape) #(set-paper-size "a8"))
>> }
>
> Uh, the return value is irrelevant.  It always _executes_ the true case.
> It also executes the false case but that is not overly interesting since
> the false case is a vector consisting of the elements 'set-paper-size
> and "a8" since you write #(...) while already in Scheme, the syntax for
> vector literals.

Uh, oh, another typo/oversight.
Note to self: Don't post anything while being overtired...

>
> Now if you want to execute only conditionally, you either need to wrap
> in lambdas or use a macro rather than a procedure:
>
> #(define-macro (proc bool x y)
>(if bool x y))
>
> \paper {
>   #(if #t (set-paper-size "a8" 'landscape) (set-paper-size "a8"))
> }
>
> Note that this will only work with a _literal_ #f or #t as argument:
> you'll likely want to have some actual condition evaluated at runtime,
> like some variable name.  Then you'll need to write
>
> #(define-macro (proc bool x y)
>   `(if ,bool ,x ,y))
>
> --
> David Kastrup

Thanks for the insights,
  Harm

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Procedure for set-paper-size in \paper ?

2018-05-19 Thread David Kastrup
Thomas Morley  writes:

> Hi all,
>
> (1)
> consider the following code (working as expected):
>
> \paper {
>   #(if #t (set-paper-size "a8" 'landscape) #(set-paper-size "a8"))
> }
>
> \score { { R1 } \layout { ragged-right = ##f } }
>
> Switching from #t to #f results in different paper-size, as desired.

Unlikely as you write #(set-paper-size ...) here, see below.

>
> (2)
> But trying to put it in a procedure, it always returns the true-case:
>
> #(define (proc bool x y)
>   (if bool x y))
>
> \paper {
>   #(proc #f (set-paper-size "a8" 'landscape) #(set-paper-size "a8"))
> }

Uh, the return value is irrelevant.  It always _executes_ the true case.
It also executes the false case but that is not overly interesting since
the false case is a vector consisting of the elements 'set-paper-size
and "a8" since you write #(...) while already in Scheme, the syntax for
vector literals.

Now if you want to execute only conditionally, you either need to wrap
in lambdas or use a macro rather than a procedure:

#(define-macro (proc bool x y)
   (if bool x y))

\paper {
  #(if #t (set-paper-size "a8" 'landscape) (set-paper-size "a8"))
}

Note that this will only work with a _literal_ #f or #t as argument:
you'll likely want to have some actual condition evaluated at runtime,
like some variable name.  Then you'll need to write

#(define-macro (proc bool x y)
  `(if ,bool ,x ,y))

-- 
David Kastrup

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Procedure for set-paper-size in \paper ?

2018-05-18 Thread Aaron Hill

On 2018-05-18 16:03, Thomas Morley wrote:

2018-05-19 0:36 GMT+02:00 Aaron Hill :

On 2018-05-18 14:24, Thomas Morley wrote:



#(define (proc bool x y)
  (if bool x y))


Your `proc` function does not have this behavior, as the arguments 
passed in

will be evaluated before you get to the inner `if`.


Hm, then I should reword my request.
Is there a way to circumvent this behaviour?


Yes, you need to use some form of lazy evaluation.  Perhaps the most 
explicit way is to pass in lambdas:



  \version "2.19.81"
  #(define (proc bool x y) ((if bool x y)))
  \paper {
#(proc #t
  (lambda () (set-paper-size "a8" 'landscape))
  (lambda () (set-paper-size "a8")))
  }
  \markup { "Are we landscape or not?" }


NOTE: There is an extra set of parentheses in the `proc` body in order 
to evaluate the selected parameter.


Another less verbose option is to simply quote the arguments and `eval` 
them as needed:



  #(define (proc bool x y)
(eval (if bool x y) (interaction-environment)))
  \paper {
#(proc #t '(set-paper-size "a8" 'landscape) '(set-paper-size "a8"))
  }


NOTE: Unlike before, we *need* the extra quote for `landscape` in this 
case, so there is a potential gotcha.


-- Aaron Hill

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Procedure for set-paper-size in \paper ?

2018-05-18 Thread Thomas Morley
2018-05-19 0:36 GMT+02:00 Aaron Hill :
> On 2018-05-18 14:24, Thomas Morley wrote:

>> #(define (proc bool x y)
>>   (if bool x y))

> Your `proc` function does not have this behavior, as the arguments passed in
> will be evaluated before you get to the inner `if`.

Hm, then I should reword my request.
Is there a way to circumvent this behaviour?

I'm finally aiming at a function selecting from different set-whatever!

> Now, `set-paper-size`
> has a side-effect, so the evaluation of that function alone is enough to
> have an impact.  Technically, the function should be named
> `set-paper-size!`, as the convention is to suffix an exclamation to indicate
> such functions.
>
> So, calling `proc` with the two functions results in both being evaluated,
> which is not what you want.

Ok, then another example for this would be:

#(define (proc bool x y)
  (if bool x y))

#(define lst #f)

#(proc #f (set! lst '(1 2)) (set! lst '(3 4)))

#(write lst)

always returns:
'(3 4)

>
> Your `apply` approach is closer to what you want, since you are using `proc`
> as a means of selecting the arguments you want and calling `set-paper-size`
> only once.  This should work, except you have an extra quote.
>
> 
>   #(apply set-paper-size (proc #t '("a8" landscape) '("a8")))
> 
>
> The outer quote for invoking the list shorthand already results in
> `landscape` being a symbol.  The extra quote would put another layer of
> indirection, which `set-paper-size` does not expect.

Ok, it's an overside then.
Thanks for spotting it.

>
> Hope this helps,
>
> -- Aaron Hill

It helped a lot.

Many thanks,
  Harm

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Re: Procedure for set-paper-size in \paper ?

2018-05-18 Thread Aaron Hill

On 2018-05-18 14:24, Thomas Morley wrote:

Hi all,

(1)
consider the following code (working as expected):

\paper {
  #(if #t (set-paper-size "a8" 'landscape) #(set-paper-size "a8"))
}

\score { { R1 } \layout { ragged-right = ##f } }

Switching from #t to #f results in different paper-size, as desired.

(2)
But trying to put it in a procedure, it always returns the true-case:

#(define (proc bool x y)
  (if bool x y))

\paper {
  #(proc #f (set-paper-size "a8" 'landscape) #(set-paper-size "a8"))
}

\score { { R1 } \layout { ragged-right = ##f } }

Paper-size is always a8-landscape.

(3)
Trying:
#(define (proc bool x y)
  (if bool x y))

\paper {
  #(apply set-paper-size (proc #t '("a8" 'landscape) '("a8")))
}

\score { { R1 } \layout { ragged-right = ##f } }

Paper-size is always a8

-

What's happening here and why?
And how to make a procedure accepting set-paper-size work, with
different settings and an if-condition?


My Scheme is a little rusty over the years, but I will try to explain 
what is going on.


Firstly, `if` has a rule that it only evaluates either the true-value or 
false-value based on the Boolean.  That means exactly one of the two 
expressions will evaluate.


Your `proc` function does not have this behavior, as the arguments 
passed in will be evaluated before you get to the inner `if`.  Now, 
`set-paper-size` has a side-effect, so the evaluation of that function 
alone is enough to have an impact.  Technically, the function should be 
named `set-paper-size!`, as the convention is to suffix an exclamation 
to indicate such functions.


So, calling `proc` with the two functions results in both being 
evaluated, which is not what you want.


Your `apply` approach is closer to what you want, since you are using 
`proc` as a means of selecting the arguments you want and calling 
`set-paper-size` only once.  This should work, except you have an extra 
quote.



  #(apply set-paper-size (proc #t '("a8" landscape) '("a8")))


The outer quote for invoking the list shorthand already results in 
`landscape` being a symbol.  The extra quote would put another layer of 
indirection, which `set-paper-size` does not expect.


Hope this helps,

-- Aaron Hill

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


Procedure for set-paper-size in \paper ?

2018-05-18 Thread Thomas Morley
Hi all,

(1)
consider the following code (working as expected):

\paper {
  #(if #t (set-paper-size "a8" 'landscape) #(set-paper-size "a8"))
}

\score { { R1 } \layout { ragged-right = ##f } }

Switching from #t to #f results in different paper-size, as desired.

(2)
But trying to put it in a procedure, it always returns the true-case:

#(define (proc bool x y)
  (if bool x y))

\paper {
  #(proc #f (set-paper-size "a8" 'landscape) #(set-paper-size "a8"))
}

\score { { R1 } \layout { ragged-right = ##f } }

Paper-size is always a8-landscape.

(3)
Trying:
#(define (proc bool x y)
  (if bool x y))

\paper {
  #(apply set-paper-size (proc #t '("a8" 'landscape) '("a8")))
}

\score { { R1 } \layout { ragged-right = ##f } }

Paper-size is always a8

-

What's happening here and why?
And how to make a procedure accepting set-paper-size work, with
different settings and an if-condition?

Cheers,
  Harm

___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user