4 ms·
> Until Rust, there's been very close to zero serious competitors for C if I wanted to write a bootloader, OS, or ISR … We've groaned and grumbled about how har
by zeveb 10y ago
> Until Rust, there's been very close to zero serious competitors for C if I wanted to write a bootloader, OS, or ISR … We've groaned and grumbled about how hard it is to parse C/C++ code for decades.
I honestly think that Common Lisp can do this quite well. It was designed to be a high-level language, but it's completely capable of working at the machine level, pleasantly and easily. Unlike C, most of the time one has safety, but one can disable safety when necessary with a simple (declare (safety 0))).
Performance is extremely good with modern compilers, although I don't know how good they would have been back in the old days.
And it makes parsing the language dead simple. Here's the entire reader algorithm: http://clhs.lisp.se/Body/02_b.htm http://clhs.lisp.se/Body/02_b.htm
From what I can tell of Rust, it doesn't look easier to parse than C (but I've not looked deeply); certainly, it's orders of magnitude more difficult to parse than Lisp.
I believe that Standard ML or OCaml could do similar things as well, albeit at the cost of being more difficult to parse. Smalltalk is maybe a little less capable, but somewhat easier to parse.
They've all been around for decades.
- wyldfire 10y ago> I honestly think that Common Lisp can do this quite well I haven't used any lisp dialects for decades, so I have naive questions: is there really sufficient support from compilers+linkers to write a bootloader in lisp? Do I have to do a lot of bootstrapping in assembly to bring up lisp interpreter before I can execute the lisp code or does the ahead-of-time-build result in executable machine code? Can I do inline assembly (not required but a really key benefit IMO)? Are there numerous examples where someone's already written one in lisp?
- sanxiyn 10y agoFor an example of operating system kernel completely written in Lisp, see https://github.com/froggey/Mezzano https://github.com/froggey/Mezzano
- tjalfi 10y agohttps://github.com/dym/movitz https://github.com/dym/movitz is a Common Lisp system that runs on bare metal x86. The source code is quite readable. The rest of this post is an excerpt from an email I sent 6 years ago. The following comments on runtime systems are partially based on a long c.l.l thread with posts by Lucid, Symbolics, and Franz alumni. Franz uses a 3-layer approach: CL, a low-level Lisp, and C. Lucid started with Lisp that generated assembler but reluctantly added some C. Symbolics Lisp Machines used bootstrap code in a Pascal-level language with prefix syntax. A Symbolics alum said that in retrospect they should have used C. Most Lisp implementations have subprimitives - low-level functions that can circumvent the type system, often with a prefix such as % or :. Assembly language integration dates to Lisp 1.5 and there are several common approaches. 1. turn the optimizer off - this is easy to use and implement. 2. optimize the assembler block - Naughty Dog GOAL did this. 3. annotate the assembler block with pragmas that indicate side effects. This can be error prone and difficult to use. https://www.pvk.ca/Blog/2014/08/16/how-to-define-new-intrinsics-in-sbcl/ https://www.pvk.ca/Blog/2014/08/16/how-to-define-new-intrins... is an example of this approach. Edited to add the SBCL intrinsic link.
- kazinator 10y ago3 sounds like where GCC got its inline asm concept from: annotate the assembly with what are the inputs and output operands with constraints (do they have to be certain kinds of registers), and whether anything has surprising side effects.
- Manishearth 10y agoYes, it's harder than lisp, but it's still much easier than C. C and C++ have issues due to ambiguities that make them context-sensitive. C++ has it worse because parsing is dependent on typechecking because of templates. Rust is not 100% context-free, but the feature that is non-context-free (raw strings, a rarely used feature) is still pretty easy to parse, and even if you capped it at 6-level raw strings you'd probably be able to parse all the Rust code out there.