Re: pure simple-closures

2006-10-28 Thread Han-Wen Nienhuys

Joe Neeman escreveu:

On Sat, 2006-10-21 at 17:29 +0200, Han-Wen Nienhuys wrote:

Joe Neeman schreef:

On Sat, 2006-10-21 at 12:15 +0200, Han-Wen Nienhuys wrote:

Joe Neeman schreef:


Mostly because at the time that I wrote it, I couldn't figure out how to
handle arbitrary length argument lists in scheme (the only way I
currently know is to build the list of arguments, cons in the function

I think you're looking for the apply function,

   (apply func arg-list)

Ah yes, that's much better. So did you want me to put call_pure_function
in scheme?
yes, I think so. The most important thing is that subsystems should not 
cross the C++/Scheme divide all too often. Since most of the func->pure 
  -func code is in Scheme, I think it's best we keep improvements there.


How's this one? I also changed from using SCM_UNDEFINED to
SCM_UNSPECIFIED so I could restore grob-closure.cc and added
pure-outside-slur-callback.


can you also update the issue (119, I think)?

--

Han-Wen Nienhuys - [EMAIL PROTECTED] - http://www.xs4all.nl/~hanwen

LilyPond Software Design
 -- Code for Music Notation
http://www.lilypond-design.com



___
lilypond-devel mailing list
lilypond-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/lilypond-devel


Re: pure simple-closures

2006-10-22 Thread Han-Wen Nienhuys

Joe Neeman escreveu:

On Sat, 2006-10-21 at 17:29 +0200, Han-Wen Nienhuys wrote:

Joe Neeman schreef:

On Sat, 2006-10-21 at 12:15 +0200, Han-Wen Nienhuys wrote:

Joe Neeman schreef:


Mostly because at the time that I wrote it, I couldn't figure out how to
handle arbitrary length argument lists in scheme (the only way I
currently know is to build the list of arguments, cons in the function

I think you're looking for the apply function,

   (apply func arg-list)

Ah yes, that's much better. So did you want me to put call_pure_function
in scheme?
yes, I think so. The most important thing is that subsystems should not 
cross the C++/Scheme divide all too often. Since most of the func->pure 
  -func code is in Scheme, I think it's best we keep improvements there.


How's this one? I also changed from using SCM_UNDEFINED to
SCM_UNSPECIFIED so I could restore grob-closure.cc and added
pure-outside-slur-callback.



Looks good please apply if output-distance agrees.

--

Han-Wen Nienhuys - [EMAIL PROTECTED] - http://www.xs4all.nl/~hanwen

LilyPond Software Design
 -- Code for Music Notation
http://www.lilypond-design.com



___
lilypond-devel mailing list
lilypond-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/lilypond-devel


Re: pure simple-closures

2006-10-22 Thread Han-Wen Nienhuys

Joe Neeman escreveu:

On Sat, 2006-10-21 at 17:29 +0200, Han-Wen Nienhuys wrote:

Joe Neeman schreef:

On Sat, 2006-10-21 at 12:15 +0200, Han-Wen Nienhuys wrote:

Joe Neeman schreef:


Mostly because at the time that I wrote it, I couldn't figure out how to
handle arbitrary length argument lists in scheme (the only way I
currently know is to build the list of arguments, cons in the function

I think you're looking for the apply function,

   (apply func arg-list)

Ah yes, that's much better. So did you want me to put call_pure_function
in scheme?
yes, I think so. The most important thing is that subsystems should not 
cross the C++/Scheme divide all too often. Since most of the func->pure 
  -func code is in Scheme, I think it's best we keep improvements there.


How's this one? I also changed from using SCM_UNDEFINED to
SCM_UNSPECIFIED so I could restore grob-closure.cc and added
pure-outside-slur-callback.


as a completely unrelated remark: I just realized that simple-closure is 
probably an incorrect name. How about simple-curry?


--

Han-Wen Nienhuys - [EMAIL PROTECTED] - http://www.xs4all.nl/~hanwen

LilyPond Software Design
 -- Code for Music Notation
http://www.lilypond-design.com



___
lilypond-devel mailing list
lilypond-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/lilypond-devel


Re: pure simple-closures

2006-10-22 Thread Joe Neeman
On Sat, 2006-10-21 at 17:29 +0200, Han-Wen Nienhuys wrote:
> Joe Neeman schreef:
> > On Sat, 2006-10-21 at 12:15 +0200, Han-Wen Nienhuys wrote:
> >> Joe Neeman schreef:
> >>
> >>> Mostly because at the time that I wrote it, I couldn't figure out how to
> >>> handle arbitrary length argument lists in scheme (the only way I
> >>> currently know is to build the list of arguments, cons in the function
> >> I think you're looking for the apply function,
> >>
> >>(apply func arg-list)
> > 
> > Ah yes, that's much better. So did you want me to put call_pure_function
> > in scheme?
> 
> yes, I think so. The most important thing is that subsystems should not 
> cross the C++/Scheme divide all too often. Since most of the func->pure 
>   -func code is in Scheme, I think it's best we keep improvements there.

How's this one? I also changed from using SCM_UNDEFINED to
SCM_UNSPECIFIED so I could restore grob-closure.cc and added
pure-outside-slur-callback.
Index: lily/grob-closure.cc
===
RCS file: /sources/lilypond/lilypond/lily/grob-closure.cc,v
retrieving revision 1.6
diff -u -r1.6 grob-closure.cc
--- lily/grob-closure.cc	3 Oct 2006 12:00:18 -	1.6
+++ lily/grob-closure.cc	22 Oct 2006 07:37:33 -
@@ -80,7 +80,7 @@
   Data may be nonnumber. In that case, it is assumed to be
   undefined.
 */
-
+
 data = SCM_UNDEFINED;
 
   SCM expr = scm_list_2 (proc, data);
Index: lily/grob-property.cc
===
RCS file: /sources/lilypond/lilypond/lily/grob-property.cc,v
retrieving revision 1.55
diff -u -r1.55 grob-property.cc
--- lily/grob-property.cc	23 Sep 2006 22:51:56 -	1.55
+++ lily/grob-property.cc	22 Oct 2006 07:37:33 -
@@ -171,7 +171,8 @@
   else if (is_simple_closure (proc))
 {
   value = evaluate_with_simple_closure (self_scm (),
-	simple_closure_expression (proc));
+	simple_closure_expression (proc),
+	false, 0, 0);
 }
 #ifndef NDEBUG
   if (debug_property_callbacks)
@@ -229,9 +230,17 @@
   return scm_is_pair (immutable_property_alist_);
 }
 
-
 bool
 Grob::internal_has_interface (SCM k)
 {
   return scm_c_memq (k, interfaces_) != SCM_BOOL_F;
 }
+
+SCM
+call_pure_function (SCM unpure, SCM args, int start, int end)
+{
+  SCM scm_call_pure_function = ly_lily_module_constant ("call-pure-function");
+
+  return scm_apply_0 (scm_call_pure_function,
+		  scm_list_4 (unpure, args, scm_from_int (start), scm_from_int (end)));
+}
Index: lily/grob.cc
===
RCS file: /sources/lilypond/lilypond/lily/grob.cc,v
retrieving revision 1.179
diff -u -r1.179 grob.cc
--- lily/grob.cc	10 Oct 2006 08:32:59 -	1.179
+++ lily/grob.cc	22 Oct 2006 07:37:34 -
@@ -287,17 +287,19 @@
   if (refp == this)
 return 0.0;
 
-  SCM pure_off = ly_lily_module_constant ("pure-Y-offset");
   Real off = 0;
 
   if (dim_cache_[Y_AXIS].offset_)
 off = *dim_cache_[Y_AXIS].offset_;
-  else if (ly_is_procedure (pure_off))
+  else
 {
+  SCM proc = get_property_data (ly_symbol2scm ("Y-offset"));
+
   dim_cache_[Y_AXIS].offset_ = new Real (0.0);
-  off = scm_to_double (scm_apply_3 (pure_off, self_scm (),
-	scm_from_int (start), scm_from_int (end),
-	SCM_EOL));
+  off = robust_scm2double (call_pure_function (proc,
+		   scm_list_1 (self_scm ()),
+		   start, end),
+			   0.0);
   delete dim_cache_[Y_AXIS].offset_;
   dim_cache_[Y_AXIS].offset_ = 0;
 }
@@ -404,6 +406,7 @@
   SCM min_ext = internal_get_property (min_ext_sym);
   if (is_number_pair (min_ext))
 	real_ext.unite (ly_scm2interval (min_ext));
+
   ((Grob*)this)->dim_cache_[a].extent_ = new Interval (real_ext);  
 }
   
@@ -415,13 +418,11 @@
 Interval
 Grob::pure_height (Grob *refp, int start, int end)
 {
-  SCM pure_height = ly_lily_module_constant ("pure-Y-extent");
-  Interval iv (0, 0);
-
-  if (ly_is_procedure (pure_height))
-iv = ly_scm2interval (scm_apply_3 (pure_height, self_scm (),
-   scm_from_int (start), scm_from_int (end),
-   SCM_EOL));
+  SCM proc = get_property_data ( ly_symbol2scm ("Y-extent"));
+  Interval iv = robust_scm2interval (call_pure_function (proc,
+			 scm_list_1 (self_scm ()),
+			 start, end),
+ Interval (0, 0));
   Real offset = pure_relative_y_coordinate (refp, start, end);
 
   SCM min_ext = get_property ("minimum-Y-extent");
Index: lily/side-position-interface.cc
===
RCS file: /sources/lilypond/lilypond/lily/side-position-interface.cc,v
retrieving revision 1.126
diff -u -r1.126 side-position-interface.cc
--- lily/side-position-interface.cc	3 Oct 2006 12:00:18 -	1.126
+++ lily/side-position-interface.cc	22 Oct 2006 07:37:34 -
@@ -190,11 +190,14 @@
   return axis_aligned_side_helper (smob, Y_AXIS, false, 0, 0, current_off);
 }
 
-MAKE_SCH

Re: pure simple-closures

2006-10-21 Thread Han-Wen Nienhuys

Joe Neeman schreef:

On Sat, 2006-10-21 at 12:15 +0200, Han-Wen Nienhuys wrote:

Joe Neeman schreef:


Mostly because at the time that I wrote it, I couldn't figure out how to
handle arbitrary length argument lists in scheme (the only way I
currently know is to build the list of arguments, cons in the function

I think you're looking for the apply function,

   (apply func arg-list)


Ah yes, that's much better. So did you want me to put call_pure_function
in scheme?


yes, I think so. The most important thing is that subsystems should not 
cross the C++/Scheme divide all too often. Since most of the func->pure 
 -func code is in Scheme, I think it's best we keep improvements there.



--

Han-Wen Nienhuys - [EMAIL PROTECTED] - http://www.xs4all.nl/~hanwen

LilyPond Software Design
 -- Code for Music Notation
http://www.lilypond-design.com



___
lilypond-devel mailing list
lilypond-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/lilypond-devel


Re: pure simple-closures

2006-10-21 Thread Joe Neeman
On Sat, 2006-10-21 at 12:15 +0200, Han-Wen Nienhuys wrote:
> Joe Neeman schreef:
> 
> > 
> > Mostly because at the time that I wrote it, I couldn't figure out how to
> > handle arbitrary length argument lists in scheme (the only way I
> > currently know is to build the list of arguments, cons in the function
> 
> I think you're looking for the apply function,
> 
>(apply func arg-list)

Ah yes, that's much better. So did you want me to put call_pure_function
in scheme?




___
lilypond-devel mailing list
lilypond-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/lilypond-devel


Re: pure simple-closures

2006-10-21 Thread Han-Wen Nienhuys

Joe Neeman schreef:



Mostly because at the time that I wrote it, I couldn't figure out how to
handle arbitrary length argument lists in scheme (the only way I
currently know is to build the list of arguments, cons in the function


I think you're looking for the apply function,

  (apply func arg-list)


2) adopt the convention that if any argument in a simple-closure is
UNDEFINED, the entire closure is UNDEFINED. This allows us to abort the
evaluation of a pure closure when there is an unpure function with no
pure equivalent. This requires changing the SCM_UNDEFINED in
grob-closure.cc to scm_from_int(0).

Isn't there another value you could use for that?

SCM_UNDEFINED is also used for callbacks with optional arguments (grep 
for OPTARGS).


It seems that in every OPTARGS callback, the optional argument defaults
to zero. The only difference in changing grob-closure.cc is that
outside_slur_callback will now return zero instead of SCM_UNDEFINED in a
few cases. But then Grob::get_offset will interpret the SCM_UNDEFINED as
zero anyway.

>

In the context of [XY]-offset, a non-procedure, non-number value is
interpreted as zero. So I don't think there is any confusion in
interpreting them as zero in chain_offset_callback.


OK; Just make sure that we can still chain procedures with non-number 
return values.


--

Han-Wen Nienhuys - [EMAIL PROTECTED] - http://www.xs4all.nl/~hanwen

LilyPond Software Design
 -- Code for Music Notation
http://www.lilypond-design.com



___
lilypond-devel mailing list
lilypond-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/lilypond-devel


Re: pure simple-closures

2006-10-20 Thread Joe Neeman
On Sat, 2006-10-21 at 00:02 +0200, Han-Wen Nienhuys wrote:
> Joe Neeman schreef:
> > Here is an attempt at making simple-closures pure-evaluatable. A
> > summary:
> > 
> > 1) move the conversion of non-pure-to-pure callbacks into C++ where it
> > is a bit easier to access and generalise it to support functions other
> > than just grob callbacks. The convention is that if a non-pure function
> 
> I'm not sure about this ; why not in Scheme?  (In general, we've had a 
> movement of stuff out of C++, not back to C++).

Mostly because at the time that I wrote it, I couldn't figure out how to
handle arbitrary length argument lists in scheme (the only way I
currently know is to build the list of arguments, cons in the function
and primitive-eval). On the other hand, guile's C API handles it easily.
Another advantage is that the function is a bit easier to call from C++
(and it is designed to be called entirely from C++). But I can rewrite
it in scheme if you prefer.

> 
> > takes (arg1 arg2 arg3) as arguments then the pure version will take
> > (arg1 start end arg2 arg3) as arguments. This order is so that we can
> > have arg3, for example, as an optional argument.
> 
> 
> > 2) adopt the convention that if any argument in a simple-closure is
> > UNDEFINED, the entire closure is UNDEFINED. This allows us to abort the
> > evaluation of a pure closure when there is an unpure function with no
> > pure equivalent. This requires changing the SCM_UNDEFINED in
> > grob-closure.cc to scm_from_int(0).
> 
> Isn't there another value you could use for that?
> 
> SCM_UNDEFINED is also used for callbacks with optional arguments (grep 
> for OPTARGS).

