unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* guile 3 update, halloween edition
@ 2019-10-30 20:13 Andy Wingo
  2019-10-30 21:19 ` Christopher Lemmer Webber
                   ` (8 more replies)
  0 siblings, 9 replies; 19+ messages in thread
From: Andy Wingo @ 2019-10-30 20:13 UTC (permalink / raw)
  To: guile-devel

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



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: guile 3 update, halloween edition
  2019-10-30 20:13 guile 3 update, halloween edition Andy Wingo
@ 2019-10-30 21:19 ` Christopher Lemmer Webber
  2019-10-31  0:01 ` Chris Vine
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 19+ messages in thread
From: Christopher Lemmer Webber @ 2019-10-30 21:19 UTC (permalink / raw)
  To: guile-devel

Hi Andy,

Wonderful update.  I'll only comment on one thing.

Andy Wingo writes:

> 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?

Exceptions, since it's what everyone uses, so "conditions" would make
Guile be an exception to the use of "exceptions".



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: guile 3 update, halloween edition
  2019-10-30 20:13 guile 3 update, halloween edition Andy Wingo
  2019-10-30 21:19 ` Christopher Lemmer Webber
@ 2019-10-31  0:01 ` Chris Vine
  2019-10-31 16:20   ` Andy Wingo
  2019-10-31  1:31 ` Nala Ginrut
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Chris Vine @ 2019-10-31  0:01 UTC (permalink / raw)
  To: guile-devel

On Wed, 30 Oct 2019 21:13:49 +0100
Andy Wingo <wingo@pobox.com> wrote:
> 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?

R6RS and R7RS speak of raising an exception, and handling the exception
in an exception handler, and racket uses similar language.  According to
R6RS "when an exception is raised, an object is provided that describes
the nature of the exceptional situation.  The report uses the condition
system described in library section 7.2 to describe exceptional
situations, classifying them by condition types".  However, condition
objects are optional when an exception is raised - you can just as well
use a symbol, or a symbol/string pair, for simple cases.

"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.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: guile 3 update, halloween edition
  2019-10-30 20:13 guile 3 update, halloween edition Andy Wingo
  2019-10-30 21:19 ` Christopher Lemmer Webber
  2019-10-31  0:01 ` Chris Vine
@ 2019-10-31  1:31 ` Nala Ginrut
  2019-10-31  1:47 ` Thompson, David
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 19+ messages in thread
From: Nala Ginrut @ 2019-10-31  1:31 UTC (permalink / raw)
  To: Andy Wingo; +Cc: guile-devel

