unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
From: Mikael Djurfeldt <mikael@djurfeldt.com>
To: Mark H Weaver <mhw@netris.org>
Cc: guile-devel <guile-devel@gnu.org>
Subject: Re: Proposal for a new (ice-9 history)
Date: Fri, 2 Nov 2018 14:35:31 +0100	[thread overview]
Message-ID: <CAA2XvwKLoaL3FcT2ze9MCT8aWhS361BCcg=Yh=JH=_HtMWJ0Bg@mail.gmail.com> (raw)
In-Reply-To: <CAA2XvwKpNGRL+f7W1t+1xXsUMV6tz9dWBedxxZaCh9hkwYOgxQ@mail.gmail.com>

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

I've thought some more about this.


What this is about is a need to refer to previous values in value history
in a relative way rather than referring specifically to some historic
value. First a simple (and perhaps not so useful) example, where we use
Heron's method to compute the square root of 9 (where $ refers to the last
value):

scheme@(guile-user)> 1
$1 = 1
scheme@(guile-user)> (/ (+ $ (/ 9 $)) 2.0)
$2 = 5.0
scheme@(guile-user)> (/ (+ $ (/ 9 $)) 2.0)
$3 = 3.4
scheme@(guile-user)> (/ (+ $ (/ 9 $)) 2.0)
$4 = 3.023529411764706
scheme@(guile-user)> (/ (+ $ (/ 9 $)) 2.0)
$5 = 3.00009155413138
scheme@(guile-user)> (/ (+ $ (/ 9 $)) 2.0)
$6 = 3.000000001396984
scheme@(guile-user)> (/ (+ $ (/ 9 $)) 2.0)
$7 = 3.0

We also have the more common case that we are debugging a program and need
to inspect the output, e.g (where $$0 = $ and $$1 is the value before $).:

scheme@(guile-user)> (foo 1)
$1 = #<some-object>
scheme@(guile-user)> (get-bar $$0)
$2 = ...
scheme@(guile-user)> (get-baz $$1)
$3 = ...
scheme@(guile-user)> (foo 2)
$4 = #<some-object>
scheme@(guile-user)> (get-bar $$0)
$5 = ...
scheme@(guile-user)> (get-baz $$1)
$6 = ...

The point is that we can use readline's value history to pick earlier lines
with minor or no editing, i.e. we don't need to say $4 in the last two
selectors. Maybe even more importantly, using relative value history
references is conceptually easier, since we don't have to pay attention to
the index of the value in value history.

Mark also mentioned a use case where procedures are successively built up
using values from value history.


We have now discussed three different problems associated with such an
extension:

1. Naming and name collisions

We currently have a GDB-compatible naming scheme where values are named $1,
$2 etc. It is then natural to extend this to the full GDB value history
naming scheme, introducing $, $$ and $$<N>.

$ collides with the auxilliary syntactic keyword $ in (ice-9 match).
Unfortunately, the interpretation of literals in syntax-rules and
syntax-case macros are influenced by bindings in the environment where
macros are used (according to R5RS 4.3.2) such that value history $ will
disrupt $ matching in (ice-9 match).

This can be solved by using different naming. Mark suggested that $ could
be renamed to $$. I suggested a naming scheme where $-1, $-2 could be used
for relative refrences. Chicken scheme uses #[N] and this could also be
extended by letting negative numbers be relative references.

However, I'm thinking that it is a bit awkward to have to consider all
possible uses of names when selecting this naming scheme. I would very much
prefer to let a GDB user feel at home. Is there a way for names to coexist?

Well, we have the module system. Ideally, I think that value history
lookups should be done in a special top level environment which is
associated with the REPL. Top level bindings in the Scheme environment
should have precedence. Now, instead, (ice-9 history) has a hack which
patches (value-history) into every environment we visit.

Given this situation, is there still a way to use the module system to give
(ice-9 match) $ precedence? There is. Göran Weinholt has pointed out that
other Scheme implementations tend to export their auxilliary keywords. If
we export $ like this:

--8<---------------cut here---------------start------------->8---
(define-module (ice-9 match)
  #:export (match
            match-lambda
            match-lambda*
            match-let
            match-let*
            match-letrec)
  #:replace ($))

[...]

(define misplaced
  (let ((m (lambda (x)
             (format #f "Misplaced aux keyword ~A" x))))
    (lambda (x)
      (syntax-case x ()
        (_ (identifier? x) (syntax-violation #f (m (syntax->datum x)) x))
        ((_ ...) (syntax-violation #f (m (car (syntax->datum x))) x))))))

(define-syntax $ misplaced)

[...]

(include-from-path "ice-9/match.upstream.scm")
--8<---------------cut here---------------start------------->8---

then (ice-9 match) will gracefully replace $ in (value-history) and match
will work as expected. A good idea would be to define *all* auxilliary
keywords to `misplaced' above, according to what Göran has said. That is
independent of the issue of name collisions.

If $ is replaced this way, the user can still write $$0 for that value.

2. Threading and multiple REPL:s

I have suggested to store value history in a fluid and use a functional
data type for the value history. That way we avoid race conditions.

3. Efficiency

If value history is stored in a vlist (a module which is used in the core
of Guile), much of it, particularly the most recent values, will be
accessed at O(1). If we care less about efficiency and want something lean
and simple, then ordinary lists will do.


Comments?

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

  reply	other threads:[~2018-11-02 13:35 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-29 14:13 Proposal for a new (ice-9 history) Mikael Djurfeldt
2018-10-29 23:54 ` Mark H Weaver
2018-10-30  0:55   ` Mikael Djurfeldt
2018-10-30 10:21     ` REPL and load deifferences (was Re: Proposal for a new (ice-9 history)) Mikael Djurfeldt
2018-10-30 12:20       ` Mikael Djurfeldt
2018-10-30 18:01         ` Göran Weinholt
2018-10-30  0:25 ` Proposal for a new (ice-9 history) Mark H Weaver
2018-10-30  1:08   ` Mikael Djurfeldt
2018-10-30  6:20     ` Mark H Weaver
2018-10-30 13:59       ` Mikael Djurfeldt
2018-10-31 16:49         ` Mikael Djurfeldt
2018-11-02 13:35           ` Mikael Djurfeldt [this message]
2018-11-02 14:02             ` Mikael Djurfeldt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAA2XvwKLoaL3FcT2ze9MCT8aWhS361BCcg=Yh=JH=_HtMWJ0Bg@mail.gmail.com' \
    --to=mikael@djurfeldt.com \
    --cc=guile-devel@gnu.org \
    --cc=mhw@netris.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).