It seems that in every OPTARGS callback, the optional argument defaults
to zero. The only difference in changing grob-closure.cc is that
outside_slur_callback will now return zero instead of SCM_UNDEFINED in a
few cases. But then Grob::get_offset will interpret the SCM_UNDEFINED as
zero anyway.

In the context of [XY]-offset, a non-procedure, non-number value is
interpreted as zero. So I don't think there is any confusion in
interpreting them as zero in chain_offset_callback.



___
lilypond-devel mailing list
lilypond-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/lilypond-devel


Re: pure simple-closures

2006-10-20 Thread Han-Wen Nienhuys

Joe Neeman schreef:

Here is an attempt at making simple-closures pure-evaluatable. A
summary:

1) move the conversion of non-pure-to-pure callbacks into C++ where it
is a bit easier to access and generalise it to support functions other
than just grob callbacks. The convention is that if a non-pure function


I'm not sure about this ; why not in Scheme?  (In general, we've had a 
movement of stuff out of C++, not back to C++).



takes (arg1 arg2 arg3) as arguments then the pure version will take
(arg1 start end arg2 arg3) as arguments. This order is so that we can
have arg3, for example, as an optional argument.




2) adopt the convention that if any argument in a simple-closure is
UNDEFINED, the entire closure is UNDEFINED. This allows us to abort the
evaluation of a pure closure when there is an unpure function with no
pure equivalent. This requires changing the SCM_UNDEFINED in
grob-closure.cc to scm_from_int(0).


