Re: [BUG] Eval sets incorrect runtime metainformation

2024-06-26 Thread Andy Wingo
On Wed 26 Jun 2024 11:36, Maxime Devos  writes:

> IIRC, the question wasn’t about debugging in general, it was about
> source locations in particular. Surely program-sources (or, in this
> case, procedure-source maybe?) (why are the procedures in this family
> even named program-whatever, this prevents doing the same for
> interpreted code later) could be adjusted to also work for ‘eval’. For
> example, ‘eval’ could set the ‘source’ (*) procedure property when a
> closure is made.

I think it's really valuable to imagine how things should be but if you
are going to argue they should be different, you should first try to
understand how they are.

`program-sources` is a mapping from bytecode offsets to source
locations.  For compiled procedures we can make this mapping because
each bytecode position has a single source.  For interpreted procedures,
what you end up getting is the bytecode-to-source mapping *for eval*,
not for the code being interpreted.

Is it a great thing that there is a debugging (I use the term on purpose
to mean all kinds of run-time reflection etc) difference between eval
and compile?  No, of course not.  I would rather there not be a
difference and not have to document something that is at best
extraneous.  There are differing pressures on eval: for bootstrap times
(and macro expansion time) you want it to have the least amount of
overhead possible, whereas for debugging you want to attach meta-data
that isn't strictly needed at run-time.  Attaching that meta-data has
memory and time overheads.

If we are looking to get the source location *just of the interpreted
closure* -- that is possible; see eval.scm:581, there you would attach
some other properties.  You would have to define a different debugging
interface that looks for source location information in a way different
from program-sources.  For me it's not worth it but I encourage you to
experiment with (ice-9 eval); it's just another Scheme program.  (You
would need to take a different approach to memoization, in order to pass
through source location information.)

Andy



Re: [BUG] Eval sets incorrect runtime metainformation

2024-06-26 Thread Andy Wingo
Hello,

On Tue 25 Jun 2024 17:07, Andrew Tropin  writes:

> (use-modules (system vm program)
>  (ice-9 eval-string))
>
> (eval-string "(define (test-fn) 'hey)"
>  #:file "hello.scm"
>  #:line 1
>  #:column 1
>  #:compile? #f)
>
> (format #t "~a\n" (program-sources test-fn))
> ;; ((0 ice-9/eval.scm 329 . 13) (12 ice-9/eval.scm 330 . 21) (44 
> ice-9/eval.scm 330 . 15))

What you are seeing here is that in general the debugging experience is
different for interpreted and compiled procedures.  For example, you
will not be able to set a breakpoint in interpreted code, because the
code for the closure that is part of `eval` corresponds to potentially
many different functions.  program-sources will only work usefully on
compiled procedures.
https://www.gnu.org/software/guile/manual/html_node/Compiled-Procedures.html.

I would suggest that if you are working on a rich IDE, that you pass
#:compile? #t.  Nothing else will work as you like.

That said, the evaluator does attach so-called "meta-data" information
to procedures, such as the procedure name.
https://www.gnu.org/software/guile/manual/html_node/Procedure-Properties.html.
If you know that you are making a procedure you can insert some
meta-data for use by your run-time, in an initial vector alist.  See
https://www.gnu.org/software/guile/manual/html_node/Procedure-Properties.html.
But that's limited and doesn't take macros, etc into account.

Regards,

Andy



Re: what to do about gnulib

2024-06-24 Thread Andy Wingo
Hi Bruno!

Thanks for your kind answer and tips :)

On Mon 24 Jun 2024 19:09, Bruno Haible  writes:

> I can reproduce a problem by
>   0. using a git checkout of guile ('main' branch, not 'master' branch),
>   1. using a GNU gettext version 0.22.5, 0.21, 0.20.2, or 0.19.8.1,
>   2. removing the gnulib-local/m4/clock_time.m4.diff file, which no longer
>  applies,
>   3. running
>  $ $GNULIB_SRCDIR/gnulib-tool --update
>   4. running
>  $ ./autogen.sh
>  (which is what the HACKING file recommends).
>
> It fails with
>
> configure:12833: error: possibly undefined macro: gl_PTHREADLIB
>   If this token and others are legitimate, please use m4_pattern_allow.
>   See the Autoconf documentation.
> configure:12943: error: possibly undefined macro: gl_WEAK_SYMBOLS
> configure:27584: error: possibly undefined macro: gl_TYPE_WINT_T_PREREQ
> autoreconf: error: /usr/bin/autoconf failed with exit status: 1
>
> Following your analysis, I locally apply the workaround from the Gnulib
> documentation section "3.11 Caveat: gettextize and autopoint users",

Thank you!  It is embarrassing but I did not know this manual existed.
I will use this workaround.

Question, do you think it would be reasonable for autopoint to avoid
overwriting newer files?  It seems like the sort of problem we could
avoid, but who knows.

>   373 | unreachable (scm_jit_state *j)

Ah interesting, will fix.

> The way Guile handles versioning of Gnulib-imported files is fine.

That's great to hear.  In that case, no change planned to how we do
things.

> Note, though, that the imported po/ infrastructure will still be from 2010,
> due to this line in configure.ac:
>   AM_GNU_GETTEXT_VERSION([0.18.1])
> It would be reasonable to bump this version specification to
>   AM_GNU_GETTEXT_VERSION([0.19.8.1])
> (from 2016) or
>   AM_GNU_GETTEXT_VERSION([0.20.2])
> (from 2020) or
>   AM_GNU_GETTEXT_VERSION([0.21.1])
> (from 2022).
>
> Note also that when upgrading to a newer Gnulib, you now have another choice
> than Gnulib's 'master' branch: the 'stable-202401' branch. See the Gnulib
> documentation [2], section "1.6.1 Stable Branches".

Thanks!!

Best regards,

Andy



fyi: deleted `master` branch

2024-06-24 Thread Andy Wingo
Hi,

Following the conventional switch to name the main development branch
`main` instead of `master`, I have deleted the `master` branch which
wasn't being automatically kept in sync and could confuse people.
Thanks to Bruno Haible for his detailed notes reproducing my problems
updating gnulib :)

Andy




what to do about gnulib

2024-06-24 Thread Andy Wingo
Hi,

I am not sure what to do about gnulib.

To recap, gnulib provides compile-time shims for "foreign" or
out-of-date target systems that allows Guile to program to a single
POSIX + GNU API and not worry too much about what the system actually
offers.  It is never installed; instead it includes the `gnulib-tool`
utility to update the in-tree copy of gnulib, for a selected set of
modules.

So far, so good.  However I was unable to update gnulib before the most
recent release.  The reason is essentially the problem described in this
issue:

  https://sourceware.org/bugzilla/show_bug.cgi?id=30051

To wit, running "autoreconf -vif" invokes the "autopoint" tool supplied
by installed gettext, which copies over .m4 files from installed
gettext, but these files are older than the ones that are already
"vendored" in-tree by gnulib.  Other parts of gnulib depend on the newer
gnulib-supplied macros which were stompled over; autoconf thus fails to
run.

So, I can't update gnulib right now.  Not a great situation.  The
options, as I understand them:

  1. Some projects (e.g. poke) seem to import the whole of gnulib as a
 git submodule, and then run "gnulib-tool --update" from that
 submodule as part of their bootstrap.  In this way the stompled
 files are restored.  However I do not want git submodules in Guile;
 they add additional steps for every time you change to a different
 HEAD, and I know from experience that I can't rely on myself to
 perform them all, much less any user with a bug report.  Do not
 want.

  2. Same as (1), but subtree merge.  This is what we do with lightening
 and what I would like to do with Whippet, if that project works
 out.  But gnulib is big; a checkout is 200 MB of data + 130 MB git
 repo.

  ** Note, for (1) and (2), if you wanted to preserve the ability to
 bootstrap from a tarball, you'd have to include gnulib in the
 tarball.  Of course you could argue that if you are not gnulib-tool
 --update'ing, are you really bootstrapping?  I don't know the
 answer.  ***

  3. Fix autopoint to not overwrite newer m4 files with its copies.  I
 don't know?

  4. Fix installed gettext to not define gl_ macros ?  That would make
 it so that it won't stomple on a local gnulib copy.  I don't know
 though.

  5. Update to whatever version of gnulib is the latest without this
 change?

  6. Something else?  Stop using gnulib?

I am not a gnulib wizard and would appreciate any thoughts :)  Cc'ing
Bruno as he is the expert.  Really I would like to avoid gnulib-tool
--update in Guile's bootstrap and just keep things like it is.  Of
course I could be being unreasonable.

Cheers,

Andy



GNU Guile 3.0.10 released

2024-06-23 Thread Andy Wingo
We are pleased to announce GNU Guile release 3.0.10, the latest in the
3.0 stable release series.

Guile 3.0.10 is a bug-fix release which also adds optimizations, support
for a new WebAssembly back-end, new custom port facilities, a new
optional front-end syntax, and more.  See the NEWS extract at the end of
the mail for full details.

Here are the compressed sources:
  ftp://ftp.gnu.org/gnu/guile/guile-3.0.10.tar.gz   (9.3MB)
  ftp://ftp.gnu.org/gnu/guile/guile-3.0.10.tar.lz   (5.3MB)
  ftp://ftp.gnu.org/gnu/guile/guile-3.0.10.tar.xz   (5.6MB)

Here are the GPG detached signatures:
  ftp://ftp.gnu.org/gnu/guile/guile-3.0.10.tar.gz.sig
  ftp://ftp.gnu.org/gnu/guile/guile-3.0.10.tar.lz.sig
  ftp://ftp.gnu.org/gnu/guile/guile-3.0.10.tar.xz.sig

Use a mirror for higher download bandwidth:
  https://www.gnu.org/order/ftp.html

Here are the SHA1 and SHA256 checksums:

ca52ff876b8552b6f8f70231cc33ef7cbcc4a95f  guile-3.0.10.tar.gz
Lb28l1mLL68xATVk77SOT+1EEx0o6ZbCar6KWyO1bCo  guile-3.0.10.tar.gz
105a99a0771d7371502b529b762abe18d729930e  guile-3.0.10.tar.lz
8Nl8zPUG5LYQTFFjm9G3v2dADgs0AfCy9rcTZTIEAyc  guile-3.0.10.tar.lz
e95e37f681dae692de52242929cbc7092eef3eb4  guile-3.0.10.tar.xz
vXFoUX/VJjM0RtT3q4FlJ5JWNAlPvTcyLhfiuNjnY4g  guile-3.0.10.tar.xz

The SHA256 checksum is base64 encoded, instead of the
hexadecimal encoding that most checksum tools default to.

Use a .sig file to verify that the corresponding file (without the
.sig suffix) is intact.  First, be sure to download both the .sig file
and the corresponding tarball.  Then, run a command like this:

  gpg --verify guile-3.0.10.tar.gz.sig

The signature should match the fingerprint of the following key:

  pub   rsa4096 2017-08-09 [SC]
4FD4 D288 D445 934E 0A14  F9A5 A880 3732 E443 6885
  uid   Andy Wingo 
  uid   Andy Wingo 
  uid   Andy Wingo 

If that command fails because you don't have the required public key,
or that public key has expired, try the following commands to retrieve
or refresh it, and then rerun the 'gpg --verify' command.

  gpg --recv-keys 4FD4D288D445934E0A14F9A5A8803732E4436885

As a last resort to find the key, you can try the official GNU
keyring:

  wget -q https://ftp.gnu.org/gnu/gnu-keyring.gpg
  gpg --keyring gnu-keyring.gpg --verify guile-3.0.10.tar.gz.sig


This release was bootstrapped with the following tools:
  Autoconf 2.71
  Automake 1.16.5
  Libtool 2.4.7
  Gnulib v0.1-4855-g8f4538a53d
  Makeinfo 7.1

An extract from NEWS follows.


* Notable changes

** Beginnings of support for alternate back-ends