[-- Attachment #1: Type: text/plain, Size: 1763 bytes --]

Hi Andy! Thanks for all the work!

On Thu, Oct 31, 2019 at 4:55 AM Andy Wingo <wingo@pobox.com> wrote:

> 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.
>

Guile powered by JIT was confirmed to increase at least 20% performance for
Artanis.
And this is a rough result of the early-bird version of Guile-2.9. I
haven't tried the latest.
I'm looking forward to an official release of Guile-3 so that I can manage
to support the version detection correctly. It was 2.9 but should detect as
3.0, IIRC.



> 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?
>

Are you talking about Guile specific record-type?
Personally, I've gradually reduced my usage of Guile records. I think R6RS
records are better for me.
I didn't know the Guile bootstrapping requires Guile specific record-type.
So I don't know better advice.


> There will be bijections
> between a Guile's "throw" arguments and structured exceptions, mostly
> inspired with what Julian did in the R6RS layer already.
>

That's cool!


> 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?
>

I never say "condition" to describe an exception. I always say "exception".
Most other languages use "exception" too. The term "condition" sounds like
conditional branching.

Best regards.

[-- Attachment #2: Type: text/html, Size: 2964 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: guile 3 update, halloween edition
  2019-10-30 20:13 guile 3 update, halloween edition Andy Wingo
                   ` (2 preceding siblings ...)
  2019-10-31  1:31 ` Nala Ginrut
@ 2019-10-31  1:47 ` Thompson, David
  2019-10-31 14:17 ` Mikael Djurfeldt
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 19+ messages in thread
From: Thompson, David @ 2019-10-31  1:47 UTC (permalink / raw)
  To: Andy Wingo; +Cc: guile-devel

On Wed, Oct 30, 2019 at 4:55 PM Andy Wingo <wingo@pobox.com> wrote:
>
> 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?

I think "exceptions" is a better name for the reasons others have
already stated.

Excited for 3.0!

- Dave



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: guile 3 update, halloween edition
  2019-10-30 20:13 guile 3 update, halloween edition Andy Wingo
                   ` (3 preceding siblings ...)
  2019-10-31  1:47 ` Thompson, David
@ 2019-10-31 14:17 ` Mikael Djurfeldt
  2019-10-31 16:13   ` Andy Wingo
  2019-10-31 14:46 ` David Pirotte
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Mikael Djurfeldt @ 2019-10-31 14:17 UTC (permalink / raw)
  To: Andy Wingo; +Cc: guile-devel

[-- Attachment #1: Type: text/plain, Size: 4867 bytes --]

Saying this without having looked at your code and also without currently
promising to do any work:

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?

Best regards,
Mikael

On Wed, Oct 30, 2019 at 9:55 PM Andy Wingo <wingo@pobox.com> wrote:

> 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
>
>

[-- Attachment #2: Type: text/html, Size: 5786 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: guile 3 update, halloween edition
  2019-10-30 20:13 guile 3 update, halloween edition Andy Wingo
                   ` (4 preceding siblings ...)
  2019-10-31 14:17 ` Mikael Djurfeldt
@ 2019-10-31 14:46 ` David Pirotte
  2019-10-31 16:44 ` Sjoerd van Leent
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 19+ messages in thread
From: David Pirotte @ 2019-10-31 14:46 UTC (permalink / raw)
  To: Andy Wingo; +Cc: guile-devel

[-- Attachment #1: Type: text/plain, Size: 1707 bytes --]

Hello Andy,

> ...
> 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?

I personally prefer "exceptions" over "conditions", though I did read
and understand Chris answer ...

Now, slightly of topic, but since/while  you are working on (ice-9
boot), exceptions ...  please allow me this gentle ping and invite you
to (re)read my answer to the following 'bug report' (1), which is a
'claim' in favor of, in 3.0, to have the repl, errors and backtraces
printers to truncate by default, then, to make things so that it would
be 'dead easy' to toggle those to full print 'on demand' ... up to one
could then bind the toggle proc(s) to an FN key ...

(1)	https://debbugs.gnu.org/cgi/bugreport.cgi?bug=36677#23

To 'quote myself':

	Imo, no matter how easy it would be/is to change, the default
	should be to enable truncated printing for the repl, erros and
	backtraces, then indeed we should have 'dead easy' 'toggle'
	mechanism for those 'extremely rare' guilers/situations
	who/that requires/want (occasionally in my experience, I
	sometimes do to of course) full print ...

I was recently reading an email (or was it on irc, I don't remember)
fom Rekado, who wrote guile-studio, which is great news, and an attempt
make guile's newbie first experience(s) quite a lot more
friendly ...

With the above claim (and a 'dead easy' toggle mechanism ...), I would
feel quite a lot more 'relax' to (try to) recommend guile-cv ... and
together with guile-studio ... it then really can be said 'try it,
you'll even have fun ...'

David

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: guile 3 update, halloween edition
  2019-10-31 14:17 ` Mikael Djurfeldt
@ 2019-10-31 16:13   ` Andy Wingo
  0 siblings, 0 replies; 19+ messages in thread
From: Andy Wingo @ 2019-10-31 16:13 UTC (permalink / raw)
  To: Mikael Djurfeldt; +Cc: guile-devel

Hey :)

On Thu 31 Oct 2019 15:17, Mikael Djurfeldt <mikael@djurfeldt.com> 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



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: guile 3 update, halloween edition
  2019-10-31  0:01 ` Chris Vine
@ 2019-10-31 16:20   ` Andy Wingo
  2019-10-31 17:27     ` Chris Vine
  0 siblings, 1 reply; 19+ messages in thread
From: Andy Wingo @ 2019-10-31 16:20 UTC (permalink / raw)
  To: Chris Vine; +Cc: guile-devel

Greets :)

On Thu 31 Oct 2019 01:01, Chris Vine <vine35792468@gmail.com> 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



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: guile 3 update, halloween edition
  2019-10-30 20:13 guile 3 update, halloween edition Andy Wingo
                   ` (5 preceding siblings ...)
  2019-10-31 14:46 ` David Pirotte
@ 2019-10-31 16:44 ` Sjoerd van Leent
  2019-11-02  5:20 ` Mark H Weaver
  2019-11-15  9:03 ` Ludovic Courtès
  8 siblings, 0 replies; 19+ messages in thread
From: Sjoerd van Leent @ 2019-10-31 16:44 UTC (permalink / raw)
  To: Andy Wingo, guile-devel

[-- Attachment #1: Type: text/plain, Size: 638 bytes --]

Op wo 30 okt. 2019 21:55 schreef Andy Wingo <wingo@pobox.com>:

>
>
> 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?
>

To my experience they are different things. An exception breaks execution
until caught/handled whereas conditions don't necessarily break execution,
and are of more informational nature. What is described are exceptions
(flow outside of the expected flow) yet thee should still be a condition
based solution, perhaps using continuation mechanisms.

My 2 cents
Sjoerd

>
>

[-- Attachment #2: Type: text/html, Size: 1339 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: guile 3 update, halloween edition
  2019-10-31 16:20   ` Andy Wingo
@ 2019-10-31 17:27     ` Chris Vine
  0 siblings, 0 replies; 19+ messages in thread
From: Chris Vine @ 2019-10-31 17:27 UTC (permalink / raw)
  To: guile-devel

On Thu, 31 Oct 2019 17:20:37 +0100
Andy Wingo <wingo@pobox.com> wrote:
> Greets :)
> 
> On Thu 31 Oct 2019 01:01, Chris Vine <vine35792468@gmail.com> 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?

I think "exception objects" would be fine.

More broadly, I view an exception as something which makes the current
thread of execution follow an exceptional path (say, implemented by
some kind of continuation object), used generally but not exclusively
to indicate that an error has occurred.  An R6RS or SRFI-35 condition
object on the other hand is a structured error information service,
intended to be a thing (but not the only thing) which might be
propagated as the payload of the exception, and which you can
conveniently match on.

Chris



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: guile 3 update, halloween edition
  2019-10-30 20:13 guile 3 update, halloween edition Andy Wingo
                   ` (6 preceding siblings ...)
  2019-10-31 16:44 ` Sjoerd van Leent
@ 2019-11-02  5:20 ` Mark H Weaver
  2019-11-02 19:33   ` Mark H Weaver
  2019-11-03 19:16   ` Andy Wingo
  2019-11-15  9:03 ` Ludovic Courtès
  8 siblings, 2 replies; 19+ messages in thread
From: Mark H Weaver @ 2019-11-02  5:20 UTC (permalink / raw)
  To: Andy Wingo; +Cc: guile-devel

Andy Wingo <wingo@pobox.com> 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.  See:

  https://git.savannah.gnu.org/cgit/guile.git/commit/?id=02500d44775a77e46febfd47a0dab8233b0c99d0

Prior to that commit, there was no representation for Guile's "throw"
arguments in terms of R6RS conditions, and moreover the R6RS exception
guards were incapable of catching anything other than R6RS conditions.
That terrible bug was reported by Göran Weinholt:

  https://bugs.gnu.org/14922

I fixed that bug, and announced the resulting work on guile-devel:

  https://lists.gnu.org/archive/html/guile-devel/2013-08/msg00004.html

Whatever you may think of me, please don't write me out of Guile's
history.

      Thanks,
        Mark



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: guile 3 update, halloween edition
  2019-11-02  5:20 ` Mark H Weaver
@ 2019-11-02 19:33   ` Mark H Weaver
  2019-11-03 19:16   ` Andy Wingo
  1 sibling, 0 replies; 19+ messages in thread
From: Mark H Weaver @ 2019-11-02 19:33 UTC (permalink / raw)
  To: Andy Wingo; +Cc: guile-devel

Mark H Weaver <mhw@netris.org> writes:

> Andy Wingo <wingo@pobox.com> writes:
>
>> [...] 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.  See:
>
>   https://git.savannah.gnu.org/cgit/guile.git/commit/?id=02500d44775a77e46febfd47a0dab8233b0c99d0

I should clarify that it's not a bijection in the strict mathematical
sense of the word, and it's not obvious to me how to define an efficient
bijection here.  I assumed that you were using the term loosely to
describe an approximate bijection in non-pathological cases, but perhaps
I misunderstood.  If you think you have a true bijection that can be
efficiently implemented, I'd like to hear the details.  Anyway, prior to
the commit above, there was only a mapping in one direction, so nothing
even remotely close to a bijection.

      Thanks,
        Mark



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: guile 3 update, halloween edition
  2019-11-02  5:20 ` Mark H Weaver
  2019-11-02 19:33   ` Mark H Weaver
@ 2019-11-03 19:16   ` Andy Wingo
  2019-11-03 20:18     ` Mark H Weaver
  1 sibling, 1 reply; 19+ messages in thread
From: Andy Wingo @ 2019-11-03 19:16 UTC (permalink / raw)
  To: Mark H Weaver; +Cc: guile-devel

On Sat 02 Nov 2019 06:20, Mark H Weaver <mhw@netris.org> writes:

> Andy Wingo <wingo@pobox.com> 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



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: guile 3 update, halloween edition
  2019-11-03 19:16   ` Andy Wingo
@ 2019-11-03 20:18     ` Mark H Weaver
  0 siblings, 0 replies; 19+ messages in thread
From: Mark H Weaver @ 2019-11-03 20:18 UTC (permalink / raw)
  To: Andy Wingo; +Cc: guile-devel

>> 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!

Thank you, Andy, I appreciate this.  Thanks also for asking for input on
the mailing list.  I'm heavily overloaded at the moment, but I will try
to respond to the other points in your email soon.  It seems like a good
approach, anyway.

    Best,
     Mark



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: guile 3 update, halloween edition
  2019-10-30 20:13 guile 3 update, halloween edition Andy Wingo
                   ` (7 preceding siblings ...)
  2019-11-02  5:20 ` Mark H Weaver
@ 2019-11-15  9:03 ` Ludovic Courtès
  2019-11-15 10:23   ` Andy Wingo
  8 siblings, 1 reply; 19+ messages in thread
From: Ludovic Courtès @ 2019-11-15  9:03 UTC (permalink / raw)
  To: Andy Wingo; +Cc: Guile Devel

Hello Andy & all!

Thanks for the great summary.

I’ve taken a look at ‘wip-exceptions’, which is also remarkably easy to
follow because all the changes are incremental and follow the path you
explained in your message; thanks a lot for making it this clear!

I’ve very much support this change, I always found the key+args
convention to be poor compared to structured error condition objects.

The changes in ‘wip-exceptions’ all make sense to me; some random
comments below.


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?

At least, that’s how I would view it :-), because ‘throw’ cannot (yet)
disappear from C code, and because it’s a migration that could take more
than two stable series to really complete.


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.)

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.


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.


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.


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


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