Isn't there another value you could use for that?

SCM_UNDEFINED is also used for callbacks with optional arguments (grep 
for OPTARGS).



I haven't actually written any new pure functions yet, so the impact is
fairly small. I'll try to do a pure_avoid_slur_callback before 2.10. I
should point out, though, that the main problem in issue #113 has been
mitigated somewhat by the fact that TextScripts usually use normal
procedures now for Y-offset.





--

Han-Wen Nienhuys - [EMAIL PROTECTED] - http://www.xs4all.nl/~hanwen

LilyPond Software Design
 -- Code for Music Notation
http://www.lilypond-design.com



___
lilypond-devel mailing list
lilypond-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/lilypond-devel


pure simple-closures

2006-10-20 Thread Joe Neeman
Here is an attempt at making simple-closures pure-evaluatable. A
summary:

1) move the conversion of non-pure-to-pure callbacks into C++ where it
is a bit easier to access and generalise it to support functions other
than just grob callbacks. The convention is that if a non-pure function
takes (arg1 arg2 arg3) as arguments then the pure version will take
(arg1 start end arg2 arg3) as arguments. This order is so that we can
have arg3, for example, as an optional argument.

2) adopt the convention that if any argument in a simple-closure is
UNDEFINED, the entire closure is UNDEFINED. This allows us to abort the
evaluation of a pure closure when there is an unpure function with no
pure equivalent. This requires changing the SCM_UNDEFINED in
grob-closure.cc to scm_from_int(0).

