1 karma · joined February 12, 2025
no
https://www.swift.org/install/linux/#platforms
> Also note that text editors really thrive on specialized string representations
No, it needs specialized editor data structures.
The first Emacs was originally written in 1976 by Guy L Steele and David Moon on top of TECO, an early text editor with a cryptic macro language. Richard Stallman did most on the early work on it.
The second Emacs was written for the then new MIT Lisp Machine in Lisp, in 1978 by Daniel Weinreb and Mike McMahon. The Emacs was called EINE.
The third Emacs was Multics Emacs, which was written in Maclisp, in 1978 by Bernard Greenberg.
One can implement editor data structures in Lisp, as was shown already way back then.
Gosling Emacs was written in C with Mocklisp, 1981. Richard Stallman took it and rewrote it into GNU Emacs.
GNU Emacs is implemented on an Emacs Lisp engine written in C, with various low-level stuff implemented in C.
The main reasons to use C for low-level stuff:
C is already a low-level language, which makes integration with various operating systems simpler.
C can be compiled to native code and will generate fast executable code.
Emacs Lisp OTOH was implemented as an Lisp interpreter and a byte code engine (byte code interpreter in C and byte code compiler in Lisp). Writing portable code is easy, but without native code it is not that fast, when the code is actually written in Lisp. Slower Lisp code calling faster C code for the performance critical sections then usually works. Also the compact byte code made the implementations slightly smaller, compared to native code.
Other Lisp implementations (like Lisp Machine Lisp and Maclisp, both from the 70s) already had faster implementations. The Maclisp compiler was producing native code.
The other reason why Stallman implemented Emacs Lisp: he wanted a simpler Lisp, because GNU Emacs was supposed to be configured/extended by people who are not hardcore Lisp experts.
well, that's obviously wrong. There are so many examples where LISP code is LISP data. It's also just one example, a code for a theorem prover can also be LISP data. The whole idea of LISP is to be able to write interpreters, code transformations, rule engines, compilers as LISP applications which process code in the form of lists.
The idea of being a LIST PROCESSOR is not an implementation detail, it is the core essence of LISP.
That's obviously false. Telegram is providing services to French and EU citizens.
I would hope that it is pretty normal, that a CEO can be treated exactly that way.
> And it's worth mentioning that a lot of the crucial components of the Lisp machine system, such as the windowing system, the garbage collector and the network stack work because they are written in a more structured and low-level manner so that they run efficiently and avoid consing.
Not all levels are low-level, there is a large higher level which is written using Flavors. Even transmitting IP packets is a Flavor method.
Something like the LispWorks IDE, with its editor-based listener tool, does the same.
Thanks for your effort!
But I need none of this. I want to open a REPL and type (dotimes (i 1000000) (print i)) - or anything morally equivalent ;-) - and I want it to do its job and the user interface to be responsive!! There were Lisp systems, which did this 40 years ago and there are some which can do it today: Execute simple plain Lisp code concurrently without any special instrumentation. Each REPL executes by default in its own thread, concurrently. I want the same for the other tools, too.
Execute (dotimes (i 1000000) (print i)) in the Emacs Lisp REPL. The UI is dead then. I find it strange that it is dead and I find it strange that there are people who don't find that strange. ;-)
> What kind of code is this that take >1 second in each repl? Out of curosity.
All kinds of stuff.
> Out of curosity.
Have you ever used a multithreaded Lisp environment as a primary work tool?
How would I do it in GNU Emacs?
via external "jobs"
One Lisp REPL doing stuff and GNU Emacs is completely dead as long as the Lisp REPL runs that Emacs Lisp code. It's not even slow, it just is completely non-responsive.
> 25. Processes
> The Lisp Machine supports multi-processing; several computations can be executed "concurrently" by placing each in a separate process. A process is like a processor, simulated by software. Each process has its own "program counter", its own stack of function calls and its own special-variable binding environment in which to execute its computation. (This is implemented with stack groups, see chapter 12, page 163.)
These computers could send/receive network traffic, handle the GUI, read from disk, while the user would have processes for each application and window.
On my mid 1980s Symbolics 3640 I could compile a Lisp application from scratch in a Lisp REPL for half an hour, while I was using Zmacs to edit code. The practical limitations were CPU speed, memory size, disk speed and the Garbage collector. A full GC would halt everything else. Better incremental GCs helped a lot.
In GNU Emacs last I tried I could not use two IELM repls executing Lisp code at the same time. One would block the rest of GNU Emacs Lisp code.
Examples:
Lexical binding. SCHEME in 1975, Common Lisp in 1984. GNU Emacs in 2012.
Native compiled code. LISP 1 got that in 1960. There are now native compiled code builds of GNU Emacs since a few years.
Cooperative threading. Common Lisp had that in the 80s. Other Lisp dialects probably earlier. Now concurrent native threads would be a thing, so that Emacs Lisp too can take advantage of preemptive single and multi-core threading.
It was implemented in Microcode on the CPU.
> Was this multi-threaded-ness something built-in in hardware?
Some. The process scheduler was written in Lisp. See for an early example on the MIT Lisp Machine: https://github.com/mietek/mit-cadr-system-software/blob/mast...
On my old Lisp Machine, Zmacs ran in a multi-threaded Lisp roughly in the early 80s. Multiple Zmacs windows each had their own thread. Applications had their own thread. GC has its own threads. Even the mouse has its own thread. It still works that way.
But you don't need a Lisp Machine OS with threaded Lisp for that. Many current implementations of Lisp support multi-threading. An example is SBCL, a natively compiled Common Lisp, which supports native threads on its platforms. Thus an editor written on top of SBCL could make use of that. IDEs of LispWorks and Allegro CL are also multi-threaded and they have their own implementations of Emacs, written in Common Lisp.
Compare with GNU Emacs, where Emacs Lisp lacks this feature. Wouldn't you want an mail thread not block the rest of Lisp code? Some Lisp action in the REPL not to block the rest of Lisp code?
Multi-threaded Lisp architectures are more complex. Emacs Lisp tried to be simple. But the stuff written in it long ago was outgrowing the provided simplicity. For a capable extension language it was "good enough" for a long time. For an "application development platform" it's not. Lack of multi-threading in Emacs Lisp and the GNU Emacs architecture is an example.
for example: https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node352.html#...
Built-in, of those above, are mapcar and loop.
Python iteration isn't so much about ranges, I thought. See: https://kinsta.com/blog/iterables-in-python/
Not all. The publications distribution feature was implement in Common Lisp.
> so a lot of Web stuff was done by fringe Internet/computer uber-nerds
That part was actually done by a team from MIT.
LISP I had an incremental compiler. The user calls the compiler with a list of functions or function definitions to compile. It's not compiling dynamic by the system and also does not use information about the running function (call statistics, call argument statistics, ...).
There is no "Just in Time" functionality provided. The developer is responsible to decide what code to compile and when to compile the code. A function needs to be compiled by the developer before it is invoked, otherwise it won't run compiled. In a JIT compiled setting the system decides when to compile the code: either on start or during runtime triggered by the system. The code will be "Just in Time" compiled.
This Wikipedia article explains the difference:
https://en.wikipedia.org/wiki/Dynamic_compilation
"Just-in-time compilation is a form of dynamic compilation."
"Unlike dynamic compilation, as defined above, incremental compilation does not involve further optimisations after the program is first run."
Later Lisp systems may have aspects of JIT compilation. For example some CLOS implementations optimize code (-> method combinations) at runtime, possibly via compilation.