From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Mikael Djurfeldt Newsgroups: gmane.lisp.guile.devel Subject: Re: Proposal for a new (ice-9 history) Date: Fri, 2 Nov 2018 14:35:31 +0100 Message-ID: References: <87lg6gmg9s.fsf@netris.org> <878t2gklad.fsf@netris.org> Reply-To: mikael@djurfeldt.com NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="000000000000df63730579ae9cf0" X-Trace: blaine.gmane.org 1541165636 32497 195.159.176.226 (2 Nov 2018 13:33:56 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Fri, 2 Nov 2018 13:33:56 +0000 (UTC) Cc: guile-devel To: Mark H Weaver Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Fri Nov 02 14:33:51 2018 Return-path: Envelope-to: guile-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gIZaB-0008Kp-Hl for guile-devel@m.gmane.org; Fri, 02 Nov 2018 14:33:51 +0100 Original-Received: from localhost ([::1]:51739 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gIZcI-0002xz-1w for guile-devel@m.gmane.org; Fri, 02 Nov 2018 09:36:02 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:58532) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gIZcA-0002vQ-St for guile-devel@gnu.org; Fri, 02 Nov 2018 09:35:56 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gIZc5-0003k2-A0 for guile-devel@gnu.org; Fri, 02 Nov 2018 09:35:53 -0400 Original-Received: from mail-it1-f173.google.com ([209.85.166.173]:36605) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gIZc4-0003iN-GM for guile-devel@gnu.org; Fri, 02 Nov 2018 09:35:48 -0400 Original-Received: by mail-it1-f173.google.com with SMTP id w7-v6so3205700itd.1 for ; Fri, 02 Nov 2018 06:35:47 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:reply-to :from:date:message-id:subject:to:cc; bh=pk88/MIwTDbF3WsntYAqG40K3SUjzy6MqXm0H5Pp2iY=; b=mfKtutDb68IVPaix2qw4/gBQo37i2ktjsohPdyND4kCS2RUmqqcJXi5kxHyuCREQcl BNk3DBVCu3WywMJg2cJU6YxkvlF9HvoDbaVT8vBTWk6RnUx8XPWArV4nyi3eA/0wLvVD gQw2b8GQ69unVy+auvesf9U4fHWcfsHVV7ZYbAT5pznPwU17/yFYyZ24djPNIG5j3/P3 ntskp9keF9DDrBCx4JaZQj9GgtjIAM8PTP3Ym69NEB1nk90OyFonDnYwqKnOZ4ABVs/t 4aAuJ8+Nv7xlr3h9W0ch6WMsTNZXkn7DjukkQo4sli5ayf8sy+t01BpMPSkajDsMHuEu uLAw== X-Gm-Message-State: AGRZ1gJ21LG4nMyyge8reqloDJFk5ZHiguJ8F78WlXcaUOqp1qZ8IEE1 yEj6tIacwWs/hVSPopVvpgI39Wxtvxy/u6UOLINZmPyv X-Google-Smtp-Source: AJdET5e/BsOfdYWgSjHxcbXuRrRa5Ij9ohcVhuPbp+fMVo0RypWC23ZjKtLrTJD6HoUPwCIZH62SnWyYPtNpg0szAek= X-Received: by 2002:a24:2e4e:: with SMTP id i75-v6mr17865ita.72.1541165746706; Fri, 02 Nov 2018 06:35:46 -0700 (PDT) In-Reply-To: X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.85.166.173 X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Original-Sender: "guile-devel" Xref: news.gmane.org gmane.lisp.guile.devel:19711 Archived-At: --000000000000df63730579ae9cf0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable 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 =3D 1 scheme@(guile-user)> (/ (+ $ (/ 9 $)) 2.0) $2 =3D 5.0 scheme@(guile-user)> (/ (+ $ (/ 9 $)) 2.0) $3 =3D 3.4 scheme@(guile-user)> (/ (+ $ (/ 9 $)) 2.0) $4 =3D 3.023529411764706 scheme@(guile-user)> (/ (+ $ (/ 9 $)) 2.0) $5 =3D 3.00009155413138 scheme@(guile-user)> (/ (+ $ (/ 9 $)) 2.0) $6 =3D 3.000000001396984 scheme@(guile-user)> (/ (+ $ (/ 9 $)) 2.0) $7 =3D 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 =3D $ and $$1 is the value before $).= : scheme@(guile-user)> (foo 1) $1 =3D # scheme@(guile-user)> (get-bar $$0) $2 =3D ... scheme@(guile-user)> (get-baz $$1) $3 =3D ... scheme@(guile-user)> (foo 2) $4 =3D # scheme@(guile-user)> (get-bar $$0) $5 =3D ... scheme@(guile-user)> (get-baz $$1) $6 =3D ... 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 $$. $ 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=C3=B6ran Weinholt has pointed out t= hat 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=C3=B6ran 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? --000000000000df63730579ae9cf0 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
I've thought some more about this.

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

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

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

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

The point is tha= t 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 con= ceptually easier, since we don't have to pay attention to the index of = the value in value history.

Mark also mentione= d a use case where procedures are successively built up using values from v= alue history.


We have now discu= ssed three different problems associated with such an extension:
<= div>
1. Naming and name collisions

W= e 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 nam= ing scheme, introducing $, $$ and $$<N>.

$ c= ollides with the auxilliary syntactic keyword $ in (ice-9 match). Unfortuna= tely, the interpretation of literals in syntax-rules and syntax-case macros= are influenced by bindings in the environment where macros are used (accor= ding to R5RS 4.3.2) such that value history $ will disrupt $ matching in (i= ce-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 r= elative references.

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

Wel= l, we have the module system. Ideally, I think that value history lookups s= hould be done in a special top level environment which is associated with t= he REPL. Top level bindings in the Scheme environment should have precedenc= e. Now, instead, (ice-9 history) has a hack which patches (value-history) i= nto every environment we visit.

Given this situati= on, is there still a way to use the module system to give (ice-9 match) $ p= recedence? There is. G=C3=B6ran Weinholt has pointed out that other Scheme = implementations tend to export their auxilliary keywords. If we export $ li= ke this:

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

[...]

(define misplaced
=C2=A0 (let ((m (lamb= da (x)
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 (format #f "Misplaced aux keyword ~A" x))))
=C2=A0= =C2=A0=C2=A0 (lambda (x)
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (syntax-case x (= )
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (_ (identifier? x) (syntax-= violation #f (m (syntax->datum x)) x))
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0 ((_ ...) (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 (valu= e-history) and match will work as expected. A good idea would be to define = *all* auxilliary keywords to `misplaced' above, according to what G=C3= =B6ran 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 REP= L:s

I have suggested to store value history in a f= luid and use a functional data type for the value history. That way we avoi= d race conditions.

3. Efficiency

If value history is stored in a vlist (a module which is used in th= e 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?
--000000000000df63730579ae9cf0--