I haven't actually written any new pure functions yet, so the impact is
fairly small. I'll try to do a pure_avoid_slur_callback before 2.10. I
should point out, though, that the main problem in issue #113 has been
mitigated somewhat by the fact that TextScripts usually use normal
procedures now for Y-offset.
Thu Oct 19 14:32:16 IST 2006  Joe Neeman <[EMAIL PROTECTED]>
  * Refactor the conversion into pure functions.
diff -rN -u old-lilypond/lily/grob.cc new-lilypond/lily/grob.cc
--- old-lilypond/lily/grob.cc	2006-10-20 18:34:18.0 +0200
+++ new-lilypond/lily/grob.cc	2006-10-20 18:34:18.0 +0200
@@ -287,17 +287,19 @@
   if (refp == this)
 return 0.0;
 
-  SCM pure_off = ly_lily_module_constant ("pure-Y-offset");
   Real off = 0;
 
   if (dim_cache_[Y_AXIS].offset_)
 off = *dim_cache_[Y_AXIS].offset_;
-  else if (ly_is_procedure (pure_off))
+  else
 {
+  SCM proc = get_property_data (ly_symbol2scm ("Y-offset"));
+
   dim_cache_[Y_AXIS].offset_ = new Real (0.0);
-  off = scm_to_double (scm_apply_3 (pure_off, self_scm (),
-	scm_from_int (start), scm_from_int (end),
-	SCM_EOL));
+  off = robust_scm2double (call_pure_function (proc,
+		   scm_list_1 (self_scm ()),
+		   start, end),
+			   0.0);
   delete dim_cache_[Y_AXIS].offset_;
   dim_cache_[Y_AXIS].offset_ = 0;
 }
