|
From: Pascal B. <pj...@in...> - 2016-11-29 20:21:39
|
> On 29 Nov 2016, at 03:52, Blake McBride <bl...@mc...> wrote: > > I do not believe that CLISP is very portable. I know CLISP runs in a great number of environments, but I do not think that makes the system portable for the following reason. Being able to run in a lot of environments, and being portable, are not the same thing. For example, I will describe two different types of systems, both of which run in a lot of environments, but only one is portable in the sense I am trying to convey. > > Type 1: This system takes maximum advantage of the underlying platform facilities in order to provide the most functionality and be as fast as possible on the system it is running on. It achieves "portability" through many, many ifdef's or constructs that have the same effect. So, while the system is "portable" in the sense that it runs on a lot of systems, it only does so through many careful ifdef like facilities and complex build procedures. > > Type 2: This system is portable because it only uses standard facilities that are broadly available on most platforms. Although there are ifdef constructs, they are seldom used. The system is simple to build because at largely depends on readily available, common facilities. > > The advantage of Type 1 is that it runs faster and provides more functionality. > > The disadvantages of Type 1 are that it is really not portable, and it is very fragile. Although it may run on many systems at one point in time, it suffers very significantly from bit rot on nearly a monthly basis - making it high maintenance. It also isn't really portable because the amount of work it would take to get it to work in a new environment is very significant. > > Type 2 systems are really portable in the sense that they can be easily ported to a new environment, and they are much, much less subject to bit rot. > > Now, having said all that, I am of the somewhat ignorant opinion that CLISP is of Type 1. I say that because, over the years, I've seen how fragile and complex the build process is. I also say that because I've seen first hand how the system wouldn't build because I had some arcane library one revision too old or too new. You’re correct, in part. That is, the part of clisp that is written in C (clisp is written half in C, half in (a subset of) Common Lisp). > Speaking for myself alone, I would prefer CLISP to be Type 2 for the following reasons: > > 1. Getting every ounce of speed is not important. No one uses CLISP if speed is their primary concern. > > 2. It seems like development and support of CLISP is beginning to dwindle. If CLISP doesn't become Type 2, it'll quickly die as soon as updates to it cease - due to rapid bit rot. > > 3. On the other hand, if it does become Type 2, it could live on and be useful for a very long time with very minimal work. > > Given how far CLISP has come, and the variety of machines it readily builds on, rather than a course correction, perhaps CLISP could use a Type 2 portability fork. In general, I don't like when forks occur, but in this case, wanting to retain CLISP's current appeal while at the same time building something that can be easier to support and better withstand the changes with time. I agree. I guess we could say that clisp has 4 parts: - a virtual machine (implemented in C), - library (CL) functions written in C, - library (CL) functions written in Common Lisp, - a CL compiler targeting this VM (implemented in Common Lisp). http://www.clisp.org/impnotes/vm.html Only the virtual machine and the library functions written in C need to be portable (the rest is already portable (being more or less conforming Common Lisp code). And then, library functions written in C are not necessarily non “conforming" standard C. Provided with a set of C macros that expand to standard C, ISTM that they could be mostly standard C code. The #if/#ifdef/#ifndef are concentrated on a small number of files, the biggest ones being lispbibl.d, and the actual OS and processor API. for f in *.h *.d *.c *.lisp ; do printf "%5d %s\n" $(grep -e '# *\<if\(\>\|n?def\)' $f |wc -l) $f; done|sort -rn 585 lispbibl.d 259 stream.d 120 pathname.d 93 spvw.d 92 intelem.d 67 foreign.d 63 arisparc.d 53 arisparc64.d 51 eval.d 47 spvw_memfile.d 40 spvw_garcol.d 40 arilev1.d 38 arilev0.d 35 io.d 30 intlog.d 26 spvw_garcol_old.d 24 intmal.d 23 constsym.d 22 unix.d 22 lightning.c 21 charstrg.d 18 unixaux.d 18 spvw_circ.d 18 arimips.d 16 gmalloc.c 16 arimips64.d 13 time.d 13 spvw_global.d 13 socket.d 13 arilev1i.d 13 arilev1c.d 12 lfloat.d 11 spvw_allocate.d 10 intgcd.d 10 genclisph.d 10 constobj.d 10 _clisp.c 9 misc.d 9 intsqrt.d 9 debug.d 9 array.d 8 subr.d 8 spvw_sigsegv.d 8 spvw_mmap.d 8 predtype.d 8 hashtabl.d 8 error.d 8 encoding.d 7 spvw_heap.d 7 ari68020.d 6 win32aux.d 6 spvwtabf.d 6 spvw_space.d 6 spvw_sigwinch.d 6 spvw_sigpipe.d 6 lisparit.d 6 execname.c 6 dfloat.d 5 xthread.d 5 spvwtabs.d 5 spvw_sigcld.d 5 spvw_page.d 5 spvw_fault.d 5 spvw_debug.d 5 intdiv.d 5 int2adic.d 5 control.d 5 ari80386.msvc.c 5 ari80386.d 4 zthread.d 4 intserial.d 4 intprint.d 4 foreign1.lisp 4 bytecode.d 4 asmi386.h 3 weak.d 3 spvw_typealloc.d 3 spvw_sigterm.d 3 spvw_sigint.d 3 spvw_mark.d 3 realelem.d 3 package.d 3 intplus.d 3 flo_rest.d 3 ffloat.d 3 compelem.d 3 built.d 3 arihppa.d 2 spvw_genera3.d 2 sfloat.d 2 record.d 2 pseudofun.d 2 modules.c 2 list.d 2 aridecl.d 2 ariarm.d 1 win32.d 1 w32shell.c 1 symbol.d 1 spvwtabo.d 1 spvw_walk.d 1 spvw_module.d 1 spvw_genera1.d 1 spvw_gcmark.d 1 sp80386.msvc.c 1 sp80386.d 1 realtran.d 1 rational.d 1 floatparam.c 1 flo_konv.d 1 constobj_tl.d 1 arivaxunix.d 1 ari68000.d plus 200 source files without a #if/n/def. When compiling clisp to various targets, I find that the main difficulty is not in the clisp code itself, but rather in its dependencies such as libsigsegv and ffcall. clisp can work without them but with some important drop of features (safety and FFI). I’m not sure you could implement something like ffcall in standard C, much less libsigsegv. > Or, if not a fork, perhaps something like this: > > ./configure real-portable > make real-portable > > What this process leaves us with is a set of source files (not any object or executable files) that are as portable as can be. You can move the files almost anywhere and just type "make". Perhaps it incluses one header file with a small number of define's someone can select from. Would this just add yet another target, making it even more difficult to maintain? ;-) -- __Pascal J. Bourguignon__ |