Hello Guile Users!
Today I came across some weird behavior or perhaps even a bug. I will describe
it in the following.
It seems like when I define a function, that has the same name as a built-in
function, inside a (library ...) and then import that library with a (prefix
(lib-name) my-prefix:), and then try to use (my-prefix:my-function ...) Guile
still tries to use the built-in function, instead of the one I defined. In my
case it lead to a type error.
I have code at
https://notabug.org/ZelphirKaltstahl/sicp-solutions/src/430dd7451a893d039038791f3e8fbf0b58efe0b1/exercise-2.73
that causes the problem:
~~~~
$ guile --fresh-auto-compile -L . -l solution-2-4-2.scm
;;; note: auto-compilation is enabled, set GUILE_AUTO_COMPILE=0
;;; or pass the --no-auto-compile argument to disable.
;;; compiling /home/user/dev/guile/guile-sicp/exercise-2.73/solution-2-4-2.scm
;;; compiling ./custom-exceptions.scm
;;; compiled
/home/user/.cache/guile/ccache/3.0-LE-8-4.6/home/user/dev/guile/guile-sicp/exercise-2.73/custom-exceptions.scm.go
;;; compiling ./rectangular.scm
;;; compiling ./tagged-data.scm
;;; compiled
/home/user/.cache/guile/ccache/3.0-LE-8-4.6/home/user/dev/guile/guile-sicp/exercise-2.73/tagged-data.scm.go
;;; compiling ./math.scm
;;; compiled
/home/user/.cache/guile/ccache/3.0-LE-8-4.6/home/user/dev/guile/guile-sicp/exercise-2.73/math.scm.go
;;; compiled
/home/user/.cache/guile/ccache/3.0-LE-8-4.6/home/user/dev/guile/guile-sicp/exercise-2.73/rectangular.scm.go
;;; compiling ./polar.scm
;;; compiled
/home/user/.cache/guile/ccache/3.0-LE-8-4.6/home/user/dev/guile/guile-sicp/exercise-2.73/polar.scm.go
;;; compiled
/home/user/.cache/guile/ccache/3.0-LE-8-4.6/home/user/dev/guile/guile-sicp/exercise-2.73/solution-2-4-2.scm.go
GNU Guile 3.0.9
Copyright (C) 1995-2023 Free Software Foundation, Inc.
Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
This program is free software, and you are welcome to redistribute it
under certain conditions; type `,show c' for details.
Enter `,help' for help.
scheme@(guile-user)> (rect:real-part (contents (attach-tag 'rectangular (cons 1
2))))
in contents: datum: (rectangular 1 . 2)
ice-9/boot-9.scm:1685:16: In procedure raise-exception:
In procedure real-part: Wrong type argument in position 1: (1 . 2)
Entering a new prompt. Type `,bt' for a backtrace or `,q' to continue.
scheme@(guile-user) [1]>
~~~~
(spacing added for easier readability)
In the REPL I found by trying thing, something weird: real-part had a doc
string:
~~~~
scheme@(guile-user) [1]> ,d rect:real-part
- Scheme Procedure: real-part z
Return the real part of the number Z.
~~~~
But how could that be? I never wrote a doc string for my function … Then I
realized, that somehow Guile must have gotten confused and itself probably
already has a definition for a function named "real-part". A quick check:
~~~~
$ guile
GNU Guile 3.0.9
Copyright (C) 1995-2023 Free Software Foundation, Inc.
Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
This program is free software, and you are welcome to redistribute it
under certain conditions; type `,show c' for details.
Enter `,help' for help.
scheme@(guile-user)> real-part
$1 = #<procedure real-part (_)>
scheme@(guile-user)>
~~~~
So somehow, even though I imported with a prefix "rect:" and called it as
`rect:real-part' Guile chose to use the built-in function `real-part', instead
of what my library `rectangle.scm' exports.
The error is of course very confusing, because a pair would be exactly the right
thing to give to my own real-part function. I began to put in debug prints to
sanity check my understanding and noticed, that the one from my own real-part
does not even print. But the one from polar.scm also did not print. It took me a
few hours of head scratching, until I tried the `,describe real-part' thingy,
and saw a suspicious doc string appear, which made me double check my imports,
but I cannot find a mistake.
I think either I am overlooking something too obvious, or something weird is
going on. It is not behaving like I would expect it to, which would be to use my
own definition of real-part, from the library defined in `rectangle.scm'.
I could of course rename real-part, but I would like not to have to rename
things, just because the built-in function has the same name. Also Guile did not
warn me about redefining a built-in function, but I am not sure whether it does
that or in which cases it does that.
Is this really a bug in Guile?
Is there a way around it, without renaming my own function, that does not
require me to restructure everything?
Regards,
Zelphir
--
repositories:https://notabug.org/ZelphirKaltstahl