Anyway, ‘wip-exceptions’ looks great to me as it is, so I’m all for
merging it to ‘master’.

Thanks a lot!

Ludo’.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: guile 3 update, halloween edition
  2019-11-15  9:03 ` Ludovic Courtès
@ 2019-11-15 10:23   ` Andy Wingo
  2019-11-16 15:26     ` Ludovic Courtès
  0 siblings, 1 reply; 19+ messages in thread
From: Andy Wingo @ 2019-11-15 10:23 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: Guile Devel

Hey thanks for the review :)

On Fri 15 Nov 2019 10:03, Ludovic Courtès <ludo@gnu.org> 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



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: guile 3 update, halloween edition
  2019-11-15 10:23   ` Andy Wingo
@ 2019-11-16 15:26     ` Ludovic Courtès
  2019-11-17 19:33       ` Andy Wingo
  0 siblings, 1 reply; 19+ messages in thread
From: Ludovic Courtès @ 2019-11-16 15:26 UTC (permalink / raw)
  To: Andy Wingo; +Cc: Guile Devel

Hi Andy!

Andy Wingo <wingo@pobox.com> skribis:

> On Fri 15 Nov 2019 10:03, Ludovic Courtès <ludo@gnu.org> 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.

Alright, sounds good.

>> 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.)

