PicoLisp
picolisp.com
picolisp.com
From a quick look I think that two of the files (the big ones) are mutually exclusive, so it may really be closer to about 1000 lines of x86_64 assembly to get it minimally working.
I have been a heavy Lisp user since the the late 1970s and I don’t recall seeing this before.
That said, picolisp is cool. I just installed it in 10 seconds. BTW, it does not include a read line clone, so alias picolisp to wrap it in wlwrap.
However, the docs are short and do sort of assume you'll pick up lots of shorthand quickly.
I used Picolisp by Example [0], and Picolisp Works [1] extensively when I was learning. Both were released under the GNU Free Documentation Licence.
The post shows an example where code calls into shared-object files from picolisp.
Something I have been wondering: why are the inspection options so weak for SO files? I expect you should be able to introspect a SO. In response, you would receive function and struct documentation, and clear type information about functions.
Relevant stack overflow question, https://unix.stackexchange.com/questions/61940/introspection.... "For C-type functions, you'll only get function names, not argument types or return values. For C++ functions, you'll get mangled names - pipe the output of that command through c++filt to get function names and argument types (still no return values though)."
You could change Elf to fix it. An alternative, the compiler could do it. Gcc could run an early preprocessor round to pick up metadata and type information. It would freeze this metadata to blobs in the code area. Through this, you could have a standard set of introspection methods built with that compiler.
I have been programming on Windows recently. In some situations, in order to build against a DLL you need need an accompanying "lib" file. If you do not have one, you can perform a circus to create one from the DLL.
What have I missed?
Which is why some systems have tried to add their own layer of extra metadata, such as Windows COM and GTK's gobject(introspection). I don't know how these systems store their metadata, but ELF at least is flexible enough that you should be able to store your metadata in extra sections of the SO.
However, (and I'm just speculating here, hopefully more informed people will correct me) there's also a risk that part of the tool ecosystem doesn't know what to do with the in-ELF metadata and accidentally removes it: "strip" comes to mind, the tool that removes extra symbols and debugging information from binaries and libraries.
Window executable and dynamic libraries are very flexible and always allowed for resource and metadata sections.
COM uses type libraries, which have been replaced by .NET Metadata on UWP (basically COM Runtime reborn, .NET genesis).
And yeah, seems like strip is one of the reasons why they don't store it in the ELF. But also: cross-platform compatibility (GTK does support Windows and macOS).
Re:> In some situations, in order to build against a DLL you need need an accompanying "lib" file. If you do not have one
.lib files are not required to use a DLL. A DLL is opened with LoadLibrary and symbols can be resolved with GetProcAddress. Those import .lib files are just some quirk of Microsoft Visual C.
Also it was how Symbian and Aix did dynamic loading as well (Aix eventually adopted other UNIXes model).
On many modern unixes you can! Functions will usually be in a "text" section (marked execute or read+execute) and data will usually be in a "data" or "bss" section (marked read-only, or read-write).
The dl* family of functions don't expose this information, but after getting a symbol you can check the protection bits on the page the pointer is on (using a system-defined mechanism).
(Although despite planning to use it for some personal project I haven't got around to it yet...)
It parses C/C++/Objective-C into JSON metadata. It uses clang/LLVM so the parsing/etc should be very accurate.
So, to implement your idea, you could just embed this JSON into an ELF section. (Or, if you don't like JSON, convert your JSON to some other format, such as S-expressions or protobuf or whatever.)
https://www.thestrangeloop.com/2014/liberating-the-smalltalk...
https://slideslive.com/38902419/adding-runtime-type-informat...
The incomplete information in header files isn't the compiler command line options, but the nuances of the API semantics. Like if a structure is passed and the structure contains pointers. Who owns the structure and must free it? Who owns the pointers inside it? Oooh, here is a functional argument: what parts of the API can be safely invoked from that callback? That size argument, is that bytes or array elements? And so on.
I was referring to the header file. Unfortunately, with C/C++ you need compile options to fully interpret source code.
> The incomplete information in header files isn't the compiler command line options, but the nuances of the API semantics.
No doubt there's much more to API semantics than basic type information. But the latter is still valuable.
Another poster highlighted Stephen Kell's work, and this is exactly what I had in mind. He highlights obstacles with mmap in one video. I did not recognise these issues until I had watched his presentation, but now see that they are difficult hurdles that are inherent to the problem.
Discloure: I am a DBA. And a Lisp addict.
The database tutorial: https://software-lab.de/doc/tut.html#db
EDIT: This not supposed to be a reply.
I stick with that is available in centos+EPEL, which includes sbcl, and use ODBC for most of my work.
The common tooling for open source databases is varied. A lot of what makes mariadb and postgresql happen is c, shell scripts and perl. A lot of 3rd party tools are still php.
pgloader is a common lisp tool, and very useful.
Both look like a lot of fun.
https://news.ycombinator.com/item?id=12363608
I think Clojure has much tighter Java interop, which you might like or loathe.
#;1> (define (make-counter)
(let ((i 0))
(lambda () (set! i (+ i 1)) i))))
#;2> (define counter (make-counter))
#;3> (counter)
1
#;4> (counter)
2
#;5> (counter)
3
To this PicoLisp one: ? (de make-counter ()
(let (i 0)
'(() (setq i (+ i 1)) i)))
-> make-counter
? (setq counter (make-counter))
-> (NIL (setq i (+ i 1)) i)
? (counter)
-> NIL
? (setq i 10)
-> 10
? (counter)
-> 11
Using `curry` and patterns, you can do substitutions into a "lambda", which
can look like a closure, or not: ? (de make-adder (@base)
(curry (@base) (n) (+ @base n)))
-> make-adder
? (setq add-three (make-adder 3))
-> ((n) (+ 3 n))
? (add-three 5)
-> 8
? (de make-counter ()
(let (@i 0)
(curry (@i) () (setq @i (+ @i 1)) @i)))
-> make-counter
? (setq counter (make-counter))
-> (NIL (setq 0 (+ 0 1)) 0)
? (counter)
!? (setq 0 (+ 0 1))
0 -- Variable expected ; oops, we're trying to redefine 0The Ersatz version has good Java integration. The 64-bit version has some more recent Java integration:
However, nowadays, I think Erzats PicoLisp, AKA the Java version of PicoLisp, gots too little love. It's an interesting way of accessing the JVM, just like Groovy or Clojure. Also, I don't have benchmarks, but PicoLisp is pretty damn fast owing to minimal datastructures and I would expect that to spill over into the Java implementation.
The 64 bit version however, I'm currently trying to get working on macOS. The 'normal' 64 bit version won't compile as it targets x86_64 ASM, in a GNU as dialect. MacOS, even using gcc appears to use clang as, I haven't found a GNU as which supports mach-O. There is an 'emulated' 64 bit version which I've been working to get running with Alex, but it currently seems to be hanging indefinitely on some of the unit tests and I haven't yet had the time to establish which bit.
Note: video is 1h long, so, you may wish to fast forward :-)
> PilMCU is an implementation of 64-bit PicoLisp directly in hardware. A truly minimalistic system. PicoLisp is both the machine language and the operating system:
>* Memory management is trivial, just the Lisp heap and the stack
>* The built-in database is extended to hold a "file system"
>* One SSD per database file for mass storage
>* "Processes" run as tasks and coroutines
>* Events (timing and interrupts) via a 'wait' instruction
>* Complex I/O protocols are delegated to peripheral chips
> The final hardware can be very lightweight. Low transistor count and power consumption. No overhead for an OS. It is conceivable for a later stage to put many interconnected CPUs on a single chip.
> At present, we have it running in the Verilog simulator, and in an emulator (adaption of the PicoLisp 'emu' architecture).
So, what's the state of affairs for 2018?
see: https://www.mail-archive.com/picolisp@software-lab.de/msg073...
beginning of the most recent thread I can find: https://www.mail-archive.com/picolisp@software-lab.de/msg073...
announcement of video I linked: https://www.mail-archive.com/picolisp@software-lab.de/msg073...