Re: Minimal example of extending Guile with Rust?

2024-01-29 Thread Jean Abou Samra

There are a number of crates with Rust bindings to the Guile C API: 
https://lib.rs/search?q=guile

Most of them are just the result of running the bindgen tool, which 
autogenerates Rust bindings from C header files. A few of them have slightly 
more convenient wrapper but none is really well-developed AFAICS.

Honestly, I think the easiest at this time is to do the interfacing with Guile 
from C. Create a Rust module which exports a function through C FFI, and 
convert between C and Guile types in C. Alternatively, use the Guile FFI 
facilities for the conversion. It is probably simpler than doing these 
conversions in Rust. It is, in any case, safer, because I'm quite sure that the 
Rust compiler will be happy to do optimizations that defeat conservative GC, by 
hiding pointers in local variables (which Rust can more easily do, thanks to 
its aliasing guarantees).

Be careful with calling Guile code from Rust code. This is fraught, because 
Guile code can raise exceptions, which are basically propagated through 
longjmp, and it is UB in Rust to unwind through Rust code with longjmp. 
Basically, if you call Guile from Rust then it must be wrapped in exception 
handling. An exception must not propagate through Rust stack frames. call/cc 
would be a problem too, so you likely want to use with-continuation-barrier.



Re: [PATCH] Fixes for custom-ports

2023-11-28 Thread Jean Abou Samra
Le mercredi 29 novembre 2023 à 07:47 +0100, Jonas Hahnfeld a écrit :
> Sure: It makes sure that the extension is loaded also when not having a
> compiled custom-ports.go. For reference, see the documentation at
> https://www.gnu.org/software/guile/manual/html_node/Eval-When.html -
> the previously specified (load) only acts when loading a compiled
> module. During my tests, when chasing an incompatibility with the
> compiled bytecode, I was experimenting with just deleting some bytecode
> files. In that case, Guile should transparently fall back to evaluating
> the code. Which it did, only that the extension wasn't loaded and it
> complained loudly about unavailable symbols. So the solution is to at
> least specify (eval) for non-compiled code, but then the documentation
> mentions: "When in doubt, use the three conditions (expand load eval),
> as in the example above. Other uses of eval-when may void your warranty
> or poison your cat." This also matches all other uses of eval-when in
> the Guile source code itself. Let me know if I should try to improve
> the patch message.


I was under the impression that all code in Guile itself was assumed
to always be byte-compiled (because of issues like the fact that trying
to evaluate the evaluator would make you chase your own tail).

If it's more consistent with other eval-when uses in Guile, that's
enough reason to apply it, though.



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


Re: [PATCH] Fixes for custom-ports

2023-11-28 Thread Jean Abou Samra
Le dimanche 29 octobre 2023 à 10:51 +0100, Jonas Hahnfeld via Developers list
for Guile, the GNU extensibility library a écrit :
> while playing with current Guile main on Windows, I found some problems
> in the implementation of custom-ports that was recently committed.
> Please consider the attached patches.


Not a Guile maintainer obviously, but: could you explain what the first patch is
for? It's not going to hurt, but I don't see what problem it fixes.

Second patch looks like a no-brainer that any committer passing by could
apply...

Jean





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


[PATCH] Pedantic corrections in macro docs

2023-07-07 Thread Jean Abou Samra
As it turns out, syntax-rules have more power than one might think.



From d026b3f2364754b559acf9ad8ec7129eddfb51c7 Mon Sep 17 00:00:00 2001
From: Jean Abou Samra 
Date: Fri, 7 Jul 2023 16:40:06 +0200
Subject: [PATCH] Pedantic corrections in macro docs

---
 doc/ref/api-macros.texi | 28 ++--
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/doc/ref/api-macros.texi b/doc/ref/api-macros.texi
index a353719cb..d0ba892f0 100644
--- a/doc/ref/api-macros.texi
+++ b/doc/ref/api-macros.texi
@@ -435,13 +435,18 @@ For a formal definition of @code{syntax-rules} and its
pattern language, see
 @xref{Macros, , Macros, r5rs, Revised(5) Report on the Algorithmic Language
 Scheme}.
 