A number of adaptations and additions of as-yet unstable interfaces have
been made to allow third-party projects such as the Hoot
Guile-to-WebAssembly whole-program compiler
(https://spritely.institute/hoot/) to use the Guile front-end and
optimizer.  Depending on how Hoot development goes, we may consider
adding first-class support for WebAssembly as a compilation target;
discussion is welcome on the guile-devel mailing list.

** `define` in all bodies

`define` adds a definition to the body in which it appears, as if each
non-tail definition or expression in that body were a binding in a
surrounding `letrec*` clause.  However, in some places, using `define`
would result in the annoying error "definition in expression context,
where definitions are not allowed", which could be fixed by explicitly
adding a surrounding binding contour, for example an empty `let`.  This
was because there was no implicit surrounding lexical binding contour
for the body of `when` and `unless`, for `cond` clauses, `case` clauses,
`and-let*` bodies, and `with-fluids`.  But no more; now these contexts
now create a binding contour, allowing the use of `define`.

** Two bug fixes of note regarding scoping of top-level variables

Previously, a reference to a top-level variable in a module other than
the current module would be silently rewritten to reference the current
module, if the variable was unbound in its original module.  This was a
hack from the early days of when we extended psyntax to know about the
module system, and is now fixed to properly use the scope of the
introduced binding instead of the scope of the macro use site.

Also, embarrassingly, sometimes macro-introduced top-level variables
would use the same generated name.  This is because of the strategy
discussed in the manual, "Hygiene and the Top-Level"; sometimes the
hashes would collide, for example if two definitions were the same in
the beginning and only differed long into the end.  This has been fixed
to ensure name uniqueness.

* New interfaces and functionality

** R6RS custom textual ports

Guile finally supports this venerable R6RS interface; see "Custom Ports"
in the manual for more.  These ports are suspendable (see "Non-Blocking
I/O").  Also new in this release, custom binary ports are now
suspendable as well.

** New "soft port" interface

Instead of using R6RS custom textual ports, we recommend

GNU Guile 3.0.8 released

2022-02-12 Thread Andy Wingo
[A resend, as original mail accidentally had two From headers; apologies
for any duplicates!]

We are delighted to announce GNU Guile release 3.0.8, the latest in the
3.0 stable release series.

The Guile 3.0.8 release mixes maintenance and optimizations that were
landed since the previous 3.0.7 stable release in May 2021.  See the
NEWS extract at the end of the mail for full details.

Compared to the previous stable series (2.2.x), Guile 3.0 adds support
for just-in-time native code generation, speeding up all Guile programs.


The Guile web page is located at http://gnu.org/software/guile/, and
among other things, it contains a copy of the Guile manual and pointers
to more resources.

Guile is an implementation of the Scheme programming language, packaged
for use in a wide variety of environments.  In addition to implementing
the R5RS, R6RS, and R7RS Scheme standards, Guile includes full access to
POSIX system calls, networking support, multiple threads, dynamic
linking, a foreign function call interface, powerful string processing,
and HTTP client and server implementations.

Guile can run interactively, as a script interpreter, and as a Scheme
compiler to VM bytecode.  It is also packaged as a library so that
applications can easily incorporate a complete Scheme interpreter/VM.
An application can use Guile as an extension language, a clean and
powerful configuration language, or as multi-purpose "glue" to connect
primitives provided by the application.  It is easy to call Scheme code
from C code and vice versa.  Applications can add new functions, data
types, control structures, and even syntax to Guile, to create a
domain-specific language tailored to the task at hand.

Guile 3.0.8 can be installed in parallel with Guile 2.2.x; see
http://www.gnu.org/software/guile/manual/html_node/Parallel-Installations.html.

A more detailed NEWS summary follows these details on how to get the
Guile sources.

Here are the compressed sources:
  http://ftp.gnu.org/gnu/guile/guile-3.0.8.tar.lz   (6MB)
  http://ftp.gnu.org/gnu/guile/guile-3.0.8.tar.xz   (6MB)
  http://ftp.gnu.org/gnu/guile/guile-3.0.8.tar.gz   (10MB)

Here are the GPG detached signatures[*]:
  http://ftp.gnu.org/gnu/guile/guile-3.0.8.tar.lz.sig
  http://ftp.gnu.org/gnu/guile/guile-3.0.8.tar.xz.sig
  http://ftp.gnu.org/gnu/guile/guile-3.0.8.tar.gz.sig

Use a mirror for higher download bandwidth:
  http://www.gnu.org/order/ftp.html

Here are the SHA256 checksums:

  96f5263f89dda2d757fe1129e489e672f5a0b7540ee6710ec7ef352120d8af52  
guile-3.0.8.tar.lz
  daa7060a56f2804e9b74c8d7e7fe8beed12b43aab2789a38585183fcc17b8a13  
guile-3.0.8.tar.xz
  f25ae0c26e911af1b5005292d4f56621879f74d6958b30741cf67d8b6feb2016  
guile-3.0.8.tar.gz

[*] Use a .sig file to verify that the corresponding file (without the
.sig suffix) is intact.  First, be sure to download both the .sig file
and the corresponding tarball.  Then, run a command like this:

  gpg --verify guile-3.0.8.tar.gz.sig

If that command fails because you don't have the required public key,
then run this command to import it:

  gpg --keyserver keys.gnupg.net --recv-keys 
4FD4D288D445934E0A14F9A5A8803732E4436885

and rerun the 'gpg --verify' command.

This release was bootstrapped with the following tools:
  Autoconf 2.71
  Automake 1.16.2
  Libtool 2.4.6
  Gnulib v0.1-4855-g8f4538a53d
  Makeinfo 6.7

An extract from NEWS follows.


Changes in 3.0.8 (since 3.0.7):

* Notable changes

** Cross-module inlining

Although historically Guile has treated modules as glorified hash
tables, most modules are actually _declarative_ -- they just define
functions and variables and provide them for other modules to use, and
don't manipulate modules as first-class objects.  See "Declarative
Modules" in the manual, for more discussion.

Since version 3.0.0, Guile has taken advantage of declarative semantics
to allow a top-level definition to be inlined within its uses in the
same compilation unit, provided the binding is never assigned and
defined exactly once.  Guile 3.0.8 extends this to allow some
exported declarative definitions to be inlined into other modules.

This facility is mostly transparent to the user and is enabled at the
default -O2 optimization level.  "Small" definitions are available for
cross-module inlining (-Oinlinable-exports, included at -O2).  The
actual inlining decision is performed by Guile's partial evaluation pass
(the -Ocross-module-inlining modifier to -Opeval, included at -O2 also),
subject to effort and size growth counters.

Note however that as with macros, when a definition changes in module A,
a separately compiled module B that uses that definition doesn't
automatically get recompiled.  This is a limitation in Guile that we
would like to fix.

As another limitation, cross-module inlining is only available for
imports from modules which have already been compiled at -O2 (or
otherwise with -Oinlinable-exports).

When determining whether to enable this facility by default, we weighed
the usabil

GNU Guile 3.0.8 released

2022-02-10 Thread Andy Wingo
We are delighted to announce GNU Guile release 3.0.8, the latest in the
3.0 stable release series.

The Guile 3.0.8 release mixes maintenance and optimizations that were
landed since the previous 3.0.7 stable release in May 2021.  See the
NEWS extract at the end of the mail for full details.

Compared to the previous stable series (2.2.x), Guile 3.0 adds support
for just-in-time native code generation, speeding up all Guile programs.


The Guile web page is located at http://gnu.org/software/guile/, and
among other things, it contains a copy of the Guile manual and pointers
to more resources.

Guile is an implementation of the Scheme programming language, packaged
for use in a wide variety of environments.  In addition to implementing
the R5RS, R6RS, and R7RS Scheme standards, Guile includes full access to
POSIX system calls, networking support, multiple threads, dynamic
linking, a foreign function call interface, powerful string processing,
and HTTP client and server implementations.

Guile can run interactively, as a script interpreter, and as a Scheme
compiler to VM bytecode.  It is also packaged as a library so that
applications can easily incorporate a complete Scheme interpreter/VM.
An application can use Guile as an extension language, a clean and
powerful configuration language, or as multi-purpose "glue" to connect
primitives provided by the application.  It is easy to call Scheme code
from C code and vice versa.  Applications can add new functions, data
types, control structures, and even syntax to Guile, to create a
domain-specific language tailored to the task at hand.

Guile 3.0.8 can be installed in parallel with Guile 2.2.x; see
http://www.gnu.org/software/guile/manual/html_node/Parallel-Installations.html.

A more detailed NEWS summary follows these details on how to get the
Guile sources.

Here are the compressed sources:
  http://ftp.gnu.org/gnu/guile/guile-3.0.8.tar.lz   (6MB)
  http://ftp.gnu.org/gnu/guile/guile-3.0.8.tar.xz   (6MB)
  http://ftp.gnu.org/gnu/guile/guile-3.0.8.tar.gz   (10MB)

Here are the GPG detached signatures[*]:
  http://ftp.gnu.org/gnu/guile/guile-3.0.8.tar.lz.sig
  http://ftp.gnu.org/gnu/guile/guile-3.0.8.tar.xz.sig
  http://ftp.gnu.org/gnu/guile/guile-3.0.8.tar.gz.sig

Use a mirror for higher download bandwidth:
  http://www.gnu.org/order/ftp.html

Here are the SHA256 checksums:

  96f5263f89dda2d757fe1129e489e672f5a0b7540ee6710ec7ef352120d8af52  
guile-3.0.8.tar.lz
  daa7060a56f2804e9b74c8d7e7fe8beed12b43aab2789a38585183fcc17b8a13  
guile-3.0.8.tar.xz
  f25ae0c26e911af1b5005292d4f56621879f74d6958b30741cf67d8b6feb2016  
guile-3.0.8.tar.gz

[*] Use a .sig file to verify that the corresponding file (without the
.sig suffix) is intact.  First, be sure to download both the .sig file
and the corresponding tarball.  Then, run a command like this:

  gpg --verify guile-3.0.8.tar.gz.sig

If that command fails because you don't have the required public key,
then run this command to import it:

  gpg --keyserver keys.gnupg.net --recv-keys 
4FD4D288D445934E0A14F9A5A8803732E4436885

and rerun the 'gpg --verify' command.

This release was bootstrapped with the following tools:
  Autoconf 2.71
  Automake 1.16.2
  Libtool 2.4.6
  Gnulib v0.1-4855-g8f4538a53d
  Makeinfo 6.7

An extract from NEWS follows.


Changes in 3.0.8 (since 3.0.7):

* Notable changes

** Cross-module inlining

Although historically Guile has treated modules as glorified hash
tables, most modules are actually _declarative_ -- they just define
functions and variables and provide them for other modules to use, and
don't manipulate modules as first-class objects.  See "Declarative
Modules" in the manual, for more discussion.

Since version 3.0.0, Guile has taken advantage of declarative semantics
to allow a top-level definition to be inlined within its uses in the
same compilation unit, provided the binding is never assigned and
defined exactly once.  Guile 3.0.8 extends this to allow some
exported declarative definitions to be inlined into other modules.

This facility is mostly transparent to the user and is enabled at the
default -O2 optimization level.  "Small" definitions are available for
cross-module inlining (-Oinlinable-exports, included at -O2).  The
actual inlining decision is performed by Guile's partial evaluation pass
(the -Ocross-module-inlining modifier to -Opeval, included at -O2 also),
subject to effort and size growth counters.

Note however that as with macros, when a definition changes in module A,
a separately compiled module B that uses that definition doesn't
automatically get recompiled.  This is a limitation in Guile that we
would like to fix.

As another limitation, cross-module inlining is only available for
imports from modules which have already been compiled at -O2 (or
otherwise with -Oinlinable-exports).

When determining whether to enable this facility by default, we weighed
the usability problems of stale inlined bindings against the benefit of
allowing module boundaries to no 

thoughts on targetting the web

2021-06-19 Thread Andy Wingo
Hi :)

A brain-dump tonight.  I was thinking about what it would mean for Guile
to target the web.  The goal would be for Guile to be a useful language
for programming client-side interaction on web pages.  Now, there are a
number of takes for Schemes of various stripes to target JS.  I haven't
made a full survey but my starting point is that in a Guile context, we
basically want the Guile Scheme language, which is to say:

 1. Tail calls.  The solution must include proper tail calls.

 2. Multiple values.  The solution should have the same semantics that
Guile has for multiple-value returns, including implicit
truncation.

 3. Varargs.  The solution should allow for rest arguments, keyword
arguments, and the like.

 4. Delimited continuations.  The solution should allow non-local exit
from any function, and should allow for capturing stack slices to
partial continuations, and should allow those continuations to be
instantiated multiple times if desired.  We should be able to target
fibers to the web.  Otherwise, why bother?

 5. Garbage collection.  *We should re-use the host GC*.  Although it
would be possible to manage a heap in linear memory, that has
retention problems due to cycles between the Guile heap and the JS
heap.

 6. Numbers.  We should support Scheme's unbounded integers.  Requires
bignums in the limit case, but thankfully JS has bignums now.  We
will still be able to unbox in many cases though.

 7. Target existing web.  We shouldn't depend on some future WebAssembly
or JS proposal -- the solution should work in the here and now and
only get better as features are added to the web platform.

>From a UX perspective, I would expect we would generally want
whole-program compilation with aggressive DCE / tree-shaking, producing
a single JS or WebAssembly artifact at build-time.  But that's a later
issue.

I have thought about this off and on over the years but in the end was
flummoxed about how to meet all requirements.  However recently I think
I have come up with a solution for most of these:

 (1) In JS, tail calls are part of ES2015, but not implemented in all
 browsers.  In WebAssembly, they are a future plan, but hard for
 various reasons.  So in practice the solution for today's web is to
 use a universal trampoline and make all calls tail calls --
 i.e. call all functions via:

   while true:
 call(pop())
 
 Whenever we can target proper tail calls, this will only get
 faster.

 (2) Neither JS nor WebAssembly have the truncation semantics we want.
 Therefore we will return values via an explicit array, and then the
 continuation will be responsible for consuming those values and
 binding any needed variables.

 (3) Although JS does have varargs support, WebAssembly does not.  But
 we can actually use the same solution here as we use for (1) and
 (2) -- pass arguments on an explicit array + nvalues, and relying
 on the function to parse them appropriately.  In this way we can
 get Guile keyword arguments.  This also makes the type of Scheme
 functions uniform, which is important in WebAssembly contexts.

 (4) This is the interesting bit!  As hinted in (1), we will transform
 the program such that all calls are tail calls.  This is a form of
 minimal CPS conversion -- minimal in the sense that functions are
 broken up into the minimum number of pieces to ensure the
 all-tail-calls property.  Non-tail calls transform to tail calls by
 saving their continuation's state on a stack, which is the same as
 stack allocation for these continuations.  The continuation of the
 call pops the saved state from the stack.  Because the stack is
 explicit, we can manipulate it as data: slice it to capture a
 delimited continuation, drop values to make a non-local exit, splat
 a saved slice back on to compose a captured delimited continuation
 with the current continuation, and so on.  Therefore we have the
 necessary primitives to implement delimited continuations as a
 library.

 (5) Scheme needs a representation that can store any value.  In JS this
 is easy because JS is untyped.  For WebAssembly, I think I would
 lean on externref for this purpose, which effectively boxes all
 values.  There are no fixnums in the current WebAssembly spec, so
 this is suboptimal, and we have to call out to JS to evaluate type
 predicates and access fields.  But, support for structured
 GC-managed types is coming to WebAssembly, which will speed up
 object access.

 (6) The easy solution here is to make JS numbers, which are doubles at
 heart, represent flonums, and use JS bignums for Scheme integers.
 Fine.

 (7) This principle has been taken into account in (1)-(6).

Now, a note on the transformation described in (4), which I call
"tailification".

The first step of tailification computes the set of 

heads-up: development branch is now "main"

2021-05-11 Thread Andy Wingo
Hi,

Just a heads-up that the main Guile development branch is now named
"main".

If you have a recent git and a fairly conventional setup, it will be
sufficient to switch your working copy by doing:

  git fetch origin
  git checkout main

Then you can continue to "git pull" as usual.

One note, the default branch that you get when you clone is currently
still "master".  This should be resolved soon.  In the meanwhile I will
keep "master" sync'd with "main".

Andy



GNU Guile 3.0.7 released

2021-05-10 Thread Andy Wingo
We are humbled to announce GNU Guile release 3.0.7, the latest in the
3.0 stable release series.

This is a fix-up release.  Compared to Guile 3.0.6, Guile 3.0.7 fixes a
number of bugs, many of which were introduced in the 3.0 series.

Compared to the previous stable series (2.2.x), Guile 3.0 adds support
for just-in-time native code generation, speeding up all Guile programs.
See the NEWS extract at the end of the mail for full details.


The Guile web page is located at http://gnu.org/software/guile/, and
among other things, it contains a copy of the Guile manual and pointers
to more resources.

Guile is an implementation of the Scheme programming language, packaged
for use in a wide variety of environments.  In addition to implementing
the R5RS, R6RS, and R7RS Scheme standards, Guile includes full access to
POSIX system calls, networking support, multiple threads, dynamic
linking, a foreign function call interface, powerful string processing,
and HTTP client and server implementations.

Guile can run interactively, as a script interpreter, and as a Scheme
compiler to VM bytecode.  It is also packaged as a library so that
applications can easily incorporate a complete Scheme interpreter/VM.
An application can use Guile as an extension language, a clean and
powerful configuration language, or as multi-purpose "glue" to connect
primitives provided by the application.  It is easy to call Scheme code
from C code and vice versa.  Applications can add new functions, data
types, control structures, and even syntax to Guile, to create a
domain-specific language tailored to the task at hand.

Guile 3.0.7 can be installed in parallel with Guile 2.2.x; see
http://www.gnu.org/software/guile/manual/html_node/Parallel-Installations.html.

A more detailed NEWS summary follows these details on how to get the
Guile sources.

Here are the compressed sources:
  http://ftp.gnu.org/gnu/guile/guile-3.0.7.tar.lz   (10MB)
  http://ftp.gnu.org/gnu/guile/guile-3.0.7.tar.xz   (13MB)
  http://ftp.gnu.org/gnu/guile/guile-3.0.7.tar.gz   (21MB)

Here are the GPG detached signatures[*]:
  http://ftp.gnu.org/gnu/guile/guile-3.0.7.tar.lz.sig
  http://ftp.gnu.org/gnu/guile/guile-3.0.7.tar.xz.sig
  http://ftp.gnu.org/gnu/guile/guile-3.0.7.tar.gz.sig

Use a mirror for higher download bandwidth:
  http://www.gnu.org/order/ftp.html

Here are the SHA256 checksums:

  f02166205ced31651d27bd037f947e199a442545ca73f913907c69469ddd7b54  
guile-3.0.7.tar.lz
  f57d86c70620271bfceb7a9be0c81744a033f08adc7ceba832c9917ab3e691b7  
guile-3.0.7.tar.xz
  c7935b7a29e42443f6a35d35cf20ffa7d028c399303f872cd1219598a83656ae  
guile-3.0.7.tar.gz

[*] Use a .sig file to verify that the corresponding file (without the
.sig suffix) is intact.  First, be sure to download both the .sig file
and the corresponding tarball.  Then, run a command like this:

  gpg --verify guile-3.0.7.tar.gz.sig

If that command fails because you don't have the required public key,
then run this command to import it:

  gpg --keyserver keys.gnupg.net --recv-keys 
4FD4D288D445934E0A14F9A5A8803732E4436885

and rerun the 'gpg --verify' command.

This release was bootstrapped with the following tools:
  Autoconf 2.71
  Automake 1.16.2
  Libtool 2.4.6
  Gnulib v0.1-4551-ga3a946f670
  Makeinfo 6.7

An extract from NEWS follows.


Changes in 3.0.7 (since 3.0.6)

* New interfaces and functionality

** More O_* POSIX constants are now defined in Scheme

Guile now defines constants such as `O_NOFOLLOW', `O_CLOEXEC',
`O_TMPFILE', and more on platforms that support them.  These may be
passed as arguments to procedures such as `open' and `open-fdes'.

* Bug fixes

** Fix bugs introduced in 3.0.6 with Scheme `read` re-write
** Fix deadlock after `primitive-fork' (#41948)
** Fix duplicates handlers for interfaces that use interfaces (#43025)
** Fix compile-psyntax.scm for (language tree-il canonicalize) removal
** Fix prompt compilation bug (#48098)
** Fix R7RS include-library-declarations, cond-expand (#40252)
** Fix --enable-mini-gmp on FreeBSD and other targets
** Fix excessive compile times for vectors >16k elements long
** Fix use of literal tree-il as source language (#45131)
** Fix SRFI-64 test-end to not remove globally-installed test runner



GNU Guile 3.0.6 released

2021-04-28 Thread Andy Wingo
We are pleased to announce GNU Guile release 3.0.6, the latest in the
3.0 stable release series.

Compared to the previous release in the 3.0 series, Guile 3.0.6 improves
source-location information for compiled code, removes the dependency on
libltdl, fixes some important bugs, adds an optional bundled "mini-gmp"
library, as well as the usual set of minor optimizations and bug fixes.

Compared to the previous stable series (2.2.x), Guile 3.0 adds support
for just-in-time native code generation, speeding up all Guile programs.
See the NEWS extract at the end of the mail for full details.


The Guile web page is located at http://gnu.org/software/guile/, and
among other things, it contains a copy of the Guile manual and pointers
to more resources.

Guile is an implementation of the Scheme programming language, packaged
for use in a wide variety of environments.  In addition to implementing
the R5RS, R6RS, and R7RS Scheme standards, Guile includes full access to
POSIX system calls, networking support, multiple threads, dynamic
linking, a foreign function call interface, powerful string processing,
and HTTP client and server implementations.

Guile can run interactively, as a script interpreter, and as a Scheme
compiler to VM bytecode.  It is also packaged as a library so that
applications can easily incorporate a complete Scheme interpreter/VM.
An application can use Guile as an extension language, a clean and
powerful configuration language, or as multi-purpose "glue" to connect
primitives provided by the application.  It is easy to call Scheme code
from C code and vice versa.  Applications can add new functions, data
types, control structures, and even syntax to Guile, to create a
domain-specific language tailored to the task at hand.

Guile 3.0.6 can be installed in parallel with Guile 2.2.x; see
http://www.gnu.org/software/guile/manual/html_node/Parallel-Installations.html.

A more detailed NEWS summary follows these details on how to get the
Guile sources.

Here are the compressed sources:
  http://ftp.gnu.org/gnu/guile/guile-3.0.6.tar.lz   (10MB)
  http://ftp.gnu.org/gnu/guile/guile-3.0.6.tar.xz   (13MB)
  http://ftp.gnu.org/gnu/guile/guile-3.0.6.tar.gz   (21MB)

Here are the GPG detached signatures[*]:
  http://ftp.gnu.org/gnu/guile/guile-3.0.6.tar.lz.sig
  http://ftp.gnu.org/gnu/guile/guile-3.0.6.tar.xz.sig
  http://ftp.gnu.org/gnu/guile/guile-3.0.6.tar.gz.sig

Use a mirror for higher download bandwidth:
  http://www.gnu.org/order/ftp.html

Here are the SHA256 checksums:

  2e5b9e3e56a967a58ae591053a65c1851875bf5e06c60caab409d5647cff4975  
guile-3.0.6.tar.lz
  e2bd83c2077d721356e7579ca33097a13a20e2b7eda6c2362ee1166fbc845d28  
guile-3.0.6.tar.xz
  000fc43c1b0a5cfbd85b67e01afd58e847bd1f279e3439bb7db37282b0459f56  
guile-3.0.6.tar.gz

[*] Use a .sig file to verify that the corresponding file (without the
.sig suffix) is intact.  First, be sure to download both the .sig file
and the corresponding tarball.  Then, run a command like this:

  gpg --verify guile-3.0.6.tar.gz.sig

If that command fails because you don't have the required public key,
then run this command to import it:

  gpg --keyserver keys.gnupg.net --recv-keys 
4FD4D288D445934E0A14F9A5A8803732E4436885

and rerun the 'gpg --verify' command.

This release was bootstrapped with the following tools:
  Autoconf 2.71
  Automake 1.16.2
  Libtool 2.4.6
  Gnulib v0.1-4551-ga3a946f670
  Makeinfo 6.7

An extract from NEWS follows.


Changes in 3.0.6 (since 3.0.5)

* Notable changes

** Reimplement dynamic library loading ("dlopening") without libltdl

Guile used to load dynamic libraries with libltdl, a library provided by
the Libtool project.

Libltdl provided some compatibility benefits when loading shared
libraries made with older toolchains on older operating systems.
However, no system from the last 10 years or so appears to need such a
thick compatibility layer.

Besides being an unmaintained dependency of limited utility, libltdl
also has the negative aspect that in its search for libraries to load,
it could swallow useful errors for libraries that are found but not
loadable, instead showing just errors for search path candidates that
are not found.

Guile now implements dynamic library loading directly in terms of the
standard "dlopen" interface, providing a limited shim for platforms with
similar functionality exposed under different names (MinGW).

This change has a few practical impacts to Guile users.  There is a new
library search path variable, `GUILE_EXTENSIONS_PATH'.  Also, errors when
loading a library fails now have better errors.  And Guile no longer has
a libltdl dependency.

Although Guile no longer uses libltdl, for backwards compatibility Guile
still adds `LTDL_LIBRARY_PATH' to the loadable library search path, and
includes ad-hoc logic to support uninstalled dynamically loadable
libraries via also adding the ".libs" subdirectories of
`LTDL_LIBRARY_PATH' elements.  See "Foreign Libraries" in the
documentation for a full discuss

Re: Preventing file descriptor leak to execl'd processes

2021-03-12 Thread Andy Wingo
On Sat 06 Mar 2021 17:55, Marius Bakke  writes:

> $ ls -l /proc/self/fd
> lrwx-- 1 marius marius 64 Mar  6 17:41 0 -> /dev/pts/18
> lrwx-- 1 marius marius 64 Mar  6 17:41 1 -> /dev/pts/18
> lrwx-- 1 marius marius 64 Mar  6 17:41 2 -> /dev/pts/18
> lr-x-- 1 marius marius 64 Mar  6 17:41 3 -> /proc/9940/fd
>
> $ /tmp/test-shell -c 'ls -l /proc/self/fd'
> lrwx-- 1 marius marius 64 Mar  6 17:41 0 -> /dev/pts/18
> lrwx-- 1 marius marius 64 Mar  6 17:41 1 -> /dev/pts/18
> lrwx-- 1 marius marius 64 Mar  6 17:41 2 -> /dev/pts/18
> lr-x-- 1 marius marius 64 Mar  6 17:41 3 -> /proc/9951/fd
> lr-x-- 1 marius marius 64 Mar  6 17:41 7 -> /tmp/test-shell
>
> I've managed to work around it by setting FD_CLOEXEC on it:
>
>   (port-for-each (lambda (port)
>(let ((name (port-filename port))
>  (self (car (program-arguments
>  (when (and name (string=? name self))
>(fcntl port F_SETFD (logior FD_CLOEXEC
>(fcntl port F_GETFD)))
>
> But it seems heavy-handed.  Is there an easier way to access the "script
> port"?  Perhaps Guile itself should make it FD_CLOEXEC by default?

I think Guile itself should make the load port FD_CLOEXEC / O_CLOEXEC.
More broadly there are a number of file descriptors in Guile that should
be cloexec but aren't yet.  Want to make a patch for the load port ? :)

Andy



Re: Some non-standard O_* flags are missing

2021-03-10 Thread Andy Wingo
Heya :)

On Tue 09 Mar 2021 22:47, Maxime Devos  writes:

> On Tue, 2021-03-09 at 21:36 +0100, Andy Wingo wrote:
>> Hi :)  Sure, would be happy to accept a patch for these.
> See <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=46220>
> and messages above.  I'll look at updating NEWS and the manual
> later.

Great!

I agree it's weird that O_NOTRANS is defined but 0 on GNU/Linux.
Perhaps better not to define it if it's zero?  Dunno tho.

>>   It's adding
>> more definitions to the base environment, which is usually a negative,
>> but we'll have to find some kind of module solution for all of these
>> flags at some point.
>
> Would defining O_* in a new module (ice-9 open-flags)
> (or the existing module (ice-9 posix) maybe?) be acceptable?
> Or alternatively, a syntax (open-flag SYMBOL) that expands to
> the flag's value --

Let's punt for now :)

>>   If you do send a patch, please update the manual
>> and NEWS also.
>
> The manual only documents O_RDONLY, O_WRONLY, O_RDWR,
> O_APPEND and O_CREAT currently, and points the reader
> at glibc's manual for additional flags.

Ah yes.  Probably the flags (possibly) supported by Guile should be in
the manual.  Document them if you have a moment? :)  Otherwise just
document the new ones.

Andy



Re: Linking to libraries in the ELF?

2021-03-09 Thread Andy Wingo
On Fri 29 Jan 2021 17:20, Maxime Devos  writes:

> I've got this crazy idea a few days ago, about the FFI interface.
> When a program written in C is compiled with some shared libraries,
> these libraries are referred to in special [insert ELF terminology
> here] of the binary.  I wonder if it would be reasonable and feasible
> to do something similar for compiles guile modules?

These sections of executables or shared libraries are actually
*interpreted* by the system dynamic library loader, ld.so.  Guile has
its own loader, independent of ld.so, and so can implement this -- or do
more flexible things.  In any case we probably shouldn't tie ourselves
to the particular implementation of a particular loader.

Of course, dynamic-link was... not a great interface.  But with the
recent changes in git I think it can be fine (see "Foreign Libraries" in
the manual).  For the FFI the bigger problem IMO is generating faster
foreign procedure bindings -- i.e. farther on the
compilation-vs-interpretation scale.

Cheers,

Andy



Re: [PATCH 1/1] scm_set_source_properties_x: optimize if only name, line, and/or col

2021-03-09 Thread Andy Wingo
On Sun 17 Jan 2021 23:55, Bruce Korb  writes:

> [Can I] swap out this code for something better now? I've disliked
> this code for years.
>
>> static SCM
>> ag_scm_c_eval_string_from_file_line(
>>     char const * pzExpr, char const * pzFile, int line)

Since Guile 2.0.1 you can

  (use-modules (ice-9 eval-string))
  (eval-string str #:file file #:line line)

>From C:

  SCM_KEYWORD (k_file, "file");
  SCM_KEYWORD (k_line, "line");

  ...

  SCM ans =
scm_call_5 (scm_c_public_ref ("ice-9 eval-string", "eval-string"),
scm_from_utf8_string (str),
k_file, scm_from utf8_string (file),
k_line, scm_from_int (line));

Regards,

Andy



Re: Some non-standard O_* flags are missing

2021-03-09 Thread Andy Wingo
Hi :)  Sure, would be happy to accept a patch for these.  It's adding
more definitions to the base environment, which is usually a negative,
but we'll have to find some kind of module solution for all of these
flags at some point.  If you do send a patch, please update the manual
and NEWS also.

Cheers,

Andy

On Sun 31 Jan 2021 22:13, Maxime Devos  writes:

> Hi guilers,
>
> I noticed the following open flags are not defined:
> O_NOFOLLOW, O_TMPFILE, O_IGNORE_CTTY, O_NOLINK,
> O_SHLOCK, O_EXLOCK, O_ASYNC, O_NOATIME.
>
> Some of these are Hurd-specific, Linux-specific
> and BSD-specific.  I'm particularily interested
> in O_NOFOLLOW, O_TMPFILE, O_IGNORE_CTTY, O_NOLINK
> and O_NOATIME, the others don't matter for me,
> though they may be useful for others.
>
> Could extra O_* flags be exported to Guile (in libguile/filesys.c)
> on systems where they are defined?
>
> Greetings,
> Maxime



Re: [PATCH] Support cross compilation

2021-03-09 Thread Andy Wingo
Hi :)

Which library is this for?  It doesn't appear to be guile itself.

Andy

On Sun 14 Feb 2021 10:16, Christopher Baines  writes:

> With these changes, I was able to cross-compile guile-lib to the GNU
> Hurd, and use part of the library at least.
>
> * configure.ac: Set GUILE_TARGET when cross compiling.
> * am/guile.mk: Pass GUILE_TARGET to guild compile.
> ---
>  am/guile.mk  | 2 +-
>  configure.ac | 4 
>  2 files changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/am/guile.mk b/am/guile.mk
> index 3adfc4f..f08e58d 100644
> --- a/am/guile.mk
> +++ b/am/guile.mk
> @@ -47,4 +47,4 @@ GUILE_WARNINGS = -Wunbound-variable -Warity-mismatch 
> -Wformat
>  SUFFIXES = .scm .go
>  .scm.go:
>   $(AM_V_GEN)$(top_builddir)/pre-inst-env \
> - guild compile $(GUILE_WARNINGS) -o "$@" "$<"
> + guild compile $(GUILE_TARGET) $(GUILE_WARNINGS) -o "$@" "$<"
> diff --git a/configure.ac b/configure.ac
> index 07be121..0aa812f 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -67,6 +67,10 @@ GUILE_GLOBAL_SITE_DIR
>  GUILE_SITE_CCACHE_DIR
>  GUILE_FLAGS
>  
> +if test \"$cross_compiling\" != no; then
> +   GUILE_TARGET=\"--target=$host_alias\"
> +   AC_SUBST([GUILE_TARGET])
> +fi
>  
>  AC_ARG_WITH(
>[guile-site],



GNU Guile 3.0.5 released

2021-01-07 Thread Andy Wingo
We are delighted to announce GNU Guile release 3.0.5, the latest in the
3.0 stable release series.

Compared to the previous release in the 3.0 series, Guile 3.0.5 can
compile chained "if" expressions into the equivalent of what a C
compiler does with "switch".  It also adds some new warning passes.

Compared to the previous stable series (2.2.x), Guile 3.0 adds support
for just-in-time native code generation, speeding up all Guile programs.
See the NEWS extract at the end of the mail for full details.


The Guile web page is located at http://gnu.org/software/guile/, and
among other things, it contains a copy of the Guile manual and pointers
to more resources.

Guile is an implementation of the Scheme programming language, packaged
for use in a wide variety of environments.  In addition to implementing
the R5RS, R6RS, and R7RS Scheme standards, Guile includes full access to
POSIX system calls, networking support, multiple threads, dynamic
linking, a foreign function call interface, powerful string processing,
and HTTP client and server implementations.

Guile can run interactively, as a script interpreter, and as a Scheme
compiler to VM bytecode.  It is also packaged as a library so that
applications can easily incorporate a complete Scheme interpreter/VM.
An application can use Guile as an extension language, a clean and
powerful configuration language, or as multi-purpose "glue" to connect
primitives provided by the application.  It is easy to call Scheme code
from C code and vice versa.  Applications can add new functions, data
types, control structures, and even syntax to Guile, to create a
domain-specific language tailored to the task at hand.

Guile 3.0.5 can be installed in parallel with Guile 2.2.x; see
http://www.gnu.org/software/guile/manual/html_node/Parallel-Installations.html.

A more detailed NEWS summary follows these details on how to get the
Guile sources.

Here are the compressed sources:
  http://ftp.gnu.org/gnu/guile/guile-3.0.5.tar.lz   (10MB)
  http://ftp.gnu.org/gnu/guile/guile-3.0.5.tar.xz   (12MB)
  http://ftp.gnu.org/gnu/guile/guile-3.0.5.tar.gz   (21MB)

Here are the GPG detached signatures[*]:
  http://ftp.gnu.org/gnu/guile/guile-3.0.5.tar.lz.sig
  http://ftp.gnu.org/gnu/guile/guile-3.0.5.tar.xz.sig
  http://ftp.gnu.org/gnu/guile/guile-3.0.5.tar.gz.sig

Use a mirror for higher download bandwidth:
  http://www.gnu.org/order/ftp.html

Here are the SHA256 checksums:

  a484eeffbd4d655b0c05b1382df8d40f1e561f7e71b963065762f6a6a497c675  
guile-3.0.5.tar.lz
  2d76fb023d2366126a5fac04704f9bd843846b80cccba6da5d752318b03350f1  
guile-3.0.5.tar.xz
  222046009a20b432ffa7c11b8d5a1d9ad0d8627be05cc1e8af612bc54ba2ea85  
guile-3.0.5.tar.gz

[*] Use a .sig file to verify that the corresponding file (without the
.sig suffix) is intact.  First, be sure to download both the .sig file
and the corresponding tarball.  Then, run a command like this:

  gpg --verify guile-3.0.5.tar.gz.sig

If that command fails because you don't have the required public key,
then run this command to import it:

  gpg --keyserver keys.gnupg.net --recv-keys 
4FD4D288D445934E0A14F9A5A8803732E4436885

and rerun the 'gpg --verify' command.

This release was bootstrapped with the following tools:
  Autoconf 2.69
  Automake 1.16.2
  Libtool 2.4.6
  Gnulib v0.1-1157-gb03f418
  Makeinfo 6.7

An extract from NEWS follows.


Changes in 3.0.5 (since 3.0.4)

* New interfaces and functionality

** O(1) compilation of `case' and related expressions

Guile now optimizes chains of eq? comparisons to constants, resulting in
O(1) dispatch time, regardless of the length of the chain.  This
optimization is also unlocked in many cases for `match' expressions with
many similar clauses whose first differentiator are constants.

** New (ice-9 copy-tree) module

This module includes the `copy-tree' procedure that was previously
implemented in C and present in the default `(guile)' module.  See
"Copying" in the manual.

** New warning: use-before-definition

This analysis, enabled at `-W1', issues warnings for programs that use
top-level variables before they are defined.

** New warning: non-idempotent-definition

This analysis, enabled at `-W1', issues warnings for programs that whose
use of a variable is ambiguous.  For example, in the program:

  (define saved-add +)
  (define + error)

The intention would seem to be to "save" the value of the base `+'
procedure, then override it locally.  However if this program is ever
loaded twice, then the second time it is loaded, `+' will be taken from
the local binding instead of the import.  Users that want this kind of
behavior should either use lexical bindings instead of top-level
bindings, or otherwise rename important clobbered bindings via modules.

* New deprecations

** `copy-tree' in the default environment, and `scm_copy_tree' from C

Import the `(ice-9 copy-tree)' module instead.

** `unbound-variable-analysis`, `macro-use-before-definition-analysis`

These bindings from `(language tree-il 

Re: The size of ‘.go’ files

2020-06-24 Thread Andy Wingo
Hi :)

On Tue 09 Jun 2020 18:09, Ludovic Courtès  writes:

> Andy Wingo  skribis:
>
>> The guile.arities section starts with a sorted array of fixed-size
>> headers, then is followed by a sequence of ULEB128 references to local
>> variable names, including non-arguments.  The size is a bit perplexing,
>> I agree.  I can think of a number of ways to encode that section
>> differently but we'd need to understand a bit more about it and why the
>> baseline compiler is significantly different.
>
> ‘.guile.arities’ size should be proportional to the number of
> procedures, right?  Additionally, if there are only/mostly thunks, the
> string table for argument names should be small if not empty.  For N
> thunks, I would expect roughly N 28-byte headers + NxM UL128, say 100
> bytes per thunk; there’s 1000 of them, so we should be ~100,000 bytes.
> This is roughly what we get observe with the baseline compiler.

Yes but that doesn't mean that you can directly compare baseline to CPS
-- CPS has many more intermediate names than baseline for non-argument
locals, all of which end up getting entries in the arities section.

Andy



Re: GNU Guile 3.0.3 released

2020-06-24 Thread Andy Wingo
On Tue 23 Jun 2020 11:36, Chris Vine  writes:

> On Tue, 23 Jun 2020 10:05:51 +0200
> Ludovic Courtès  wrote:
>> Hi Chris,
>> 
>> Chris Vine  skribis:
>> 
>> > On Sun, 21 Jun 2020 23:04:03 +0200
>> > Ludovic Courtès  wrote:
>> >> We are delighted to announce GNU Guile release 3.0.3, the third bug-fix
>> >> release of the new 3.0 stable series.  This release represents 170
>> >> commits by 17 people since version 3.0.2.  See the NEWS excerpt that
>> >> follows for full details.
>> > [snip]
>> >
>> > This has a libguile so ABI jump from libguile-3.0.so.1 to
>> > libguile-3.0.so.3, which breaks my binaries linked to libguile.  Is that
>> > normal for a micro update in the stable release series and if so can
>> > there be some warning in the announcement?
>> 
>> Yes, it means you need to relink those binaries.
>> 
>> I was hesitant about the SONAME: the ABI jump was unnecessary unless in
>> ‘--disable-deprecated’ builds.  I erred on the side of cautiousness:
>> 
>>   
>> https://git.savannah.gnu.org/cgit/guile.git/commit/?id=5d052c87bd8f0fd894e67f0bebd4fa6f6160d83c
>
> Hi,
>
> Ah right.  There must have been two SO breaks between guile-3.0.2 and
> guile-3.0.3.
>
> It's a nuisance having SO bumps on micro releases and I wonder if that
> could be included in the announcement so that you don't first notice it
> when stuff fails to run?

I think I agree with Chris.  The intention is certainly to have a stable
ABI within a stable series, so 3.0.3 should have the same CURRENT.

It's certainly correct that a --disable-deprecated 3.0.3 build has a
different ABI than 3.0.2, and if that were what we were looking at, we
would indeed need the CURRENT version bump; but I think the premise is
wrong: we do *not* have a stable ABI in --disable-deprecated builds, and
we never have.  Otherwise we wouldn't ever be able to deprecate anything
within a stable series.

WDYT about a quick 3.0.4 that restores the CURRENT ?

Cheers,

Andy



Re: The size of ‘.go’ files

2020-06-08 Thread Andy Wingo
Hi :)

A few points of information :)

On Fri 05 Jun 2020 22:50, Ludovic Courtès  writes:

> [Sorting] the ELF sections of a .go file by size; for ‘python-xyz.go’,
> I get this:
>
> $13 = ((".rtl-text" . 3417108)
>  (".guile.arities" . 1358536)
>  (".data" . 586912)
>  (".rodata" . 361599)
>  (".symtab" . 117000)
>  (".debug_line" . 97342)
>  (".debug_info" . 54519)
>  (".guile.frame-maps" . 47114)
>  ("" . 1344)
>  (".guile.arities.strtab" . 681)
>  ("" . 232)
>  (".shstrtab" . 229)
>  (".dynamic" . 112)
>  (".debug_str" . 87)
>  (".strtab" . 75)
>  (".debug_abbrev" . 65)
>  (".guile.docstrs.strtab" . 1)
>  ("" . 0)
>  (".guile.procprops" . 0)
>  (".guile.docstrs" . 0)
>  (".debug_loc" . 0))
>
> More than half of those 6 MiB is code, and more than 1 MiB is
> “.guile.arities” (info "(guile) Object File Format"), which is
> surprisingly large; presumably the file only contains thunks (the
> ‘thunked’ fields of ).

The guile.arities section starts with a sorted array of fixed-size
headers, then is followed by a sequence of ULEB128 references to local
variable names, including non-arguments.  The size is a bit perplexing,
I agree.  I can think of a number of ways to encode that section
differently but we'd need to understand a bit more about it and why the
baseline compiler is significantly different.

> Stripping the .debug_* sections (if that works) clearly wouldn’t help.

I believe that it should eventually be possible to strip guile.arities,
fwiw.

> So I guess we could generate less code (reduce ‘.rtl-text’), perhaps by
> tweaking ‘define-record-type*’, but I have little hope there.

Hehe :)  As you mention later:

> With 3.0.3-to-be and -O1, python-xyz.go weighs in at 3.4 MiB instead of
> 5.9 MiB!  Here’s the section size distribution:
>
> $4 = ((".rtl-text" . 2101168)
>  (".data" . 586392)
>  (".rodata" . 360703)
>  (".guile.arities" . 193106)
>  (".symtab" . 117000)
>  (".debug_line" . 76685)
>  (".debug_info" . 53513)
>  ("" . 1280)
>  (".guile.arities.strtab" . 517)
>  ("" . 232)
>  (".shstrtab" . 211)
>  (".dynamic" . 96)
>  (".debug_str" . 87)
>  (".strtab" . 75)
>  (".debug_abbrev" . 56)
>  (".guile.docstrs.strtab" . 1)
>  ("" . 0)
>  (".guile.procprops" . 0)
>  (".guile.docstrs" . 0)
>  (".debug_loc" . 0))
> scheme@(guile-user)> (stat:size (stat go))
> $5 = 3519323
>
> “.rtl-text” is 38% smaller and “.guile.arities” is almost a tenth of
> what it was.

The difference in the text are the new baseline intrinsics,
e.g. $vector-ref.  It goes in the opposite direction from instruction
explosion, which sought to (1) make the JIT compiler easier by
decomposing compound operations into their atomic parts, (2) make the
optimizer learn more information from flow rather than type-checking
side effects, and (3) allow the optimizer to eliminate / hoist / move
the component pieces of macro-operations.

However in the baseline compiler (2) and (3) aren't possible because
there is no optimizer on that level, and therefore the result is
actually a lose -- 10 micro-ops cost more than 1 macro-op because of
stack traffic overhead, which isn't currently mitigated by the JIT (1).

So instruction explosion is residual code explosion, which should pay
off in theory, but not for the baseline compiler.  So I added new
intrinsics for e.g. $vector-ref et al.  Thus the smaller code size.

I am not sure what causes the significantly different .guile.arities
size!

> Something’s going on here!  Thoughts?

There are more possibilities for making code size smaller, e.g. having
two equivalent encodings for bytecode, where one is smaller:

  https://webkit.org/blog/9329/a-new-bytecode-format-for-javascriptcore/

Or it could be that if we could do register allocation for a
target-dependent fixed set of registers in bytecode already, that could
decrease minimum instruction size, making more instructions fit into
single 32-bit words.  Would be nice if the JIT could rely on the
bytecode compiler to already have done register allocation, and reify
corresponding debug information.  Just a thought though, and not really
appropriate to the baseline compiler.

Cheers,

Andy



Re: [PATCH] Avoid malloc/free/dynwind for POSIX subrs that take strings

2020-05-17 Thread Andy Wingo
On Sun 17 May 2020 23:46, Ludovic Courtès  writes:

> The libunistring functions can take a pre-allocated buffer, but they
> always malloc a fresh one if needed.  So the best we could do is have a
> ‘scm_to_stringn’ variant that takes a buffer, but it’s not guaranteed
> that it’ll actually be used.  All in all, it seems the added complexity
> is not warranted.  The worst case of ‘scm_locale_string_data’ is also
> rare enough.
>
> Thoughts?

Interesting.  Probably we want to make a public
scm_to_{,locale_,utf8_}gc_string{,n} API and use that as a fallback.
GC-managed character buffers are less error-prone and probably just as
fast.

We can mostly avoid the double-copy by inline conversions, as we do with
UTF-8.  For narrow strings scm_to_gc_stringn can always run iconv in a
mode that just calculates output byte size; surely equivalent
functionality is available from unistring, also.

Andy



Re: [PATCH] Add tree-il optimizations for equal? on char and number literals

2020-05-14 Thread Andy Wingo
On Wed 13 May 2020 23:16, Linus Björnstam  writes:

> On the latest master equal? was not reduced to eq? on chars in the repl
> for things like ,opt (define (a b) (equal? b #\b)).

This turned out to be that I had broken the REPL command.  The optimizer
was working fine though.  Fixed now :)

Cheers,

Andy



Re: [PATCH] Add tree-il optimizations for equal? on char and number literals

2020-05-13 Thread Andy Wingo
Hi :)

On Wed 13 May 2020 13:20, Linus Björnstam  writes:

> Hi there!
>
> Aleix and I noticed that equal? has a lot higher overhead than eqv? on
> chars, which means using (ice-9 match) for chars was suboptimal. This
> patch fixes that.

I think we can be a little more simple here.  Scheme doesn't specify
what (eqv? #\a x) is, but in Guile it is equivalent to (eq? #\a x), and
our compiler should be free to turn the portable eqv? invocation into
eq?.  But as the comment on line 416 says, we should really do this in
peval and not in the expander.  So you nerd-sniped me ;)  I just
pushed a patch that did this.

While looking, I found this:

> + (make-conditional src (make-primcall src prim (list a b))
> +   (make-primcall src prim (cons b rest))
> +   (make-const src #f))

This was in the original code but is wrong: if "b" has a side-effect, it
will happen twice.  I have fixed it in git.

Thanks for the debugging and patch!

Andy



Re: [PATCH] Avoid malloc/free/dynwind for POSIX subrs that take strings

2020-05-05 Thread Andy Wingo
Hi :)


On Wed 29 Apr 2020 22:22, Ludovic Courtès  writes:

> As discussed on IRC, the patch below arranges so that subrs that take
> strings and pass them to syscall wrappers can avoid the
> malloc/free/dynwind overhead.  This gives a 10% speedup on a tight loop
> that calls these subrs:

Neat optimization.  Since it's internal, no problem from me.  My concern
is only about calcifying aspects of our C / GC interface in API.

> On IRC, Andy mentioned concerns that the SCM could disappear and thus,
> our the internal pointer returned by ‘scm_locale_string_data’ wouldn’t
> be enough to prevent the stringbuf from being GC’d.

I would suggest doing the whole optimization and being sure to do
scm_remember_upto_here_1 on the SCM value at use sites.

Andy



Re: [PATCH, v2] Fix build on platforms where the stack grows upwards

2020-03-13 Thread Andy Wingo
On Tue 10 Mar 2020 23:58, John David Anglin  writes:

> On 2020-02-08 9:07 a.m., Ludovic Courtès wrote:
>> John Paul Adrian Glaubitz  skribis:
>>
>>>  * libguile/continuations.c (scm_dynthrow): Fix missing mra
>>>parameter to grow_stack for SCM_STACK_GROWS_UP.
>> Applied, thanks!
> I believe that this change was also applied to the 2.2 stable branch 
> (v2.2.7).  There is no mra
> parameter on 2.2.

Indeed; fixed.  Thanks for the fix and the note, and thanks Ludo for
getting the fix into 3.0.1 :)

Andy



a hack to do -- jitmaps

2020-02-26 Thread Andy Wingo
Hey :)

I thought of a thing that I don't have time to implement right now:
perf jitmap support in Guile.

Basically, the "perf" Linux tool is a widely-available instruction-level
and microarchitectural profiler.  It's great: you run "perf record guile
foo.scm", and then you run "perf report", and you get instruction-level
info on the profile.  You can grab call graphs, see performance
counters, all kinds of things.  Good stuff.

With run-time code generation though, perf needs some help from the
program generating code.  The most basic step is what's known as "perf
maps", placed in /tmp/perf-$PID.map.  These are super-basic and just
identify code ranges with functions.  I just pushed a patch doing this.

The more useful thing is what's known as "jitmaps".  See
https://lwn.net/Articles/633846/, and
https://chromium.googlesource.com/v8/v8/+/refs/heads/master/src/diagnostics/perf-jit.cc.
It's totally underdocumented, but it actually saves the JIT code to a
file, which is needed to have instruction-level profiling.  It also adds
support for unwinding frames and source info.

Anyway if anyone wants to take this task in the next few weeks, LMK :)

Andy



Re: Segfault while building on 64-bit Cygwin

2020-02-17 Thread Andy Wingo
Aah, you all are amazing -- thank you!!  Applied and merged.

Cheers,

Andy

On Mon 17 Feb 2020 20:27, Charles Stanhope  writes:

> On 2/16/20, Charles Stanhope  wrote:
>> On 2/16/20, Mike Gran  wrote:
>>>
>>> I can confirm that Charles's patch, plus another one line patch
>>> to define CPU_SETSIZE, is enough to get Guile 3.0.x to build and run
>>> on my box.  All tests pass except strptime in French, and the absence
>>> of crypt.  This is a 64-bit build.
>>
>> Mike, thanks for going further with the Guile build. The CPU_SETSIZE
>> issue was what was hanging me up from compiling before Andy's comment
>> got me to look at lightening. I assumed I had some configuration,
>> package, or compiler issue. Good to know there's a simple fix.
>>
>> Just a further warning to anyone watching, that patch I posted is a
>> real hack job just to test my theory of the cause of the segfault. I
>> would expect it to fail when you have fewer than four arguments in a
>> JITed function call. I wouldn't try doing much else with that Guile
>> build besides run the tests. :)
>
> I had a little bit more time to look into the lightening
> implementation last night. I've attached a patch that is less horrible
> and more correct than my previous one. It reserves the stack space
> regardless of the number of parameters and appears to work. But I'm
> new to the lightening code base, so I'm not convinced it is the
> correct solution. It's just the solution I was left with after my time
> ran out. I wanted to post this patch as a replacement to the prior one
> in case people did want to do more testing with Guile 3.0 on Cygwin
> x64.
>
> With that, I will let more experienced people come up with the
> appropriate solution. Happy hacking, everybody!
>
> --
> Charles
>
> diff --git a/lightening/x86.c b/lightening/x86.c
> index 965191a..bdd26e1 100644
> --- a/lightening/x86.c
> +++ b/lightening/x86.c
> @@ -328,6 +328,10 @@ reset_abi_arg_iterator(struct abi_arg_iterator *iter, 
> size_t argc,
>memset(iter, 0, sizeof *iter);
>iter->argc = argc;
>iter->args = args;
> +#if __CYGWIN__ && __X64
> +  // Reserve slots on the stack for 4 register parameters (8 bytes each).
> +  iter->stack_size = 32;
> +#endif
>  }
>  
>  static void