@@ -415,13 +417,11 @@
 Interval
 Grob::pure_height (Grob *refp, int start, int end)
 {
-  SCM pure_height = ly_lily_module_constant ("pure-Y-extent");
-  Interval iv (0, 0);
-
-  if (ly_is_procedure (pure_height))
-iv = ly_scm2interval (scm_apply_3 (pure_height, self_scm (),
-   scm_from_int (start), scm_from_int (end),
-   SCM_EOL));
+  SCM proc = get_property_data ( ly_symbol2scm ("Y-extent"));
+  Interval iv = robust_scm2interval (call_pure_function (proc,
+			 scm_list_1 (self_scm ()),
+			 start, end),
+ Interval (0, 0));
   Real offset = pure_relative_y_coordinate (refp, start, end);
 
   SCM min_ext = get_property ("minimum-Y-extent");
diff -rN -u old-lilypond/lily/include/lily-guile.hh new-lilypond/lily/include/lily-guile.hh
--- old-lilypond/lily/include/lily-guile.hh	2006-10-20 18:34:18.0 +0200
+++ new-lilypond/lily/include/lily-guile.hh	2006-10-20 18:34:18.0 +0200
@@ -181,5 +181,6 @@
 inline SCM ly_cdr (SCM x) { return SCM_CDR (x); }
 inline bool ly_is_pair (SCM x) { return SCM_I_CONSP (x); }
 
+SCM call_pure_function (SCM unpure, SCM args, int start, int end);
 
 #endif /* LILY_GUILE_HH */
diff -rN -u old-lilypond/lily/lily-guile.cc new-lilypond/lily/lily-guile.cc
--- old-lilypond/lily/lily-guile.cc	2006-10-20 18:34:18.0 +0200
+++ new-lilypond/lily/lily-guile.cc	2006-10-20 18:34:18.0 +0200
@@ -746,3 +746,29 @@
   return cxx_id;
 }
 
