From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Mark H Weaver Newsgroups: gmane.lisp.guile.user Subject: Re: exporting GOOPS generic functions, was: [ANN] guile-file-names 0.2 Date: Fri, 24 May 2019 21:21:12 -0400 Message-ID: <87tvdjs50c.fsf@netris.org> References: <87a7fmkbtv.fsf@invergo.net> <87y336b232.fsf@netris.org> <87mujekuzs.fsf@invergo.net> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="29462"; mail-complaints-to="usenet@blaine.gmane.org" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux) Cc: guile-user@gnu.org To: Brandon Invergo Original-X-From: guile-user-bounces+guile-user=m.gmane.org@gnu.org Sat May 25 03:34:23 2019 Return-path: Envelope-to: guile-user@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1hULZm-0007Xz-RR for guile-user@m.gmane.org; Sat, 25 May 2019 03:34:22 +0200 Original-Received: from localhost ([127.0.0.1]:34435 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hULZl-0001aG-OR for guile-user@m.gmane.org; Fri, 24 May 2019 21:34:21 -0400 Original-Received: from eggs.gnu.org ([209.51.188.92]:45343) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hULZM-0001Xx-OF for guile-user@gnu.org; Fri, 24 May 2019 21:33:57 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hULP6-00061g-BR for guile-user@gnu.org; Fri, 24 May 2019 21:23:21 -0400 Original-Received: from world.peace.net ([64.112.178.59]:37070) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hULP5-0005t4-KS for guile-user@gnu.org; Fri, 24 May 2019 21:23:19 -0400 Original-Received: from mhw by world.peace.net with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1hULOs-0006yn-Sw; Fri, 24 May 2019 21:23:07 -0400 In-Reply-To: <87mujekuzs.fsf@invergo.net> (Brandon Invergo's message of "Wed, 22 May 2019 23:03:03 +0100") X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 64.112.178.59 X-BeenThere: guile-user@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: General Guile related discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-user-bounces+guile-user=m.gmane.org@gnu.org Original-Sender: "guile-user" Xref: news.gmane.org gmane.lisp.guile.user:15492 Archived-At: Hi Brandon, Brandon Invergo writes: > I can try something like this: > > (let ((old-absolute-file-name? absolute-file-name?)) > (define-generic absolute-file-name?) > (define-method (absolute-file-name? (f )) > (proper-list? (route f))) > (define-method (absolute-file-name? (f )) > (old-absolute-file-name? f))) > > But that strangely gives me this upon compiling the module: > > While compiling expression: > Unbound variable: absolute-file-name? > > I'm not sure what to make of that. A compile-time error, but why? It's because you tried to export a binding that doesn't exist at the top-level of your module. That's because the definitions you gave above are not in a top-level context. They are local variables. One easy solution is to use Guile's (@ module var) syntax to explicitly reference a variable from a particular module. For example: (define-method (absolute-file-name? (f )) ((@ (guile) absolute-file-name?) f))) Here, the reference (@ (guile) absolute-file-name?) explicitly asks for the binding from the (guile) module. Another option is to *rename* bindings while importing them, using either #:prefix or #:select. For example, see module/system/repl/command.scm in Guile's source, which includes the following lines in its 'define-module' form: #:use-module ((ice-9 pretty-print) #:select ((pretty-print . pp))) #:use-module ((system vm inspect) #:select ((inspect . %inspect))) Those modules include 'pretty-print' and 'inspect' among their exported bindings, but the bindings will be visible as 'pp' and '%inspect' within command.scm. When using #:select, the imports are limited to the bindings you specifically asked for. Sometimes it's more convenient to add a prefix to every binding imported from a given module, like the following example from Guile's module/ice-9/streams.scm: (define-module (ice-9 streams) #:use-module ((srfi srfi-41) #:prefix srfi-41:) Bindings can also be renamed when they are exported, and (ice-9 streams) does this. > ps - You say that I should use #:export and #:replace, but according to > the manual, #:replace "[exports] all identifiers in LIST ... and mark[s] > them as =E2=80=9Creplacing bindings=E2=80=9D." So, shouldn't be unnecess= ary to put the > symbol in both lists? Yes, you're right. If a binding is listed in the #:replace list, there's no need to add it to the #:export list. * * * Finally, I wanted to mention that, in my opinion, the degree to which this library modifies existing Guile bindings is regrettable. I'm glad that Guile is hackable in this way, but I generally prefer to avoid libraries that do these kinds of hacks, unless there is a compelling reason to justify it. In my opinion, it would be better to use plain strings as the representation for file names, and instead provide procedures to conveniently manipulate those strings. Consider: (1) Your objects are much larger than plain strings in terms of their memory use. (2) Every time you pass a object to a file system primitive, it needs to be converted back into a string, which makes them slower to use as well. (3) If Guile ever extends our file system primitives in the future, e.g. by adding additional keyword or optional arguments, your library will likely cause problems with that. For example, a few years ago we added the #:guess-encoding and #:encoding keyword arguments to 'open-file' and several other similar procedures. Also, I had a question: a big part of your library seems to be aimed at supporting Windows drive letters and separators. Have tested your library on Guile running on Windows? One thing I know is that there's no need for us to use backslash as the file separator on Windows. My understanding is that the POSIX compatibility layer, used in Guile's Windows port, automatically handles interpreting forward slashes as a directory separator. Guile already includes code to try to ensure that from the perspective of Guile code, we will see and use forward slashes uniformly, regardless of platform. For example, see 'scm_i_mirror_backslashes' in libguile/load.c and its associated comment. Regards, Mark