-@code{syntax-rules} macros are simple and clean, but do they have limitations.
-They do not lend themselves to expressive error messages: patterns either match
-or they don't. Their ability to generate code is limited to template-driven
-expansion; often one needs to define a number of helper macros to get real work
-done. Sometimes one wants to introduce a binding into the lexical context of
the
-generated code; this is impossible with @code{syntax-rules}. Relatedly, they
-cannot programmatically generate identifiers.
+@code{syntax-rules} macros are simple and clean, but do they have
+limitations.  They do not lend themselves to expressive error messages:
+patterns either match or they don't. Their ability to generate code is
+limited to template-driven expansion; often one needs to define a number
+of helper macros to get real work done. Sometimes one wants to introduce
+a binding into the lexical context of the generated code; this is very
+difficult with @code{syntax-rules}@footnote{It is in fact surprising
+that this is possible at all. See Oleg Kiselyov paper
+@uref{https://okmij.org/ftp/Scheme/macros.html#dirty-macros,How to Write
+Seemingly Unhygienic and Referentially Opaque Macros with
+Syntax-rules}. Relatedly, they cannot programmatically generate
+identifiers.
 
 The solution to all of these problems is to use @code{syntax-case} if you need
 its features. But if for some reason you're stuck with @code{syntax-rules}, you
@@ -581,9 +586,12 @@ verbose, which is true. But there is a difference:
@code{syntax-case} creates
 @emph{procedural} macros, giving the full power of Scheme to the macro
expander.
 This has many practical applications.
 
-A common desire is to be able to match a form only if it is an identifier. This
-is impossible with @code{syntax-rules}, given the datum matching forms. But
with
-@code{syntax-case} it is easy:
+A common desire is to be able to match a form only if it is an
+identifier. This is difficult with @code{syntax-rules}, given the datum
+matching forms@footnote{See
+@uref{https://okmij.org/ftp/Scheme/macros.html#macro-symbol-p, How to
+write @code{symbol?} with syntax-rules} on Oleg Kiselyov's
+website.}. But with @code{syntax-case} it is easy:
 
 @deffn {Scheme Procedure} identifier? syntax-object
 Returns @code{#t} if @var{syntax-object} is an identifier, or @code{#f}
-- 
2.40.1




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


Re: [PATCH] Add atomic-box-update! function to (ice-9 atomic)

2023-06-21 Thread Jean Abou Samra



> Le 21 juin 2023 à 18:46, Andrew Tropin  a écrit :
> 
> Make sense, but it's hard for me to say something valuable on this
> topic.  Usually, I don't use eq? and don't have enough knowledge of its
> internals.


*Currently*, it just checks whether the two C-level SCM values are the same 
bitwise, so even implicit copies of fixnums will remain eq?. In theory, Guile 
could make copies of bignums. I am not aware of it doing so.

However, all that is guaranteed is that (eq? a a) when a is a non-immediate 
(pair, string, vector, hashtable, etc) or one of a few constants like booleans, 
the empty list and *unspecified*. Notably, it isn't guaranteed for numbers or 
characters.


> I went the way suggested by the manual: "Returns the
> previous value of the box in either case, so you can know if the swap
> worked by checking if the return value is eq? to expected."
> 
> https://www.gnu.org/software/guile/manual/html_node/Atomics.html


As long as you use boxes for values for which eq? is well-defined, that is 
fine. I guess this would cover most cases, although I'm not familiar with this 
module.

But in general, eqv? seems saner.



Re: [PATCH] Add atomic-box-update! function to (ice-9 atomic)

2023-06-21 Thread Jean Abou Samra
Le mercredi 21 juin 2023 à 11:06 +0200, Jean Abou Samra a écrit :
> Le lundi 19 juin 2023 à 16:20 +0400, Andrew Tropin a écrit :
> > +  (if (eq? old-value (atomic-box-compare-and-swap! box old-value 
> > new-value))
> 
> 
> Are you sure eq? is a good idea here? (eq? 5 5) is unspecified, for example. 
> Perhaps eqv? would be more appropriate.

(P.S. And according to the manual, even (let ((a 5)) (eq? a a)) is unspecified.)


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


Re: [PATCH] Add atomic-box-update! function to (ice-9 atomic)

2023-06-21 Thread Jean Abou Samra
Le lundi 19 juin 2023 à 16:20 +0400, Andrew Tropin a écrit :
> +  (if (eq? old-value (atomic-box-compare-and-swap! box old-value 
> new-value))


Are you sure eq? is a good idea here? (eq? 5 5) is unspecified, for example. 
Perhaps eqv? would be more appropriate.


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


Re: [RFC,PATCH] Do not GC_INIT the Boehm GC if already initialized

2023-02-06 Thread Jean Abou Samra
On 06/02/2023 19:34, Jose E. Marchesi wrote:
> 
> Hello Guile hackers.
> 
> We are in the process of integrating GNU poke[1] in GDB by mean of
> libpoke.
> 
> Problem is, libpoke uses the Boehm GC, as guile does.  We are working on
> switching to an ad-hoc exact collector, but it will get some time.
> 
> So, in the interim, we may:
> 
> 1) Make both libguile and libpoke to do GC_INIT conditionally, only if
>no one else has initialized the collector before.  This is already in
>poke master.  A suggested (untested!) patch for guile below.
> 
> 2) Test to see if the collector works properly.
> 
> 3) Do bug-fix releases of both libguile and libpoke so the GDB people
>can check for the right version in configure.ac in order to allow
>configuring GDB with both libpoke and libguile support.
> 
> Does this sound like a plan?
> Thanks in advance!
> 
> [1] https://jemarch.net/poke
> 
> diff --git a/libguile/gc.c b/libguile/gc.c
> index 7717e9bef..36653d373 100644
> --- a/libguile/gc.c
> +++ b/libguile/gc.c
> @@ -462,7 +462,8 @@ scm_storage_prehistory ()
>setenv ("GC_MARKERS", "1", 1);
>  #endif
>  
> -  GC_INIT ();
> +  if(!GC_is_init_called ())
> +GC_INIT ();
>  
>size_t heap_size = GC_get_heap_size ();
>if (heap_size < DEFAULT_INITIAL_HEAP_SIZE)
> 



Isn't that going to cause problems if the configurations clash?
For example, the scm_storage_prehistory () function that you
are modifying does

GC_set_all_interior_pointers (0);

If the application that previously initialized the GC relies
on interior pointer tracing, Guile disabling it is going to
cause trouble.




OpenPGP_signature
Description: OpenPGP digital signature


Re: Doc patches outstanding

2023-01-17 Thread Jean Abou Samra



Le 17/01/2023 à 07:21, Dr. Arne Babenhauserheide a écrit :

Hello Jean,

Jean Abou Samra  writes:

Thank you for applying the first one nevertheless. I am attaching
patch files for the other two, that should work better.

They are applied and pushed now — thank you, and thank you for your patience!

For the eval-when-example I wrote a small change to the wording, because
I found that the example actually runs in Guile 3.0.8, but retrieves the
runtime value of the date-time instead of the compile-time value.

Can you have a look? If it’s good to go from your side, I’d push it.



Well... you're right. Although it cannot be byte-compiled, it can be 
evaluated (actually, I find it surprising that evaluating a file 
evaluates the S-exprs one by one rather than first macroexpanding 
everything...).


You can push it.

Best,
Jean



OpenPGP_signature
Description: OpenPGP digital signature


Re: [PATCH] Add 'bytevector-slice'.

2023-01-11 Thread Jean Abou Samra

Hi Ludovic,

Le 11/01/2023 à 16:00, Ludovic Courtès a écrit :

+@node Bytevector Slices
+@subsubsection Bytevector Slices
+
+@cindex subset, of a bytevector
+@cindex slice, of a bytevector
+@cindex slice, of a uniform vector
+As an extension to the R6RS specification, the @code{(rnrs bytevectors
+gnu)} module provides the @code{bytevector-slice} procedure, which
+returns a bytevector aliasing part of an existing bytevector.
+
+@deffn {Scheme Procedure} bytevector-slice @var{bv} @var{offset} [@var{size}]
+@deffnx {C Function} scm_bytevector_slice (@var{bv}, @var{offset}, @var{size})
+Return the slice of @var{bv} starting at @var{offset} and counting
+@var{size} bytes.  When @var{size} is omitted, the slice covers all
+of @var{bv} starting from @var{offset}.  The returned slice shares
+storage with @var{bv}: changes to the slice are visible in @var{bv}
+and vice-versa.




What do you think about making it more similar to substrings?
There the 'substring' procedure makes a copy-on-write substring,
and you have substring/shared if you really want shared mutation.
Would something like this be meaningful / feasible / useful
for bytevectors?

Best,
Jean




OpenPGP_signature
Description: OpenPGP digital signature


Re: Doc patches outstanding

2023-01-10 Thread Jean Abou Samra

Le 11/12/2022 à 12:30, Jean Abou Samra a écrit :

Aargh, it looks like there is some whitespace mangling at some
point between my mail client and debbugs, preventing the patches
from being applied as-is.

Thank you for applying the first one nevertheless. I am attaching
patch files for the other two, that should work better.



Friendly ping?


OpenPGP_signature
Description: OpenPGP digital signature


Re: define-module, #:export and export

2023-01-08 Thread Jean Abou Samra

Le 08/01/2023 à 16:18, yarl baudig a écrit :

Obviously...

Ok, I tried more.
Apparently,

(define-syntax define-enumerate-type
   (syntax-rules ()
 ((_ name->int (name id) ...)
  (define-syntax name->int
(syntax-rules (name ...)
 ((_ name) id) ...)

works the same as

(define-syntax define-enumerate-type
   (syntax-rules ()
 ((_ name->int (name id) ...)
  (define-syntax name->int
(lambda (x)
 (syntax-case x ()
   ((_ n) (free-identifier=? #'name #'n) #'id) ...))

. Now what about

(define-syntax define-enumerate-type
   (syntax-rules ()
 ((_ name->int (name id) ...)
  (define-syntax name->int
(lambda (x)
 (syntax-case x ()
   ((_ n) (equal?
   (syntax->datum #'name)
   (syntax->datum #'n))
#'id) ...))

?




Yes, that was Maxime's suggestion (c). It essentially means you take the 
symbol

value of the argument to the macro without caring about whether it is bound
or renamed.

If you're doing this, maybe it's simpler to just turn the macro into a 
function
that accepts symbol values and call it as (my-enum 'foo) instead of 
(my-enum foo)?






OpenPGP_signature
Description: OpenPGP digital signature


Re: define-module, #:export and export

2023-01-08 Thread Jean Abou Samra

Le 08/01/2023 à 10:46, yarl baudig a écrit :

What if I replace

(define-syntax define-enumerate-type
   (syntax-rules ()
 ((_ name->int (name id) ...)
  (define-syntax name->int
(syntax-rules (name ...)
  ((_ name) id) ...)

with

(define-syntax define-enumerate-type
   (syntax-rules ()
 ((_ name->int (name id) ...)
  (define-syntax name->int
(syntax-rules ()
  ((_ name) id) ...)

?





Not going to work.

(define-syntax define-enumerate-type
  (syntax-rules ()
    ((_ name->int (name id) ...)
 (define-syntax name->int
   (syntax-rules ()
 ((_ name) id) ...)

(define-enumerate-type my-enum
  (member1 1)
  (member2 2))

(my-enum member2)
⇒ 1


The define-enumerate-type invocation expands to

(define-syntax my-enum
  (syntax-rules ()
    ((_ member1) 1)
    ((_ member2) 2)))

and since member1 is not declared as a literal in the first
argument to syntax-rules, it matches anything.



OpenPGP_signature
Description: OpenPGP digital signature


Re: define-module, #:export and export

2023-01-07 Thread Jean Abou Samra

Le 06/01/2023 à 14:55, Maxime Devos a écrit :

Guile's implementation of macros is a little lax with typing,
in the sense that objects like #false and #true (but not symbols, 
because hygiene) can be returned too, but IIUC this is undocumented 
and not standard Scheme (*).




Well, that is what I thought too, but after checking, I realize that it 
actually is standard. See


http://www.r6rs.org/final/html/r6rs-lib/r6rs-lib-Z-H-13.html

"""
More formally, a syntax object is:

- a pair of syntax objects,
-a vector of syntax objects,
- a nonpair, nonvector, nonsymbol value, or
- a wrapped syntax object.
"""

I learnt something today.



OpenPGP_signature
Description: OpenPGP digital signature


Re: define-module, #:export and export

2023-01-04 Thread Jean Abou Samra

Le 04/01/2023 à 18:28, Maxime Devos a écrit :

On 04-01-2023 16:11, yarl baudig wrote:

Hello guile.

I don't know if that's a bug. Anyway, I am confused about this so I 
ask. I came across this problem playing with guix source code. I will 
share different "tests" each test is a directory with nothing but the 
files I share.
each time the command to try the test (inside it's directory) is 
`guile --no-auto-compile -L . main.scm`

[...]

My (untested) hypothesis (*: things I'm unsure about)

If there is no #:export (...), then when
(define-operation (valid-path?)) is expanded, the identifier 
'valid-path?' is free (*).


Hence, the following ...

> (syntax-rules (name ...)
>   ((_ name) id) ...)

refers to the free identifier 'valid-path?'.

Conversely, if there is #:export, then the (syntax-rules (name ...) 
...) looks for the bound identifier 'valid-path?' (*).


Important: bound identifiers != free-identifier, even if they have the 
same symbol!  For (simple-format #t "~S\n" (operation-id valid-path?)) 
to work, the 'valid-path?' of that expression must be bound if the 
syntax-rules looks for a bound identifier, and free if it looks for a 
free identifier.



That is also my understanding, confirmed by

$ cat lib.scm
(define-module (lib)
  #:export (test))

(define-syntax test
  (lambda (sintax)
    (syntax-case sintax ()
  ((test id)
   (datum->syntax sintax (free-identifier=? #'id #'thing))

$ cat test.scm
(define-module (main)
  #:use-module (lib)
  #:export (thing)
  )

(display (test thing))
(newline)

(define thing 5)

$ guile3.0 -L . test.scm
#f


If you comment out #:export (thing), the result changes to #t.

To put it perhaps more simply, the use of #:export causes Guile to 
understand early that there will be a variable 'thing' in this module, 
and makes the identifier 'thing' refer to this variable that is not yet 
defined. However, hygiene implies that you want to be able to use 
keywords as if they were not keywords if they are rebound, e.g. the 
'else' here doesn't cause the cond clause to be taken:


(let ((else #f)) (cond (#f 'bla) (else 'foo) (#t 'bar)))
$1 = bar

The way this is done is by comparing with the original identifier given 
to syntax-rules. Technically, they are compared with free-identifier=? . 
This means that a use of the identifier matches the keyword iff both are 
unbound, or both are bound to the same lexical binding. However, this 
isn't the case here, as the keyword in the macro was unbound, but at the 
point of use, it has been bound by #:export.


Honestly, I think it is better to choose a different way of writing 
these macros that avoids this confusing issue. Try defining the 
operations at the same time as the enum so that the macro giving an enum 
member refers to the bindings of the operators. If you give more context 
on what you're trying to do, we could help more.


Best,
Jean



OpenPGP_signature
Description: OpenPGP digital signature


Re: Guile VM interpreter in GraalVM Truffle framework

2022-12-24 Thread Jean Abou Samra

Le 23/12/2022 à 18:06, Arvydas Silanskas a écrit :

Good day,

I have aspirations to run scheme on graalvm's truffle framework. And 
on superficial research, it seems implementing a Guile VM bytecode 
interpreter could be easiest path. I just want to inquire, if someone 
already had similar ideas and in secrecy is working or planning to on 
this? If you're familiar with truffle (I'm not), any insights on 
"guile on graal" would also be welcome.




I don't know anything about Truffle, but call/cc and delimited 
continuations strike me as feature that could be hard to

implement on such a thing. At least, it seems so from

https://www.graalvm.org/latest/reference-manual/ruby/Compatibility/

On the other hand, upwards-only continuations, aka escape continuations, 
which are just a different way to do exceptions, should be doable, so 
you could probably ship a version of call/cc where the "cont" value in 
(call/cc (lambda (cont) ...)) can only be used inside of the lambda. 
Same for prompts.


Best,
Jean



OpenPGP_signature
Description: OpenPGP digital signature


Re: Doc patches outstanding

2022-12-11 Thread Jean Abou Samra

Le 11/12/2022 à 03:05, Dr. Arne Babenhauserheide a écrit :

Hi,

Jean Abou Samra  writes:

I submitted a few doc patches which are awaiting someone
to review / push. They should be simple :-)  I hope someone
can have a look.


- Document that eq?, eqv? and equal? take any number
   of arguments.

https://lists.gnu.org/archive/html/guile-devel/2022-11/msg9.html

I reviewed and pushed this. It took a bit longer than expected, because
my git didn’t apply them cleanly to the main branch (I copied them from
the archive website which turned out to be a bad idea), so I had to do
most of that manually.

I plan to take a look at the other two soon.





Aargh, it looks like there is some whitespace mangling at some
point between my mail client and debbugs, preventing the patches
from being applied as-is.

Thank you for applying the first one nevertheless. I am attaching
patch files for the other two, that should work better.

Best,
Jean

From 759da55e72bb313ad5565c8502f7cd98a1454b93 Mon Sep 17 00:00:00 2001
From: Jean Abou Samra 
Date: Sun, 11 Dec 2022 12:26:18 +0100
Subject: [PATCH 1/2] doc: Fix eval-when example

* doc/ref/api-macros.texi: make the macro expand to the literal
  date, not to a call to the date function.  The example previously
  did not actually need eval-when and did not show the intended
  effect.
---
 doc/ref/api-macros.texi | 29 ++---
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/doc/ref/api-macros.texi b/doc/ref/api-macros.texi
index cdb33df31..a353719cb 100644
--- a/doc/ref/api-macros.texi
+++ b/doc/ref/api-macros.texi
@@ -63,7 +63,7 @@ transformers, consider the following example macro definition:
  (begin exp ...)
 
 (when #t
-  (display "hey ho\n") 
+  (display "hey ho\n")
   (display "let's go\n"))
 @print{} hey ho
 @print{} let's go
@@ -87,7 +87,7 @@ One can also establish local syntactic bindings with @code{let-syntax}.
 Bind each @var{keyword} to its corresponding @var{transformer} while
 expanding @var{exp1} @var{exp2} @enddots{}.
 
-A @code{let-syntax} binding only exists at expansion-time. 
+A @code{let-syntax} binding only exists at expansion-time.
 
 @example
 (let-syntax ((unless
@@ -1236,14 +1236,19 @@ But if a syntactic definition needs to call out to a normal procedure at
 expansion-time, it might well need need special declarations to indicate that
 the procedure should be made available at expansion-time.
 
-For example, the following code will work at a REPL, but not in a file:
+For example, the following code tries to embed a compilation
+timestamp in the compiled bytecode using a macro that expands
+to the date as a string literal.  It will work at a REPL, but
+not in a file, as it cannot be byte-compiled:
 
 @example
-;; incorrect
 (use-modules (srfi srfi-19))
-(define (date) (date->string (current-date)))
-(define-syntax %date (identifier-syntax (date)))
-(define *compilation-date* %date)
+(define start-date (date->string (current-date)))
+(define-syntax *compilation-date*
+ (lambda (sintax)
+start-date))
+(display *compilation-date*)
+(newline)
 @end example
 
 It works at a REPL because the expressions are evaluated one-by-one, in order,
@@ -1253,12 +1258,14 @@ evaluated until the compiled file is loaded.
 The fix is to use @code{eval-when}.
 
 @example
-;; correct: using eval-when
 (use-modules (srfi srfi-19))
 (eval-when (expand load eval)
-  (define (date) (date->string (current-date
-(define-syntax %date (identifier-syntax (date)))
-(define *compilation-date* %date)
+  (define start-date (date->string (current-date
+(define-syntax *compilation-date*
+ (lambda (sintax)
+start-date))
+(display *compilation-date*)
+(newline)
 @end example
 
 @deffn {Syntax} eval-when conditions exp...
-- 
2.38.1

From f5140bf63c624b975f1dcf98dcf18bf7cc44abfa Mon Sep 17 00:00:00 2001
From: Jean Abou Samra 
Date: Sun, 11 Dec 2022 12:28:02 +0100
Subject: [PATCH 2/2] Doc: clarification on regexes and encodings

* doc/ref/api-regex.texi: make it more obviously clear that regexp
  matching supports only characters supported by the locale encoding.
---
 doc/ref/api-regex.texi | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/doc/ref/api-regex.texi b/doc/ref/api-regex.texi
index b14c2b39c..d778f969f 100644
--- a/doc/ref/api-regex.texi
+++ b/doc/ref/api-regex.texi
@@ -57,7 +57,11 @@ locale's encoding, and then passed to the C library's regular expression
 routines (@pxref{Regular Expressions,,, libc, The GNU C Library
 Reference Manual}).  The returned match structures always point to
 characters in the strings, not to individual bytes, even in the case of
-multi-byte encodings.
+multi-byte encodings.  This ensures that the match structures are
+correct when performing matching with characters that have a multi-byte
+representation in the locale encoding.  Note, however, that using
+characters which cannot be represented in the locale encoding 

Doc patches outstanding

2022-12-07 Thread Jean Abou Samra

Hi,

I submitted a few doc patches which are awaiting someone
to review / push. They should be simple :-)  I hope someone
can have a look.


- Document that eq?, eqv? and equal? take any number
  of arguments.

https://lists.gnu.org/archive/html/guile-devel/2022-11/msg9.html

- Fix eval-when example.

  https://debbugs.gnu.org/cgi/bugreport.cgi?bug=58646

- Clarify that regular expression matching is locale-dependent.

  https://debbugs.gnu.org/cgi/bugreport.cgi?bug=57507

Thanks!

Jean



OpenPGP_signature
Description: OpenPGP digital signature


Re: [Doc] Patch: eq? and friends accepts more than two arguments

2022-11-06 Thread Jean Abou Samra

Le 06/11/2022 à 15:47, Thomas Morley a écrit :

Hi,

please find attached a doc-patch, clearifying eq?/eqv?/equal? are
working with more than two arguments.



Well, but the signature

eq? x y ...

is still not correct, because (eq?) and (eq? x) are also valid.
eq? takes *any* number of arguments.

Probably better to do:



From 09177dab48dabee4b6b6ac5fe110cd56e3e6e261 Mon Sep 17 00:00:00 2001
From: Jean Abou Samra 
Date: Sun, 6 Nov 2022 15:55:24 +0100
Subject: [PATCH] Doc: document that eq?, eqv? and equal? take any number of
 arguments

---
 doc/ref/api-utility.texi | 29 -
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/doc/ref/api-utility.texi b/doc/ref/api-utility.texi
index cb7e32f2b..27c6b42f7 100644
--- a/doc/ref/api-utility.texi
+++ b/doc/ref/api-utility.texi
@@ -55,11 +55,12 @@ made up of the same pairs.  Such lists look the same 
(when printed),

 and @code{equal?} will consider them the same.

 @sp 1
-@deffn {Scheme Procedure} eq? x y
+@deffn {Scheme Procedure} eq? @dots{}
 @deffnx {C Function} scm_eq_p (x, y)
 @rnindex eq?
-Return @code{#t} if @var{x} and @var{y} are the same object, except
-for numbers and characters.  For example,
+The Scheme procedure returns @code{#t} if all of its arguments are the
+same object, except for numbers and characters.  The C function does the
+same but takes exactly two arguments.  For example,

 @example
 (define x (vector 1 2 3))
@@ -109,18 +110,19 @@ The @code{==} operator should not be used on 
@code{SCM} values, an

 @end deftypefn

 @sp 1
-@deffn {Scheme Procedure} eqv? x y
+@deffn {Scheme Procedure} eqv? @dots{}
 @deffnx {C Function} scm_eqv_p (x, y)
 @rnindex eqv?
-Return @code{#t} if @var{x} and @var{y} are the same object, or for
-characters and numbers the same value.
+The Scheme procedure returns @code{#t} if all of its arguments are the
+same object, or for characters and numbers the same value.  The C function
+is similar but takes exactly two arguments.

 On objects except characters and numbers, @code{eqv?} is the same as
-@code{eq?} above, it's true if @var{x} and @var{y} are the same
-object.
+@code{eq?} above.  @code{(eqv? x y)} is true if @var{x} and @var{y} are
+the same object.

-If @var{x} and @var{y} are numbers or characters, @code{eqv?} compares
-their type and value.  An exact number is not @code{eqv?} to an
+If @var{x} and @var{y} are numbers or characters, @code{(eqv? x y)}
+compares their type and value.  An exact number is not @code{eqv?} to an
 inexact number (even if their value is the same).

 @example
@@ -130,11 +132,12 @@ inexact number (even if their value is the same).
 @end deffn

 @sp 1
-@deffn {Scheme Procedure} equal? x y
+@deffn {Scheme Procedure} equal? @dots{}
 @deffnx {C Function} scm_equal_p (x, y)
 @rnindex equal?
-Return @code{#t} if @var{x} and @var{y} are the same type, and their
-contents or value are equal.
+The Scheme procedure returns @code{#t} if all of its arguments are the
+same type, and their contents or value are equal.  The C function is
+similar, but takes exactly two arguments.

 For a pair, string, vector, array or structure, @code{equal?} compares the
 contents, and does so using the same @code{equal?} recursively,
--
2.37.3




OpenPGP_signature
Description: OpenPGP digital signature


define-syntax-public

2022-11-04 Thread Jean Abou Samra

Hi,

Guile 1.8's (ice-9 syncase) provides define-syntax-public
as a convenience for define-syntax + export. It is not
found in Guile 2.2 and later, though. Was this an oversight
or intentional? Would it make sense to add it back as well
as define-syntax-rule-public?

Thanks,
Jean



OpenPGP_signature
Description: OpenPGP digital signature


Re: Feature request: Ability to document variables like defvar in elisp

2022-11-04 Thread Jean Abou Samra

Le 02/11/2022 à 11:15, Mikael Djurfeldt a écrit :

(define a 5)
(set-object-property! (module-variable (current-module) 'a) 
'documentation "The variable a contains a number.")

?




Why not, but I wanted to point out that variable documentation
cannot be done in a way that is consistent with procedure documentation.
It needs to be a different mechanism, tied to the module system, which
brings some restrictions (what about local variables?).

Best,
Jean




OpenPGP_signature
Description: OpenPGP digital signature


Re: Feature request: Ability to document variables like defvar in elisp

2022-11-02 Thread Jean Abou Samra

Le 02/11/2022 à 02:08, Jacob Hrbek a écrit :
The ability to document variables is critical for many projects such 
as libfive where the variables is used to declares functional computer 
aided design structure and other projects where variables influence 
the workflow.


Thus proposing to change the 'define' behavior for variables to implement:

    (define variable default-value docstring)
                                                   ^^

Where docstring is optional and in case it's provided to call for example:

(set-procedure-property! variable 'documentation docstring)





The problem is that in Scheme, you cannot attach metadata to immediate
values. According to the Scheme standards and the Guile documentation,


(define a 5)
(define b 5)

(eq? a b) => may be #t or #f
(eq? a a) => may be #t or #f


So it's considerably more complicated than using an object property,
because that would not work reliably for variables defined to immediates
like numbers and characters. Instead you would need to attach the
metadata to the name you're defining the variable to, like Elisp does,
but unlike Guile does with procedures right now, and it's not as simple
in Scheme due to lexical scoping.

Best,
Jean




Crashes with continuations in Guile 2.2 on MinGW

2022-10-17 Thread Jean Abou Samra

Hi,

See https://gitlab.com/lilypond/lilypond/-/issues/6430
In LilyPond, we are observing crashes when reinstating
(undelimited) continuations in our Windows binaries
compiled via MinGW. Note that this is with Guile 2.2;
it is possible that we will move to Guile 3 at some point,
but for our next stable release, this is no longer an
option.

Does this ring a bell? Do you have any idea how to fix
it?

Thanks,
Jean




Re: Relaxing the copyright assignment policy

2022-10-08 Thread Jean Abou Samra
FYI, it looks like the file HACKING mentions copyright assignment. You 
probably want to update it.




Re: Relaxing the copyright assignment policy

2022-10-06 Thread Jean Abou Samra




Le 06/10/2022 à 22:18, Ludovic Courtès a écrit :

Hello Guilers!

Until now, we required copyright for “legally significant¹”
contributions to Guile to be assigned to the Free Software Foundation
(FSF).  This requirement did not exist for code not initially written
for Guile—e.g., (ice-9 match), sxml-match, etc.  The purported advantage
of copyright assignment is described at
.

Your unreachable-but-nonetheless-friendly co-maintainers, Andy Wingo and
myself, came to the conclusion that the cost/benefit ratio of mandatory
copyright assignment is not good for Guile.  Like other projects such as
GCC², we have decided to relax that policy.

Nothing changes for contributors who have already assigned copyright on
future changes to Guile to the FSF.

New contributors are encouraged to assign copyright to the FSF by
emailing them one of the forms at
,
especially if they intend to contribute significantly going forward.

New contributors may instead choose to not assign copyright to the FSF.
In that case, copyright on the new code is held by the contributor
themself or, possibly, by their employer—contributors who choose this
option are expected to clarify which of these two applies to their
situation.  A copyright line for the new copyright holder is added to
files modified in a “legally significant” way³.

Guile remains under the same license, the GNU Lesser General Public
License, version 3 or any later version; contributions are expected
under the same terms.

We hope this to be one of the changes that will make it easier to
contribute to Guile.

Let us know if you have any questions, and enjoy the good hack!

Ludo’ & Andy.

¹ https://www.gnu.org/prep/maintain/maintain.html#Legally-Significant
² https://gcc.gnu.org/pipermail/gcc/2021-June/236182.html
³ https://www.gnu.org/prep/maintain/maintain.html#Copyright-Notices




This is very good news!

When I did this copyright assignment for Emacs, I recall
that the procedure was a bit demotivating (the person
was very friendly, but when you live in an isolated area
and don't have a printer and you must print the document
to sign it ...).

Thanks a lot for doing this.

Jean




Re: Recursive Macros generating Definitions

2022-10-03 Thread Jean Abou Samra




Le 03/10/2022 à 15:41, Frank Terbeck a écrit :

I get the point, but I think it's sort of surprising, when everything in
the macro-language is  otherwise quite literal, to  my understanding. It
may be warranted to  point this out in the documentation  that this is a
side effect of hygienic macros, I think.



It *is* extensively documented.

https://www.gnu.org/software/guile/manual/html_node/Hygiene-and-the-Top_002dLevel.html#Hygiene-and-the-Top_002dLevel



This behaviour  is probably  explained in one  of the  ‘syntax-case’ and
‘datum->syntax’ examples  in the manual,  but it  wasn't clear to  me at
all. Not sure how, but I think there's room for improvement here. :)

Thanks for  clearing this up!  And feel free  to correct anything  I got
wrong in what I wrote in the above.



I think it is worth taking a look not just at the Guile documentation 
but also at the Scheme standards, which are more verbose on the details 
of syntax->datum and such. See


http://www.r6rs.org/final/html/r6rs-lib/r6rs-lib-Z-H-13.html




Re: bug#58109: simple-format vs (ice-9 format) bug in 3.0.7?

2022-10-01 Thread Jean Abou Samra




Le 01/10/2022 à 15:40, Ludovic Courtès a écrit :

Hi,

Jean Abou Samra  skribis:


Uh, at the end of module/ice-9/format.scm, there is

;; Thanks to Shuji Narazaki
(module-set! the-root-module 'format format)

which dates back to

commit 14469b7c69feb0f2c5b8a093f19fe2a548b31c5b
Author: Greg J. Badros 
Date:   Thu Jan 20 20:58:30 2000 +

[...]


This probably predates #:replace and could be removed now, right?

Yes, it could be removed, but probably not before the 4.0 series.

The ‘-Wformat’ warning introduced sometime in the 2.0 or 2.2 series
prepared for that removal by warning about simple-format/format
mismatches, but there’s probably still code out there that assumes
‘format’ is the full-blown ‘format’, even when (ice-9 format) is not
explicitly imported.




OK, understood. How about adding comments and documentation?

diff --git a/doc/ref/misc-modules.texi b/doc/ref/misc-modules.texi
index 6c899a905..2c00ed859 100644
--- a/doc/ref/misc-modules.texi
+++ b/doc/ref/misc-modules.texi
@@ -1122,6 +1122,13 @@ you try to use one of them.  The reason for two 
versions is that the

 full @code{format} is fairly large and requires some time to load.
 @code{simple-format} is often adequate too.

+Beware that when @code{(ice-9 format)} is loaded, it replaces the
+binding for @code{format} on the toplevel.  If your module loads
+another module that loads @code{(ice-9 format)}, then your module
+will see the @code{format} function from @code{(ice-9 format)},
+even if it does not itself import @code{(ice-9 format)}.  This is
+legacy behavior and may be removed in a future Guile version.
+

 @node File Tree Walk
 @section File Tree Walk
diff --git a/module/ice-9/format.scm b/module/ice-9/format.scm
index ee7cba910..026fd9b54 100644
--- a/module/ice-9/format.scm
+++ b/module/ice-9/format.scm
@@ -32,6 +32,8 @@
 (define-module (ice-9 format)
   #:autoload (ice-9 pretty-print) (pretty-print truncated-print)
   #:autoload (ice-9 i18n) (%global-locale number->locale-string)
+  ;; Actually replaces the global format as soon as loaded; see the end
+  ;; of this file.
   #:replace (format))

 (define format:version "3.0")
@@ -83,7 +85,7 @@
   ;; format's user error handler

   (define (format-error . args)   ; never returns!
-    (with-throw-handler #t
+    (with-throw-handler #t
   (lambda ()
 (let ((port (current-error-port)))
   (unless (zero? %arg-pos)
@@ -1560,5 +1562,10 @@
   (close-port port)
   str)

-;; Thanks to Shuji Narazaki
+;; Set the format variable in the root module.  This is legacy and
+;; no longer necessary.  It means that as soon as (ice-9 format) is
+;; loaded somewhere by some module, the predefined binding for format
+;; becomes the extended format function, even in modules where (ice-9 
format)

+;; isn't imported.  Because of this, removing this line should be done
+;; when a backwards compatibility break is allowed.
 (module-set! the-root-module 'format format)




Best,
Jean




Re: simple-format vs (ice-9 format) bug in 3.0.7?

2022-09-27 Thread Jean Abou Samra




Le 27/09/2022 à 12:23, Christopher Lam a écrit :

Hi guilers, here's a short bash session.
Why would the first bash call to "guile s.scm" work, but not the 
second one?

guile-3.0.7 on ubuntu.




This is a duplicate of
https://debbugs.gnu.org/cgi/bugreport.cgi?bug=50059




Re: simple-format vs (ice-9 format) bug in 3.0.7?

2022-09-27 Thread Jean Abou Samra




Le 27/09/2022 à 12:35, Jean Abou Samra a écrit :



Le 27/09/2022 à 12:23, Christopher Lam a écrit :

Hi guilers, here's a short bash session.
Why would the first bash call to "guile s.scm" work, but not the 
second one?

guile-3.0.7 on ubuntu.




This is a duplicate of
https://debbugs.gnu.org/cgi/bugreport.cgi?bug=50059




Uh, at the end of module/ice-9/format.scm, there is

;; Thanks to Shuji Narazaki
(module-set! the-root-module 'format format)

which dates back to

commit 14469b7c69feb0f2c5b8a093f19fe2a548b31c5b
Author: Greg J. Badros 
Date:   Thu Jan 20 20:58:30 2000 +

    * format.scm: Use (variable-set! (builtin-variable 'format)) to
    re-define format to be format:format (instead of just define,
    which interacts poorly with the module system).  Thanks to Shuji
    Narazaki for this change.

diff --git a/ice-9/format.scm b/ice-9/format.scm
index fce2737ce..40f20b3da 100644
--- a/ice-9/format.scm
+++ b/ice-9/format.scm
@@ -1670,7 +1670,9 @@

 (define format:abort (lambda () (error "error in format")))

-(define format format:format)
+;;(define format format:format)
+;; Thanks to Shuji Narazaki
+(variable-set! (builtin-variable 'format) format:format)

 ;; If this is not possible then a continuation is used to recover
 ;; properly from a format error. In this case format returns #f.



This probably predates #:replace and could be removed now, right?



Re: Strongly typed language my ass

2022-09-20 Thread Jean Abou Samra


> Le 20 sept. 2022 à 23:44, Jacob Hrbek  a écrit :
> 
> 
> In what world is this considered a strongly typed language when I need to do 
> these checks like it's a weakly typed one?
> 
> (define* (lazy-assign key #:optional (val ""))
>   "Assign environmental variable KEY with an optional value VAL, both  
> must be a string or a thunk that evaluates to a string
> 
> This procedure sets an entry in the @{%makevars} hash table"
> 
>   (cond ((procedure? key)
> (set! key (key)))
> ((string? key)
> ;; FIXME-QA(Krey): Seems like a wasteful @{format}
> (set! key (format #f "~a" key)))
> ;; FIXME-QA(Krey): Make sure that the error here is clear and descriptive
> (else (make-non-continuable-error)))
> 
>   ;; FIXME-QA(Krey): Add check for sanity of VAL
> 
>   (makevars-set key (delay val)))
> 
> Instead of something like:
> 
>   (define* (lazy-assign (string-type key) #:optional (val ""))
>   "Assign environmental variable KEY with an optional value VAL, both must be 
> a string or a thunk that evaluates to a string
> 
>   This procedure sets an entry in the @{%makevars} hash table"
> 
>   (makevars-set key (delay val)))
> 
> Notice the (string-type key) meant to declare that it's only expecting an 
> input that is a string or evaluates into a string which mitigates the need to 
> include sanity checking in every procedure..
> 
> or even something like:
> 
> (define* (lazy-assign key:string #:optional (var:string "")) ...)
> 
> -- Jacob "Kreyren" Hrbek




https://www.gnu.org/software/guile/manual/html_node/GOOPS.html

Writing that denigrates is unlikely to attract helpful responses. I won’t reply 
further.



Re: [PATCH] Properly display locations in "source vector" form.

2022-08-26 Thread Jean Abou Samra




Le 26/08/2022 à 12:50, lloda a écrit :

Ah this one has been bugging me. Applied in 
eb5ecf4944cd646341f7e47dda5396cf96a4b8a3.

Thank you!


This likely fixes https://debbugs.gnu.org/cgi/bugreport.cgi?bug=56493.



Re: “Too many root sets” when calling compile frequently

2022-08-20 Thread Jean Abou Samra



> Le 19 août 2022 à 12:19, Maxime Devos  a écrit :
> 
> 
>> On 19-08-2022 00:18, Jean Abou Samra wrote:
>> Hi,
>> 
>> Calling the Guile compiler often causes this BDWGC error: “Too
>> many root sets”.
>> 
>> scheme@(guile-user)> (define-syntax-rule (repeat n expr expr* ...) (do ((i 0 
>> (1+ i))) ((eqv? i n)) expr expr* ...))
>> scheme@(guile-user)> (use-modules (system base compile))
>> scheme@(guile-user)> (repeat 1 (compile 5))
>> Too many root sets
>> Abandon (core dumped)
>> 
>> Any idea what is going on here? Should I report it as a bug?
>> Is there a workaround?
>> 
>> Thanks,
>> Jean
> 
> IIRC, Guile used to support garbage collection of compiled code, but that 
> support has been removed.
> 
> I cannot find that in the Git history or NEWS, so maybe that's incorrect.
> 
> If that is correct, maybe with sufficient tests and care, support for 
> unloading compiled code can be restored, removing the call to GC_add_roots.


Thanks for your reply. I didn’t dig into the history yet, but I might do it 
later. For now, I have a question. What is the actual purpose of the 
GC_add_roots call? Is it just to give eternal protection to the objects pointed 
to by pointers in the memory section? In that case, wouldn’t it also work to 
create a bytevector from the root section and use scm_permanent_object on it? 
Or is this a subtlety where Guile registers its ELF bytecode as if it were a 
dynamic library (also ELF)?

It would be great if Guile supported garbage collection of loaded bytecode, but 
for my use case in LilyPond, it is actually not strictly  necessary. It should 
suffice not to error out on the nth call.

Jean






Re: “Too many root sets” when calling compile frequently

2022-08-19 Thread Jean Abou Samra

Le 19/08/2022 à 00:33, Jean Abou Samra a écrit :

Le 19/08/2022 à 00:18, Jean Abou Samra a écrit :

Calling the Guile compiler often causes this BDWGC error: “Too
many root sets”.

scheme@(guile-user)> (define-syntax-rule (repeat n expr expr* ...) 
(do ((i 0 (1+ i))) ((eqv? i n)) expr expr* ...))

scheme@(guile-user)> (use-modules (system base compile))
scheme@(guile-user)> (repeat 1 (compile 5))
Too many root sets
Abandon (core dumped)

Any idea what is going on here? Should I report it as a bug?
Is there a workaround?



Interestingly:

scheme@(guile-user)> (define-syntax-rule (repeat n expr expr* ...) (do 
((i 0 (1+ i))) ((eqv? i n)) expr expr* ...))

scheme@(guile-user)> (use-modules (system base compile))
scheme@(guile-user)> (repeat 1 (compile 5 #:to 'bytecode))
scheme@(guile-user)> (use-modules (system vm loader))
scheme@(guile-user)> (repeat 1 (load-thunk-from-memory (compile 5 
#:to 'bytecode)))

Too many root sets
Abandon (core dumped)


So the problem lies in the VM loading infrastructure. (This is
as far as I can investigate for now.)




I tried this code:

(use-modules (system vm loader))

(define-syntax-rule (repeat n-expr expr expr* ...)
  (let ((n n-expr))
    (do ((i 0 (1+ i)))
  ((eqv? i n))
  expr expr* ...)))

(let ((code (compile 5 #:to 'bytecode)))
  (repeat 1
    (load-thunk-from-memory code)
    (display (length (all-mapped-elf-images))) (newline)))


For me, the output ends with

8174
8175
8176
8177
8178
8179
8180
8181
Too many root sets
Abandon (core dumped)


Now, BDWGC defines MAX_ROOT_SETS in include/private/gc_priv.h as

/* Root sets.  Logically private to mark_rts.c.  But we don't want the  */
/* tables scanned, so we put them here. */
/* MAX_ROOT_SETS is the maximum number of ranges that can be    */
/* registered as static roots.  */
# ifdef LARGE_CONFIG
#   define MAX_ROOT_SETS 8192
# elif !defined(SMALL_CONFIG)
#   define MAX_ROOT_SETS 2048
# else
#   define MAX_ROOT_SETS 512
# endif


I am using Fedora, where BDWGC is compiled with --enable-large-config. When
the loader ingests a VM code chunk, it does (loader.c)


  if (gc_root)
    GC_add_roots (gc_root, gc_root + gc_root_size);


So each load is really adding a root until this threshold of 8192
is crossed.

I have no idea if it is possible to fix and/or work around this
other than by not calling compile often like this.

(Yes, I know, I should be using eval for one-off code evaluation,
but it discards source locations, which is what brought me here
in the first place.)

Jean




Re: “Too many root sets” when calling compile frequently

2022-08-18 Thread Jean Abou Samra

Le 19/08/2022 à 00:18, Jean Abou Samra a écrit :

Calling the Guile compiler often causes this BDWGC error: “Too
many root sets”.

scheme@(guile-user)> (define-syntax-rule (repeat n expr expr* ...) (do 
((i 0 (1+ i))) ((eqv? i n)) expr expr* ...))

scheme@(guile-user)> (use-modules (system base compile))
scheme@(guile-user)> (repeat 1 (compile 5))
Too many root sets
Abandon (core dumped)

Any idea what is going on here? Should I report it as a bug?
Is there a workaround?



Interestingly:

scheme@(guile-user)> (define-syntax-rule (repeat n expr expr* ...) (do 
((i 0 (1+ i))) ((eqv? i n)) expr expr* ...))

scheme@(guile-user)> (use-modules (system base compile))
scheme@(guile-user)> (repeat 1 (compile 5 #:to 'bytecode))
scheme@(guile-user)> (use-modules (system vm loader))
scheme@(guile-user)> (repeat 1 (load-thunk-from-memory (compile 5 
#:to 'bytecode)))

Too many root sets
Abandon (core dumped)


So the problem lies in the VM loading infrastructure. (This is
as far as I can investigate for now.)




“Too many root sets” when calling compile frequently

2022-08-18 Thread Jean Abou Samra

Hi,

Calling the Guile compiler often causes this BDWGC error: “Too
many root sets”.

scheme@(guile-user)> (define-syntax-rule (repeat n expr expr* ...) (do 
((i 0 (1+ i))) ((eqv? i n)) expr expr* ...))

scheme@(guile-user)> (use-modules (system base compile))
scheme@(guile-user)> (repeat 1 (compile 5))
Too many root sets
Abandon (core dumped)

Any idea what is going on here? Should I report it as a bug?
Is there a workaround?

Thanks,
Jean




Re: string is read-only

2022-08-03 Thread Jean Abou Samra


> Le 3 août 2022 à 11:49, Taylan Kammer  a écrit :
> 
> On 03.08.2022 11:12, Damien Mattei wrote:
>> GNU Guile 3.0.1
>> Copyright (C) 1995-2020 Free Software Foundation, Inc.
>> 
>> Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
>> This program is free software, and you are welcome to redistribute it
>> under certain conditions; type `,show c' for details.
>> 
>> Enter `,help' for help.
>> scheme@(guile-user)> (define str2 "hello")
>> scheme@(guile-user)> (string-set! str2 4 #\a)
>> ice-9/boot-9.scm:1669:16: In procedure raise-exception:
>> string is read-only: "hello"
>> 
>> Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
>> scheme@(guile-user) [1]> ,q
>> scheme@(guile-user)> (string? str2)
>> #t
>> 
>> is it a bug in Guile ? :-O
>> 
>> i can only find reference to deprecated read-only string in old doc:
>> https://www.gnu.org/software/guile/docs/docs-1.6/guile-ref/Read-Only-Strings.html#Read%20Only%20Strings
>>  
>> 
>> 
>> Regards,
>> 
>> Damien
> 
> String literals are constants, and it's intentional.
> 
> I'm not sure if it's mentioned anywhere in the manual.
> 
> If you want to get a mutable string from a literal, you can use:
> 
>  (define str (string-copy "foobar"))
> 
> -- 
> Taylan

This is standard. See the intro of

https://srfi.schemers.org/srfi-135/

> 


Re: string is read-only

2022-08-03 Thread Jean Abou Samra


> Le 3 août 2022 à 12:30, Taylan Kammer  a écrit :
> 
> On 03.08.2022 11:50, Jean Abou Samra wrote:
>> 
>> 
>>>> Le 3 août 2022 à 11:49, Taylan Kammer  a écrit :
>>> 
>>> On 03.08.2022 11:12, Damien Mattei wrote:
>>>> GNU Guile 3.0.1
>>>> Copyright (C) 1995-2020 Free Software Foundation, Inc.
>>>> 
>>>> Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
>>>> This program is free software, and you are welcome to redistribute it
>>>> under certain conditions; type `,show c' for details.
>>>> 
>>>> Enter `,help' for help.
>>>> scheme@(guile-user)> (define str2 "hello")
>>>> scheme@(guile-user)> (string-set! str2 4 #\a)
>>>> ice-9/boot-9.scm:1669:16: In procedure raise-exception:
>>>> string is read-only: "hello"
>>>> 
>>>> Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
>>>> scheme@(guile-user) [1]> ,q
>>>> scheme@(guile-user)> (string? str2)
>>>> #t
>>>> 
>>>> is it a bug in Guile ? :-O
>>>> 
>>>> i can only find reference to deprecated read-only string in old doc:
>>>> https://www.gnu.org/software/guile/docs/docs-1.6/guile-ref/Read-Only-Strings.html#Read%20Only%20Strings
>>>>  
>>>> <https://www.gnu.org/software/guile/docs/docs-1.6/guile-ref/Read-Only-Strings.html#Read%20Only%20Strings>
>>>> 
>>>> Regards,
>>>> 
>>>> Damien
>>> 
>>> String literals are constants, and it's intentional.
>>> 
>>> I'm not sure if it's mentioned anywhere in the manual.
>>> 
>>> If you want to get a mutable string from a literal, you can use:
>>> 
>>>  (define str (string-copy "foobar"))
>>> 
>>> -- 
>>> Taylan
>> 
>> This is standard. See the intro of
>> 
>> https://srfi.schemers.org/srfi-135/ <https://srfi.schemers.org/srfi-135/>
>> 
>>> 
> 
> This SRFI defines a new data type, which is not really relevant here.
> 
> As far as I know, Guile doesn't support it yet anyway.



I just wanted to point to the intro, which summarizes the state of literal 
string immutability in all recent RnRSes:

"""
In Scheme, strings are a mutable data type. Although it "is an error" (R5RS and 
R7RS) to use string-set! on literal strings or on strings returned by 
symbol->string, and any attempt to do so "should raise an exception" (R6RS),
"""



> -- 
> Taylan


Re: Mysterious crash in BDWGC on Windows

2022-06-19 Thread Jean Abou Samra

Reposting because of mangled formatting, sorry. Not sure what went wrong.

Hi Guilers,

Sorry about the double post on guile-devel and guile-user,
I wasn't sure which one was more appropriate for this.

In LilyPond, we're getting random crashes on Windows builds,
with Guile 2.2 [*]. These are builds are done by cross-compilation
to MinGW. Tracker issue:

https://gitlab.com/lilypond/lilypond/-/issues/6361


Example backtrace (trimmed):

Thread 1 received signal SIGSEGV, Segmentation fault.
GC_mark_from (mark_stack_top=0x24956eb0ae0, mark_stack=0x24956eb, 
mark_stack_limit=0x24956ec) at 
/home/jean/repos/lilypond/release/binaries/mingw/dependencies/src/gc-8.2.0/mark.c:816
816 
/home/jean/repos/lilypond/release/binaries/mingw/dependencies/src/gc-8.2.0/mark.c: 
No such file or directory.

(gdb) backtrace
#0 GC_mark_from (mark_stack_top=0x24956eb0ae0, mark_stack=0x24956eb, 
mark_stack_limit=0x24956ec)
at 
/home/jean/repos/lilypond/release/binaries/mingw/dependencies/src/gc-8.2.0/mark.c:816

#1 0x7ff6c2950338 in GC_mark_some (cold_gc_frame=0x7b439fba10 "\006")
at 
/home/jean/repos/lilypond/release/binaries/mingw/dependencies/src/gc-8.2.0/mark.c:321
#2 0x7ff6c2947a25 in GC_stopped_mark 
(stop_func=stop_func@entry=0x7ff6c29478b0 )
at 
/home/jean/repos/lilypond/release/binaries/mingw/dependencies/src/gc-8.2.0/alloc.c:880
#3 0x7ff6c2948abb in GC_try_to_collect_inner 
(stop_func=stop_func@entry=0x7ff6c29478b0 )
at 
/home/jean/repos/lilypond/release/binaries/mingw/dependencies/src/gc-8.2.0/alloc.c:626
#4 0x7ff6c2948d58 in GC_try_to_collect_inner 
(stop_func=0x7ff6c29478b0 )
at 
/home/jean/repos/lilypond/release/binaries/mingw/dependencies/src/gc-8.2.0/alloc.c:577
#5 GC_try_to_collect_general (stop_func=stop_func@entry=0x0, 
force_unmap=force_unmap@entry=0)
at 
/home/jean/repos/lilypond/release/binaries/mingw/dependencies/src/gc-8.2.0/alloc.c:1298

#6 0x7ff6c294918d in GC_gcollect ()
at 
/home/jean/repos/lilypond/release/binaries/mingw/dependencies/src/gc-8.2.0/alloc.c:1323

#7 0x7ff6c2896b69 in scm_i_gc (what=)
at 
/home/jean/repos/lilypond/release/binaries/mingw/dependencies/src/guile-2.2.7/libguile/gc.c:266
#8 scm_gc () at 
/home/jean/repos/lilypond/release/binaries/mingw/dependencies/src/guile-2.2.7/libguile/gc.c:255
#9 0x7ff6c290788f in vm_regular_engine (thread=0x0, 
vp=0x2495b083f30, registers=0x24956ec, resume=1016)
at 
/home/jean/repos/lilypond/release/binaries/mingw/dependencies/src/guile-2.2.7/libguile/vm-engine.c:786
#10 0x7ff6c2909c9b in scm_call_n (proc=0x249590a3d40, 
argv=argv@entry=0x7b439fbe78, nargs=nargs@entry=1)
at 
/home/jean/repos/lilypond/release/binaries/mingw/dependencies/src/guile-2.2.7/libguile/vm.c:1260
#11 0x7ff6c288ee19 in scm_call_1 (proc=, 
arg1=)
at 
/home/jean/repos/lilypond/release/binaries/mingw/dependencies/src/guile-2.2.7/libguile/eval.c:485

#12 0x7ff6c2836e0a in Method_instance::operator() (this=)
at 
/home/jean/repos/lilypond/release/binaries/mingw/lilypond/lilypond-2.23.10/lily/include/callback.hh:212
#13 Translator_group::precomputed_translator_foreach 
(idx=STOP_TRANSLATION_TIMESTEP, this=0x2495d75bb90)
at 
/home/jean/repos/lilypond/release/binaries/mingw/lilypond/lilypond-2.23.10/lily/translator-group.cc:267




As a further data point, the bug only reproduces with address space
layout randomization enabled.


Do you have any idea what might be causing this? At LilyPond, we're
totally lost on what could provoke such an internal crash in BDWGC.
Do you have successful experience with using Guile 2.2 on Windows?
Did you see this kind of thing before? In short, does it ring a bell?

Thanks,
Jean

[*] I quickly tried checking if they reproduced with Guile 3 but got a
    boot failure and didn't dig deeper. See the issue.






Mysterious crash in BDWGC on Windows

2022-06-19 Thread Jean Abou Samra

Hi Guilers,

Sorry about the double post on guile-devel and guile-user,
I wasn't sure which one was more appropriate for this.

In LilyPond, we're getting random crashes on Windows builds,
with Guile 2.2 [*]. These are builds are done by cross-compilation
to MinGW. Tracker issue:

https://gitlab.com/lilypond/lilypond/-/issues/6361


Example backtrace (trimmed):

Thread 1 received signal SIGSEGV, Segmentation fault.
GC_mark_from (mark_stack_top=0x24956eb0ae0, mark_stack=0x24956eb, 
mark_stack_limit=0x24956ec) at 
/home/jean/repos/lilypond/release/binaries/mingw/dependencies/src/gc-8.2.0/mark.c:816
816 
/home/jean/repos/lilypond/release/binaries/mingw/dependencies/src/gc-8.2.0/mark.c: 
No such file or directory.

(gdb) backtrace
#0 GC_mark_from (mark_stack_top=0x24956eb0ae0, mark_stack=0x24956eb, 
mark_stack_limit=0x24956ec)
at 
/home/jean/repos/lilypond/release/binaries/mingw/dependencies/src/gc-8.2.0/mark.c:816

#1 0x7ff6c2950338 in GC_mark_some (cold_gc_frame=0x7b439fba10 "\006")
at 
/home/jean/repos/lilypond/release/binaries/mingw/dependencies/src/gc-8.2.0/mark.c:321
#2 0x7ff6c2947a25 in GC_stopped_mark 
(stop_func=stop_func@entry=0x7ff6c29478b0 )
at 
/home/jean/repos/lilypond/release/binaries/mingw/dependencies/src/gc-8.2.0/alloc.c:880
#3 0x7ff6c2948abb in GC_try_to_collect_inner 
(stop_func=stop_func@entry=0x7ff6c29478b0 )
at 
/home/jean/repos/lilypond/release/binaries/mingw/dependencies/src/gc-8.2.0/alloc.c:626
#4 0x7ff6c2948d58 in GC_try_to_collect_inner 
(stop_func=0x7ff6c29478b0 )
at 
/home/jean/repos/lilypond/release/binaries/mingw/dependencies/src/gc-8.2.0/alloc.c:577
#5 GC_try_to_collect_general (stop_func=stop_func@entry=0x0, 
force_unmap=force_unmap@entry=0)
at 
/home/jean/repos/lilypond/release/binaries/mingw/dependencies/src/gc-8.2.0/alloc.c:1298

#6 0x7ff6c294918d in GC_gcollect ()
at 
/home/jean/repos/lilypond/release/binaries/mingw/dependencies/src/gc-8.2.0/alloc.c:1323

#7 0x7ff6c2896b69 in scm_i_gc (what=)
at 
/home/jean/repos/lilypond/release/binaries/mingw/dependencies/src/guile-2.2.7/libguile/gc.c:266
#8 scm_gc () at 
/home/jean/repos/lilypond/release/binaries/mingw/dependencies/src/guile-2.2.7/libguile/gc.c:255
#9 0x7ff6c290788f in vm_regular_engine (thread=0x0, 
vp=0x2495b083f30, registers=0x24956ec, resume=1016)
at 
/home/jean/repos/lilypond/release/binaries/mingw/dependencies/src/guile-2.2.7/libguile/vm-engine.c:786
#10 0x7ff6c2909c9b in scm_call_n (proc=0x249590a3d40, 
argv=argv@entry=0x7b439fbe78, nargs=nargs@entry=1)
at 
/home/jean/repos/lilypond/release/binaries/mingw/dependencies/src/guile-2.2.7/libguile/vm.c:1260
#11 0x7ff6c288ee19 in scm_call_1 (proc=, 
arg1=)
at 
/home/jean/repos/lilypond/release/binaries/mingw/dependencies/src/guile-2.2.7/libguile/eval.c:485

#12 0x7ff6c2836e0a in Method_instance::operator() (this=)
at 
/home/jean/repos/lilypond/release/binaries/mingw/lilypond/lilypond-2.23.10/lily/include/callback.hh:212
#13 Translator_group::precomputed_translator_foreach 
(idx=STOP_TRANSLATION_TIMESTEP, this=0x2495d75bb90)
at 
/home/jean/repos/lilypond/release/binaries/mingw/lilypond/lilypond-2.23.10/lily/translator-group.cc:267
As a further data point, the bug only reproduces with address space 
layout randomization enabled. Do you have any idea what might be causing 
this? At LilyPond, we're totally lost on what could provoke such an 
internal crash in BDWGC. Do you have successful experience with using 
Guile 2.2 on Windows? Did you see this kind of thing before? In short, 
does it ring a bell? Thanks, Jean [*] I quickly tried checking if they 
reproduced with Guile 3 but got a boot failure and didn't dig deeper. 
See the issue.





Re: Are source locations broken?

2022-05-01 Thread Jean Abou Samra

Le 01/05/2022 à 19:04, Olivier Dion a écrit :

Any news on that bug?



Last time I looked, it seemed that there had been an oversight with
source locations having changed representation (becoming 3-element
vectors instead of alists with symbol keys). But since the bugfix
patch I have submitted for curried definitions with docstrings has
received no reaction, I didn't want to invest time without much
hope that the effort would pay off :-(

Jean






(ice-9 sandbox) vs. (ice-9 safe)

2022-04-24 Thread Jean Abou Samra

Hi,

Guile 2.2 has a (ice-9 sandbox) module, documented at

https://www.gnu.org/software/guile/docs/docs-2.2/guile-ref/Sandboxed-Evaluation.html#index-make_002dsandbox_002dmodule

Earlier Guile already had the (ice-9 safe) module, which
provided a somewhat similar facility (which is also richer,
as it allows imposing time and memory limits on execution).

LilyPond currently uses (ice-9 safe) to implement its -dsafe mode.
Is it deprecated? Should we move to (ice-9 sandbox)? Is there anything
particular to be aware of in that transition that explains why (ice-9 safe)
remains around?

Thanks,
Jean





"INTERNAL ERROR IN FORMAT-ERROR!"

2022-04-19 Thread Jean Abou Samra

Hi,

The simple file

(format #f "~f" 'invalid)

gives me

FORMAT: error with call: (format #f "~f<===" ===>invalid )
    argument is not a number or a number string
FORMAT: INTERNAL ERROR IN FORMAT-ERROR!
    destination: #f
    format string: "~f"
    format args: (invalid)
    error args:  (#f "error in format" () #f)
ice-9/boot-9.scm:1685:16: In procedure raise-exception:
error in format


Is it expected to see 'INTERNAL ERROR IN FORMAT-ERROR!'?
To me, that has a meaning similar to an assertion failure.

Best,
Jean




[PATCH] In curried definitions, move docstrings to outermost lambda

2022-03-28 Thread Jean Abou Samra

Hi,

Please consider the following patch, fixing bug #50068.

Best regards,
Jean



From 79552d2974e9cbcfcf01960aab68cb6824c88972 Mon Sep 17 00:00:00 2001
From: Jean Abou Samra 
Date: Tue, 29 Mar 2022 00:14:45 +0200
Subject: [PATCH] In curried definitions, move docstrings to outermost lambda

This makes the docstring attached to the curried function being defined
rather than the result of its application until a function that runs the
body is obtained, fixing
https://debbugs.gnu.org/cgi/bugreport.cgi?bug=50068
---
 module/ice-9/curried-definitions.scm  | 72 ---
 test-suite/tests/curried-definitions.test | 56 --
 2 files changed, 90 insertions(+), 38 deletions(-)

diff --git a/module/ice-9/curried-definitions.scm 
b/module/ice-9/curried-definitions.scm

index 7545338e3..7e758be5e 100644
--- a/module/ice-9/curried-definitions.scm
+++ b/module/ice-9/curried-definitions.scm
@@ -4,12 +4,12 @@
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 3 of the License, or (at your option) any later version.
-
+
  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.
-
+
  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
02110-1301 USA

@@ -20,38 +20,42 @@
  define-public
  define*-public))

-(define-syntax cdefine
-  (syntax-rules ()
-    ((_ (head . rest) body body* ...)
- (cdefine head
-   (lambda rest body body* ...)))
-    ((_ name val)
- (define name val
+(define-syntax make-currying-define
+  (syntax-rules ::: ()
+    ((_ currying-name lambda-name)
+ (define-syntax currying-name
+   (lambda (St-Ax)
+ (syntax-case St-Ax ()
+   ((_ ((head2 . rest2) . rest) docstring body body* ...)
+    (string? (syntax->datum #'docstring))
+    ;; Keep moving docstring to outermost lambda.
+    #'(currying-name (head2 . rest2)
+    docstring
+    (lambda-name rest body body* ...)))
+   ((_ (head . rest) body body* ...)
+    #'(currying-name head
+    (lambda-name rest body body* ...)))
+   ((_ name val)
+    #'(define name val

-(define-syntax cdefine*
-  (syntax-rules ()
-    ((_ (head . rest) body body* ...)
- (cdefine* head
-   (lambda* rest body body* ...)))
-    ((_ name val)
- (define* name val
+(make-currying-define cdefine lambda)
+(make-currying-define cdefine* lambda*)

-(define-syntax define-public
-  (syntax-rules ()
-    ((_ (head . rest) body body* ...)
- (define-public head
-   (lambda rest body body* ...)))
-    ((_ name val)
- (begin
-   (define name val)
-   (export name)
+(define-syntax make-currying-define-public
+  (syntax-rules ::: ()
+    ((_ public-name define-name)
+ (define-syntax public-name
+   (lambda (St-Ax)
+ (syntax-case St-Ax ()
+   ((_ binding body body* ...)
+    #`(begin
+    (define-name binding body body* ...)
+    (export #,(let find-name ((form #'binding))
+    (syntax-case form ()
+  ((head . tail)
+   (find-name #'head))
+  (name
+   #'name

-(define-syntax define*-public
-  (syntax-rules ()
-    ((_ (head . rest) body body* ...)
- (define*-public head
-   (lambda* rest body body* ...)))
-    ((_ name val)
- (begin
-   (define* name val)
-   (export name)
+(make-currying-define-public define-public cdefine)
+(make-currying-define-public define*-public cdefine*)
diff --git a/test-suite/tests/curried-definitions.test 
b/test-suite/tests/curried-definitions.test

index b4a1f6509..cd535b162 100644
--- a/test-suite/tests/curried-definitions.test
+++ b/test-suite/tests/curried-definitions.test
@@ -5,12 +5,12 @@
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 3 of the License, or (at your option) any later version.
-
+
  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.
-
+
  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, 

Macro for Python-style debugging output

2022-03-28 Thread Jean Abou Samra

The following macro is a variant of peek that mimics Python's = format
specifier (e.g. print(f"{a=} {a+b=}")) by printing expressions and the
values they evaluate to.

(define-syntax-rule (db arg ...)
  (begin
    (let ((evaluated-arg arg))
  (format (current-error-port) ";;; ~s => ~s\n" (quote arg) 
evaluated-arg)

  evaluated-arg)
    ...))

Am I reinventing the wheel? Does anyone see value in this
being added to Guile?

Thanks,
Jean




Are source locations broken?

2022-03-25 Thread Jean Abou Samra

Hi,

Please have a look at:

$ ./libguile/guile test.scm
;;; note: auto-compilation is enabled, set GUILE_AUTO_COMPILE=0
;;;   or pass the --no-auto-compile argument to disable.
;;; compiling /home/jean/Bureau/ENS-1A/dm_anac/test.scm
;;; : warning: possibly unbound variable 
`unbound-variable'
;;; compiled 
/home/jean/.cache/guile/ccache/3.0-LE-8-4.6/home/jean/Bureau/ENS-1A/dm_anac/test.scm.go 


Backtrace:
[snipped]


Note the . In LilyPond, I suddenly lost
all locations for compilation warnings when upgrading from
Guile 3.0.5 to 3.0.8. The above is with the main branch.





Heads-up: LilyPond now running Guile 2.2

2022-03-17 Thread Jean Abou Samra

For your information:

https://gitlab.com/lilypond/lilypond/-/merge_requests/1250





Re: Guile optimizations slowing down the program?

2022-03-09 Thread Jean Abou Samra



> Le 9 mars 2022 à 08:53, "Dr. Arne Babenhauserheide"  a écrit 
> :
> 
> 
> Maxime Devos  writes:
>> Jean Abou Samra schreef op wo 09-03-2022 om 00:31 [+0100]:
>>> In summary, the less Guile optimizes, the faster LilyPond runs. Is that
>>> something expected?
>> 
>> I don't think so, but I don't have a clue how this happens ...
> 
> Do I understand it correctly that Lilypond has lots of snippets that are
> executed exactly once? In that case it could be expected that the
> overhead of optimization dominates — maybe even the overhead of
> increased code-size from inlining?


What is byte-compiled in these experiments is not the code from .ly files 
(which is always evaluated via primitive-eval and not compiled), but the code 
from LilyPond's .scm files. The compilation is done ahead of time, so its 
overhead can't be responsible for these results.


> Also the new baseline compiler is already pretty good:
> https://wingolog.org/archives/2020/06/03/a-baseline-compiler-for-guile



> Maybe this?
> 
>> There is also a felicitous feedback effect in that because the
>> baseline compiler is much smaller than the CPS compiler, it takes less
>> time to macro-expand — 
>> https://wingolog.org/archives/2020/06/03/a-baseline-compiler-for-guile


As far as I understand, this is about the speed of compilation. For the reason 
explained above, it doesn't factor into the speed of LilyPond.

Thanks for responding!

Jean


> 
> Best wishes,
> Arne
> -- 
> Unpolitisch sein
> heißt politisch sein,
> ohne es zu merken.
> draketo.de



Guile optimizations slowing down the program?

2022-03-08 Thread Jean Abou Samra

Hi,

LilyPond has a fairly sized body of Scheme code. With Guile 2,
the byte-compilation with default settings takes 1 minute, and
1min30 with Guile 3, so I've been experimenting with reducing
optimizations to make it faster for development cycles. I've found
that disabling optimizations reduces the byte-compilation time to
20s in Guile 2, and just 4s in Guile 3 (thanks to the baseline
compiler). Naturally, I've tried to see how much that slowed down
the resulting version of LilyPond. To my surprise, it looks like
these unoptimized versions are actually faster. In Guile 2, I'm
not sure if the difference is significant, but it definitely looks
so in Guile 3. This is one benchmark, comparing optimization level
0 against level 2 (the latter is the default):

  Baseline   New executable    Delta
_
│ Min    │ 4.060    │ 4.020  │ 
-0.99% │
│ Mean   │ 4.138    │ 4.096  │ 
-1.03% │
│    │  │    │ (difference is -2.86 
times standard error) │
│ Standard error │ 0.014    │ 0.015 
│    │

└┴──┴┴┘


Here's a different benchmark (on a much larger LilyPond file):

  Baseline   New executable    Delta
___
│ Min    │ 35.380   │ 34.600 │ 
-2.20% │
│ Mean   │ 36.065   │ 34.913 │ 
-3.20% │
│    │  │    │ (difference is -9.10 
times standard error) │
│ Standard error │ 0.173    │ 0.080 
│    │

└┴──┴┴┘



Same benchmarks, with optimization level 1:

   Baseline   New executable   Delta
___
│ Min    │ 4.040    │ 4.040  │ 
0.00%  │
│ Mean   │ 4.256    │ 4.244  │ 
-0.28% │
│    │  │    │ (difference is -0.57 
times standard error) │
│ Standard error │ 0.022    │ 0.020 
│    │

└─|

  Baseline    New executable   Delta

___
│ Min    │ 35.500   │ 34.450 │ 
-2.96% │
│ Mean   │ 36.069   │ 35.081 │ 
-2.74% │
│    │  │    │ (difference is -6.27 
times standard error) │
│ Standard error │ 0.117    │ 0.198 
│    │

└┴──┴┴┘


In summary, the less Guile optimizes, the faster LilyPond runs. Is that
something expected?

Best,
Jean




Re: 'guild compile' and C(++) extensions (in the context of LilyPond)

2022-02-21 Thread Jean Abou Samra




Le 19/02/2022 à 22:25, Olivier Dion a écrit :

On Sat, 19 Feb 2022, Jean Abou Samra  wrote:

I had similar problem with Jami.  I added C++ primitives to Guile, but
these were not load using the foreign function interface.  Note, I'm
using Guile 3.0.8, but I think the same could be done for Guile 2.0.

Basically what I do is to add a `compile` command to my program so to
speak.

So usually the program does this:
 main -> install_scheme_primitives() -> Run the program

And for compilation
 main -> compile_in_guile() -> install_scheme_primitives() -> 
compile-file


To be clear here's what install_scheme_primitives() does:

void
install_scheme_primitives()
{
 /* Define modules here */
 auto load_module = [](auto name, auto init){
 scm_c_define_module(name, init, NULL);
 };

 load_module("jami account", install_account_primitives);
 load_module("jami call", install_call_primitives);
 load_module("jami conversation", install_conversation_primitives);
 load_module("jami logger bindings", install_logger_primitives);
 load_module("jami signal bindings", install_signal_primitives);
}


and here's what compile_in_guile() does:

void*
compile_in_guile(void* args_raw)
{
 // ...
 install_scheme_primitives();

 // This string is usually formatted
 scm_c_eval_string("(use-modules (system base compile))"
   "(compile-file \"foo.scm\" #:output-file \"foo.go\")")

// ..
}


so now I can correctly compile any file in the project.  I just add this
to Makefile.am:

MODULES  = foo.scm
GOBJECTS = $(MODULES:%=%.go)

%.go: %.scm | program
 @echo GUILD; ./program compile $< $@


Hope that can help.




Thank you Olivier, this is hugely helpful. So far we thought
we'd need to restructure our set of Scheme files in proper
modules to make separate byte-compilation happen. This works
in my experiments, and can compile several files that are
part of the same module as well, using the #:env argument
of compile-file. Thanks again, much appreciated.

Best regards,
Jean




'guild compile' and C(++) extensions (in the context of LilyPond)

2022-02-19 Thread Jean Abou Samra

Hi,

(Cross-posted to guile-user, guile-devel and the debbugs
issue, I'm unsure where this should go.)

In LilyPond, we have now made a development release with
binaries using Guile 2.2. However, a major problem is that
we don't ship Guile bytecode yet. Notably, one problem
to get the bytecode in a build system is that we are
currently forced to use GUILE_AUTO_COMPILE=1 to generate
it -- which means we need to compile the entire suite of
regression tests in order to exercise all files. This
also means spurious test differences when Guile gets
noisy about byte-compilation 
(https://debbugs.gnu.org/cgi/bugreport.cgi?bug=16364).

In summary: it would mean a lot less headache to be
able to use 'guild compile'. Unfortunately, this does
not work. One issue is that our Scheme files are mostly
not Guile modules, but loaded directly with primitive-load-path.
This will be a lot of work to fix, but it is on our end.
However, I don't understand how to get around another
issue, which is how our Scheme code interfaces with C++.

  https://debbugs.gnu.org/cgi/bugreport.cgi?bug=52230

Basically, if a Scheme file has something like

  (define-public point-stencil (ly:make-stencil "" '(0 . 0) '(0 . 0)))

where ly:make-stencil is a procedure defined in C++,
I can get this file to compile, but I can't get files
using it as a module to compile. Investigation shows
that Guile is apparently trying to load the module
when compiling.

$ cat print.scm
(define-module (print))

(display "Module running!")
$ guild compile print.scm
wrote 
`/home/jean/.cache/guile/ccache/3.0-LE-8-4.4/home/jean/repos/lilypond/print.scm.go' 


$ cat import.scm
(use-modules (print))
$ guild compile -L . print.scm
wrote 
`/home/jean/.cache/guile/ccache/3.0-LE-8-4.4/home/jean/repos/lilypond/print.scm.go' 


$ guild compile -L . import.scm
Module running!wrote 
`/home/jean/.cache/guile/ccache/3.0-LE-8-4.4/home/jean/repos/lilypond/import.scm.go' 




For functions defined in C++, that does not work: they
are added by the entry point in the function that scm_boot_guile
calls, using scm_c_define_gsubr. They aren't defined until
the program is actually run.

So how is 'guild compile' supposed to work with C(++) code?

Thanks in advance,
Jean




Re: Maintenance and future of Guile (was: [patch] Add instructions for sending patches)

2021-12-13 Thread Jean Abou Samra

Le 13/12/2021 à 23:18, Jean Abou Samra a écrit :

I understand the cost of reviewing and I know that
nobody is entitled to anything in the free software
world.




Sorry, this is me non-native-speaker mixing up
terms. I meant _obligated_, of course!

Jean



Maintenance and future of Guile (was: [patch] Add instructions for sending patches)

2021-12-13 Thread Jean Abou Samra

Hi,

Dr. Arne Babenhauserheide schreef op za 11-12-2021 om 16:12 [+0100]:
>/+ (p "To contribute small improvements, please send patches to/
>/"/
>/+    (a (@ (href "mailto:guile-devel@gnu.org; 
<mailto:guile-devel@gnu.org;>;))/

>/"guile-devel@gnu.org")/
>/+   ".")/

What about contributing _large_ improvements?
Where should patches for large improvements go?

>/+ (p "For larger changes, please discuss them first in the "/
>/+ (a (@ (href "https://mail.gnu.org/mailman/listinfo/guile->/
devel/")) "development mailing list")

What if I tried to discuss them, but nobody answered?
(https://debbugs.gnu.org/cgi/bugreport.cgi?bug=46258)
(Not 100% accurate though, because I discussed the interface on IRC a
bit IIRC? I can't find it in the logs anymore though.)

What if, I then proceed with writing the patches, and nobody responds
with some points to work on or applies it?
(https://lists.gnu.org/archive/html/guile-devel/2021-03/msg00026.html)
(The only response is a +1-style response.)

What if, eight months later, I send a simplified patch series, with
things made more consistent, and with much more tests, and this time,
there is exactly one response, with a minor point that is quickly
addressed
(https://lists.gnu.org/archive/html/guile-devel/2021-11/msg00019.html),
but the patches aren't applied?

There have been many commits and two releases since the first patch
series
(https://git.savannah.gnu.org/cgit/guile.git/log/?id=653cc0bf953a11432f77ade9c007848e947cc430=range=653cc0bf953a11432f77ade9c007848e947cc430..HEAD=100
  
<https://git.savannah.gnu.org/cgit/guile.git/log/?id=653cc0bf953a11432f77ade9c007848e947cc430=range=653cc0bf953a11432f77ade9c007848e947cc430..HEAD=100>)
, without any signs that it will actually ever be applied.

So I guess what I'm trying to say, is that while your patch documenting
how to contribute seems reasonable to me, it has been very inaccurate
for me in practice (not your fault!).

Greetings,
Maxime



I concur with this concern. The patch
https://lists.gnu.org/archive/html/guile-devel/2021-07/msg0.html
has been proposed five months ago and after
several pings still only saw responses from Maxime.
It comes from a LilyPond developer trying to fix
issues relevant for LilyPond.

https://debbugs.gnu.org/cgi/bugreport.cgi?bug=16364#19
is a patch allowing to silence the auto-compilation
logging, which is also somewhat relevant to our use
case. It has not seen any reaction.

I see a number of similar cases on the mailing list.

I understand the cost of reviewing and I know that
nobody is entitled to anything in the free software
world. However, I would like to voice the concern that
Guile's maintenance is not scaling, and the project
cannot attract new contributors if patches do not
make it to the main branch. If the current maintainers
need to drop their activity, it would be nice if
they could share maintainership so that at least
bug fixes can be applied.

(NB: Sending this as myself, _not_ after any sort
of discussion at LilyPond.)

Thank you for your consideration,
Jean Abou Samra




Re: Auto-compilation and the REPL

2021-07-03 Thread Jean Abou Samra


 
 
  
   
Le 27/06/2021 00:04, Jean Abou Samra <j...@abou-samra.fr> a écrit :
   
   

   
   

   
   
Hello,
   
   

   
   
It seems that Guile always compiles the code
   
   
entered at the REPL even with --no-auto-compile:
   
   

   
   
jean@laptop-jean:~/repos/lilypond$ guile --no-auto-compile
   
   
GNU Guile 3.0.5.130-5a1e7
   
   
[Copyright notices...]
   
   
scheme@(guile-user)> (nonexistent-procedure)
   
   
;;; :1:1: warning: possibly unbound variable `nonexistent-procedure'
   
   
ice-9/boot-9.scm:1685:16: In procedure raise-exception:
   
   
Unbound variable: nonexistent-procedure
   
   

   
   
Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
   
   

   
   

   
   
The ;;;  warning is the same as when compiling this
   
   
code in a script.
   
   

   
   
Is this expected? I couldn't find anything about it in the
   
   
documentation.
   
   

   
   
Thanks,
   
   
Jean Abou Samra
   
  
  
   
  
  
   Forwarding this to the guile-devel list. Should this be considered a bug?
   
  
  
   
  
  
   Best regards,
   
  
  
   Jean Abou Samra