+SCM
+call_pure_function (SCM unpure, SCM args, int start, int end)
+{
+  static SCM pures = 0;
+  static SCM conversions = 0;
+  if (!pures)
+{
+  pures = ly_lily_module_constant ("pure-functions");
+  conversions = ly_lily_module_constant ("pure-conversions-alist");
+}
+
+  if (!ly_is_procedure (unpure))
+return unpure;
+
+  if (scm_memq (unpure, pures) != SCM_BOOL_F)
+return scm_apply_0 (unpure, args);
+
+  SCM pure = scm_assq (unpure, conversions);
+  if (pure != SCM_BOOL_F)
+{
+  SCM newargs = scm_append (scm_list_2 (args, scm_list_2 (scm_from_int (start),
+			  scm_from_int (end;
+  return scm_apply_0 (scm_cdr (pure), newargs);
+}
+  return SCM_UNDEFINED;
+}
diff -rN -u old-lilypond/ly/paper-defaults.ly new-lilypond/ly/paper-defaults.ly
--- old-lilypond/ly/paper-defaults.ly	2006-10-20 18:34:18.0 +0200
+++ new-lilypond/ly/paper-defaults.ly	2006-10-20 18:34:18.0 +0200
@@ -80,7 +80,7 @@
 %% settings for the page breaker
 %%
 blank-last-page-force = 0
-blank-page-force = 10
+blank-page-force = 2
 
 #(define font-defaults
   '((font-encoding . fetaMusic)))
diff -rN -u old-lilypond/scm/define-grobs.scm new-lilypond/scm/define-grobs.scm
--- old-lilypond/scm/define-grobs.scm	2006-10-20 18:34:18.0 +0200
+++ new-lilypond/scm/define-grobs.scm	2006-10-20 18:34:18.0 +0200
@@ -2031,72 +2031,45 @@