Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
PicoLisp Tutorials (picolisp-explored.com)
98 points by damir on Aug 4, 2023 | hide | past | favorite | 31 comments


A slight nitpick, but I like how we went from Scheme's "define" over the classic "defun", through Clojure's "defn" and Bel's "def" to PicoLisp's "de". Looking forward to seeing the next S-expression language defining functions with "d".


nitpick : picolisp is from 1988


Yeah, the list isn't in chronological order (I believe "defun" was standardised years before the algorithmic programming language Scheme was conceived), it's more about the d-evolution.


I love(d) PicoLisp. I have run Windows, Linux (many flavors on many machines), and MacOS, but my working OS is Windows, and I could not get the x64 PicoLisp running on Windows back then without using Cygwin or MinGW. I can run it on WSL[1], however, it still requires a POSIX environment. Is there a way to compile a Windows binary without the POSIX required for a working PicoLisp environment?

I know it switched to an LLVM-IR base, but I don't know enough about the POSIX dependencies and creating a Windows binary.

I love PicoLisp's succinctness (I program in J and APL, learning BQN), practicality with a Prolog and built-in database. It has certainly been around for a while like me; I've been programming since 1978.

[Edit/Add] I really liked Shen[2], a Lisp built on Kλ, a small Lisp of 46 or so functions, which allows Shen to be ported to many platforms and other languages. Shen also has a Prolog, pattern matching, optional lazy evaluation and static type checking, and more. For me, it is between Shen and PicoLisp to displace my use of SBCL.

  [1]  https://picolisp.com/wiki/?WSL

  [2]  https://shenlanguage.org/index.html


Wouldn’t surprise me if it could be made to work in Justines “APE”. I ported PicoLisp to Windows many years ago by removing some POSIX stuff, don’t remember what exactly. But that was when it was written i C and 32 bit.

I think it’s more of an effort missing to port it, the core is extremely small.


Modern picolisp written on raw llvm-ir.


Nice collection of tutorials! My only gripe about picolisp is that it really can’t run on macOS, but that is only a tiny inconvenience.


Edit: it works on MacOS!


Thanks!


The problem with Lisp is that there are different dialects, and if you program in more than one, you need to be aware of the differences between them. It would be nice to be able to switch between them on different projects without being caught out by their differences before getting used to the other dialect, or having to context-switch. It would also be nice to port programs from one dialect to another without major editing. But Picolisp is another dialect, which on the surface is quite different from Common Lisp and Scheme/Racket and, I assume, Clojure. If you want to keep your Lisp implementation small, why not just implement a subset of Common Lisp, or build/use a Scheme variant?


Lisp is a family of languages, not any single one. There's (thankfully, lisps needs innovation like everything else) room for different types.

In the C family for example, you have both C and Javascript.

> It would also be nice to port programs from one dialect to another without major editing

If the languages are the same, they wouldn't be different dialects, they would be the same language, so porting them doesn't make much sense. I think the closest thing to what you're describing is Clojure, where you can swap the targeted environment (JVM if you're working on a server, babashka if you're making a script, javascript if it's a web app, dart/flutter if you're making mobile apps, etc...)


C and Javascript are very different languages with similar syntax. Common Lisp and Picolisp are very similar languages/dialects with different syntax/function names. Common Lisp based its syntax on Maclisp so that Maclisp code could run without much alteration on common Lisp systems.


> C and Javascript are very different languages with similar syntax

I don't know specifically about Picolisp, but many lisps are as different between themselves as C and Javascript are.

For example, Scheme is a functional language, while Common Lisp is multi-paradigm

One has only lexically scoped variables, the other has also dynamically scoped variables.

They have two completely different macro systems (hygienic vs non-hygienic).

One has continuations, the other doesn't.

These are just the few that come to my mind right now. Those are not trivial difference, they completely change the way you reason about you program, and what you can do with it.


Scheme is not functional per se.

Scheme the language supports multiple programming paradigms.

The culture pushes people towards functional programs, but having mutation available has always been part of Scheme.

Most Scheme implementations also offer some sort of object oriented solution.


I first read “suffer from some sort of object oriented solution”.


Scheme exists in various forms and standards. There are small educational definitions and implementations which provide most SRFIs and thus have all features of CL and more. https://srfi.schemers.org

At its core Scheme is procedural, imperation and functional. Common Lisp is also "object-oriented" in its core.