> 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.

Yes, I agree.

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)?

If it were public, I imagine that users could take advantage of it to
support both exception styles, just like Guile does.  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.)

WDYT?

>> 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.

Yeah, it might be that having C stick to ‘throw’ + allowing for
user-defined exception converters would be enough.

>> 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 :-)).

Thank you!

Ludo’.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: guile 3 update, halloween edition
  2019-11-16 15:26     ` Ludovic Courtès
@ 2019-11-17 19:33       ` Andy Wingo
  0 siblings, 0 replies; 19+ messages in thread
From: Andy Wingo @ 2019-11-17 19:33 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: Guile Devel

Hi :)

On Sat 16 Nov 2019 16:26, Ludovic Courtès <ludo@gnu.org> writes:

> Andy Wingo <wingo@pobox.com> skribis:
>
>> On Fri 15 Nov 2019 10:03, Ludovic Courtès <ludo@gnu.org> 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



^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2019-11-17 19:33 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-30 20:13 guile 3 update, halloween edition Andy Wingo
2019-10-30 21:19 ` Christopher Lemmer Webber
2019-10-31  0:01 ` Chris Vine
2019-10-31 16:20   ` Andy Wingo
2019-10-31 17:27     ` Chris Vine
2019-10-31  1:31 ` Nala Ginrut
2019-10-31  1:47 ` Thompson, David
2019-10-31 14:17 ` Mikael Djurfeldt
2019-10-31 16:13   ` Andy Wingo
2019-10-31 14:46 ` David Pirotte
2019-10-31 16:44 ` Sjoerd van Leent
2019-11-02  5:20 ` Mark H Weaver
2019-11-02 19:33   ` Mark H Weaver
2019-11-03 19:16   ` Andy Wingo
2019-11-03 20:18     ` Mark H Weaver
2019-11-15  9:03 ` Ludovic Courtès
2019-11-15 10:23   ` Andy Wingo
2019-11-16 15:26     ` Ludovic Courtès
2019-11-17 19:33       ` Andy Wingo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).