sasagawa888 / eisl

ISLisp interpreter/compiler
Other
272 stars 22 forks source link

Minimalism: make ncurses and nana dependencies optional #225

Closed Irvise closed 1 year ago

Irvise commented 1 year ago

Dear Sasagawa and Bane (@poldy),

I messaged Mr. Sasagawa to inform him on some test I had performed with Easy-ISLisp and to share my findings. He recommended I open up an issue to help bring more knowledge to the discussion. Here are the important bits of information:

Currently Easy-ISLisp only requires a C compiler and ncurses to be compiled. edlisp makes heavy use of ncurses as it is the backbone of the editor. However, eisl uses ncurses only for the REPL. Some implementations such as TR7 Scheme implement their REPL directly in C.

The reason I am bringing this up, is because I think the requirement for ncurses in eisl could be put behind some compiler directive (for example, -DWITHOUT_NCURSES=1) and this would in turn make ncurses optional. With this change, Easy-ISLisp would only require a C compiler and would in turn make it more minimal. This compilation flag could in turn turn of the REPL completely (leaving eisl as an interpreter/compiler) or it could substitute the ncurses implementation with a basic one.

@poldy do you think this is doable? Do you think this is worth doing?

I am personally interested in minimalism as we are looking for Scheme/Lisps/ implementations that are small and that fit within the bootstrappable criteria and the live-boostrap project. You can see my current work and comparison between Scheme/Lisps/ implementations in here.

Regarding the above, here are some other relevant findings I made:

Best regards, Fer

sasagawa888 commented 1 year ago

I've considered curses and ncurses. Originally curses was the standard in UNIX. However, ncurses has become mainstream in Linux OS. I think ncurses is the standard C compiler for Linux. Therefore, I would like to distinguish between Linux and others by conditional compilation.

sasagawa888 commented 1 year ago

Please let me know if you have any other good ideas. Thank you.

poldy commented 1 year ago

Thanks for reviewing the code, I'll try to answer some of your questions.

I presume you know about the "-r" command-line flag, so you're trying to eliminate curses at compile-time instead. I see no great problem with this, you could look at where the repl_flag variable is used and implement something parallel at compile-time. If you're doing this think it would be a good idea to make it a configurable option, the command-line editing is helpful for new users on larger OSs and we wouldn't want to lose it. But this wouldn't "turn off the REPL" like you say, just make it a bit less friendly because you'd lose history and editing (although you could always regain this by running under rlwrap or similar).

To clarify a bit on what Sasagawa-san wrote, curses is an X-Open standard so I don't think there's any need to avoid it. I tried to isolate non-portable ncurses stuff inside NCURSES_VERSION #ifdefs but this may even be a bit academic as any platform I have access to runs ncurses.

I'm surprised that nana is a requirement for production builds though. That wasn't my intention, the WITHOUT_NANA #define used for non-debug builds should completely exclude it. Can you provide more details here, exactly how did you build and what was the error?

Thanks.

Irvise commented 1 year ago

To be honest, I had overlooked the -r flag... This probably simplifies my proposed change even further. If my proposed change does take place, it will be for sure with a configurable option and turned off by default. My proposal to avoid curses stems from the stringent requirements that the live-bootstrap project has, as they only build what is of up-most necessity. Therefore curses (X-Open) or ncurses should be avoided there. I am not trying to make a distinction between curses or ncurses here.

I saw that there was indeed the WITHOUT_NANA flag during compilation, so I was also a bit surprised it was still being pulled. However, it is easy to reproduce what I did to get these findings. Here is a step by step list:

  1. Clone master and move or remove the nana directory. This can be done with a simple git mv nana nana-mv. This action will prevent any files from nana being found or used.
  2. Run make

There are two set of errors here. The first set is regarding imports. Easy-ISLisp has some #include "nana.h" and friends that are not warded by the WITHOUT_NANA flag. Therefore they always get included, even if it not a debug build. Secondly, when those #includes are commented out, some nana macros become undefined. This indicates that some nana functionality is still being used even when the WITHOUT_NANA flag is active.

This could be fixed by warding the includes and nana macros with the WITHOUT_NANA flag. I could provide a patch/PR for this is you would like.

Regards, Fer

poldy commented 1 year ago

I see what you were trying to do now, thanks for clarifying that.

I opened a pull request to fix your problem, feel free to review. Even though it wasn't a strong legal/technical requirement, I think the code is slightly clearer now.

sasagawa888 commented 1 year ago

Thank you for your pull request.

sasagawa888 commented 1 year ago

Dear Irvise`

Easy-ISLisp itself depends on ncurses/curses in only a few places. I think you can give makefile an option to generate code that doesn't depend on it. I look forward to your pull requests.

Irvise commented 1 year ago

Thank you @poldy for your PR. That should do it.

I will try to submit a PR that makes (n)curses optional. It will take me a while, but it should come in the following days/weeks.

Irvise commented 1 year ago

Hi. The PR I just created just adds the WITHOUT_CURSES flag and documents it. I have followed @poldy's approach and created an auxiliary header file in compat.

I took a look a deeper look into the REPL code in main.c. From what I saw, -r sets a global variable and each REPL function checks whether that flag is set or not. If the flag is set, then plain C functions get used, otherwise, the curses version is used.

This is a big problem as the curses code and the plain C methods are intertwined, which makes separating them more difficult. I was expecting that the -r flag would set a different control flow than the normal REPL and that would allow a simple decoupling between the systems, but this doesn't look like it...

The REPL code would need to be refactored/split in order to make curses support easily optional...

What is your opinion and your feedback?

sasagawa888 commented 1 year ago

Thank you for your pull request. It works well on Linux MINT.

sasagawa888 commented 1 year ago

The -r option was added later by request. Easy-ISLisp was intended for use on RaspberryPI for children. So I made it editable REPL. However, some users using Emacs appeared. They don't need editable REPL. Therefore, the -r option was added in a hurry. The addition is ado-hoc. I am very busy now. I would be very happy to have it refactored.

poldy commented 1 year ago

I opened a pull request to take "optional curses" further. I was aiming for as little LOC churn as possible, so relied on the optimizer to help. This may not work great for compilers like tcc, but it should at least compile and run correctly.

Irvise commented 1 year ago

I think we are done here, but I would like to have your feedback.

Irvise commented 1 year ago

I think this issue can now be closed then :) Thank you for your support!