> In the C family for example, you have both C and Javascript.

There is no reasonable sense in which JavaScript is in the “C family”. It's not really even in the broader Algol family that C is in, being most closely related to Self and Scheme (the latter being in the Lisp family.)


I just took a random example from the wikipedia page of C languages:

https://en.wikipedia.org/wiki/List_of_C-family_programming_l...

I don't think that takes away from my point, in each family of programming languages you can find very different ones and lisp is not a language but a family of languages.

Besides using S-expressions, I don't know what else you would need to be considered a Lisp.


If you know C, you don't need to learn a new syntax if you learn C++, Java, C#, or Javascript, except where their semantics is different from C. In those languages, this was a good design choice, which encouraged people to adopt those languages.


A language syntax is quite a bit more than { }.


C family here refers to syntax style. In this case the general use of curly braces to denote blocks and often semicolons to denote end of statements. Another example of such a family would be the ML language family with languages like Haskell and F Sharp.


Is Haskell in ML family? I know Fsharp and Ocaml are but Haskell seems to be very different from them synctically with the only similarity being that it is functional


"port programs from one dialect to another without major editing" isn't the same as "the languages are the same", so why did you parse it that way?


This only sounds like a 'problem' because the lisp dialects are so similar that you would almost expect them to be the same, no?

That seems like a nice feature - you know Common Lisp so you have to only learn some nuances to write PicoLisp effectively.

When it comes to the c-family of languages, you wouldn't expect a complaint about having to be aware of the differences between C and JavaScript since you can't even entertain the idea that they are all that similar.


I have my own libs that equalize lisps/schemes for everything I use it for. That really wasn't that much work. I don't work with clojure because I insist on s-expressions all the way, so I cannot speak of that.


The problem is vocabulary.

There's no mistake that there's a lineage from, say, C to JavaScript. Nor the lineage along the line of S-expression languages.

But when folks speak of JavaScript, or Java, they never refer to them as "C" or "a C". But when something is written in a S-expression language, suddenly it's all Lisp.

"3D graphics is Lisp!" is the headline, then you learn it's some S-expr language that is not Common Lisp.

Common Lisp is a Thing, much like C is a Thing. There are several implementations that call consider themselves compatible with Common Lisp. It has the closest ties and heritage to Lisp 1.5 ("the" Lisp).

Scheme is a thing. When it comes to the "family of languages" idea, Scheme is most certainly practiced that way. There are a LOT of Schemes out there, all with various levels of compatibility and conformance to the assorted Revised Standard documents, but at the same time they all solve different problems.

At a time there were several Lisps, but they were all essentially merged into Common Lisp. Now, we have "one" Lisp, and Scheme. Scheme forked off down its own branch, making conscious decisions to differ from the Lisps of the day. It's fair to point out that two Lisps survived that time, the other being Emacs Lisp.

Then there's things like Clojure, AutoLisp, or even this PicoLisp which are S-expr based languages, but that's about where the similarity ends. They're as much the same as Java and C, and probably not even that close to be honest.

I ported some simple C to Java. It was a fairly trivial mechanical conversion, but 80% of the code just drag and dropped across. But I would never call Java a C or vice a versa.

Pascal is not an Algol, despite the heritage. "Structured programming language" is the vernacular. All of them are that: Algol, Pascal, C, Common Lisp, Schema, Java. But, of course, we don't disuss the s-expr languages in those terms, even though they are, indeed, supportive of "structured programming".

When I see "Lisp" I think Common Lisp. Lisp == Common Lisp, Scheme == (one of the) Scheme, Emacs == Emacs Lisp (we almost never hear of someone doing XXX in "Emacs Lisp", it's almost always just "Emacs"). That's how I divide up the world.

PicoLisp is as much a Lisp as Java is a C.


I was briefly excited that this was Lisp for the Raspberry Pi Pico, but it is not.


I guess that's microlisp: http://www.ulisp.com/show?3M



> Dual-core Arm Cortex M0+ processor, flexible clock running up to 133 MHz

> 264kB of SRAM, and 2MB of on-board flash memory

I wonder if my lisp can run on that... It targets freestanding Linux environments and is able to manage statically allocated memory all by itself. The hash table of system calls alone took up about 200 kB of memory last time I measured it but if I replaced those tables with direct hardware integration...


It would easily fit, though.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: