eisl icon indicating copy to clipboard operation
eisl copied to clipboard

Bug report: defmodule doesn't permit class definitions

Open wasamasa opened this issue 2 years ago • 6 comments

Suppose I write the following test.lsp and run it with eisl -l test.lsp:

(defmodule util

(defclass <rect> ()
  ((size :accessor rect-size
         :initarg size)))

)

I get the following error:

Definition must be on top level at DEFCLASS (UTIL::<RECT> NIL ((UTIL::SIZE UTIL:::ACCESSOR UTIL::RECT-SIZE UTIL:::INITARG UTIL::SIZE)))

wasamasa avatar Aug 21 '22 15:08 wasamasa

OK I will improve. Thank you.

sasagawa888 avatar Aug 22 '22 00:08 sasagawa888

I improved.

sasagawa888 avatar Aug 22 '22 07:08 sasagawa888

Alright, it does permit class definitions now, but how do I use the accessors now?

edit: Wild idea: Maybe it would be better to allow declaring what identifiers to export. Something like (declare (visible rect-size)). It could be used for functions, accessors, macros, ...

wasamasa avatar Aug 22 '22 09:08 wasamasa

Write it like this:

(defmodule util

    (defclass <rect> () ((size :accessor rect-size :initarg size)))
    
    (defpublic foo ()
        (create (class <rect>) 'util::size 999) )

    (defpublic bar (x)
        (rect-size x) )

)

> (load "tests/bug.lsp")
T
> (defglobal a (foo))
A
> (bar a)
999
> 

sasagawa888 avatar Aug 23 '22 00:08 sasagawa888

Ok, so you'd need to define a wrapper function. A function to define a public alias would be convenient. This concept is known as reexport in other programming languages.

edit:

  • Why does the module name appear in the create call?
  • I cannot name the wrapper function the same as the original one because I otherwise run into a stack overflow due to mutual recursion (should I open an issue for this? I'm used to Emacs and friends catching call stack overflows)

wasamasa avatar Aug 23 '22 08:08 wasamasa

Why does the module name appear in the create call?

This is because the module-name :: is added to the symbol name in defmodule.

I cannot name the wrapper function the same as the original one because I otherwise run into a stack overflow due to mutual >recursion (should I open an issue for this? I'm used to Emacs and friends catching call stack overflows)

I would appreciate it if you could show me a concrete example of mutual recursion.

sasagawa888 avatar Aug 23 '22 22:08 sasagawa888

(defmodule util

    (defclass <rect> () ((size :accessor rect-size :initarg size)))
    
    (defpublic foo ()
        (create (class <rect>) 'util::size 999) )

    (defpublic rect-size (x)
        (rect-size x) )
)
> (load "tests/bug.lsp")
T
> (defglobal a (foo))
A
> (rect-size a)
zsh: segmentation fault (core dumped)  eisl -r

wasamasa avatar Aug 25 '22 17:08 wasamasa

Thanks for the code example. I considered.

The code defines defclass inside the module. I think that this is the purpose of wanting to hide the generated class and instance. I don't feel the need to dare to expose the accessor to the outside.

You can use accessors in the following ways if you need them:

> (defglobal a (foo))
A
> (util::rect-size a)
999
> 

sasagawa888 avatar Aug 25 '22 22:08 sasagawa888