unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
From: Zelphir Kaltstahl <zelphirkaltstahl@posteo.de>
To: Nala Ginrut <nalaginrut@gmail.com>
Cc: Guile User <guile-user@gnu.org>
Subject: Re: Handling modules with same name (from library and from current project)
Date: Mon,  6 Jan 2025 01:08:59 +0000	[thread overview]
Message-ID: <93959885-36a6-43d9-9622-ece752a3ad91@posteo.de> (raw)
In-Reply-To: <CAPjoZofz+5OGsgFmems1EL9w3k64W7zH9N72vmdWdbFsXVPCQg@mail.gmail.com>

Hi Nala!

Thank you for your response! I tried it and got that structure working. As far 
as I see the rules are as follows:

(1) prefix with something library specific, so that there are no conflicts with 
other projects/libraries

(2) In order to not have all the utility modules on the top level of a project, 
one can move them into a subdirectory (obviously). Lets say the subdirectory's 
name is "libs". But then one needs to add that subdirectory to the load path 
using the `-L` argument of guile (OK, also kind of obvious), so `guile ... -L 
libs ...`.

(3) In order to make ones module named uniquely for the library one is writing, 
one should prefix their module names/identifiers. For example `(define-modules 
(my-lib-name the-module-name))`. In order for Guile to be able to find such a 
module however, it has to be inside a folder named "my-lib-name". That means, 
that inside ones "libs" directory, one needs to create a folder named 
"my-lib-name" and move all the modules inside that folder.

(4) However! One would be mistaken to now change the load path to `guile ... -L 
libs/my-lib-name ...`! The load path still needs to be added as follows: `guile 
... -L libs/ ...`. This seems to be, because Guile takes each part of the module 
name, and tries to find a file defining that module inside a file structure that 
corresponds to the name. So for finding a module imported and named 
`(my-lib-name my-module-name)` Guile would try to find it as follows: For each 
directories on the load path check, if there is a module "my-module-name" inside 
a directory "my-lib-name". Since we added "libs" to the load path, Guile will be 
able to find the "my-lib-name" directory inside it. Inside the "my-lib-name" 
directory, I am guessing, that it checks all the non-directory files inside, 
whether any of them contains a module that has the name `(my-lib-name 
my-module-name)`.

Conclusion:

What I did not check is, whether the file, that contains the actual module needs 
to be named "my-module-name.scm" or not. I guess it should not hurt to name it 
that way.

As a consequence of this, I must update my guile-fslib package, if I want to be 
able to use it anywhere properly, and its current state is basically unusable.

OK, but now I know better how to structure things in Guile projects! Thank you!

Best regards,
Zelphir

On 05.01.25 16:42, Nala Ginrut wrote:
>
> > How do you
> avoid these module name conflicts? How do you make sure that only libraries
> themselves use their own helper function modules?
>
> If I understand you correctly.
> I think you should add a namespace as directory inside lib dir, pick your own 
> unique project name as the namespace, say mylib, and define it as 
> (define-module (mylib list-utils))
>
> Best regards.
>
>
> Zelphir Kaltstahl <zelphirkaltstahl@posteo.de> 于 2025年1月5日周日 下午11:50写道:
>
>     Hello Guile Users!
>
>     I have a question regarding an issue I run into again and again, and have not
>     found an adequate solution for yet. I want to know how you are handling this,
>     what your solution is.
>
>     (1) recent story:
>
>     I have a website, that I wrote manually in pure HTML and CSS. It does what it
>     should and there is no actual issue with it. However, I have been thinking it
>     would be cool to implement it in Guile and make a sort of minimal example
>     or web
>     "framework", of how one can make such a static website using Guile. I already
>     have some example in my examples repository. However, that example has
>     code in
>     it, that is copied from my existing "guile-fslib", which is on guix
>     already. So
>     I have been thinking: "I should just install the package from guix and remove
>     this code from my new website repository, having it hidden away in the
>     guile-fslib library." It is just some code to work with file names and
>     directories and paths, not directly web related, but important for checking,
>     whether a request for a static resource/an asset is within the "static"
>     directory, and not just anywhere on the server, which would be a security
>     issue.
>
>     Of course I could put everything in a docker container or something, or
>     completely serve static assets using a HTTP server, as one should, but
>     then the
>     Guile thing I want to build would not work on its own. I want to at least
>     have
>     it implemented as a fallback, so that one could run it without an additional
>     thing in front of it for handling static resource requests.
>
>     (2) So far so good. But now comes the problem:
>
>     "guile-fslib" has a module named "string-utils" and a module named
>     "list-utils".
>     In my guile web development example code I also have modules with those
>     names.
>     Guile then gets confused about which one I am referring to, when I
>     `(use-modules
>     ...)` them and in the code that makes use of the functions from those
>     modules,
>     it then claims, that no bindings with some name exist, because it has looked
>     into the "list-utils" or "string-utils" of the guix package, instead of
>     the one
>     of my web project.
>
>     (3) Thoughts:
>
>     I don't know how to resolve this. I think it is very unreasonable to have to
>     look out to name no module the same name as any module in any library I am
>     using. Obviously many libraries or projects will have some list utilities or
>     helpers for convenience. Many projects will have some special string
>     functions.
>     Having a name like "string-utils" or "string-helpers" should not be an
>     impossibility.
>
>      From a past/previous case of this, I remember someone saying I should get my
>     load path in order. But what does this mean? In my projects I invoke Guile
>     doing
>     something like this:
>
>     ~~~~
>     guile -L . -L libs main.scm
>     ~~~~
>
>     I simply use the `-L` argument to pass in all the directories, in which my
>     modules reside, for example "libs/list-utils.scm" or "libs/string-utils.scm",
>     which I then import into various other modules and the main file, the
>     entrypoint.
>
>     (4) Solution ideas:
>
>     (4.1) I already abstain from doing `(add-to-load-path ...)` manipulations
>     in my
>     code. As far as I know I am not doing anything dirty there. But ... Guile
>     gets
>     confused about which module to import and it seems to see the one from
>     installed
>     library first and then not consider the one of my current project. I am
>     not even
>     sure how Guile could possibly know which module I am referring to, because
>     I am
>     not telling it anything about that. So I am wondering, whether some dark
>     magic
>     of dynamically changing load path is perhaps a _necessary_ evil?
>
>     (4.2) Or perhaps I have to give my modules multi part names like
>     `(define-module
>     (fslib helpers list-utils))` to scope module names? But that would be
>     annoying
>     when using them inside the library itself, because it is more to write and
>     I am
>     not sure others are doing that always. Usually I just name my modules
>     `(list-utils)` or `(string-utils)`. Is that a bad thing, when these are
>     modules
>     of helper functions, which are not supposed to be exported for use in other
>     projects?
>
>     (4.3) The ugly solution I so far had to reach for, because I couldn't
>     figure out
>     a better way: Integrate library code directly into the source tree of a
>     project,
>     copying code. This cannot be the right way to do it, can it? Seems unlikely.
>
>     How do you manage this? I know people have written much bigger projects
>     than I
>     have and surely someone has some dependency on another Guile library. How
>     do you
>     avoid these module name conflicts? How do you make sure that only libraries
>     themselves use their own helper function modules?
>
>     The bad thing is, that I always run into this, when I actually want to do
>     something else. In this case build a website thing in Guile. But now I am
>     side
>     tracked again by this issue, because I don't know how to do this properly.
>
>     Best regards,
>     Zelphir
>
>     -- 
>     repositories:https://notabug.org/ZelphirKaltstahl,https://codeberg.org/ZelphirKaltstahl
>
-- 
repositories:https://notabug.org/ZelphirKaltstahl,https://codeberg.org/ZelphirKaltstahl


  reply	other threads:[~2025-01-06  1:08 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-01-05 14:49 Handling modules with same name (from library and from current project) Zelphir Kaltstahl
2025-01-05 15:42 ` Nala Ginrut
2025-01-06  1:08   ` Zelphir Kaltstahl [this message]
2025-01-06  2:38     ` Nala Ginrut

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=93959885-36a6-43d9-9622-ece752a3ad91@posteo.de \
    --to=zelphirkaltstahl@posteo.de \
    --cc=guile-user@gnu.org \
    --cc=nalaginrut@gmail.com \
    /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).