Re: Segfault while building on 64-bit Cygwin

2020-02-06 Thread Andy Wingo
On Mon 20 Jan 2020 18:22, Mike Gran  writes:

> On Mon, Jan 20, 2020 at 11:38:35AM -0500, John Cowan wrote:
>> Yes, gladly, but I don't know how to get one in this context.  Do I need to
>> add some flags to the Makefile, and if so, where?  (It's a twisty maze of
>> passages, all different.) . Note that this *is* a build with JIT enabled;
>> when I disable it using the env variable, there are no errors and 3.0.0
>> works fine.
>> 
>> Also, it may take some time, as I have to rebuild my Windows system.
>
> I also tried building Guile 3.0.0 on Cygwin 3.1.x.  The failure comes from
> trying to parse compiled .go files.
>
> The last time that I had this sort of problem, it was because the
> O_BINARY flag was dropped or missing when writing .go files, leading
> to CR+LF characters in the compiled files.  And I diagnosed it by
> byte-comparing Linux-compiled .go files with Cygwin-compiled .go
> files, and by looking for CR+LF combinations in the compiled .go
> files.
>
> I don't know if that is what is happening here, but, I'll check that
> next time I have a chance.

Given that John said that compilation went fine with
GUILE_JIT_THRESHOLD=-1, I think perhaps this problem may have been fixed
in the past.  My suspicions are that this issue is an ABI issue with
lightening that could perhaps be reproduced by:

  git co https://gitlab.com/wingo/lightening
  cd lightening
  make -C tests test-native

Of course any additional confirmation is useful and welcome!

Cheers,

Andy



Re: CPU and GC cost of bignums

2020-02-06 Thread Andy Wingo
Hi :)

Nice investigation!  Perhaps slot-allocation should track live variables
using something that's not bigints, but who knows.

On Wed 05 Feb 2020 17:29, Ludovic Courtès  writes:

>  /* The next three functions (custom_libgmp_*) are passed to
> mp_set_memory_functions (in GMP) so that memory used by the digits
> themselves is known to the garbage collector.  This is needed so
> @@ -237,19 +227,20 @@ finalize_bignum (void *ptr, void *data)
>  static void *
>  custom_gmp_malloc (size_t alloc_size)
>  {
> -  return scm_malloc (alloc_size);
> +  return scm_gc_malloc (alloc_size, "GMP");
>  }
>  
>  static void *
>  custom_gmp_realloc (void *old_ptr, size_t old_size, size_t new_size)
>  {
> -  return scm_realloc (old_ptr, new_size);
> +  return scm_gc_realloc (old_ptr, old_size, new_size, "GMP");
>  }
>  
>  static void
>  custom_gmp_free (void *ptr, size_t size)
>  {
> -  free (ptr);
> +  /* Do nothing: all memory allocated by GMP is under GC control and
> + will be freed when needed.  */
>  }

I think this makes sense to me as a short-term fix.  The down-side is
that limbs can alias Scheme objects.

In the long-term I think we should be representing bignums as
pointerless objects whose first word is the tag and a word count,
followed by inline "limbs" (in the sense of
https://gmplib.org/manual/Nomenclature-and-Types.html#Nomenclature-and-Types).
Generally we can use the low-level API to work on these
(https://gmplib.org/manual/Low_002dlevel-Functions.html#Low_002dlevel-Functions),
and if we need to use mpz_t, we can easily create an mpz_t that points
to these values.

Cheers,

Andy



Re: Removal of hppa support

2020-02-04 Thread Andy Wingo
Greets,

On Tue 04 Feb 2020 12:02, John Paul Adrian Glaubitz 
 writes:

> On 1/27/20 4:46 PM, Andy Wingo wrote:
>> William is correct.  HPPA support is not gone from Guile; and indeed
>> it's good to hear from you :)  I wasn't sure there were any IA64 users
>> remaining.
>
> It fails to build from source on Debian hppa, however:

Thanks for these reports and apologies for the breakages.  Looking
forward to the patches.

> I fixed the preprocessor conditional, but then I'm running into another
> issue:
>
> continuations.c: In function 'capture_auxiliary_stack':
> continuations.c:152:7: warning: implicit declaration of function 'getcontext' 
> [-Wimplicit-function-declaration]

Probably a missing include for ucontext.h.

>> If someone would like to write an IA64 backend for Lightening, I would
>> be happy to accept it :)  The beginnings of one are there in the git
>> history.
>
> Ok. I assume that applies to alpha, hppa, m68k, powerpc*, riscv*, sparc* as 
> well.

Yes indeed!

Andy



Re: Removal of hppa support

2020-01-27 Thread Andy Wingo
Hi :)

On Sun 26 Jan 2020 07:19, William ML Leslie  
writes:

> On Sun, 26 Jan 2020, 4:46 pm William ML Leslie, 
>  wrote:
>  On Sun, 26 Jan 2020, 8:20 am John Paul Adrian Glaubitz, 
>  wrote:
>
>  > I noticed that you recently purged hppa support from guile [1].
>
>  This change does not remove hppa support from guile, only support for
>  the jit.
>
>  As an ia64 user, i'm a bit sad that we lost jit too - but i don't run
>  any performance-sensitive guile jobs on that system.
>
> Maybe /lost/ is the wrong word. We won't be benefitting from the work
> the lightning team have done in supporting hacker-friendly
> architectures in guile 3. This jit is completely new.

William is correct.  HPPA support is not gone from Guile; and indeed
it's good to hear from you :)  I wasn't sure there were any IA64 users
remaining.

Initially in Guile I planned to use GNU Lightning, in part because of
its great platform support.  However it turned out to not be the right
thing, and reluctantly I ended up doing something that was more like a
rewrite than a refactor.  In that context I personally don't have the
budget to write the IA64 backend.  So, Guile 3 still runs on IA64, just
without JIT support.

If someone would like to write an IA64 backend for Lightening, I would
be happy to accept it :)  The beginnings of one are there in the git
history.

Andy



GNU Guile 3.0.0 released

2020-01-16 Thread Andy Wingo
We are delighted to announce GNU Guile release 3.0.0, the first in the
new 3.0 stable release series.

Compared to the previous stable series (2.2.x), Guile 3.0 adds support
for just-in-time native code generation, speeding up all Guile programs.
See the NEWS extract at the end of the mail for full details.


The Guile web page is located at http://gnu.org/software/guile/, and
among other things, it contains a copy of the Guile manual and pointers
to more resources.

Guile is an implementation of the Scheme programming language, packaged
for use in a wide variety of environments.  In addition to implementing
the R5RS, R6RS, and R7RS Scheme standards, Guile includes full access to
POSIX system calls, networking support, multiple threads, dynamic
linking, a foreign function call interface, powerful string processing,
and HTTP client and server implementations.

Guile can run interactively, as a script interpreter, and as a Scheme
compiler to VM bytecode.  It is also packaged as a library so that
applications can easily incorporate a complete Scheme interpreter/VM.
An application can use Guile as an extension language, a clean and
powerful configuration language, or as multi-purpose "glue" to connect
primitives provided by the application.  It is easy to call Scheme code
from C code and vice versa.  Applications can add new functions, data
types, control structures, and even syntax to Guile, to create a
domain-specific language tailored to the task at hand.

Guile 3.0.0 can be installed in parallel with Guile 2.2.x; see
http://www.gnu.org/software/guile/manual/html_node/Parallel-Installations.html.

A more detailed NEWS summary follows these details on how to get the
Guile sources.

Here are the compressed sources:
  http://ftp.gnu.org/gnu/guile/guile-3.0.0.tar.lz   (10MB)
  http://ftp.gnu.org/gnu/guile/guile-3.0.0.tar.xz   (12MB)
  http://ftp.gnu.org/gnu/guile/guile-3.0.0.tar.gz   (21MB)

Here are the GPG detached signatures[*]:
  http://ftp.gnu.org/gnu/guile/guile-3.0.0.tar.lz.sig
  http://ftp.gnu.org/gnu/guile/guile-3.0.0.tar.xz.sig
  http://ftp.gnu.org/gnu/guile/guile-3.0.0.tar.gz.sig

Use a mirror for higher download bandwidth:
  http://www.gnu.org/order/ftp.html

Here are the SHA256 checksums:

  e28c450d11f7335769f607214f9b79547400881ddbbc9805ccf3ce2121aa97e0  
guile-3.0.0.tar.lz
  c9138d6595a9f69bf9733d0bc2d3b9f3d8b79f35f289006912b3361cb0510c75  
guile-3.0.0.tar.xz
  049b286849fa9764fac781071c4ec9daef707da51e5050ffb498d7bf6422da2f  
guile-3.0.0.tar.gz

[*] Use a .sig file to verify that the corresponding file (without the
.sig suffix) is intact.  First, be sure to download both the .sig file
and the corresponding tarball.  Then, run a command like this:

  gpg --verify guile-3.0.0.tar.gz.sig

If that command fails because you don't have the required public key,
then run this command to import it:

  gpg --keyserver keys.gnupg.net --recv-keys 
4FD4D288D445934E0A14F9A5A8803732E4436885

and rerun the 'gpg --verify' command.

This release was bootstrapped with the following tools:
  Autoconf 2.69
  Automake 1.16.1
  Libtool 2.4.6
  Gnulib v0.1-1157-gb03f418
  Makeinfo 6.7

An extract from NEWS follows.


Changes in 3.0.0 (since the stable 2.2 series):

* Notable changes

** Just-in-time code generation

Guile programs now run up to 4 times faster, relative to Guile 2.2,
thanks to just-in-time (JIT) native code generation.  Notably, this
brings the performance of "eval" as written in Scheme back to the level
of "eval" written in C, as in the days of Guile 1.8.

See "Just-In-Time Native Code" in the manual, for more information.  JIT
compilation will be enabled automatically and transparently.  To disable
JIT compilation, configure Guile with `--enable-jit=no' or
`--disable-jit'.  The default is `--enable-jit=auto', which enables the
JIT if it is available.  See `./configure --help' for more.

JIT compilation is enabled by default on x86-64, i686, ARMv7, and
AArch64 targets.

** Lower-level bytecode

Relative to the virtual machine in Guile 2.2, Guile's VM instruction set
is now more low-level.  This allows it to express more advanced
optimizations, for example type check elision or integer
devirtualization, and makes the task of JIT code generation easier.

Note that this change can mean that for a given function, the
corresponding number of instructions in Guile 3.0 may be higher than
Guile 2.2, which can lead to slowdowns when the function is interpreted.
We hope that JIT compilation more than makes up for this slight
slowdown.

** Interleaved internal definitions and expressions allowed

It used to be that internal definitions had to precede all expressions
in their bodies.  This restriction has been relaxed.  If an expression
precedes an internal definition, it is treated as if it were a
definition of an unreferenced variable.  For example, the expression
`(foo)' transforms to the equivalent of `(define _ (begin (foo) #f))',
if it precedes other definitions.

This change improves the readability of Gui

Re: %module-public-interface

2020-01-15 Thread Andy Wingo
On Wed 15 Jan 2020 07:50, dsm...@roadrunner.com writes:

> I'm porting some old code to 3.0 and I've come across this:
>
> (define-module (bobotpp bot))
>
> (set-module-uses! %module-public-interface
>
>   (list (module-ref (resolve-module '(guile-user) #f)
>
> 'the-bot-module)))
>
> What is the 3.0 equivalent?   I'm not sure what the above is trying to do.

As mentioned in IRC, (module-public-interface (current-module)).  (This
change was part of 2.0.)

Cheers,

Andy



Re: GNU Guile 2.9.9 Released [beta]

2020-01-15 Thread Andy Wingo
On Tue 14 Jan 2020 22:48, Stefan Israelsson Tampe  
writes:

> Strange that I did not dee this error before in the 2.x series
> ever. Isn't it so that for procedures define in a (let () ...) the
> case you are mentioning happened before but I was on the impression
> that no inlining was done for defines on different places in the
> module before

This is correct, yes.  The declarative bindings optimization makes
toplevel bindings more like letrec bindings, which exposes them to this
other optimization.  My point was that since Guile 2.0, procedure
identity has not been firmly guaranteed in all cases.

Andy



Re: GNU Guile 2.9.9 Released [beta]

2020-01-14 Thread Andy Wingo
On Tue 14 Jan 2020 21:13, Stefan Israelsson Tampe  
writes:

> Okey, here is another case that fails with the patch that prevents identity 
> misses for toplevels e.g we need similar fixes for anonymous functions.
>
> (define-module (b)
>   #:export (q))
>
> (define h (make-hash-table))
> (define (method f)
>   (hash-set! h f 1)
>   f)
> (define q (method (lambda x x)))
>
> (pk (hash-ref h q))
>
> This fails with (#f)
>
> I solved this in my code by placing the method function in another module.

Interestingly, this case is not really related to the declarative
bindings optimization, letrectification, or other things.  It's the same
as:

  (let ((h (make-hash-table)))
(define (method f)
  (hash-set! h f 1)
  f)
(let* ((q (let ((f (lambda x x)))
(method f
  (pk (hash-ref h q

I.e. no top-level bindings are needed.  This prints #f in releases as
old as 2.0.14 and probably older :)  It optimizes as:

  (let* ((h (make-hash-table))
 (q (begin
  (hash-set! h (lambda x x) 1)
  (lambda x x
(pk (hash-ref h q)))

So, not a recent change.  Of course we can discuss whether it's the
right thing or not!

Andy



Re: GNU Guile 2.9.9 Released [beta]

2020-01-14 Thread Andy Wingo
On Tue 14 Jan 2020 17:03, Mikael Djurfeldt  writes:

> Hmm... it seems like both Stefan and you have interpreted my post
> exactly the opposite way compared to how it was meant. :)

Hah!  My apologies :)

> What I wanted to say is that I probably prefer you to *reverse* the
> recent patch because I prefer to have good optimization also when
> procedures are referenced by value in more than one non-operator
> position. I prefer this over having (eq? p p) => #t for the reasons I
> stated.

I understand this also!  However what Stefan is saying echoes what I've
heard from other people.  There are some cases where eta-converting all
lexical procedure references helps nobody -- it makes (eqv? p p) be
false in places where many people expect it would be true, without
enabling significant optimizations.  In that case, the choice is pretty
clear.  But if there are significant optimizations left on the table, I
would hesitate a lot before chasing an ideal of procedure identity in
cases where the procedure's behavior cannot possibly differ.  Anyway
that's not where we are currently, thankfully!

Cheers,

Andy



Re: GNU Guile 2.9.9 Released [beta]

2020-01-14 Thread Andy Wingo
On Tue 14 Jan 2020 15:47, Stefan Israelsson Tampe  
writes:

> Yes, your patch is indicating when you should use the same identity
> e.g. all uses of procedures in a higher order position such as an
> argument or a return value. But I looked at your patch, which looks
> good but I saw that for operator position you decrease the count. Why?
> Also you are free to use one version in argument / return position and
> another one in operator position the only limit is to use the same
> identity for on operator position. Finally don't you need to count
> usage of returning a variable as well?

Not sure what the bug is.  Do you have a test case that shows the
behavior that you think is not good?

Andy



Re: GNU Guile 2.9.9 Released [beta]

2020-01-14 Thread Andy Wingo
On Tue 14 Jan 2020 13:18, Mikael Djurfeldt  writes:

> I probably don't have a clue about what you are talking about (or at
> least hope so), but this---the "eq change"---sounds scary to me.
>
> One of the *strengths* of Scheme is that procedures are first class
> citizens. As wonderfully show-cased in e.g. SICP this can be used to
> obtain expressive and concise programs, where procedures can occur
> many times as values outside operator position.
>
> I would certainly *not* want to trade in an important optimization
> step in those cases to obtain intuitive procedure equality. The risk
> is then that you would tend to avoid passing around procedures as
> values.

Is this true?

  (eq? '() '())

What about this?

  (eq? '(a) '(a))

And yet, are datums not first-class values?  What does being first-class
have to do with it?

Does it matter whether it's eq? or eqv?

What about:

  (eq? (lambda () 10) (lambda () 10))

What's the difference?

What's the difference in the lambda calculus between "\x.f x" and "f"?

What if in a partial evaluator, you see a `(eq? x y)`, and you notice
that `x' is bound to a lambda expression?  Can you say anything about
the value of the expression?

Does comparing procedures for equality mean anything at all?
https://cs-syd.eu/posts/2016-01-17-function-equality-in-haskell

Anyway :)  All that is a bit of trolling on my part.  What I mean to say
is that instincts are tricky when it comes to object identity, equality,
equivalence, and especially all of those combined with procedures.  The
R6RS (what can be more Schemely than a Scheme standard?) makes this
clear.

All that said, with the recent patch, I believe that Guile 3.0's
behavior preserves your intuitions.  Bug reports very welcome!

Andy



Re: GNU Guile 2.9.9 Released [beta]

2020-01-14 Thread Andy Wingo
On Mon 13 Jan 2020 22:32, Stefan Israelsson Tampe  
writes:

> In current guile (eq? f f) = #f for a procedure f. Try:

Note that procedure equality is explicitly unspecified by R6RS.  Guile's
declarative modules optimization took advantage of this to eta-expand
references to declaratively-bound top-level lambda expressions.  This
unlocks the "well-known" closure optimizations: closure elision,
contification, and so on.

However, the intention with the eta expansion was really to prevent the

  (module-add! mod 'foo foo)

from making the procedure not-well-known.  If that's the only reference
to `foo' outside the operator position, procedure identity for `foo' is
kept, because it's only accessed outside the module.  But then I
realized thanks to your mail (and the three or four times that people
stumbled against this beforehand) that we can preserve the optimizations
and peoples' intuitions about procedure equality if we restrict
eta-expansion to those procedures that are only referenced by value in
at most a single position.

It would be best to implement the eta-expansion after peval; doing it
where we do leaves some optimization opportunities on the table.  But I
have implemented this change in git and it should fix this issue.

Comparative benchmark results:

  
https://wingolog.org/pub/guile-2.9.7-vs-guile-2.9.9-with-eq-change-microbenchmarks.png

Regards,

Andy



Re: GNU Guile 2.9.9 Released [beta]

2020-01-13 Thread Andy Wingo
On Mon 13 Jan 2020 09:39, Andy Wingo  writes:

> Compared to the previous prerelease (2.9.7), Guile 2.9.8 fixes a number
> of bugs.

Obviously this was meant to be 2.9.9 versus 2.9.8 :)

> Changes since alpha 2.9.8 (since 2.9.7):

Here too :)



GNU Guile 2.9.9 Released [beta]

2020-01-13 Thread Andy Wingo
We are pleased to announce GNU Guile release 2.9.9.  This is the ninfth
and probably final pre-release of what will eventually become the 3.0
release series.

Compared to the current stable series (2.2.x), the future Guile 3.0 adds
support for just-in-time native code generation, speeding up all Guile
programs.  See the NEWS extract at the end of the mail for full details.

Compared to the previous prerelease (2.9.7), Guile 2.9.8 fixes a number
of bugs.

The current plan is to make a 3.0.0 final release on 17 January 2020.
If there's nothing wrong with this prerelease, 3.0.0 will be essentially
identical to 2.9.9.  With that in mind, please test and make sure the
release works on your platform!  Please send any build reports (success
or failure) to guile-devel@gnu.org, along with platform details.  You
can file a bug by sending mail to bug-gu...@gnu.org.

The Guile web page is located at http://gnu.org/software/guile/, and
among other things, it contains a copy of the Guile manual and pointers
to more resources.

Guile is an implementation of the Scheme programming language, packaged
for use in a wide variety of environments.  In addition to implementing
the R5RS, R6RS, and R7RS Scheme standards, Guile includes a module
system, full access to POSIX system calls, networking support, multiple
threads, dynamic linking, a foreign function call interface, powerful
string processing, and HTTP client and server implementations.

Guile can run interactively, as a script interpreter, and as a Scheme
compiler to VM bytecode.  It is also packaged as a library so that
applications can easily incorporate a complete Scheme interpreter/VM.
An application can use Guile as an extension language, a clean and
powerful configuration language, or as multi-purpose "glue" to connect
primitives provided by the application.  It is easy to call Scheme code
>From C code and vice versa.  Applications can add new functions, data
types, control structures, and even syntax to Guile, to create a
domain-specific language tailored to the task at hand.

Guile 2.9.9 can be installed in parallel with Guile 2.2.x; see
http://www.gnu.org/software/guile/manual/html_node/Parallel-Installations.html.

A more detailed NEWS summary follows these details on how to get the
Guile sources.

Here are the compressed sources:
  http://alpha.gnu.org/gnu/guile/guile-2.9.9.tar.lz   (10MB)
  http://alpha.gnu.org/gnu/guile/guile-2.9.9.tar.xz   (12MB)
  http://alpha.gnu.org/gnu/guile/guile-2.9.9.tar.gz   (21MB)

Here are the GPG detached signatures[*]:
  http://alpha.gnu.org/gnu/guile/guile-2.9.9.tar.lz.sig
  http://alpha.gnu.org/gnu/guile/guile-2.9.9.tar.xz.sig
  http://alpha.gnu.org/gnu/guile/guile-2.9.9.tar.gz.sig

Use a mirror for higher download bandwidth:
  http://www.gnu.org/order/ftp.html

Here are the SHA256 checksums:

  59f136e5db36eba070cc5e68784e632dc2beae4b21fd6c7c8ed2c598cc992efc  
guile-2.9.9.tar.lz
  bf71920cfa23e59fc6257bee84ef4dfeccf4f03e96bb8205592e09f9dbff2969  
guile-2.9.9.tar.xz
  eafe394cf99d9dd1ab837e6d1b9b2b8d9f0cd13bc34e64ca92456ce1bc2b1925  
guile-2.9.9.tar.gz

[*] Use a .sig file to verify that the corresponding file (without the
.sig suffix) is intact.  First, be sure to download both the .sig file
and the corresponding tarball.  Then, run a command like this:

  gpg --verify guile-2.9.9.tar.gz.sig

If that command fails because you don't have the required public key,
then run this command to import it:

  gpg --keyserver keys.gnupg.net --recv-keys 
4FD4D288D445934E0A14F9A5A8803732E4436885

and rerun the 'gpg --verify' command.

This release was bootstrapped with the following tools:
  Autoconf 2.69
  Automake 1.16.1
  Libtool 2.4.6
  Gnulib v0.1-1157-gb03f418
  Makeinfo 6.7

An extract from NEWS follows.


Changes since alpha 2.9.8 (since 2.9.7):

* Notable changes

** `define-module' #:autoload no longer pulls in the whole module

One of the ways that a module can use another is "autoloads".  For
example:

  (define-module (a) #:autoload (b) (make-b))

In this example, module `(b)' will only be imported when the `make-b'
identifier is referenced.  However besides the imprecision about when a
given binding is actually referenced, this mechanism used to cause the
whole imported module to become available, not just the specified
bindings.  This has now been changed to only import the specified bindings.

This is a backward-incompatible change.  The fix is to mention all
bindings of interest in the autoload clause.  Feedback is welcome.

** `guard' no longer unwinds the stack for clause tests

SRFI-34, and then R6RS and R7RS, defines a `guard' form that is a
shorthand for `with-exception-handler'.  The cond-like clauses for the
exception handling are specified to run with the continuation of the
`guard', while any re-propagation of the exception happens with the
continuation of the original `raise'.

In practice, this means that one needs full `call-with-continuation' to
implement the specified semantics, to be able to unwind the stac

Re: GNU Guile 2.9.8 Released [beta]

2020-01-11 Thread Andy Wingo
On Wed 08 Jan 2020 15:22, Nala Ginrut  writes:

> In unknown file:
>4 (primitive-load-path "artanis/server/server-context" #<…>)
> In ice-9/eval.scm:
>626:19  3 (_ #)
> 155:9  2 (_ #)
> In ice-9/boot-9.scm:
>   1153:19  1 (_ _ _ _ _ _ _)
>   1655:16  0 (raise-exception _ #:continuable? _)
>
> ice-9/boot-9.scm:1655:16: In procedure raise-exception:
> Wrong number of arguments to # ice-9/boot-9.scm:1153:19 (a b c d e f)>
> 
>
> Any hint that I can figure out whait's incompatible?

Gosh we need to improve this info.  Anyway the procedure at
boot-9.scm:1153:19 is a record constructor, for a record with 6 fields.
Apparently somewhere in (artanis server server-context) is calling it
with the wrong number of arguments.  What do you use for records?  Do
you have your own abstraction or do you use R6RS records or something?
Perhaps something in artanis relied on the way that R6RS records used to
implement single inheritance, as a chain of objects instead of a flat
record.  Or perhaps the adaptations to R6RS records in Guile introduced
a bug.  I am interested to know the answer :)

Andy



Re: GNU Guile 2.9.8 Released [beta]

2020-01-11 Thread Andy Wingo
On Thu 09 Jan 2020 22:14, Stefan Israelsson Tampe  
writes:

> In language/cps/closure-conversion.scm: 
>   749:15  5 (_ 2705 _) 
>   771:22  4 (lp # …) 
>   771:22  3 (lp # …) 
>   771:22  2 (lp # …) 
>   610:11  1 (allocate-closure _ _ _ _ _ 1) 

Nice bug!  I wish I had a test case :)  Can you try the following patch
and see if it fixes the issue for you?

Cheers,

Andy

diff --git a/module/language/cps/closure-conversion.scm 
b/module/language/cps/closure-conversion.scm
index 1452212f0..17a81f674 100644
--- a/module/language/cps/closure-conversion.scm
+++ b/module/language/cps/closure-conversion.scm
@@ -1,6 +1,6 @@
 ;;; Continuation-passing style (CPS) intermediate language (IL)
 
-;; Copyright (C) 2013-2019 Free Software Foundation, Inc.
+;; Copyright (C) 2013-2020 Free Software Foundation, Inc.
 
  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
@@ -596,6 +596,17 @@ term."
  ($continue ktag0 src
($primcall 'allocate-words/immediate `(closure . ,(+ nfree 2))
   ())
+(#(#t 0)
+ (with-cps cps
+   (build-term ($continue k src ($const #f)
+(#(#t 1)
+ ;; A well-known closure of one free variable is replaced
+ ;; at each use with the free variable itself, so we don't
+ ;; need a binding at all; and yet, the continuation
+ ;; expects one value, so give it something.  DCE should
+ ;; clean up later.
+ (with-cps cps
+   (build-term ($continue k src ($const #f)
 (#(#t 2)
  ;; Well-known closure with two free variables; the closure is a
  ;; pair.
@@ -666,17 +677,6 @@ bound to @var{var}, and continue to @var{k}."
   (#(#f 0)
(with-cps cps
  (build-term ($continue k src ($const-fun kfun)
-  (#(#t 0)
-   (with-cps cps
- (build-term ($continue k src ($const #f)
-  (#(#t 1)
-   ;; A well-known closure of one free variable is replaced
-   ;; at each use with the free variable itself, so we don't
-   ;; need a binding at all; and yet, the continuation
-   ;; expects one value, so give it something.  DCE should
-   ;; clean up later.
-   (with-cps cps
- (build-term ($continue k src ($const #f)
   (#(well-known? nfree)
;; A bit of a mess, but beta conversion should remove the
;; final $values if possible.



Re: Better HTTPS support in (web client)

2020-01-10 Thread Andy Wingo
On Fri 10 Jan 2020 15:49, Ludovic Courtès  writes:

> Hello Guilers!
>
> I’ve pushed a ‘wip-https-client’ branch that contains improvements for
> HTTPS support in (web client) that I’d like to be part of Guile 3:
>
>   https://git.savannah.gnu.org/cgit/guile.git/log/?h=wip-https-client

Looks nice, sounds like a great thing to merge in!

Andy



Re: GNU Guile 2.9.5 Released [beta]

2020-01-07 Thread Andy Wingo
On Tue 07 Jan 2020 00:14, Chris Vine  writes:

> I wonder if it would surprise the programmer to have the cond
> conditionals evaluated in a different dynamic environment from the one
> in which the cond consequential is evaluated where there is a
> conditional which is true.

I entirely agree it's not ideal and can be surprising!  I am not sure
that there is an "ideal" here though; with-exception-handler is
wonderfully expressive but can be verbose, guard is a pleasant
abbreviation but how to deal with re-raising from the original context?

In the end, "guard" is just a macro over a more general facility.  But
it's a macro that we expect people to use, and to cover the common case.
To that end I think we should make it cheap and avoid rewinding while
also preserving the nice characteristic of evaluating cond consequents
in the continuation of the "guard" itself.

Andy



Re: SHA256 performance with Guile 2.2 vs. Guile 3.0

2020-01-07 Thread Andy Wingo
On Tue 07 Jan 2020 12:08, Ludovic Courtès  writes:

> Andy Wingo  skribis:
>
>> Concretely I would add a little part of the compiler to the Tree-IL
>> phase to serialize a bytecode for the "small" definitions in the module,
>> for declarative modules, both public and private (because public
>> definitions may alias private definitions).  This would be stored as a
>> bytevector in an additional field of the module, and the program being
>> compiled would be transformed to initialize the "lto" field (placeholder
>> name) of the module, so that once the compiled module is loaded, we have
>> the inlinable bindings.  I think this can be done compatibly.
>
> OK, sounds great.  What are your thoughts about versioning that wire
> Tree-IL representation?

It would be a little bytecode language, with its own versioning
considerations.  It would need to have a translation to and from
Tree-IL, though not necessarily lossless.  It would change only in
ABI-compatible ways, using the bytecode version of the Guile doing the
compilation as a proxy for what is OK to support.

A



Re: GNU Guile 2.9.8 Released [beta]

2020-01-07 Thread Andy Wingo
On Tue 07 Jan 2020 21:00, Stefan Israelsson Tampe  
writes:

> Bump!
>
> Great, but loading an extension like:
>
> (catch #t
>   (lambda ()
> (throw #t)
> (load-extension "libguile-persist" "persist_init") (pk 1))
>   (lambda x  
> (let ((file  
>(%search-load-path "src/.libs/libguile-persist.so")))
>   (if 
>file
>(catch #t
>  (lambda ()  
>(load-extension file "persist_init"))
>  (lambda x
>(warn
> "libguile-persist is not loadable!")))
>(warn 
> "libguile-persist is not present, did you forget to make it?")
>
> And then have  line like
>
> (pk 5 serialize-vm-ra)
>
> Loading this module prints
> (5 #f)
>
> Worked in releases before.

Surely this test case can be shortened?  All the load-extension bits
appear to not be necessary, right?

Andy



Re: support for mips32r6

2020-01-06 Thread Andy Wingo
On Fri 30 Aug 2019 10:09, Bruno Haible  writes:

> A libffcall bug report [1] made me aware of an incompatible change in
> the MIPS ISAs. Namely, for jumping to an address given in a register,
> starting with mips32r6, the existing 'jr' instruction does not work
> any more: it produces an 'illegal instruction'.

Thanks for the fix; applied :)

Andy



Re: landed r7rs support

2020-01-06 Thread Andy Wingo
On Fri 22 Nov 2019 17:00, Nala Ginrut  writes:

> On Tue, Nov 19, 2019, 03:34 Amirouche Boubekki  
> wrote;
>
>  link: 
> https://www.gnu.org/software/guile/manual/guile.html#Extending-the-Compiler
>
>  In that section, maybe add a note about a web assembly backend?
>
> +1
> In the past decade, we've gotten some experiences about compiler frontend 
> around the Guile community. However, Guile is so powerful that we can also 
> add backend in a elegant way. It's
> better to mention it explicitly, and it's deserved to have more information 
> jn the manual.

Done :)

Cheers,

Andy



Re: GNU Guile 2.9.5 Released [beta]

2020-01-06 Thread Andy Wingo
On Mon 06 Jan 2020 00:26, Chris Vine  writes:

> I have a 'try' macro which adopts the approach that if an exception
> arises, the macro unwinds from the dynamic environment of the code
> where the exception arose to the dynamic environment of the call to
> 'try', evaluates the cond clauses in that environment, and then if no
> cond clause matches re-raises the exception in that environment with
> 'raise' (rather than 'raise-continuable').  In other words, it does
> stack unwinding in the same way as exception implementations in almost
> all other mainstream languages which use exceptions.  It would be
> trivial to implement this with guile-3.0's with-exception-handler with
> its unwind? argument set to true.

I am not sure this really matches with this use case:

  (define (call-with-backtrace thunk)
(call/ec
 (lambda (ret)
   (with-exception-handler
 (lambda (exn)
   (show-backtrace exn) ;; placeholder
   (ret))
 thunk

  (define (false-on-file-errors thunk)
(call/ec
 (lambda (ret)
   (with-exception-handler
 (lambda (exn)
   (if (file-error? exn)
   (ret #f)
   (raise-continuable exn)))
 thunk
   
  (define (foo f)
(call-with-backtrace
 (lambda ()
   (false-on-file-errors f
 
 
If there's an error while invoking `f' that's not a file error, you want
to have remained in the context of the error so you can show a full
backtrace.  To my mind this is central to the exception handler design.
So far so good I think.

If I change the implementation of `false-on-file-errors' to be:

  (define (false-on-file-errors thunk)
(guard (exn ((file-error? exn) #f))
  (thunk)))

I think this change should preserve the not-unwinding environment that
`call-with-backtrace' expects.

> On the other hand, as you say it does not seem feasible to implement
> in guile the R6RS/R7RS requirement to unwind to the environment of the
> call to 'guard' when evaluating the cond clauses, and then return to
> the environment of the original exception in order to re-raise if no
> cond clause matches.

It's feasible, just not a good idea IMO.  The problem is that call/cc is
quite expensive.  Additionally that it captures the whole state of the
current thread, so a fiber (github.com/wingo/fibers) with a `guard' may
error if it is preempted and migrated to a different CPU.

> Furthermore such a return is only relevant if the exception is to be
> re-raised with 'raise-continuable' instead of 'raise': it is pointless
> if the exception is re-raised with 'raise' because with 'raise' you
> can never get back there again.

FWIW I am not sure how raise-continuable will be used but it's a fairly
straightforward thing implementation-wise that doesn't bother me.

> I am somewhat influenced by my view of 'raise-continuable'.  I don't
> like it - how often does anyone use continuable exceptions, which seem
> to be a reimplementation of common lisp restarts?

I am not sure that they are restarts.  A restart to my mind is more
like:

  (define (with-restart name thunk)
(let lp ()
  (define tag (make-prompt-tag))
  (call-with-prompt
   tag
   (lambda ()
 (parameterize ((current-restarts (acons name tag (current-restart
   (thunk)))
   (lambda (k)
 (lp)

   (define (invoke-restart-by-name name . vals)
 (match (assoc name (current-restarts))
   ((name . tag)
(apply abort-to-prompt tag vals

So you could invoke a restart within an exception handler but it has
nothing to do with whether raise or raise-continuable was used.  The
continuation captured by the equivalent of common lisp's `restart-case'
isn't the continuation that raises the error.

Regards,

Andy



Re: SHA256 performance with Guile 2.2 vs. Guile 3.0

2020-01-06 Thread Andy Wingo
On Mon 06 Jan 2020 10:47, Ludovic Courtès  writes:

> Andy Wingo  skribis:
>
>> With cross-module inlining of "small" definitions, I think we would
>> solve a lot of this kind of problem.  I think we could add this during
>> 3.0 and for this reason I would hesitate to apply this patch for 3.0
>> because it changes "fx+" exports to be macros rather than "normal"
>> values in the ABI.  WDYT?
>
> I agree that cross-module inlining is the better fix whereas this patch
> is the immediate workaround.
>
> Are you confident that cross-module inlining can happen be added without
> introducing incompatibilities over in the 3.0 series?  (At first sight
> it seems tricky to me, notably because we’d have to store Tree-IL in
> object files, which introduces compatibility and thus external
> representation versioning considerations.)

Concretely I would add a little part of the compiler to the Tree-IL
phase to serialize a bytecode for the "small" definitions in the module,
for declarative modules, both public and private (because public
definitions may alias private definitions).  This would be stored as a
bytevector in an additional field of the module, and the program being
compiled would be transformed to initialize the "lto" field (placeholder
name) of the module, so that once the compiled module is loaded, we have
the inlinable bindings.  I think this can be done compatibly.

> If you do, then it’s fine to drop this patch.  If conversely
> cross-module inlining might take longer, then we can have this patch in
> and drop it in 3.2.  Your call!  (I guess I’m not being that helpful
> here.  :-))

:)

I hesitate to land this patch because we haven't shown that it
significantly helps things, it would need to be undone, and it makes the
ABI more fragile.  So if that's OK let's do nothing :)

Cheers,

Andy



Re: GNU Guile 2.9.5 Released [beta]

2020-01-05 Thread Andy Wingo
On Sun 01 Dec 2019 21:41, Chris Vine  writes:

> Is this rewrite, and the new with-exception-handler procedure, an
> opportunity to think about standardization of guile's implementation of
> the R6RS/R7RS 'guard' form, or at least think about what is wanted for
> 'guard'?
>
> The formal semantics (including specimen implementation) of 'guard' for
> R6RS with the corrigendum to §7.1 of the standard library at
> http://www.r6rs.org/r6rs-errata.html, and for R7RS without corrigendum
> (at §4.2.7 and §7.3, page 72 of the standard), is:
>
> (i) to evaluate the guard body within a block with its own continuation
> (as constructed by call/cc);
>
> (ii) if an exception is thrown, evaluate the handler (and its cond
> clauses) in the dynamic context of the original caller of 'guard' via
> that continuation;
>
> (iii) if no matching cond clause and no else clause is found, return to
> the dynamic environment of the original 'raise' and re-raise the
> exception with 'raise-continuable', even for non-continuable
> exceptions.
>
> If a fully conforming R6RS/R7RS implementation runs this code:
>
>   (guard (exn [(equal? exn 5) #f])
> (guard (exn [(equal? exn 6) 'never-reached])
>   (dynamic-wind
> (lambda () (display "in") (newline))
> (lambda () (raise 5))
> (lambda () (display "out") (newline)
>
> the code evaluates to #f and should print this:
>
>   in
>   out
>   in
>   out
>
> In chez scheme it does so.  In most other implementations (including
> guile and racket) it seems to print:
>
>   in
>   out

I really think the standards messed up regarding the specification of
"guard":

  http://scheme-reports.org/mail/scheme-reports/msg03247.html

But those ships have sailed and are now lost at sea.  Guile currently
has two separate implementations of "guard" for SRFI-34 (used by R7RS)
and R6RS.  It would seem that besides not respecting the specification,
the R6RS one is broken, as it expects the "cond" clauses to evaluate to
a single value.

For SRFI-34 (and R7RS), after the exception refactor, I did a re-write
to give a shot at implementing the specified behavior.  It works with a
caveat:  because it uses delimited continuations as the rewind
mechanism, and Guile has a limitation that some delimited continuations
can't be rewound (if the continuation bounces through C), then
re-raising the exception fails because the context can't be rewound.
This can cause previously working programs to break!

Which makes me think, if call/cc (rather than call-with-prompt /
abort-to-prompt) is necessary to implement "guard", we are in a bad
place and we should specify something else.

I have long thought that the right thing to do is this: we evaluate the
"cond" tests in the dynamic environment of the "raise".  Then if a test
succeeds, we unwind and run the corresponding consequent.  That way
there's no rewinding.  Here's an implementation:

  (define-syntax guard
(syntax-rules (else)
  ((guard (var (t e e* ...) ...) body body* ...)
   (let ((tag (make-prompt-tag)))
 (call-with-prompt
  tag
  (lambda ()
(with-exception-handler
 (lambda (var)
   (cond
(t (abort-to-prompt tag (lambda () e e* ...)))
...)
   (raise var))
 (lambda ()
   body body* ...)))
  (lambda (k thunk)
(thunk)))

Though I think it might be reasonable to use "raise-continuable" instead
of "raise" if nothing matches.

WDYT?

Andy



Re: [PATCH] Add string-replace-substring to (ice-9 string-fun)

2020-01-05 Thread Andy Wingo
On Fri 20 Dec 2019 18:32, lloda  writes:

> This patch adds string-replace-substring that wingo posted to the
> mailing list to (ice-9 strings). This is a commonly used function and a
> good implementation isn't trivial, so I think it deserves inclusion.

I didn't know that this module existed :)  Sure, why not.  Please fix
the commit message when you push.

Andy



Re: [PATCH] Add srfi-171 to guile

2020-01-05 Thread Andy Wingo
Hi :)

Since this is a final SRFI I think there's no problem getting it in.
Some formatting notes follow; since it's your first Guile patch I'm a
bit verbose :)  Probably this will miss 3.0.0 but make 3.0.1, FWIW.

On Sun 22 Dec 2019 15:55, Linus Björnstam  writes:

> From 7e8d3b22ba5f814c40dbb5ab616a318c0cdc2f3e Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?Linus=20Bj=C3=B6rnstam?= 
> Date: Sun, 22 Dec 2019 15:38:34 +0100
> Subject: [PATCH 1/2] Added srfi-171 to guile under the module name (srfi
>  srfi-171).
>
> For more info, read the SRFI document: 
> https://srfi.schemers.org/srfi-171/srfi-171.html

Needs a note per-file; see other commit log messages.  Also please wrap
to 72 characters.

> --- /dev/null
> +++ b/module/srfi/srfi-171.scm
> @@ -0,0 +1,498 @@
> +;
> +;; Copyright 2019 Linus Bj.rnstam
> +;;

I think you've assigned copyright so this can have the standard Guile
copyright block, right?

> +;; This module name is guile-specific. The correct module name is of course
> +;; (srfi 171)

I don't think it's right to say there is a "correct" name.  R6RS, R7RS,
and Guile have different naming conventions for SRFI modules and that's
OK.

The style in Guile is generally that block comments like this should be
complete sentences, starting with capital letters and including
terminating punctuation.  Generally we do two spaces after periods,
also.

> +(define-module (srfi srfi-171)
> +  #:declarative? #t
> +  #:use-module (srfi srfi-9)
> +  #:use-module ((srfi srfi-43)
> +#:select (vector->list))
> +  #:use-module ((srfi srfi-69) #:prefix srfi69:)
> +  #:use-module ((rnrs hashtables) #:prefix rnrs:)
> +  #:use-module (srfi srfi-171 meta)
> +  #:export (rcons reverse-rcons
> +  rcount
> +  rany

Better to put rcons on its own line so that other exports are also
aligned with the open paren.

> +;; A special value to be used as a placeholder where no value has been set 
> and #f
> +;; doesn't cut it. Not exported.
> +
> +(define-record-type 
> +  (make-nothing)
> +  nothing?)
> +(define nothing (make-nothing))

Note that this can be somewhat cheaper as:

  (define nothing (list 'nothing))
  (define (nothing? x) (eq? x nothing))

> +;; helper function which ensures x is reduced.

Capitalize.  FWIW, better done as a docstring:

  (define (ensure-reduced x)
"Ensure that @var{x} is reduced."
...)

> +;; helper function that wraps a reduced value twice since reducing functions 
> (like list-reduce)
> +;; unwraps them. tconcatenate is a good example: it re-uses it's reducer on 
> it's input using list-reduce.
> +;; If that reduction finishes early and returns a reduced value, list-reduce 
> would "unreduce"
> +;; that value and try to continue the transducing process.

Capitalize and limit to 80 characters wide.

> +(define (preserving-reduced f)
> +  (lambda (a b)
> +(let ((return (f a b)))
> +  (if (reduced? return)
> +  (reduced return)
> +  return
> +
> +
> +
> +

Generally, put one blank line between functions.  Two lines can be
between sections.  Four is too much :)

> +
> +;; Reducing functions meant to be used at the end at the transducing
> +;; process.;

This is a fairly non-standard comment style, FWIW; consider just
prefixing with ";;;".

> +;; a transducer-friendly cons with the empty list as identity
> +(define rcons
> +  (case-lambda

Similar comment regarding docstrings

> +;; Use this as the f in transduce to count the amount of elements passed 
> through.
> +;; (transduce (tfilter odd?) tcount (list 1 2 3)) => 2

80 characters, and the example can go in an @example if you like:

  (define rcount
(case-lambda
  "A transducer that counts the number of elements passing through. \
@example
(transduce (tfilter odd?) tcount (list 1 2 3)) @result{} 2
@end example"
  ...))

> +(define (make-replacer map)
> +  (cond
> +   ((list? map)
> +(lambda (x)
> +  (let ((replacer? (assoc x map)))
> +(if replacer?
> +(cdr replacer?)
> +x

I generally find this sort of thing better with (ice-9 match):

  (match (assoc x map)
((x . replacer) replacer)
(#f x))

> +;; Flattens everything and passes each value through the reducer
> +;; (list-transduce tflatten conj (list 1 2 (list 3 4 '(5 6) 7 8))) => (1 2 3 
> 4 5 6 7 8)

80 chars

> +;; I am not sure about the correctness of this. It seems to work.
> +;; we could maybe make it faster?
> +(define (tpartition f)

How could you know about the correctness?  Probably a good idea to do
what it takes to be sure and then remove the comment.  Regarding speed,
I would remove the comment, if it's slow then people can work on it.

Note that in general comments shouldn't be from a first-person
perspective, because the code will be maintai

Re: GNU Guile 2.9.8 Released [beta]

2020-01-05 Thread Andy Wingo
On Fri 03 Jan 2020 06:34, Nala Ginrut  writes:

> When I was trying to compile Artanis, the configure threw an error:
> 
> checking for Guile version >= 3.0... configure: error: Guile 3.0 required, 
> but 2.9.8 found
> 
>
> Here's what I put in configure.ac:
> GUILE_PKG(2.2 2.3 2.9 3.0)
>
> My question is "what's the correct config here"?

There was a bug in guile.m4 from a few years ago doesn't do the right
thing for major version changes.  I think you need to update guile.m4
from git, then do:

GUILE_PKG([2.2 3.0])

Also note that it's not meaningful to put in alpha releases to GUILE_PKG
-- 2.9.7's effective version is 3.0.

FWIW I would encourage doing GUILE_PKG([3.0 2.2]) instead, as it's
generally the right thing to default to newer Guile release series.

Cheers,

Andy



Re: Re-exporting a replaced binding

2020-01-05 Thread Andy Wingo
On Fri 03 Jan 2020 19:30, Ludovic Courtès  writes:

> I’m not sure if this is an intended consequence of
> cf08dbdc189f0005cab6f2ec7b23ed9d150ec43d, so I thought I’d share this
> example of a practical effect:
>
> ludo@ribbon /tmp [env]$ cat x.scm
> (define-module (x)
>   #:use-module (srfi srfi-1)
>   #:re-export (delete))
> ludo@ribbon /tmp [env]$ cat y.scm
> (define-module (y)
>   #:use-module (x))
>
> (pk 'delete delete)
> ludo@ribbon /tmp [env]$ guile -L . -c '(use-modules (y))'
> WARNING: (y): imported module (x) overrides core binding `delete'
>
> ;;; (delete #)
> ludo@ribbon /tmp [env]$ guile --version
> guile (GNU Guile) 2.9.8
>
> Here ‘delete’ is replaced by srfi-1, but the replaced bit is not
> propagated to module (x), even though (x) simply re-exports it.
>
> Should the #:re-export clause propagate the replace bit, or should
> it not?  :-)

It is a good question :)  Before, if you re-exported a #:replace
binding, it wasn't possible to have it be exported without the "replace"
bit set.  After the change it is possible to do either, and the default
changes to not replacing.  From NEWS:

  Note to make this change, we had to change the way replacement flags
  are stored, to being associated with modules instead of individual
  variable objects.  This means that users who #:re-export an imported
  binding that was already marked as #:replace by another module will
  now see warnings, as they need to use #:re-export-and-replace instead.

The 3.0 behavior differs from 2.2 in this regard, although it's just
warnings and not run-time behavior.  I am sympathetic to the concern
that it can be difficult to make a system that warns/doesn't warn in the
same way on 2.2 vs 3.0 but I think the change is the right thing, as the
new behavior is more expressive.  Because it's a user-visible change it
is in NEWS.  LMK if you think we need a change here!

Andy



Re: SHA256 performance with Guile 2.2 vs. Guile 3.0

2020-01-05 Thread Andy Wingo
On Sat 04 Jan 2020 01:40, Ludovic Courtès  writes:

> Ludovic Courtès  skribis:
>
>> ludo@ribbon ~/src/guix$ ./pre-inst-env guix environment --pure --ad-hoc 
>> guile-next guile3.0-hashing -- guile ~/tmp/sha256.scm
>>
>> ;;; (hash "b33576331465a60b003573541bf3b1c205936a16c407bc69f8419a527bf5c988")
>> clock utime stime cutime cstime gctime
>> 65.17 89.75  0.45   0.00   0.00  35.63
>
>   (define fx32xor fxxor)
>   …

>From a speed perspective I think there is one major issue and one minor
issue.

The major issue is that we don't do cross-module inlining.  But now that
we have declarative modules, this is a possibility:

  https://lists.gnu.org/archive/html/guile-devel/2016-03/msg00026.html
  https://lists.gnu.org/archive/html/guile-devel/2016-03/msg00027.html

With cross-module inlining of "small" definitions, I think we would
solve a lot of this kind of problem.  I think we could add this during
3.0 and for this reason I would hesitate to apply this patch for 3.0
because it changes "fx+" exports to be macros rather than "normal"
values in the ABI.  WDYT?

The minor issue, at least relatively speaking, is that IMO the (rnrs
arithmetic fixnums) API is not appropriate for bitwise operations.  When
you do bitwise operations and you want to ensure that you're within some
fixed domain, it's best to do e.g. "(logand x #x)" on operands
and results.  Guile will optimize this well.  The good optimization
isn't fixnum vs other kinds of numbers, it's unboxing to raw unsigned
integers; and you usually want to exclude negative numbers.  fx+ doesn't
help with that.

Cheers,

Andy



GNU Guile 2.9.8 Released [beta]

2020-01-02 Thread Andy Wingo
We are pleased to announce GNU Guile release 2.9.8.  This is the eighth
and possibly final pre-release of what will eventually become the 3.0
release series.

Compared to the current stable series (2.2.x), the future Guile 3.0 adds
support for just-in-time native code generation, speeding up all Guile
programs.  See the NEWS extract at the end of the mail for full details.

Compared to the previous prerelease (2.9.7), Guile 2.9.8 fixes a bug in
libguile that caused writes to unmapped memory in some circumstances.
This problem manifested itself as a failure of Guile to compile itself
on some systems, notably Ubuntu 18.04 on x86-64.  It also fixes a couple
warnings related to SRFI-35.

The current plan is to make a 3.0.0 final release on 17 January 2020.
We may need another prerelease in the interim.  It's a good time to test
the prereleases to make sure they work on your platform.  Please send
any build reports (success or failure) to guile-devel@gnu.org, along
with platform details.  You can file a bug by sending mail to
bug-gu...@gnu.org.

The Guile web page is located at http://gnu.org/software/guile/, and
among other things, it contains a copy of the Guile manual and pointers
to more resources.

Guile is an implementation of the Scheme programming language, with
support for many SRFIs, packaged for use in a wide variety of
environments.  In addition to implementing the R5RS Scheme standard,
Guile includes a module system, full access to POSIX system calls,
networking support, multiple threads, dynamic linking, a foreign
function call interface, and powerful string processing.

Guile can run interactively, as a script interpreter, and as a Scheme
compiler to VM bytecode.  It is also packaged as a library so that
applications can easily incorporate a complete Scheme interpreter/VM.
An application can use Guile as an extension language, a clean and
powerful configuration language, or as multi-purpose "glue" to connect
primitives provided by the application.  It is easy to call Scheme code
>From C code and vice versa.  Applications can add new functions, data
types, control structures, and even syntax to Guile, to create a
domain-specific language tailored to the task at hand.

Guile 2.9.8 can be installed in parallel with Guile 2.2.x; see
http://www.gnu.org/software/guile/manual/html_node/Parallel-Installations.html.

A more detailed NEWS summary follows these details on how to get the
Guile sources.

Here are the compressed sources:
  http://alpha.gnu.org/gnu/guile/guile-2.9.8.tar.lz   (10MB)
  http://alpha.gnu.org/gnu/guile/guile-2.9.8.tar.xz   (12MB)
  http://alpha.gnu.org/gnu/guile/guile-2.9.8.tar.gz   (21MB)

Here are the GPG detached signatures[*]:
  http://alpha.gnu.org/gnu/guile/guile-2.9.8.tar.lz.sig
  http://alpha.gnu.org/gnu/guile/guile-2.9.8.tar.xz.sig
  http://alpha.gnu.org/gnu/guile/guile-2.9.8.tar.gz.sig

Use a mirror for higher download bandwidth:
  http://www.gnu.org/order/ftp.html

Here are the SHA256 checksums:

  3ce11e9dca0f475fa944729d99f33c379fe8962e729bd21a99470249624c71d7  
guile-2.9.8.tar.lz
  4a8cf663b8bfd435168935c74a8ec434328ffad16230322c64f0ac567dda2c26  
guile-2.9.8.tar.xz
  31c3d458ff9342db130e27c8d82d2a33912da92845e5ee431b6a125971a823d2  
guile-2.9.8.tar.gz

[*] Use a .sig file to verify that the corresponding file (without the
.sig suffix) is intact.  First, be sure to download both the .sig file
and the corresponding tarball.  Then, run a command like this:

  gpg --verify guile-2.9.8.tar.gz.sig

If that command fails because you don't have the required public key,
then run this command to import it:

  gpg --keyserver keys.gnupg.net --recv-keys 
4FD4D288D445934E0A14F9A5A8803732E4436885

and rerun the 'gpg --verify' command.

This release was bootstrapped with the following tools:
  Autoconf 2.69
  Automake 1.16.1
  Libtool 2.4.6
  Gnulib v0.1-1157-gb03f418
  Makeinfo 6.5

An extract from NEWS follows.


Changes in alpha 2.9.8 (since alpha 2.9.7):

* Bug fixes

** Fix bug in which abort_to_prompt used an invalid stack pointer

This bug manifested itself as a bootstrap compile error on some systems,
notably Ubuntu 18.04 on x86-64, and was due to failing to recalculate a
local variable after a possible stack relocation.

** SRFI-35 does a #:re-export-and-replace on `&error'
** SRFI-35 avoids compiler warnings for multiply-defined condition types


Changes in alpha 2.9.x (since the stable 2.2 series):

* Notable changes

** Just-in-time code generation

Guile programs now run up to 4 times faster, relative to Guile 2.2,
thanks to just-in-time (JIT) native code generation.  Notably, this
brings the performance of "eval" as written in Scheme back to the level
of "eval" written in C, as in the days of Guile 1.8.

See "Just-In-Time Native Code" in the manual, for more information.  JIT
compilation will be enabled automatically and transparently.  To disable
JIT compilation, configure Guile with `--enable-jit=no' or
`--disable-jit'.  The default is `--enable-jit=auto', which enab

Re: Removing the locale warning?

2019-12-16 Thread Andy Wingo
On Sat 14 Dec 2019 16:44, Ludovic Courtès  writes:

> What about getting rid of the locale warning?
>
> More generally, I'm in favor of reducing run-time warnings to a bare
> minimum, because application users often don’t care about them (plus
> they’re not i18n’d), and because application developers cannot silence
> them or handle them in a way that is more suitable for the application.
>
> Thoughts?

Funny, I find them really useful as they let me know when my environment
isn't correctly configured, so I can then take action.  How can we
resolve these two use cases?

Andy



draft 3.0 release schedule

2019-12-11 Thread Andy Wingo
Hi,

I've been trying to put out releases on an every-other-Friday schedule.
Due to holidays I will probably bump this next one (2.9.7) up to this
Friday.  Current plan would then be to do 2.9.8 on 3 January 2020, and
then if all goes well 3.0.0 on 17 January 2020.

Cheers,

Andy



test message; please ignore

2019-12-06 Thread Andy Wingo
Please ignore this test message.  Thanks :)



GNU Guile 2.9.6 Released [beta]

2019-12-06 Thread Andy Wingo
We are pleased to announce GNU Guile release 2.9.6.  This is the sixth
pre-release of what will eventually become the 3.0 release series.

Compared to the current stable series (2.2.x), the future Guile 3.0 adds
support for just-in-time native code generation, speeding up all Guile
programs.  See the NEWS extract at the end of the mail for full details.

Compared to the previous prerelease (2.9.5), Guile 2.9.6 fixes a number
of bugs, adds some optimizations, and adds a guile-3 cond-expand
feature.

We encourage you to test this release and provide feedback to
guile-devel@gnu.org, and to file bugs by sending mail to
bug-gu...@gnu.org.

The Guile web page is located at http://gnu.org/software/guile/, and
among other things, it contains a copy of the Guile manual and pointers
to more resources.

Guile is an implementation of the Scheme programming language, with
support for many SRFIs, packaged for use in a wide variety of
environments.  In addition to implementing the R5RS Scheme standard,
Guile includes a module system, full access to POSIX system calls,
networking support, multiple threads, dynamic linking, a foreign
function call interface, and powerful string processing.

Guile can run interactively, as a script interpreter, and as a Scheme
compiler to VM bytecode.  It is also packaged as a library so that
applications can easily incorporate a complete Scheme interpreter/VM.
An application can use Guile as an extension language, a clean and
powerful configuration language, or as multi-purpose "glue" to connect
primitives provided by the application.  It is easy to call Scheme code
>From C code and vice versa.  Applications can add new functions, data
types, control structures, and even syntax to Guile, to create a
domain-specific language tailored to the task at hand.

Guile 2.9.6 can be installed in parallel with Guile 2.2.x; see
http://www.gnu.org/software/guile/manual/html_node/Parallel-Installations.html.

A more detailed NEWS summary follows these details on how to get the
Guile sources.

Here are the compressed sources:
  http://alpha.gnu.org/gnu/guile/guile-2.9.6.tar.lz   (10MB)
  http://alpha.gnu.org/gnu/guile/guile-2.9.6.tar.xz   (12MB)
  http://alpha.gnu.org/gnu/guile/guile-2.9.6.tar.gz   (21MB)

Here are the GPG detached signatures[*]:
  http://alpha.gnu.org/gnu/guile/guile-2.9.6.tar.lz.sig
  http://alpha.gnu.org/gnu/guile/guile-2.9.6.tar.xz.sig
  http://alpha.gnu.org/gnu/guile/guile-2.9.6.tar.gz.sig

Use a mirror for higher download bandwidth:
  http://www.gnu.org/order/ftp.html

Here are the SHA256 checksums:

  615e6cabeb6ada4c1b04e9547ce3796e3c80948abd310113ff50a3ee880deba8  
guile-2.9.6.tar.lz
  6eede2df10c7aa4c4f46d5eeb714752d196fa5325bdde9a0990d7eb8ca833127  
guile-2.9.6.tar.xz
  cb7dbcfb02ea4d5f697d16e95f82959fa76963556cadab0afef741a82f705cbf  
guile-2.9.6.tar.gz

[*] Use a .sig file to verify that the corresponding file (without the
.sig suffix) is intact.  First, be sure to download both the .sig file
and the corresponding tarball.  Then, run a command like this:

  gpg --verify guile-2.9.6.tar.gz.sig

If that command fails because you don't have the required public key,
then run this command to import it:

  gpg --keyserver keys.gnupg.net --recv-keys 
4FD4D288D445934E0A14F9A5A8803732E4436885

and rerun the 'gpg --verify' command.

This release was bootstrapped with the following tools:
  Autoconf 2.69
  Automake 1.16.1
  Libtool 2.4.6
  Gnulib v0.1-1157-gb03f418
  Makeinfo 6.5


The NEWS extract follows, but as a present for having read down this
far, here's a comparison of some microbenchmark results between Guile
2.2.6 and Guile 2.9.6:


Happy hacking!  Now the NEWS:


Changes in alpha 2.9.6 (since alpha 2.9.5):

* Notable changes

** Add --r6rs, --r7rs options to `guild compile'

This makes compiling R6RS or R7RS code a bit easier.  See "R6RS Support"
and "R7RS Support" in the manual, for more.

** Add guile-3, guile-3.0 cond-expand features

See "SRFI-0" in the manual, for more.

** Add #:re-export-and-replace argument to `define-module'

This new keyword specifies a set of bindings to re-export, but also
marks them as intended to replace core bindings.  See "Creating Guile
Modules" in the manual, for full details.

Note to make this change, we had to change the way replacement flags are
stored, to being associated with modules instead of individual variable
objects.  This means that users who #:re-export an imported binding that
was already marked as #:replace by another module will now see warnings,
as they need to use #:re-export-and-replace instead.

** Better optimizations for vector-length et al

Sometimes the compiler get confused and think it couldn't hoist a
`vector-length' call out of a loop.  This has been fixed.

* Bug fixes

** Fix range inference on division in unreachable code
** Fix frame-call-representation for callees without closures
** Fix range inference for right-shifts
** Fix port-position documentation
** Fix stack overflow if printing a pre-boot error th

Re: [PATCH 1/2] srfi-34: Replace the 'raise' core binding.

2019-11-29 Thread Andy Wingo
On Tue 26 Nov 2019 14:09, Ludovic Courtès  writes:

> AFAICS there are two blockers:
>
>   1. We cannot replace & re-export at the same time.

Following discussion on IRC, this is fixed now, with
#:re-export-and-replace.  Would be nice if #:re-export could know
whether a binding is local or re-exported and DTRT but that isn't the
case currently.

>   2. ‘raise’ takes exactly one argument, whereas ‘raise-exception’ takes
>  an additional keyword argument.

I think ignoring this one is fine FWIW.

> Perhaps also we should provide a mechanism similar to GCC attributes to
> mark a procedure as throwing, so that the compiler can DTRT?

An interesting option :)  FWIW the compiler has to also know how to call
the callee...  Something to think about.

Cheers,

Andy



Re: For a cheaper ‘bytevector->pointer’

2019-11-26 Thread Andy Wingo
Hi :)

On Mon 25 Nov 2019 23:03, Ludovic Courtès  writes:

> Andy Wingo  skribis:
>
>> Honestly I would prefer not to do this.  If I understand correctly, the
>> problem is in FFI calls -- you have a bytevector and you want to pass it
>> as a pointer.  In that case the "right" optimization is to avoid the
>> scm_tc7_pointer altogether and instead having an unboxed raw pointer.
>> The idioms used in FFI are local enough that a compiler can do this.
>
> I agree!  I have a patch from the 2.0 era (attached), but it doesn’t
> work because all the tc3s are already taken.  I don’t think this has
> changed but I could well be missing something about the tag space.
> WDYT?

I was actually thinking about raw pointer values -- i.e. not
immediate-tagged values.  If you think about it these values are
generally live only between the bytevector->pointer and the FFI call --
the compiler is capable of safely unboxing values in spaces like that.
But this would work better with a more compiler-focussed FFI than with
the current "interpreted" FFI.

But, immediate pointers would be nice too; nicer, in some ways.  See
also Mark's fixrat work.

>> In the short term, what about allowing bytevectors as arguments
>> whereever a pointer is allowed?  Perhaps it's bad to expand the domain
>> of these functions but it may be the right trade-off.
>
> So in practice, every time there’s '* in the FFI, it’d accept a
> bytevector, right?

That was the idea :)

> I would prefer immediate pointers if that’s possible, and then one of
> the two other solutions.

In that case I am not sure what a good solution is.  Having to add an
additional 2-word internal displacement is a bit unfortunate, if that's
the case!

Andy



Re: [PATCH 1/2] srfi-34: Replace the 'raise' core binding.

2019-11-26 Thread Andy Wingo
On Mon 25 Nov 2019 17:45, Ludovic Courtès  writes:

> In Guile 2.x, (srfi srfi-34) would already replace 'raise'.  Replacing
> avoids a run-time warning about the core binding being overridden.
>
> * module/srfi/srfi-34.scm (raise): New variable.
> Mark it as #:replace instead of #:re-export.
> ---
>  module/srfi/srfi-34.scm | 10 +++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/module/srfi/srfi-34.scm b/module/srfi/srfi-34.scm
> index 0e7ad995d..255bfecb9 100644
> --- a/module/srfi/srfi-34.scm
> +++ b/module/srfi/srfi-34.scm
> @@ -1,6 +1,6 @@
>  ;;; srfi-34.scm --- Exception handling for programs
>  
> -;; Copyright (C) 2003, 2006, 2008, 2010 Free Software Foundation, Inc.
> +;; Copyright (C) 2003, 2006, 2008, 2010, 2019 Free Software Foundation, Inc.
>  ;;
>  ;; This library is free software; you can redistribute it and/or
>  ;; modify it under the terms of the GNU Lesser General Public
> @@ -27,12 +27,16 @@
>  ;;; Code:
>  
>  (define-module (srfi srfi-34)
> -  #:re-export (with-exception-handler
> -   (raise-exception . raise))
> +  #:re-export (with-exception-handler)
> +  #:replace (raise)
>#:export-syntax (guard))
>  
>  (cond-expand-provide (current-module) '(srfi-34))
>  
> +(define (raise exn)
> +  "Raise the given exception, invoking the current exception handler on EXN."
> +  (raise-exception exn))

LGTM but it is better to re-export if possible.  The reason is that
right now the compiler recognizes "throw" and "error" as not falling
through, and this is good for a number of reasons; it would be nice to
extend this to raise-exception.  We should make it possible to re-export
and replace at the same time, IMO.

Andy



guile-devel@gnu.org

2019-11-26 Thread Andy Wingo
On Mon 25 Nov 2019 17:45, Ludovic Courtès  writes:

> This ensures core binding '&error' is silently replaced by the SRFI-35
> variant.

Again LGTM but it would be nicest to really re-export the binding
instead of making a new definition :)

Andy



Re: For a cheaper ‘bytevector->pointer’

2019-11-25 Thread Andy Wingo
On Sun 24 Nov 2019 11:52, Ludovic Courtès  writes:

> A few days ago David was explaining on #guile how ‘bytevector->pointer’
> was generating too much garbage for his use case.  An idea we came up
> with was to embed the pointer object in the bytevector.
>
> The patch below does that but it leads to segfaults because I’m guessing
> there’s generated bytecode somewhere that still uses the wrong offset; I
> adjusted code that emits ‘pointer-ref/immediate’, what else did I
> miss?

The compiler :)  Bytevector literals are stored statically in the .go
files, so the assembler would need to change to emit the new layout.
Also, compiled access to bytevectors; see prepare-bytevector-access in
(language tree-il compile-cps).

> Also, since we disable internal pointers, we’d need to register an
> additional displacement, and I’m not sure if this is a good idea.
>
> Thoughts?

Honestly I would prefer not to do this.  If I understand correctly, the
problem is in FFI calls -- you have a bytevector and you want to pass it
as a pointer.  In that case the "right" optimization is to avoid the
scm_tc7_pointer altogether and instead having an unboxed raw pointer.
The idioms used in FFI are local enough that a compiler can do this.

More broadly -- the current FFI is an interpreter but it should be a
compiler.  When a call happens, the code interprets the description of
the ABI.  Instead, pointer->function should ideally *compile* a
trampoline.  In an ideal world this compilation can happen
ahead-of-time, when the .go file is compiled.

In the short term, what about allowing bytevectors as arguments
whereever a pointer is allowed?  Perhaps it's bad to expand the domain
of these functions but it may be the right trade-off.

Andy



Re: Mutating public bindings of a declarative module

2019-11-25 Thread Andy Wingo
Hi :)

On Sun 24 Nov 2019 18:54, Ludovic Courtès  writes:

> It seems that if you ‘set!’ a public variable of a declarative module,
> the change is visible to all the module users, but it’s not necessarily
> visible to procedures within that module, presumably because they use an
> inlined or specialized variant of that thing.
>
> I would have imagined that public bindings are considered mutable and
> thus not subject to inlining; OTOH, that would obviously be a loss, so
> the current approach makes sense.

Right, I understand the frustration.  For what it is worth, I think we
have the right default for what it means to be a declarative module, but
I'm definitely open to having that conversation.

> Anyway, it complicates a use case for me.  In Guix, we “mock” bindings
> like so:
>
>   (define-syntax-rule (mock (module proc replacement) body ...)
> "Within BODY, replace the definition of PROC from MODULE with the 
> definition
>   given by REPLACEMENT."
> (let* ((m (resolve-interface 'module))
>(original (module-ref m 'proc)))
>   (dynamic-wind
> (lambda () (module-set! m 'proc replacement))
> (lambda () body ...)
> (lambda () (module-set! m 'proc original)
>
> and that allows us to write tests that temporarily modify public (or
> private!) bindings.
>
> It seems like this could be addressed by compiling selected modules with
> ‘user-modules-declarative?’ set to #false, or by avoiding the above hack
> altogether when possible, but I thought I’d share my impressions and
> listen to what people think.  :-)

This works.  (Actually the way I would do it is to pass #:declarative?
#f in the define-module for the modules in question.)  Marking some
bindings as not declarative also works (e.g. (set! foo foo)).

For me the most robust solution would be to have `mock' verify that the
module it's funging isn't declarative.  We don't currently have a way to
know if an individual module binding is declarative or not (though we
could add this).

Cheers,

Andy



GNU Guile 2.9.5 Released [beta]

2019-11-22 Thread Andy Wingo
We are pleased to announce GNU Guile release 2.9.5.  This is the fifth
pre-release of what will eventually become the 3.0 release series.

Compared to the current stable series (2.2.x), the future Guile 3.0 adds
support for just-in-time native code generation, speeding up all Guile
programs.  See the NEWS extract at the end of the mail for full details.

Compared to the previous prerelease (2.9.4), Guile 2.9.5 adds low-level
optimizations for converting between unboxed integers and floating-point
values, generates faster code at optimization level -O3, adds R7RS
support, a --r6rs command-line argument, and a fresh implementation of
raise-exception and with-exception-handler.

We encourage you to test this release and provide feedback to
guile-devel@gnu.org, and to file bugs by sending mail to
bug-gu...@gnu.org.

The Guile web page is located at http://gnu.org/software/guile/, and
among other things, it contains a copy of the Guile manual and pointers
to more resources.

Guile is an implementation of the Scheme programming language, with
support for many SRFIs, packaged for use in a wide variety of
environments.  In addition to implementing the R5RS Scheme standard,
Guile includes a module system, full access to POSIX system calls,
networking support, multiple threads, dynamic linking, a foreign
function call interface, and powerful string processing.

Guile can run interactively, as a script interpreter, and as a Scheme
compiler to VM bytecode.  It is also packaged as a library so that
applications can easily incorporate a complete Scheme interpreter/VM.
An application can use Guile as an extension language, a clean and
powerful configuration language, or as multi-purpose "glue" to connect
primitives provided by the application.  It is easy to call Scheme code
>From C code and vice versa.  Applications can add new functions, data
types, control structures, and even syntax to Guile, to create a
domain-specific language tailored to the task at hand.

Guile 2.9.5 can be installed in parallel with Guile 2.2.x; see
http://www.gnu.org/software/guile/manual/html_node/Parallel-Installations.html.

A more detailed NEWS summary follows these details on how to get the
Guile sources.

Here are the compressed sources:
  http://alpha.gnu.org/gnu/guile/guile-2.9.5.tar.lz   (10MB)
  http://alpha.gnu.org/gnu/guile/guile-2.9.5.tar.xz   (12MB)
  http://alpha.gnu.org/gnu/guile/guile-2.9.5.tar.gz   (21MB)

Here are the GPG detached signatures[*]:
  http://alpha.gnu.org/gnu/guile/guile-2.9.5.tar.lz.sig
  http://alpha.gnu.org/gnu/guile/guile-2.9.5.tar.xz.sig
  http://alpha.gnu.org/gnu/guile/guile-2.9.5.tar.gz.sig

Use a mirror for higher download bandwidth:
  http://www.gnu.org/order/ftp.html

Here are the SHA256 checksums:
  0c0097092fc5b0b40c5eb97ce09bf5415b31c5f7241f4cdcb01284f81cb2f70f  
guile-2.9.5.tar.lz
  f917cb8578740887df8e0090fdecf3f06aaf60d2331067b88ff5c3bb610d69b5  
guile-2.9.5.tar.xz
  199c5dbba3ec4322dfd9f1e1af6c19deca77fa4a104c59f26aeea23f7640720d  
guile-2.9.5.tar.gz

[*] Use a .sig file to verify that the corresponding file (without the
.sig suffix) is intact.  First, be sure to download both the .sig file
and the corresponding tarball.  Then, run a command like this:

  gpg --verify guile-2.9.5.tar.gz.sig

If that command fails because you don't have the required public key,
then run this command to import it:

  gpg --keyserver keys.gnupg.net --recv-keys 
4FD4D288D445934E0A14F9A5A8803732E4436885

and rerun the 'gpg --verify' command.

This release was bootstrapped with the following tools:
  Autoconf 2.69
  Automake 1.16.1
  Libtool 2.4.6
  Gnulib v0.1-1157-gb03f418
  Makeinfo 6.5


Changes in beta 2.9.5 (since beta 2.9.4):

* Notable changes

** Record unification

Guile used to have a number of implementations of structured data types
in the form of "records": a core facility, SRFI-9 (records), SRFI-35
(condition types -- a form of records) and R6RS records.  These
facilities were not compatible, as they all were built in different
ways.  This had the unfortunate corollary that SRFI-35 conditions were
not compatible with R6RS conditions.  To fix this problem, we have now
added the union of functionality from all of these record types into
core records: single-inheritance subtyping, mutable and immutable
fields, and so on.  See "Records" in the manual, for full details.

R6RS records, SRFI-9 records, and the SRFI-35 and R6RS exception types
have been accordingly "rebased" on top of core records.

** Reimplementation of exceptions

Since Guile's origins 25 years ago, `throw' and `catch' have been the
primary exception-handling primitives.  However these primitives have
two problems.  One is that it's hard to handle exceptions in a
structured way using `catch'.  Few people remember what the
corresponding `key' and `args' are that an exception handler would see
in response to a call to `error', for example.  In practice, this
results in more generic catch-all exception handling than one might
like.

The other pr

Re: guile 3 update, halloween edition

2019-11-17 Thread Andy Wingo
Hi :)

On Sat 16 Nov 2019 16:26, Ludovic Courtès  writes:

> Andy Wingo  skribis:
>
>> On Fri 15 Nov 2019 10:03, Ludovic Courtès  writes:
>>
>>> I guess we could add a specific ‘&type-exception’ exception or similar,
>>> which would allow us to improve error reporting (that can come later, of
>>> course.)
>
> What I meant is that type errors are “special” enough to deserve their
> own type more specific than the catch-all ‘&assertion-failure’ (just
> like there’s already a separate ‘&undefined-variable’, for instance.)

Agreed!

> Speaking of which, it seems that ‘set-guile-exception-converter!’ is
> currently private, but I wonder if the goal was to make it public (it
> seems to be unused)?

It was private also in the exception conversion work that Mark did,
FWIW; it just moved over as-is.

Honestly I think that now that exceptions are "primary" we should
probably move in the opposite direction: instead of adding more
converters from key+args to exception objects, we should encourage
exception throwers to switch from "throw" to "raise-exception", and
allow library authors to define converters in the other way from
exception object to the equivalent arguments for "catch".  So I think
exposing set-guile-exception-converter! might be the wrong thing at this
point.  Dunno tho.

> For instance, C bindings that currently call ‘throw’ could provide
> additional “exception converters” for the benefit of Scheme users
> who’d rather use structured exceptions.  (That would also give less of
> an incentive to provide a C API for all of this.)

This is a good point!

FWIW Regarding C and migration, I have the impression that probably 90%
of exception throwers in C use the helpers from error.h
(scm_wrong_num_args and so on), which we can change transparently.  A
remaining 5% might use scm_error_scm, for which a registry might make
sense, and 5% use scm_throw directly.  These are just guesses tho.

>>> 4. Is ‘&warning’ actually used?  Is the goal to make it continuable?
>>> That sounds great.
>>
>> Any exception can be raised in a continuable way.  Whether a raise is
>> continuable or not depends on the value of the #:continuable? keyword to
>> raise-exception.  I think that's the intention of &warning but I don't
>> really have instincts about how it might be used.  Guile defines it
>> because it's in R6RS, but how it will be used is an open question :)
>
> I suppose the intent is to effectively allow users to implement the UI
> stuff as a sort of co-routine to support separation of concerns: you
> just raise a ‘&warning’ that some other code displays in its preferred
> way (console message, popup window, whatever) and eventually calls your
> continuation.
>
> That’s something I’ve been wanting for some time, because right now
> we’re able to separate out the UI concern for exception display, but not
> for warnings.
>
> However, it seems that the handler passed to ‘with-exception-handler’
> does not receive the continuation, so is it the case that currently
> handlers cannot resume exceptions?  (Again not a showstopper IMO but
> rather another wishlist item :-)).

The handler runs within the continuation of "raise-continuable":

  (with-exception-handler
   (lambda (exn) (+ exn 30))
   (lambda () (+ 2 (raise-exception 10 #:continuable? #t
  => 42

However I'm not sure this facility is what you want.  Like for example
there's lots of false-if-exception / catch #t out there; that's
equivalent to:

  (define-syntax-rule (false-if-exception expr)
(let/ec k
  (with-exception-handler
   (lambda (exn) (k #f))
   (lambda () expr

So the exception handler there would intervene and get a first crack at
the warning, messing up your intent.  To me warnings are like logging,
and logging is notoriously difficult to standardize :)  If it were me I
would make a mechanism for warnings that had a with-warning-handler and
I would make sure to raise all warnings via a separate raise-warning
procedure or something, independent of exceptions.  But that's just me
:)

Andy



Re: landed r7rs support

2019-11-17 Thread Andy Wingo
Hi,

On Sun 17 Nov 2019 16:52, Linus Björnstam  writes:

> The text about the standards process is probably going to annoy people
> since it does not mention the division between r7rs small and large :)

I suppose that is fair, as I am annoyed by R7RS :)  However, the report
published in 2013 does bear the name R7RS and not R7RS-small, so it's
not an error to refer to it as such.  In any case, it does not seem to
me that R7RS-large is similar to the other reports in the RnRS series.
To me it is more similar in flavor to the SRFI process.

Andy



landed r7rs support

2019-11-17 Thread Andy Wingo
Hey all :)

Just a little heads-up that I just landed R7RS support.  Thanks to Göran
Weinholt for akku-scm (https://gitlab.com/akkuscm/akku-r7rs/) and
OKUMURA Yuki for yuni (https://github.com/okuoku/yuni), off of which
some of these files were based.  (These projects are public domain /
CC0).

The library syntax for R7RS is a subset of R6RS, so to use R7RS you just
(import (scheme base)) and off you go.  As with R6RS also, there are
some small lexical incompatibilities regarding hex escapes; see "R7RS
Incompatibilities" in the manual.  Also there is a --r7rs command-line
option.

Cheers,

Andy



Re: guile 3 update, halloween edition

2019-11-15 Thread Andy Wingo
Hey thanks for the review :)

On Fri 15 Nov 2019 10:03, Ludovic Courtès  writes:

> 0. Do I get it right that ‘throw’ and ‘catch’ are not “deprecated” in
> the sense of (ice-9 deprecated) and are instead simply not the
> “preferred” exception mechanism?

Correct.  I think we could envision deprecating them in some future but
not within the next couple years at least.

> 1. I see things like:
>
> +(define (make-condition type . field+value)
> +  "Return a new condition of type TYPE with fields initialized as specified
> +by FIELD+VALUE, a sequence of field names (symbols) and values."
> +  (unless (exception-type? type)
> +(scm-error 'wrong-type-arg "make-condition" "Not a condition type: ~S"
> +   (list type) #f))
>
> and:
>
> +  (unless (symbol? key)
> +(throw 'wrong-type-arg "throw" "Wrong type argument in position ~a: 
> ~a"
> +   (list 1 key) (list key)))
>
> I guess we could add a specific ‘&type-exception’ exception or similar,
> which would allow us to improve error reporting (that can come later, of
> course.)

Yes.  So right now Guile is in a bit of a transitional state -- it still
signals 99.9% of errors via `throw'.  Probably we want to change to have
structured exceptions for almost all of these.  To preserve
compatibility we would probably need to mix in an
&exception-with-kind-and-args to all of these exceptions, or otherwise
augment `exception-kind' and `exception-args' to synthesize these values
when appropriate.

> Guix has ‘&location’ error conditions, which I’ve found useful when
> combined with other error conditions in cases where location info from
> the stack isn’t useful:
>
>   https://git.savannah.gnu.org/cgit/guix.git/tree/guix/utils.scm#n832
>
> I wonder if (ice-9 exceptions) should provide something like that.

Neat :)  Yes sure.  I think, any exception type can be added to (ice-9
exceptions) -- there's little "name cost" like there is in boot-9.
Which reminds me, I want to make boot-9 do a (resolve-module '(ice-9
exceptions)) so that the more capable make-exception-from-throw always
gets installed.

> 2. What are you thoughts regarding exposing structured exceptions to C?
> I’ve always been frustrated by ‘system-error’ :-).  Guix has a hack to
> augment ‘system-error’ with information about the offending file name:
>
>   https://git.savannah.gnu.org/cgit/guix.git/tree/guix/ui.scm#n520
>
> If the POSIX bindings would emit a structured ‘&system-error’ record,
> that’d be pretty cool.

I don't know :)  Right now raise-exception is marked SCM_INTERNAL.
Probably it should be public.  There is no public C API for any of this
new functionality, as it stands; a TODO.

Regarding exception objects, there are two questions: one, how to create
exceptions of specific kinds; I suspect scm_make_system_error () would
be fine, and probably you want scm_make_exception to be able to mix
various exceptions.  Second question, do we want to expose accessors
too?  It can be a lot of API surface and I am a bit wary of it.  But,
perhaps it is the right thing.  I do not know.

> 3. I wonder if we could take advantage of the new ‘&message’ exception
> to start i18n of error messages.  It might be as simple as telling
> xgettext to recognize ‘make-exception-with-message’ as a keyword, though
> currently there are few calls to ‘make-exception-with-message’ followed
> by a literal.

Eventually this will get called by `error', I think; Guile's R7RS layer
in wip-r7rs defines `error' as being:

  (define (error message . irritants)
(raise-exception
 (let ((exn (make-exception-with-message message)))
   (if (null? irritants)
   exn
   (make-exception exn
   (make-exception-with-irritants irritants))

But yes this is definitely something to think about it.

> 4. Is ‘&warning’ actually used?  Is the goal to make it continuable?
> That sounds great.

Any exception can be raised in a continuable way.  Whether a raise is
continuable or not depends on the value of the #:continuable? keyword to
raise-exception.  I think that's the intention of &warning but I don't
really have instincts about how it might be used.  Guile defines it
because it's in R6RS, but how it will be used is an open question :)

> Bah, you give us a present and I reply with an additional wishlist.
> ;-)

:)  I hope that the exceptions work can serve as a foundation for
further incremental, compatible improvement.

Cheers,

Andy



Re: guile 3 update, halloween edition

2019-11-03 Thread Andy Wingo
On Sat 02 Nov 2019 06:20, Mark H Weaver  writes:

> Andy Wingo  writes:
>
>> So, now the pending task is to somehow get a condition/exception
>> hierarchy into Guile core.  I will try to mostly push things off to side
>> modules but it won't always be possible.  There will be bijections
>> between a Guile's "throw" arguments and structured exceptions, mostly
>> inspired with what Julian did in the R6RS layer already.
>
> For the record, the bijection between R6RS conditions and Guile's throw
> arguments was my work, not Julian's.

An honest mistake on my part.  My sincere apologies!

Warm regards,

Andy



Re: guile 3 update, halloween edition

2019-10-31 Thread Andy Wingo
Greets :)

On Thu 31 Oct 2019 01:01, Chris Vine  writes:

> "Condition" is a strange word for describing structured error objects,
> I agree.  However, I think it would be quite confusing to describe
> error objects as exceptions.  "Error object" or "error condition object"
> seems a reasonable alternative if the bare word "condition" is thought
> to be inappropriate.

I'm very sympathetic to this argument -- an exception seems like a
thing-in-motion, not a thing-at-rest.  But perhaps it's just the effect
of habit, setting up expectations about what good names are.  (After
all, plenty of people seem happy with the term "condition"!)

Perhaps there is a middle ground of sorts: maybe the manual can
comprehensively describe what R6RS refers to as conditions using the
term "exception objects".  WDYT?

Andy



Re: guile 3 update, halloween edition

2019-10-31 Thread Andy Wingo
Hey :)

On Thu 31 Oct 2019 15:17, Mikael Djurfeldt  writes:

> How does the record subtyping relate to GOOPS? I do realize that there
> are issues related to keeping bootstrapping lean, but shouldn't record
> types and classes share mechanisms?

They share the struct layer.

Records are simple: their fields are laid out in order, are all unboxed,
and can be treated as a simple kind of nominal product type.  `match'
takes advantage of this.

GOOPS is more flexible: it can have different slot allocations, unboxed
slots, multiple inheritance, and so on.  Because of multiple inheritance
its accessors have to do dynamic dispatch; whereas for records, if
supertype A allocates slot X to index I, all subtypes will have that
slot in the same place.  A check whether a record is an instance of A is
a simple O(1) check, rather than the CPL search of GOOPS.

Exceptions have a kind of multiple inheritance, but it's more about
object composition than typing.  You can make a compound condition from
a heterogeneous collection of other conditions.  While you could
implement compound conditions with subtyping, it's more straightforward
to use composition.

I think the current status is close to the sweet spot but your thoughts
are welcome :)  I would dearly like to be able to subtype records in
GOOPS, but having looked at it a few times I haven't found quite the
right way to do it.

Cheers,

Andy



guile 3 update, halloween edition

2019-10-30 Thread Andy Wingo
Hey folks!

I wanted to send out an update on Guile 3.  Do take a look at
https://git.savannah.gnu.org/cgit/guile.git/tree/NEWS to see where we've
come; basically the JIT is done, and we're ready to release soonish.

However!  Here begins a long chain of yak-shaving:

I wanted good benchmarks.  Generally up to now, we haven't really been
doing good incremental benchmarks.  Ideally we could see some benchmark
results historically, on every commit, and against other Scheme
implementations.  To a degree it's been possible with
https://ecraven.github.io/r7rs-benchmarks/, but those benchmarks have a
few problems:

 (1) They use unsafe optimizations on e.g. Chez and Gambit
 (2) They are infrequently run
 (3) They rely on R7RS, adding their own little compat layer for Guile,
 which isn't optimal.

Now, regarding (3), probably Guile should just have its own R7RS layer.
And it should be easier to enable R6RS too.  So I added an --r6rs
option, and started importing some R7RS code from Göran Weinholt
(thanks!), with the idea of adding --r7rs.  That way we can just
benchmark the different implementations, just passing --r7rs or whatever
to get the behavior we want.  We can reduce the set of other scheme
implementations to just the high-performance ones: Gambit, Larceny,
Chez, and Racket.

However!  R7RS, like R6RS and like SRFI-35/SRFI-34, and also like
Racket, specifies an error-handling system in terms of "raise" and
"with-exception-handler".  Guile uses "throw" and "catch".  There is a
pretty good compatibility layer in Guile's R6RS exceptions/conditions
code, but it's not shared by SRFI-35/SRFI-34, and unless we built R7RS
in terms of R6RS -- something I prefer not to do; these things should be
layered on Guile core directly -- we'd have to duplicate the mechanism.

Which, of course, is a bit trash.  And when you come to think of it,
throw/catch/with-throw-handler is also a bit trash.  It is too hard to
handle exceptions in Guile; the addition of `print-exception' a few
years back improved things, but still, making any sense out of the
"args" corresponding to a "key" is a mess.

All this made me think -- Guile should probably switch to
raise/with-exception-handler and structured exceptions.  (Or conditions,
or whatever we choose to call them.  I find the "condition" name a bit
weird but maybe that's just a personal problem.)  Racket does this too,
for what it's worth, though they have their own historical baggage.

But, we need to maintain compatibility with throw/catch, because that's
not going anywhere any time soon (if ever).  So I hacked a bit and
eventually came up with a decent implementation of throw/catch on top of
raise/with-exception-handler, and I think it's compatible in all the
weird ways that it needs to be.

But!  Now we have bootstrapping problems; how to get the implementation
in boot-9?  Exceptions in SRFI-35, R6RS, R7RS, and Racket are these
hierarchical things: they form a DAG of subtypes.  But core records in
Guile aren't subtypeable, so what to do?

Well, my thinking was that we needed to sedimentarily deposit down into
Guile core those commonalities between the different record
implementations in Guile: SRFI-35 conditions, R6RS records, and SRFI-9
records.  So core now has the notion of field mutability on the record
layer (as opposed to the struct layer), a notion of subtyping, a notion
of extensibility, and so on.  This is all now in the manual and will be
in NEWS.

With that, we now have just one implementation of records!!!  I am very
pleased about this.  Now you can use core record introspection
facilities on any record in Guile.  Cool.  This also helped untangle
some knots in the R6RS inter-module graph.

So, now the pending task is to somehow get a condition/exception
hierarchy into Guile core.  I will try to mostly push things off to side
modules but it won't always be possible.  There will be bijections
between a Guile's "throw" arguments and structured exceptions, mostly
inspired with what Julian did in the R6RS layer already.

Thoughts welcome!  Also: should these structured error objects be named
exceptions or conditions?  SRFI-35, R6RS, and R7RS say "conditions", but
racket and my heart say "exceptions"; wdyt?

Cheers,

Andy



conflicts in the gnu project now affect guile

2019-10-16 Thread Andy Wingo
Hello all,

In the last few weeks, a conversation among GNU maintainers that has
been simmering for years burst into public.  For a while it resubmerged
into private GNU lists, but now it has resurfaced to affect the Guile
project.

Just for background information, I wrote about my thoughts here:

  https://wingolog.org/archives/2019/10/08/thoughts-on-rms-and-gnu

The summary is that, like many people in GNU, I have long treated
Richard Stallman not as a hero, not as a leader, but rather a "missing
stair" (https://en.wikipedia.org/wiki/Missing_stair) that one has to
route around.  This approach was never very inclusive -- if you don't
have much experience in GNU, it's possible to not know about it, and to
fall in the hole yourself.  On the other hand if you know of RMS but not
Guile, you might think that Guile developers support RMS.

However, recent events made me realize this approach was not only unfair
to newcomers, but unjust as well, as by continuing to work on GNU and
not saying anything, I was both lending unmerited prestige to RMS,
enabling his creepy behavior towards women, and additionally, enabling
his apparent pedophilia-advocacy.

Regarding this latter point, I wasn't really aware that this was a view
RMS was promoting, but I am ashamed to admit that I had heard rumors
that Richard publically advocated sex between adults and teenagers,
defended sexual harassers, and questioned the experience of victims of
sexual assault, and I preferred not to listen.  Looking again, and I
think Richard's web site speaks for itself:

  
https://web.archive.org/web/20170612074722/http://stallman.org/archives/2017-mar-jun.html#26_May_2017_(Prudish_ignorantism)
  
https://web.archive.org/web/20180131020215/https://stallman.org/archives/2017-jul-oct.html#29_October_2017_(Pestering_women)
  
https://web.archive.org/web/20180104112431/https://www.stallman.org/archives/2017-nov-feb.html#27_November_2017_(Roy_Moore's_relationships)
  
https://web.archive.org/web/20180509120046/https://stallman.org/archives/2018-mar-jun.html#30_April_2018_(UN_peacekeepers_in_South_Sudan)
  
https://web.archive.org/web/20180911075211/https://www.stallman.org/archives/2018-jul-oct.html#17_July_2018_(The_bullshitter's_flirting)
  
https://web.archive.org/web/20180911075211/https://www.stallman.org/archives/2018-jul-oct.html#21_August_2018_(Age_and_attraction)
  
https://web.archive.org/web/20180924231708/https://stallman.org/archives/2018-jul-oct.html#23_September_2018_(Cody_Wilson)
  
https://web.archive.org/web/20181113161736/https://www.stallman.org/archives/2018-sep-dec.html#6_November_2018_(Sex_according_to_porn)
  
https://web.archive.org/web/20190325024048/https://stallman.org/archives/2019-jan-apr.html#14_February_2019_(Respecting_peoples_right_to_say_no)
  
https://www.stallman.org/archives/2019-may-aug.html#11_June_2019_(Stretching_meaning_of_terms)
  
https://web.archive.org/web/20190801201704/https://stallman.org/archives/2019-may-aug.html#12_June_2019_(Declining_sex_rates)
  
https://web.archive.org/web/20190801201704/https://stallman.org/archives/2019-may-aug.html#30_July_2019_(Al_Franken)
  
https://web.archive.org/web/20190903050208/https://stallman.org/archives/2019-jul-oct.html#27_August_2019_(Me-too_frenzy)

Anyway.  So far, so GNU.  A couple weeks ago I thought it an opportune
moment to declare publicly the views that I have long held privately:
that I do not consider RMS to be the leader of GNU, and that GNU
maintainers and other developers with a stake in the project should
organize to fill the void.

   *  *  *

I pause here to mention that you may not agree with this perspective and
that is fine.  There are many ways that we can continue to work together
while this discussion plays out.  Part of the purpose of this mail
though is to make it clear that there are differences of opinion and
that the GNU project is in flux.

   *  *  *

Now we get to how this issue affects Guile.

Before the RMS/GNU/FSF conversation started, Mark Weaver left Guile, for
essentially unrelated reasons.  He threatened to leave because he wished
to be consulted before I landed mixed definitions and expressions and
shipped them in the 2.9.4 release; I responded over email asking to talk
about the issues; in response a week later I see that he resigned from
maintainership and left the Guile group on Savannah.  It was truly a
shame for Guile, as Mark is an excellent hacker and has done a lot of
good work for Guile.

It's true also that, mixed with the sadness, I felt a modicum of relief.
It has never been easy to work with Mark.  I could toil on Guile for
weeks, taking time away from my family, and then wake up to receive a
private mail excoriating me for my work.  It was also far from the first
time he threatened to leave the project if he did not get his way.  I
have never let the problems between Mark and me into the public sphere
though, preferring to preserve his reputation, and it 

Maintainership changes: many thanks to Mark!

2019-09-11 Thread Andy Wingo
Hi all,

After many years working on Guile and more than 5 years in a
maintainer role, Mark Weaver has decided to step down.  Taking over
from him and remaining as Guile co-maintainers are Ludovic Courtès and
Andy Wingo.

On behalf of myself and Ludovic and no doubt all Guile users and
developers: a heartfelt thanks, Mark, for all of your years of
service, and see you around the Guile community!

Happy hacking,

Andy and Ludovic



GNU Guile 2.9.4 Released [beta]

2019-08-25 Thread Andy Wingo
We are pleased to announce GNU Guile release 2.9.4.  This is the fourth
pre-release of what will eventually become the 3.0 release series.

Compared to the current stable series (2.2.x), the future Guile 3.0 adds
support for just-in-time native code generation, speeding up all Guile
programs.  See the NEWS extract at the end of the mail for full details.

Compared to the previous prerelease (2.9.3), Guile 2.9.4 adds support
for more unboxed floating-point operations, enables inlining of
top-level definitions, improves compilation of `letrec*' and internal
definitions, and allows mixed internal definitions and expressions in
body contexts (e.g. in a `let').

We encourage you to test this release and provide feedback to
guile-devel@gnu.org, and to file bugs by sending mail to
bug-gu...@gnu.org.

The Guile web page is located at http://gnu.org/software/guile/, and
among other things, it contains a copy of the Guile manual and pointers
to more resources.

Guile is an implementation of the Scheme programming language, with
support for many SRFIs, packaged for use in a wide variety of
environments.  In addition to implementing the R5RS Scheme standard,
Guile includes a module system, full access to POSIX system calls,
networking support, multiple threads, dynamic linking, a foreign
function call interface, and powerful string processing.

Guile can run interactively, as a script interpreter, and as a Scheme
compiler to VM bytecode.  It is also packaged as a library so that
applications can easily incorporate a complete Scheme interpreter/VM.
An application can use Guile as an extension language, a clean and
powerful configuration language, or as multi-purpose "glue" to connect
primitives provided by the application.  It is easy to call Scheme code
>From C code and vice versa.  Applications can add new functions, data
types, control structures, and even syntax to Guile, to create a
domain-specific language tailored to the task at hand.

Guile 2.9.4 can be installed in parallel with Guile 2.2.x; see
http://www.gnu.org/software/guile/manual/html_node/Parallel-Installations.html.

A more detailed NEWS summary follows these details on how to get the
Guile sources.

Here are the compressed sources:
  http://alpha.gnu.org/gnu/guile/guile-2.9.4.tar.lz   (10MB)
  http://alpha.gnu.org/gnu/guile/guile-2.9.4.tar.xz   (12MB)
  http://alpha.gnu.org/gnu/guile/guile-2.9.4.tar.gz   (21MB)

Here are the GPG detached signatures[*]:
  http://alpha.gnu.org/gnu/guile/guile-2.9.4.tar.lz.sig
  http://alpha.gnu.org/gnu/guile/guile-2.9.4.tar.xz.sig
  http://alpha.gnu.org/gnu/guile/guile-2.9.4.tar.gz.sig

Use a mirror for higher download bandwidth:
  http://www.gnu.org/order/ftp.html

Here are the SHA256 checksums:

  e2da91bf20ab7b82ec6913dd9adcf64885f232f2242cdcdc7e612ead10ccf4fa  
guile-2.9.4.tar.lz
  17ecf3c09c9784526c6f27955bf9a74a2adf6f7f16e20b00e9cedf0871dc34d6  
guile-2.9.4.tar.xz
  4b495513866c52b2ce70997711cd3263914e946200c3541b79ccb82ccca69b9c  
guile-2.9.4.tar.gz

[*] Use a .sig file to verify that the corresponding file (without the
.sig suffix) is intact.  First, be sure to download both the .sig file
and the corresponding tarball.  Then, run a command like this:

  gpg --verify guile-2.9.4.tar.gz.sig

If that command fails because you don't have the required public key,
then run this command to import it:

  gpg --keyserver keys.gnupg.net --recv-keys 
4FD4D288D445934E0A14F9A5A8803732E4436885

and rerun the 'gpg --verify' command.

This release was bootstrapped with the following tools:
  Autoconf 2.69
  Automake 1.16.1
  Libtool 2.4.6
  Gnulib v0.1-1157-gb03f418
  Makeinfo 6.5


Changes in alpha 2.9.4 (since alpha 2.9.3):

* Notable changes

** Improved compilation of many floating-point primitives

Heavy floating-point computations that use `sqrt', `abs', `floor',
`ceiling', `sin', `cos', `tan', `asin', `acos', and `atan' will be
faster, as the compiler can unbox inexact rationals (flonums) in more
cases.

** Improved compilation of internal `define'

Internal definitions -- like the `define' in `(let () (define x 10)
...)' -- are now compiled more optimally, using the algorithm from
Ghuloum and Dybvig's "Fixing Letrec (reloaded)" paper.  This change
makes internal `define' just as efficient as `let', `let*', `letrec',
and similar.

** Interleaved internal definitions and expressions allowed

It used to be that internal definitions had to precede all expressions
in their bodies.  This restriction has been relaxed.  If an expression
precedes an internal definition, it is treated as if it were a
definition of an unreferenced variable.  For example, the expression
`(foo)' transforms to the equivalent of `(define _ (begin (foo) #f))',
if it precedes other definitions.

This change improves the readability of Guile programs, as it used to be
that program indentation tended to increase needlessly to allow nested
`let' and `letrec' to re-establish definition contexts after initial
expressions, for example for type-checks on proce

GNU Guile 2.9.3 Released [beta]

2019-08-03 Thread Andy Wingo
We are pleased to announce GNU Guile release 2.9.3.  This is the third
pre-release of what will eventually become the 3.0 release series.

Compared to the current stable series (2.2.x), the future Guile 3.0 adds
support for just-in-time native code generation, speeding up all Guile
programs.  See the NEWS extract at the end of the mail for full details.

Compared to the previous prerelease (2.9.2), Guile 2.9.3 improves the
quality of generated machine code, speeding up some programs by up to
50%.

We encourage you to test this release and provide feedback to
guile-devel@gnu.org, and to file bugs by sending mail to
bug-gu...@gnu.org.

The Guile web page is located at http://gnu.org/software/guile/, and
among other things, it contains a copy of the Guile manual and pointers
to more resources.

Guile is an implementation of the Scheme programming language, with
support for many SRFIs, packaged for use in a wide variety of
environments.  In addition to implementing the R5RS Scheme standard,
Guile includes a module system, full access to POSIX system calls,
networking support, multiple threads, dynamic linking, a foreign
function call interface, and powerful string processing.

Guile can run interactively, as a script interpreter, and as a Scheme
compiler to VM bytecode.  It is also packaged as a library so that
applications can easily incorporate a complete Scheme interpreter/VM.
An application can use Guile as an extension language, a clean and
powerful configuration language, or as multi-purpose "glue" to connect
primitives provided by the application.  It is easy to call Scheme code
>From C code and vice versa.  Applications can add new functions, data
types, control structures, and even syntax to Guile, to create a
domain-specific language tailored to the task at hand.

Guile 2.9.3 can be installed in parallel with Guile 2.2.x; see
http://www.gnu.org/software/guile/manual/html_node/Parallel-Installations.html.

A more detailed NEWS summary follows these details on how to get the
Guile sources.

Here are the compressed sources:
  http://alpha.gnu.org/gnu/guile/guile-2.9.3.tar.lz   (10MB)
  http://alpha.gnu.org/gnu/guile/guile-2.9.3.tar.xz   (12MB)
  http://alpha.gnu.org/gnu/guile/guile-2.9.3.tar.gz   (21MB)

Here are the GPG detached signatures[*]:
  http://alpha.gnu.org/gnu/guile/guile-2.9.3.tar.lz.sig
  http://alpha.gnu.org/gnu/guile/guile-2.9.3.tar.xz.sig
  http://alpha.gnu.org/gnu/guile/guile-2.9.3.tar.gz.sig

Use a mirror for higher download bandwidth:
  http://www.gnu.org/order/ftp.html

Here are the SHA256 checksums:

  24b2ebbcc06e37f6d5d56a6053676d7f3fc54886717aa5ab589383ce8739e685  
guile-2.9.3.tar.lz
  f9cd59233bde1a6b316bfcf82a49fa25d6f7e25b7c0019272afc697f19072991  
guile-2.9.3.tar.xz
  b549d5bc7a00247b89f40e495b0ab96947b9f7935829fb6d20573545c1156535  
guile-2.9.3.tar.gz

[*] Use a .sig file to verify that the corresponding file (without the
.sig suffix) is intact.  First, be sure to download both the .sig file
and the corresponding tarball.  Then, run a command like this:

  gpg --verify guile-2.9.3.tar.gz.sig

If that command fails because you don't have the required public key,
then run this command to import it:

  gpg --keyserver keys.gnupg.net --recv-keys 
4FD4D288D445934E0A14F9A5A8803732E4436885

and rerun the 'gpg --verify' command.

This release was bootstrapped with the following tools:
  Autoconf 2.69
  Automake 1.16.1
  Libtool 2.4.6
  Gnulib v0.1-1157-gb03f418
  Makeinfo 6.5


Changes in alpha 2.9.3 (since alpha 2.9.2):

* Notable changes

** Improved just-in-time machine code generation

Guile's JIT compiler emits better code for indirect procedure calls,
atomic instructions, numeric comparisons, procedure prologues,
well-known closures with no free variables, calls and returns, and
allocations.  Together these improvements can speed up some benchmarks
by up to 50%.


Cumulative changes in the alpha 2.9.x series (since the stable 2.2 series):

* Notable changes

** Just-in-time code generation

Guile programs now run up to 4 times faster, relative to Guile 2.2,
thanks to just-in-time (JIT) native code generation.  Notably, this
brings the performance of "eval" as written in Scheme back to the level
of "eval" written in C, as in the days of Guile 1.8.

See "Just-In-Time Native Code" in the manual, for more information.  JIT
compilation will be enabled automatically and transparently.  To disable
JIT compilation, configure Guile with `--enable-jit=no' or
`--disable-jit'.  The default is `--enable-jit=auto', which enables the
JIT if it is available.  See `./configure --help' for more.

JIT compilation is enabled by default on x86-64, i686, ARMv7, and
AArch64 targets.

** Lower-level bytecode

Relative to the virtual machine in Guile 2.2, Guile's VM instruction set
is now more low-level.  This allows it to express more advanced
optimizations, for example type check elision or integer
devirtualization, and makes the task of JIT code generation easier.

Note that this change can mean th

GNU Guile 2.9.2 Released [beta]

2019-05-23 Thread Andy Wingo
We are pleased to announce GNU Guile release 2.9.2.  This is the second
pre-release of what will eventually become the 3.0 release series.

Compared to the current stable series (2.2.x), the future Guile 3.0 adds
support for just-in-time native code generation, speeding up all Guile
programs.  See the NEWS extract at the end of the mail for full details.

Compared to the previous prerelease (2.9.1), Guile 2.9.2 adds native
code generation support on the ia32, ARMv7, and AArch64 architectures.

We encourage you to test this release and provide feedback to
guile-devel@gnu.org, and to file bugs by sending mail to
bug-gu...@gnu.org.

The Guile web page is located at http://gnu.org/software/guile/, and
among other things, it contains a copy of the Guile manual and pointers
to more resources.

Guile is an implementation of the Scheme programming language, with
support for many SRFIs, packaged for use in a wide variety of
environments.  In addition to implementing the R5RS Scheme standard,
Guile includes a module system, full access to POSIX system calls,
networking support, multiple threads, dynamic linking, a foreign
function call interface, and powerful string processing.

Guile can run interactively, as a script interpreter, and as a Scheme
compiler to VM bytecode.  It is also packaged as a library so that
applications can easily incorporate a complete Scheme interpreter/VM.
An application can use Guile as an extension language, a clean and
powerful configuration language, or as multi-purpose "glue" to connect
primitives provided by the application.  It is easy to call Scheme code
>From C code and vice versa.  Applications can add new functions, data
types, control structures, and even syntax to Guile, to create a
domain-specific language tailored to the task at hand.

Guile 2.9.2 can be installed in parallel with Guile 2.2.x; see
http://www.gnu.org/software/guile/manual/html_node/Parallel-Installations.html.

A more detailed NEWS summary follows these details on how to get the
Guile sources.

Here are the compressed sources:
  http://alpha.gnu.org/gnu/guile/guile-2.9.2.tar.lz   (10MB)
  http://alpha.gnu.org/gnu/guile/guile-2.9.2.tar.xz   (12MB)
  http://alpha.gnu.org/gnu/guile/guile-2.9.2.tar.gz   (21MB)

Here are the GPG detached signatures[*]:
  http://alpha.gnu.org/gnu/guile/guile-2.9.2.tar.lz.sig
  http://alpha.gnu.org/gnu/guile/guile-2.9.2.tar.xz.sig
  http://alpha.gnu.org/gnu/guile/guile-2.9.2.tar.gz.sig

Use a mirror for higher download bandwidth:
  http://www.gnu.org/order/ftp.html

Here are the SHA256 checksums:

  823dce6c89a993663dbd3eba058cb65daa7a67ef120fcf0295f6ba5682c05fef  
guile-2.9.2.tar.gz
  1a64b2e4d7f0d394df437355662219cbfa13fda5ebde93db4ad11356449b7d6c  
guile-2.9.2.tar.lz
  e403be8e0ace0ee1150260288755c64a47cce11732e3f8c5fc9e552e5c4365f0  
guile-2.9.2.tar.xz

[*] Use a .sig file to verify that the corresponding file (without the
.sig suffix) is intact.  First, be sure to download both the .sig file
and the corresponding tarball.  Then, run a command like this:

  gpg --verify guile-2.9.2.tar.gz.sig

If that command fails because you don't have the required public key,
then run this command to import it:

  gpg --keyserver keys.gnupg.net --recv-keys 
4FD4D288D445934E0A14F9A5A8803732E4436885

and rerun the 'gpg --verify' command.

This release was bootstrapped with the following tools:
  Autoconf 2.69
  Automake 1.16.1
  Libtool 2.4.6
  Gnulib v0.1-1157-gb03f418
  Makeinfo 6.5


Changes in alpha 2.9.2 (since alpha 2.9.1):

* Notable changes

** Just-in-time code generation support on ARMv7, ia32, AArch64

This release adds just-in-time (JIT) native code generation for the
ia32, ARMv7, and AArch64 platforms, in addition to the x86-64 support
already present in 2.9.1.

** Cheaper just-in-time code generation

Guile now includes a forked version of GNU Lightning.  This "Lightening"
effort, spun out as a separate project, aims to build on the back-end
support from GNU Lightning, but adapting the API and behavior of the
library to match Guile's needs.

One of the important points that this project fixes is run-time
overhead.  With the adoption of Lightening, Guile has lowered its
thresholds for when to generate native code at run-time, so that user
programs run faster, sooner.

For more information, see https://gitlab.com/wingo/lightening.


Cumulative changes in the alpha 2.9.x series (since the stable 2.2 series):

* Notable changes

** Just-in-time code generation

Guile programs now run up to 4 times faster, relative to Guile 2.2,
thanks to just-in-time (JIT) native code generation.  Notably, this
brings the performance of "eval" as written in Scheme back to the level
of "eval" written in C, as in the days of Guile 1.8.

See "Just-In-Time Native Code" in the manual, for more information.  JIT
compilation will be enabled automatically and transparently.  To disable
JIT compilation, configure Guile with `--enable-jit=no' or
`--disable-jit'.  The default is `--enable-jit=auto', which enables

Re: guile-2.9.1 impressions

2019-05-23 Thread Andy Wingo
Hi!

On Thu 06 Dec 2018 06:21, Linas Vepstas  writes:

> After sending the email below, I scanned the guile-devel archives,
> and I see Thomas Morley talking about Lilypond performance.
> The example program he offers up caught my eye: nested deep
> in a loop is this:
>
> (eval-string "'(a b c)")

In this case I believe Guile 2.9 / 3 should be significantly faster than
2.2, because `eval' is compiled to native code rather than bytecode.  My
measurements showed it to be on par with the hand-optimized C
implementation from 1.8 and before.  Depends of course on how much the
expander is part of your workload, there are differences relative to
Guile 1.8.  Anyway, thanks for the note and I just wanted to mention
this point.

Regarding Scheme -> C++ transitions, there is the possibility that this
too could be much faster with Guile 2.9.x given that these calls are now
JIT-compiled instead of interpreted.  We'll have to see.

Cheers,

Andy



GNU Guile 2.9.1 Released [beta]

2018-10-10 Thread Andy Wingo
We are pleased to announce GNU Guile release 2.9.1.  This is the first
pre-release of what will eventually become the 3.0 release series.

Compared to the current stable series (2.2.x), Guile 2.9.1 adds support
for just-in-time native code generation, speeding up all Guile programs.
See the NEWS extract at the end of the mail for full details.

We encourage you to test this release and provide feedback to
guile-devel@gnu.org, and to file bugs by sending mail to
bug-gu...@gnu.org.

The Guile web page is located at http://gnu.org/software/guile/, and
among other things, it contains a copy of the Guile manual and pointers
to more resources.

Guile is an implementation of the Scheme programming language, with
support for many SRFIs, packaged for use in a wide variety of
environments.  In addition to implementing the R5RS Scheme standard,
Guile includes a module system, full access to POSIX system calls,
networking support, multiple threads, dynamic linking, a foreign
function call interface, and powerful string processing.

Guile can run interactively, as a script interpreter, and as a Scheme
compiler to VM bytecode.  It is also packaged as a library so that
applications can easily incorporate a complete Scheme interpreter/VM.
An application can use Guile as an extension language, a clean and
powerful configuration language, or as multi-purpose "glue" to connect
primitives provided by the application.  It is easy to call Scheme code
From C code and vice versa.  Applications can add new functions, data
types, control structures, and even syntax to Guile, to create a
domain-specific language tailored to the task at hand.

Guile 2.9.1 can be installed in parallel with Guile 2.2.x; see
http://www.gnu.org/software/guile/manual/html_node/Parallel-Installations.html.

A more detailed NEWS summary follows these details on how to get the
Guile sources.

Here are the compressed sources:
  http://alpha.gnu.org/gnu/guile/guile-2.9.1.tar.lz   (10.3MB)
  http://alpha.gnu.org/gnu/guile/guile-2.9.1.tar.xz   (12.3MB)
  http://alpha.gnu.org/gnu/guile/guile-2.9.1.tar.gz   (20.8MB)

Here are the GPG detached signatures[*]:
  http://alpha.gnu.org/gnu/guile/guile-2.9.1.tar.lz.sig
  http://alpha.gnu.org/gnu/guile/guile-2.9.1.tar.xz.sig
  http://alpha.gnu.org/gnu/guile/guile-2.9.1.tar.gz.sig

Use a mirror for higher download bandwidth:
  http://www.gnu.org/order/ftp.html

Here are the SHA256 checksums:

  9e1dc7ed34a5581e47dafb920276fbb12c9c318ba432d19cb970c01aa1ab3a09  
guile-2.9.1.tar.gz
  f24e6778e3e45ea0691b591ad7e74fdd0040689915b09ae0e52bd2a80f8e2b33  
guile-2.9.1.tar.lz
  01be24335d4208af3bbd0d3354d3bb66545f157959bb0c5a7cbb1a8bfd486a45  
guile-2.9.1.tar.xz

[*] Use a .sig file to verify that the corresponding file (without the
.sig suffix) is intact.  First, be sure to download both the .sig file
and the corresponding tarball.  Then, run a command like this:

  gpg --verify guile-2.9.1.tar.gz.sig

If that command fails because you don't have the required public key,
then run this command to import it:

  gpg --keyserver keys.gnupg.net --recv-keys 
4FD4D288D445934E0A14F9A5A8803732E4436885

and rerun the 'gpg --verify' command.

This release was bootstrapped with the following tools:
  Autoconf 2.69
  Automake 1.16.1
  Libtool 2.4.6
  Gnulib v0.1-1157-gb03f418
  Makeinfo 6.5


Changes in alpha 2.9.1 (since the stable 2.2 series):

* Notable changes

** Just-in-time code generation

Guile programs now run up to 4 times faster, relative to Guile 2.2,
thanks to just-in-time (JIT) native code generation.  Notably, this
brings the performance of "eval" as written in Scheme back to the level
of "eval" written in C, as in the days of Guile 1.8.

See "Just-In-Time Native Code" in the manual, for more information.  JIT
compilation will be enabled automatically and transparently.  To disable
JIT compilation, configure Guile with `--enable-jit=no' or
`--disable-jit'.  The default is `--enable-jit=auto', which enables the
JIT if it is available.  See `./configure --help' for more.

In this release, JIT compilation is enabled only on x86-64.  In future
prereleases support will be added for all architectures supported by GNU
lightning.  Intrepid users on other platforms can try passing
`--enable-jit=yes' to see the state of JIT on their platform.

** Lower-level bytecode

Relative to the virtual machine in Guile 2.2, Guile's VM instruction set
is now more low-level.  This allows it to express more advanced
optimizations, for example type check elision or integer
devirtualization, and makes the task of JIT code generation easier.

Note that this change can mean that for a given function, the
corresponding number of instructions in Guile 3.0 may be higher than
Guile 2.2, which can lead to slowdowns when the function is interpreted.
We hope that JIT compilation more than makes up for this slight
slowdown.

** By default, GOOPS classes are not redefinable

It used to be that all GOOPS classes were redefinable, at least in
theory.  This facility wa

Re: guile 3 update, september edition

2018-09-18 Thread Andy Wingo
Greets :)

On Mon 17 Sep 2018 11:35, l...@gnu.org (Ludovic Courtès) writes:

>> The threshold at which Guile will automatically JIT-compile is set from
>> the GUILE_JIT_THRESHOLD environment variable.  By default it is 5.
>> If you set it to -1, you disable the JIT.  If you set it to 0, *all*
>> code will be JIT-compiled.  The test suite passes at
>> GUILE_JIT_THRESHOLD=0, indicating that all features in Guile are
>> supported by the JIT.  Set the GUILE_JIT_LOG environment variable to 1
>> or 2 to see JIT progress.
>
> Just to be clear, does GUILE_JIT_THRESHOLD represents the number of
> times a given instruction pointer is hit?

No.  It is an abstract "hotness" counter associated with a function's
code.  (I say "function's code" because many closures can share the same
code and thus the same counter.  It's not in the scm_tc7_program object
because some procedures don't have these.)

All counters start at 0 when Guile starts.  A function's counters
increment by 30 when a function is called, currently, and 2 on every
loop back-edge.  I have not attempted to tweak these values yet.

>> Using GNU Lightning has been useful but in the long term I don't think
>> it's the library that we need, for a few reasons:
>
> [...]
>
> It might be that the lightning 1.x branch would be a better fit (it was
> exactly as you describe.)  I think that’s what Racket was (is?) using.

Could be!  I will have a look.

Cheers,

Andy



guile 3 update, september edition

2018-09-17 Thread Andy Wingo
Hi!

This is an update on progress towards Guile 3.  In our last update, we
saw the first bits of generated code:

  https://lists.gnu.org/archive/html/guile-devel/2018-08/msg5.html

Since then, the JIT is now feature-complete.  It can JIT-compile *all*
code in Guile, including delimited continuations, dynamic-wind, all
that.  It runs automatically, in response to a function being called a
lot.  It can also tier up from within hot loops.

The threshold at which Guile will automatically JIT-compile is set from
the GUILE_JIT_THRESHOLD environment variable.  By default it is 5.
If you set it to -1, you disable the JIT.  If you set it to 0, *all*
code will be JIT-compiled.  The test suite passes at
GUILE_JIT_THRESHOLD=0, indicating that all features in Guile are
supported by the JIT.  Set the GUILE_JIT_LOG environment variable to 1
or 2 to see JIT progress.

For debugging (single-stepping, tracing, breakpoints), Guile will fall
back to the bytecode interpreter (the VM), for the thread that has
debugging enabled.  Once debugging is no longer enabled (no more hooks
active), that thread can return to JIT-compiled code.

Right now the JIT-compiled code exactly replicates what the bytecode
interpreter does: the same stack reads and writes, etc.  There is some
specialization when a bytecode has immediate operands of course.
However the choice to do debugging via the bytecode interpreter --
effectively, to always have bytecode around -- will allow machine code
(compiled either just-in-time or ahead-of-time) to do register
allocation.  JIT will probably do a simple block-local allocation.  An
AOT compiler is free to do something smarter.

As far as I can tell, with the default setting of
GUILE_JIT_THRESHOLD=5, JIT does not increase startup latency for any
workload, and always increases throughput.  More benchmarking is needed
though.

Using GNU Lightning has been useful but in the long term I don't think
it's the library that we need, for a few reasons:

  * When Lightning does a JIT compilation, it builds a graph of
operations, does some minor optimizations, and then emits code.  But
the graph phase takes time and memory.  I think we just need a
library that just emits code directly.  That would lower the cost of
JIT and allow us to lower the default GUILE_JIT_THRESHOLD.

  * The register allocation phase in Lightning exists essentially for
calls.  However we have a very restricted set of calls that we need
to do, and can do the allocation by hand on each architecture.  This
(We don't use CPU call instructions for Scheme function calls
because we use the VM stack.  We might be able to revise this in the
future but again Lightning is in the way).  Doing it by hand would
allow a few benefits:

  * Hand allocation would free up more temporary registers.  Right
now lightning reserves all registers used as part of the platform
calling convention; they are unavailable to the JIT.

  * Sometimes when Lightning needs a temporary register, it can
clobber one that we're using as part of an internal calling
convention.  I believe this is fixed for x86-64 but I can't be
sure for other architectures!  See commit
449ef7d9755b553cb0ad2629bca3bc42c5913e88.

  * We need to do our own register allocation; having Lightning also
do it is a misfeature.

  * Sometimes we know that we can get better emitted code, but the
lightning abstraction doesn't let us do it.  We should allow
ourselves to punch through that abstraction.

The platform-specific Lightning files basically expose most of the API
we need.  We could consider incrementally punching through lightning.h
to reach those files.  Something to think about for the future.

Finally, as far as performance goes -- we're generally somewhere around
80% faster than 2.2.  Sometimes more, sometimes less, always faster
though AFAIK.  As an example, here's a simple fib.scm:

   $ cat /tmp/fib.scm
   (define (fib n)
 (if (< n 2)
 1
 (+ (fib (- n 1))
(fib (- n 2)

Now let's use eval-in-scheme to print the 35th fibonacci number.  For
Guile 2.2:

   $ time /opt/guile-2.2/bin/guile -c \
   '(begin (primitive-load "/tmp/fib.scm") (pk (fib 35)))'

   ;;; (14930352)

   real 0m9.610s
   user 0m10.547s
   sys  0m0.040s

But with Guile from the lightning branch, we get:

   $ time /opt/guile/bin/guile -c \
   '(begin (primitive-load "/tmp/fib.scm") (pk (fib 35)))'

   ;;; (14930352)

   real 0m5.299s
   user 0m6.167s
   sys  0m0.064s

Meaning that "eval" in Guile 3 is somewhere around 80% faster than in
Guile 2.2 -- because "eval" is now JIT-compiled.  (Otherwise it's the
same program.)  This improves bootstrap times, though Guile 3's compiler
will generally make more CPS nodes than Guile 2.2 for the same
expression, which takes more time and memory, so the gain isn't
earth-shattering.

Incidentally, as a comparison, Guile 2.0 (whose 

Re: FOSDEM 2019

2018-08-22 Thread Andy Wingo
On Tue 21 Aug 2018 19:57, Ricardo Wurmus  writes:

> If we base our application on this proposal I think we should make these
> changes:
>
> - mention the work on adding JIT

Yes definitely!  This will be Guile 3, so we can call it "Just-in-time
code generation for Scheme: Speed for free in Guile 3" or something.
I'd be happy to give this talk.

Andy



Guile 3 update, August edition

2018-08-20 Thread Andy Wingo
Hi!

Last dispatch was here:

  https://lists.gnu.org/archive/html/guile-devel/2018-07/msg00037.html

To recap, I merged in GNU lightning and added an extra machine-code
return address to frames, but hadn't actually written the JIT yet.

Since July, I made it so that all Guile bytecode function entry points
start with an "instrument-entry" bytecode that holds a counter.  The
intention is that when the counter increments beyond a certain value,
the function should be automatically JIT-compiled.  Associated with the
counter is a native-code pointer corresponding to the function.  I also
added "instrument-loop" bytecodes to all loops, to be able to tier up
from within hot loops.

With all of this done and some other bytecode tweaks, I was able to move
on to the JIT compiler itself.  I'm happy to say that I now have a first
version.  It's about 3500 lines of C, so a bit gnarly.  It's
architecture-independent, as it uses lightning, and there are lightning
backends for about every architecture.  Lightning seems OK.  Not
optimal, but OK, and an OK thing to use for now anyway.  I did have to
write special cases for 32-bit machines, as Guile's VM supports 64-bit
arithmetic, and some-endian-specific code.  I probably got some of that
wrong; review is very welcome:

  https://git.savannah.gnu.org/cgit/guile.git/tree/libguile/jit.c?h=lightning

If you have fixes and are a committer, please feel free to just commit
them directly.  If you aren't a committer yet and you spot some fixes,
mail the list; you should definitely be a committer if you can do that
:)

I just got the JIT working today.  For the time being, the interface is
a public function, %jit-compile.  Eventually I will remove this when I
have more confidence, relying only on the automatic compilation
triggered by function entry and loop iterations.

As an example:

  $ cat foo.scm
  (use-modules (rnrs bytevectors))
  (define (f32v-sum bv)
(let lp ((n 0) (sum 0.0))
  (if (< n (bytevector-length bv))
  (lp (+ n 4)
  (+ sum (bytevector-ieee-single-native-ref bv n)))
  sum)))
  (define ones (make-f32vector #e1e7 1.0))

  # The JIT currently doesn't emit hook code.
  $ meta/guile --no-debug
  scheme@(guile-user)> (load "foo.scm")
  scheme@(guile-user)> ,time (f32v-sum ones)
  $2 = 1.0e7
  ;; 0.143017s real time, 0.142986s run time.  0.00s spent in GC.
  scheme@(guile-user)> (%jit-compile f32v-sum)
  scheme@(guile-user)> ,time (f32v-sum ones)
  $3 = 1.0e7
  ;; 0.048514s real time, 0.048499s run time.  0.00s spent in GC.

In this particular example, the JITted code runs about 3x faster than
the interpreted code.  The JIT doesn't do register allocation; not sure
precisely how to do that.  A future topic.  For the moment I want to
consolidate what we have and once it's all just magically working and
everybody's programs are faster, we release Guile 3.

Cheers,

Andy



guile 3 update, july edition

2018-07-21 Thread Andy Wingo
Hi :)

Just a brief update with Guile 3.  Last one was here:

  https://lists.gnu.org/archive/html/guile-devel/2018-06/msg00026.html

There is a now a "lightning" branch that has GNU lightning merged in and
built statically into Guile.  It causes about 1 MB of overhead in the
-Og libguile-3.0.so, bringing it to 6.1 MB, or 1.36 MB stripped.  Seems
OK for now.  By way of contrast, libguile-2.2.so is 5.65 MB when built
with -Og, or 1.19 MB stripped.

There's some scaffolding for making JIT code emitters for each
instruction.  But then I ran into a problem about how to intermingle JIT
and interpreter returns on the stack.  I was hoping to avoid having
separate interpreter and JIT return addresses in a stack frame, to avoid
adding overhead.  That didn't work out:

  https://lists.gnu.org/archive/html/guile-devel/2018-07/msg00013.html

So, I added a slot to the "overhead" part of stack frames.  From
frames.h:

   Stack frame layout
   --

   | ...  |
   +==+ <- fp + 3 = SCM_FRAME_PREVIOUS_SP (fp)
   | Dynamic link |
   +--+
   | Virtual return address (vRA) |
   +--+
   | Machine return address (mRA) |
   +==+ <- fp
   | Local 0  |
   +--+
   | Local 1  |
   +--+
   | ...  |
   +--+
   | Local N-1|
   \--/ <- sp

   The stack grows down.

   The calling convention is that a caller prepares a stack frame
   consisting of the saved FP, the saved virtual return addres, and the
   saved machine return address of the calling function, followed by the
   procedure and then the arguments to the call, in order.  Thus in the
   beginning of a call, the procedure being called is in slot 0, the
   first argument is in slot 1, and the SP points to the last argument.
   The number of arguments, including the procedure, is thus FP - SP.

That took a while.  Anything that changes calling conventions is gnarly.
While I was at it, I changed the return calling convention to expect
return values from slot 0 instead of from slot 1, and made some other
minor changes to instructions related to calls and returns.

The next step will be to add an "enter-function" instruction or
something to function entries.  This instruction's only real purpose
will be to increment a counter associated with the function.  If the
counter exceeds some threshold, JIT code will be emitted for the
function and the function will tier up.  If the enter-function
instruction sees that the function already has JIT code (e.g. emitted
from another thread), then it will tier up directly.

Because enter-function is in the right place to run the apply hook for
debugging, we'll probably move that functionality there, instead of
being inline with the call instructions.

The "enter-function" opcode will take an offset to writable data for the
counter, allocated in the ELF image.  This data will have the form:

  struct jit_data {
void* mcode;
uint32_t counter;
uint32_t start;
uint32_t end;
  }

The mcode pointer indicates the JIT code, if any.  It will probably need
to be referenced atomically (maybe release/consume ordering?).  The
counter is the counter associated with this function; entering a
function will increment it by some amount.  The start and end elements
indicate the bounds of the function, and are offsets into the vcode,
relative to the jit_data struct.  These are not writable.

Loops will also have an instruction that increments the counter,
possibly tiering up if needed.  The whole function will share one
"struct jit_data".

I am currently thinking that we can make JIT-JIT function calls peek
ahead in the vcode of the callee to find the callee JIT code, if any.
I.e.:

  (if (has-tc7? callee %tc7-program)
  (let ((vcode (word-ref callee 1)))
(if (= (logand (u32-ref vcode 0) #xff)
   %enter-function-opcode)
(let ((mcode ((+ vcode (* (u32-ref vcode 1) 4)
  (if (zero? mcode)
  (jmp! mcode)
  (return!))) ;; return to interpreter
(return!)))
  (return!))

It's a dependent memory load on the function-call hot path but it will
predict really well.  The upside of this is that there is just one
mutable mcode pointer for a function, for all its closures in all
threads.  It also avoids reserving more space on the heap for another
mcode word in program objects.

Loops will tier up ("on-stack replacement") by jumping to an offset in
the mcode corresponding to the vcode for the counter-incrementing
instruction.  The offset will be determined by running the JIT compiler
for the function but without actually emitting the code and flushing
icache; the compiler is run in a mode just to determine the mc

Re: guile 3 update, june 2018 edition

2018-07-05 Thread Andy Wingo
Hi :)

On Mon 02 Jul 2018 11:28, l...@gnu.org (Ludovic Courtès) writes:

> Andy Wingo  skribis:
>
>> My current plan is that the frame overhead will still be two slots: the
>> saved previous FP, and the saved return address.  Right now the return
>> address is always a bytecode address.  In the future it will be bytecode
>> or native code.  Guile will keep a runtime routine marking regions of
>> native code so it can know if it needs to if an RA is bytecode or native
>> code, for debugging reasons; but in most operation, Guile won't need to
>> know.  The interpreter will tier up to JIT code through an adapter frame
>> that will do impedance matching over virtual<->physical addresses.  To
>> tier down to the interpreter (e.g. when JIT code calls interpreted
>> code), the JIT will simply return to the interpreter, which will pick up
>> state from the virtual IP, SP, and FP saved in the VM state.
>
> What will the “adapter frame” look like?

Aah, sadly it won't work like this.  Somehow I was thinking of an
adapter frame on the C stack.  However an adapter frame corresponds to a
continuation, so it would have to have the life of a continuation, so it
would have to be on the VM stack.  I don't think I want adapter frames
on the VM stack, so I have to scrap this.  More below...

>> We do walk the stack from Scheme sometimes, notably when making a
>> backtrace.  So, we'll make the runtime translate the JIT return
>> addresses to virtual return addresses in the frame API.  To Scheme, it
>> will be as if all things were interpreted.
>
> Currently you can inspect the locals of a stack frame.  Will that be
> possible with frames corresponding to native code? (I suppose that’d be
> difficult.)

Yes, because native code manipulates the VM stack in exactly the same
way as bytecode.  Eventually we should do register allocation and avoid
always writing values to the stack, but that is down the road.

>> My current problem is knowing when a callee has JIT code.  Say you're in
>> JITted function F which calls G.  Can you directly jump to G's native
>> code, or is G not compiled yet and you need to use the interpreter?  I
>> haven't solved this yet.  "Known calls" that use call-label and similar
>> can of course eagerly ensure their callees are JIT-compiled, at
>> compilation time.  Unknown calls are the problem.  I don't know whether
>> to consider reserving another word in scm_tc7_program objects for JIT
>> code.  I have avoided JIT overhead elsewhere and would like to do so
>> here as well!
>
> In the absence of a native code pointer in scm_tc7_program objects, how
> will libguile find the native code for a given program?

This is a good question and it was not clear to me when I wrote this!  I
think I have a solution now but it involves memory overhead.  Oh well.

Firstly, I propose to add a slot to stack frames.  Stack frames will now
store the saved FP, the virtual return address (vRA), and the machine
return address IP (mRA).  When in JIT code, a return will check if the
mRA is nonzero, and if so jump to that mRA.  Otherwise it will return
from JIT, and the interpreter should continue.

Likewise when doing a function return from the interpreter and the mRA
is nonzero, the interpreter should return by entering JIT code to that
address.

When building an interpreter-only Guile (Guile without JIT) or an
AOT-only Guile (doesn't exist currently), we could configure Guile to
not reserve this extra stack word.  However that would be a different
ABI: a .go file built with interpreter-only Guile wouldn't work on
Guile-with-JIT, because interpreter-only Guile would think stack frames
only need two reserved words, whereas Guile-with-JIT would write three
words.  To avoid the complication, for 3.0 I think we should just use
3-word frames all the time.

So, that's returns.  Other kinds of non-local returns like
abort-to-prompt, resuming delimited continuations, or calling
undelimited continuations would work similarly: the continuation would
additionally record an mRA, and resuming would jump there instead, if
appropriate.

Now, calls.  One of the reasons that I wanted to avoid an extra program
word was because scm_tc7_program doesn't exist in a one-to-one
relationship with code.  "Well-known" procedures get compiled by closure
optimization to be always called via call-label or tail-call-label -- so
some code doesn't have program objects.  On the other hand, closures
mean that some code has many program objects.

So I thought about using side tables indexed by code; or inline
"maybe-tier-up-here" instructions, which would reference a code pointer
location, that if nonzero, would be the JIT code.

However I see now that really we need to optimize for the JI

guile 3 update, june 2018 edition

2018-06-29 Thread Andy Wingo
Hi,

Just wanted to give an update on Guile 3 developments.  Last note was
here:

  https://lists.gnu.org/archive/html/guile-devel/2018-04/msg4.html

The news is that the VM has been completely converted over to call out
to the Guile runtime through an "intrinsics" vtable.  For some
intrinsics, the compiler will emit specialized call-intrinsic opcodes.
(There's one of these opcodes for each intrinsic function type.)  For
others that are a bit more specialized, like the intrinsic used in
call-with-prompt, the VM calls out directly to the intrinsic.

The upshot is that we're now ready to do JIT compilation.  JIT-compiled
code will use the intrinsics vtable to embed references to runtime
routines.  In some future, AOT-compiled code can keep the intrinsics
vtable in a register, and call indirectly through that register.

My current plan is that the frame overhead will still be two slots: the
saved previous FP, and the saved return address.  Right now the return
address is always a bytecode address.  In the future it will be bytecode
or native code.  Guile will keep a runtime routine marking regions of
native code so it can know if it needs to if an RA is bytecode or native
code, for debugging reasons; but in most operation, Guile won't need to
know.  The interpreter will tier up to JIT code through an adapter frame
that will do impedance matching over virtual<->physical addresses.  To
tier down to the interpreter (e.g. when JIT code calls interpreted
code), the JIT will simply return to the interpreter, which will pick up
state from the virtual IP, SP, and FP saved in the VM state.

We do walk the stack from Scheme sometimes, notably when making a
backtrace.  So, we'll make the runtime translate the JIT return
addresses to virtual return addresses in the frame API.  To Scheme, it
will be as if all things were interpreted.

This strategy relies on the JIT being a simple code generator, not an
optimizer -- the state of the stack whether JIT or interpreted is the
same.  We can consider relaxing this in the future.

My current problem is knowing when a callee has JIT code.  Say you're in
JITted function F which calls G.  Can you directly jump to G's native
code, or is G not compiled yet and you need to use the interpreter?  I
haven't solved this yet.  "Known calls" that use call-label and similar
can of course eagerly ensure their callees are JIT-compiled, at
compilation time.  Unknown calls are the problem.  I don't know whether
to consider reserving another word in scm_tc7_program objects for JIT
code.  I have avoided JIT overhead elsewhere and would like to do so
here as well!

For actual JIT code generation, I think my current plan is to import a
copy of GNU lightning into Guile's source, using git-subtree merges.
Lightning is fine for our purposes as we only need code generation, not
optimization, and it supports lots of architectures: ARM, MIPS, PPC,
SPARC, x86 / x86-64, IA64, HPPA, AArch64, S390, and Alpha.

Lightning will be built statically into libguile.  This has the
advantage that we always know the version being used, and we are able to
extend lightning without waiting for distros to pick up a new version.
Already we will need to extend it to support atomic ops.  Subtree merges
should allow us to pick up upstream improvements without too much pain.
This strategy also allows us to drop lightning in the future if that's
the right thing.  Basically from the user POV it should be transparent.
The whole thing will be behind an --enable-jit / --disable-jit configure
option.  When it is working we can consider enabling shared lightning
usage.

Happy hacking,

Andy



Re: c99 support

2018-06-29 Thread Andy Wingo
On Sat 23 Jun 2018 22:12, Andy Wingo  writes:

> Is there anyone who compiles Guile with a compiler that does not support
> C99?  If so, please give platform and compiler.
>
> I think my questions are limited to, in decreasing order of importance:
>
>   * Is there any system that we target that doesn't have C99 stdint.h
> and stddef.h ?
>
>   * Is there any system that we target that doesn't support C99 inline
> functions?
>
>   * C99 mixed decls and statements?
>
>   * C99 one-line comments (// foo) ?
>
>   * C99 compound literals? ((struct x) { 1, 2 }) ?
>
>   * stdbool.h
>
> I would like to use C99 inside Guile, and I want to eventually replace
> scm_t_uint8 with uint8_t.

Thanks all for the responses.  It would seem that the first four
features of C99 are OK for all platforms that we target, with the
following caveats:

 * We should avoid using C++ keywords (e.g. throw) in Guile API files.

 * We might want to avoid mixed decls and statements in inline functions
   in Guile API files.

We should probably avoid stdbool.h and compound literals, for C++
reasons.

In Guile 3.0 (master branch), the types "scm_t_uint8" and so on are now
deprecated.  My recommendation is that all users switch to use
e.g. "uint8_t", "ptrdiff_t", etc from  instead of the
scm_t_uint8, etc definitions that they are now using.  The definitions
are compatible on all systems, AFAIU, and on GNU, scm_t_uint8 has long
been a simple typedef for uint8_t.

If you make the change while targetting current Guile (2.2), then you'll
won't have deprecation warnings when 3.0 comes out.

Cheers,

Andy



Re: c99 support

2018-06-23 Thread Andy Wingo
On Sat 23 Jun 2018 21:23, Eli Zaretskii  writes:

>> From: Andy Wingo 
>> Date: Sat, 23 Jun 2018 21:11:29 +0200
>> Cc: guile-devel@gnu.org
>> 
>> Is there anyone who compiles Guile with a compiler that does not support
>> C99?  If so, please give platform and compiler.
>
> You mean C99 compiler or C99 C run-time library?  Or both?
>
> MS-Windows (MinGW) doesn't have a C99 compliant C library, although
> quite a few of what's needed is present.

Hard to say :)  I think my questions are limited to, in decreasing order
of importance:

  * Is there any system that we target that doesn't have C99 stdint.h
and stddef.h ?

  * Is there any system that we target that doesn't support C99 inline
functions?

  * C99 mixed decls and statements?

  * C99 one-line comments (// foo) ?

  * C99 compound literals? ((struct x) { 1, 2 }) ?

  * stdbool.h

I want to use C99 inside Guile, and I want to eventually replace
scm_t_uint8 with uint8_t.

I assume MinGW uses GCC.  What version?  I see that the version 6 series
is available on mingw.org.

Andy



c99 support

2018-06-23 Thread Andy Wingo
Hi,

Is there anyone who compiles Guile with a compiler that does not support
C99?  If so, please give platform and compiler.

Thanks,

Andy



Re: tracepoints/breakpoints and native compilation

2018-05-14 Thread Andy Wingo
On Tue 15 May 2018 05:08, Mark H Weaver  writes:

> I think we should consider deprecating these legacy debug hooks, and
> instead to support debugging features similar to GDB, using the same
> implementation methods that GDB uses.
>
> Alternatively, I wonder if it would be feasible to enhance GDB itself to
> support debugging native Guile code.

Tx for feedback.  FWIW GDB will patch the executable code in-place.  It
does so while the program being debugged is stopped; it uses ptrace for
this AFAIU.  I guess in Guile we'd set asyncs on all active threads to
synchronize.  Actually modifying the executable code is pretty gnarly
and target-specific though.

FWIW JS and Java VMs will often "deoptimize" functions that have
breakpoints or tracepoints.  Some can avoid deoptimization in some
cases, but the mechanism is the same: recompile functions.

The hooks that Guile has aren't so legacy, and aren't immutable API --
they showed up in 2.0, changed a bit in 2.2, and if we keep them they
will change a bit more in 3.0.  Their users are already deep in the
engine and can adapt.

Regarding GDB, it would certainly be feasible to enhance it to
understand Guile's native code.  Probably it's all possible to do from
Scheme.  But for tracepoints and and for when you don't have an
appropriate GDB you probably do want to be able to also have in-process
debugging capabilities.

Cheers,

Andy



tracepoints/breakpoints and native compilation

2018-05-09 Thread Andy Wingo
Hi :)

A design question for everyone.  I am wondering how to support
breakpoints, tracepoints, and the like in a Guile with native-code
compilation.  If you are not familiar with what Guile does currently,
see:

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

Basically Guile supports calling out to user-defined procedures when:

  (1) pushing a new continuation (stack frame)
  (2) tail-calling a procedure
  (3) popping a continuation (e.g. on return)
  (4) non-local return (after abort, or after calling a call/cc continuation)
  (5) advancing the instruction pointer

This last one is obviously expensive.  To mitigate this cost, Guile
builds the VM twice: once with hooks and once without.  When run with
--debug, you get the VM with hooks; otherwise, no hooks for you.

Note that without hooks, you still get interrupts, so you can do
statistical profiling, or interrupt a loop.  But unlike hooks,
interrupts are placed in the code.  Practically speaking, without hooks,
what you lose is the ability to set a breakpoint.  You also lose the
ability to trace a procedure, but because tracing can recursively invoke
the right VM, that's not a problem in practice.

Generally you only care about hook performance when they are disabled,
so what you need to do is minimize overhead in that case.  In a bytecode
interpreter (as Guile has now), the hooks do add some overhead, but they
are very predictable branches, so it's not a big deal.  Debug mode is on
by default in the Guile REPL and I think it adds some 10 or 20%
overhead.

However in native-code compilation, hooks are more of a problem.  They
increase the executable size, as each hook invocation has to be present
in the text somewhere.  They pollute the branch predictor, as there are
many more branches.  They increase instruction cache size, even in the
best case where the slow branches are all out of line.  Boo.

So... I have a proposal.  Right now in the short term I am going to make
a JIT for Guile 3.0 (master branch) bytecode.  I am still working on
massaging the bytecode into a state where it is very easily JITtable,
but that will be soon I hope (weeks) and then, outside circumstances
permitting, we can have a JIT within the next 3 months.  For JIT
compilation, the "hook" problem resolves itself very easily: we can JIT
in two modes, one that adds hooks and one that doesn't.  We can alter
the hook API to allow the VM to know when to re-JIT code; adding a
breakpoint doesn't have to re-JIT everything.  Or of course we can keep
the current API and just re-JIT everything.

For the bytecode interpreter, we can keep the two VMs.  Also easy.

However if we ship native code in the .go files -- what do we do?  Three
options, I see -- one, ship "regular" code (no hooks) -- fast, but no
breakpoints from Guile.  Two, ship "debug" code (with hooks).  Or three,
ship the bytecode also, and a JIT compiler, so that we can re-JIT if
needed.

The first possibility would mean that some Guile-compiled code is not
really debuggable in a nice way.  It's not ideal.  The second is OK, but
it would be slow.  However the third option seems to offer a good choice
for general-purpose installs.  If we we ship the bytecode in .go files
by default and the built Guile supports JIT compilation, then maybe we
can get all the advantages -- peak performance with native code without
embedded hook calls, but still the ability to insert hooks if needed.

So I am looking at going with the third option.  It also opens the door
to potential experiments with trace compilation and optimization.  I am
currently not looking at adaptive optimization otherwise, but anyway
that's a bit far off; we need native compilation first to get good
startup time.

Thoughts welcome!

Andy



Guile 3 update -- more instruction explosion, intrinsics

2018-04-13 Thread Andy Wingo
Hello all :)

This mail is an update on Guile 3 progress.  Some previous updates were
here:

  https://lists.gnu.org/archive/html/guile-devel/2018-01/msg9.html
  https://lists.gnu.org/archive/html/guile-devel/2018-01/msg3.html

I took a break for a while and picked up this work again a couple weeks
ago.  I think the reason I stopped was because I got to agonizing about
how to call out to run-time routines from eventual native code.  Like,
you want to call out from native code to scm_string_set_x; or some more
specialized routine that's part of the ABI but not the API, like an
internal internal_string_set_x routine.  How do you get the pointer to
that code?  How do you manage saving the VM state and restoring it?  Can
you have custom calling conventions?  How do you preserve cross-process
sharing of code pages?

For a while I thought inline caches would be a kind of answer, but after
looking at it for a while I think I am going to punt:

  
https://wingolog.org/archives/2018/02/07/design-notes-on-inline-caches-in-guile

Guile simply isn't all that polymorphic, and the set of runtime routines
callable from native code compiled by Guile is bounded.  Better instead
to simply provide a vtable to native code that contains function
pointers to anything that might need to be callable at run-time.

So that's what I settled on.  I call them "intrinsics" (I would call
them "builtins" but that word is used for something else).  I started
moving over "macro-instructions" that can't be usefully broken apart,
like string-set!, to be intrinsic calls.  AOT-compiled native code will
compile these to vtable calls ("call [reg + offset]"), where reg holds a
pointer to the intrinsics and offset is a fixed offset.  JIT-compiled
native code can inline the intrinsic address of course.

I also pushed ahead with instruction explosion for string-length,
string-ref, the atomics, integer/char conversion, make-closure, and
f64->scm.  I made a bunch more instructions be intrinsics.  The VM is
thus now smaller and has fewer instructions whose implementations
contain internal branches, which means we're getting closer to native
code.

There are still some more instructions to push to intrinsics.  (Q: When
should an instruction be an intrinsic rather than "exploded" (lowered to
more primitive instructions and control flow)?  A: When the optimizer is
unlikely to be able to elide components of the exploded implementation.)

Then the biggest remaining task is dealing with the call instructions,
which are somewhat large still.  Probably they need exploding.  Once
that's done I think we can look to implementing a simple template method
JIT.  If the performance of that beats 2.2 (as I think it should!), then
it could be a good point to release 3.0 just like that.

Long-term I think it makes sense to do AOT compilation.  That also opens
the door for self-hosted adaptive optimization.  But, I don't know quite
how to get there and keep our portability story.  Do we keep bytecode
forever?  Only in some cases?  I don't know.  I certainly want to
minimize the amount of C that we have to maintain :)

Likewise in the medium term I think we should be actively moving library
code from C to Scheme.  With the move to intrinsics in the VM, the VM
itself is relying less and less on libguile, making the whole system
less coupled to libguile.  For Guile to prosper in the next 10 years, we
need to be able to retarget it, to WebAssembly and Racket-on-Chez and
PyPy and Graal and a whole host of other things.  The compiler is
producing low-level, fairly portable output currently, which is
appropriate to this goal, but we are limited by libguile.  So let's be
thinking about how to move much of the remaining 80KLOC of C over to
Scheme.  We won't be able to move all of it, but certainly we can move
some of it.

Happy hacking,

Andy



guile 3 update: instruction explosion for bytevectors

2018-01-17 Thread Andy Wingo
Greets,

FYI I wrote up a new update on the road to Guile 3; as I seem to be
getting closer, it's in blog form:

  https://wingolog.org/archives/2018/01/17/instruction-explosion-in-guile

Cheers,

A



  1   2   3   4   5   6   7   8   9   10   >