HNHacker News
TopNewBestAskShowJobs

lispm

1 karma · joined February 12, 2025

submissionscomments
lispm··on Steve Jobs, NeXTSTEP, and early object-oriented programming (2016)
Thanks, Mikel, for the explanations!
lispm··on Steve Jobs, NeXTSTEP, and early object-oriented programming (2016)
The MCL kernel was written in C.
lispm··on Steve Jobs, NeXTSTEP, and early object-oriented programming (2016)
> UI development?

The interface builder was written in Dylan and running inside the Dylan runtime.

The early use of Dylan (actually its precursor language Ralph) was to develop software on a Mac for an external device, like tablets and handheld computers. The development system was an external mainboard attached to a Mac. Apple released eventually a first device with ARM 610 20Mhz CPU, 640Kb RAM and 4MB ROM as a product. A few of the early internal development environments were written in Lisp on the Mac, using a lot of memory (precious and expensive megabytes!).

> Apple Dylan environment

That was a prototype of the Apple Dylan environment, later released as a technical preview. It was also never a product. Apple at that time often developed software prototypes and the released product was then recoded as a more efficient tool. The technical preview was for the Mac and for develop software for the Mac.

lispm··on Steve Jobs, NeXTSTEP, and early object-oriented programming (2016)
> The platform which Dylan was originally designed for, the Newton had no C to begin with.

These platforms had no development tools. The firmware and software runtimes were created outside. I would guess that there definitely C was involved for much of the firmware and that an on device Dylan runtime had C and assembler code.

lispm··on Steve Jobs, NeXTSTEP, and early object-oriented programming (2016)
The teams he assembled and worked with had a crazy impact on programmers, software development, computer platforms and end users. Even when he way not a developer himself, he looked for very bright people in software development to make it possible to develop new computer platforms. Home computers, early graphical workstations, desktop publishing, UNIX workstation for students, next generation operating systems for personal computers, ...
lispm··on M4 Mac mini's efficiency
why not? Having the specs and benchmark results for both CPUs in a table gives a good overview.

What advantage would it bring to manually write such comparison tables?

lispm··on M4 Mac mini's efficiency
https://nanoreview.net/en/cpu-compare/apple-m4-vs-amd-ryzen-...
lispm··on Show HN: Term-Lisp – A Lisp, based on pattern matching and term rewriting
I would think that's still the case.
lispm··on State of Python 3.13 performance: Free-threading
> CL has a very similar degree of dynamism and remains fast.

But not the dynamic parts remain "really" fast. Common Lisp introduced very early a lot of features to support optimizing compilers -> some of those reduce "dynamism". Code inlining (-> inline declarations), file compiler semantics, type declarations, optimization qualities (speed, compilation-speed, space, safety, debug, ...), stack allocation, tail call optimization, type inferencing, ...

lispm··on Alonzo Church: Architect of computer intelligence
probably there were no such machine-level instructions, but assembler macros

https://en.wikipedia.org/wiki/CAR_and_CDR

lispm··on Alonzo Church: Architect of computer intelligence
"usually" probably means at the time of writing this book. lambda, car and cdr are from the 50s/60s when short names were preferred for various reasons (small memory, input on cards, output on paper, small screens, ...).
lispm··on Weird Lexical Syntax
Reader macros are there to program and configure the reader. The reader is responsible for reading s-expressions into internal data structures. There are basically two main uses of reader-macros: data structures and reader control.

A CL implementation will implement reading lists, symbols, numbers, arrays, strings, structures, characters, pathnames, ... via reader macros. Additionally the reader implements various forms of control operations: conditional reading, reading and evaluation, circular datastructures, quoting and comments.

This is user programmable&configurable. Most uses will be in the two above categories: data structure syntax and control. For example we could add a syntax for hash tables to s-expressions. An example for a control extension would be to add support for named readtables. For example a Common Lisp implementation could add a readtable for reading s-expressions from Scheme, which has a slightly different syntax.

Reader macros were optimized for implementing s-expressions, thus the mechanism isn't that convenient as a lexer/parser for actual programming languages. It's a a bit painful to do so, but possible.

A typical reader macro usage, beyond the usage described above, is one which implements a different token or expression syntax. For example there are reader macros which parse infix expressions. This might be useful in Lisp code where arithmetic expressions can be written in a more conventional infix syntax. The infix reader macro would convert infix expressions into prefix data.

lispm··on Weird Lexical Syntax
Is Pyret based on reader macros? I would think it's much easier to use a syntax parser for that.
lispm··on Apple's M4 Max chip is the fastest single-core performer in consumer computing
Far enough. I had a Symbolics Lisp Machine on a NuBus card, the MacIvory. Actually I still have it, in a Quadra 950.
lispm··on Apple's M4 Max chip is the fastest single-core performer in consumer computing
It was wild to see the still ongoing overclocking Ghz competition, while suddenly one could use a laptop with good performance, no fans, no noise and while using it mobile.
lispm··on Apple's M4 Max chip is the fastest single-core performer in consumer computing
I have the M4 iPad with the new OLED. That screen would be great in a Macbook Air.
lispm··on Apple's M4 Max chip is the fastest single-core performer in consumer computing
The Nubus in the IIx was great.
lispm··on Asterinas: OS kernel written in Rust and providing Linux-compatible ABI
> many people in the Lisp world were unhappy because Common Lisp didn't have this or that from whatever they were working on, and because CL was standard they would have to use it.

There were many unhappy, but from very different camps. Some were unhappy (for example people in the small Standard Lisp camp) because Common Lisp was not dynamic enough (it has features of static compilation, no fexprs, ...). Others were unhappy because it was too dynamic and difficult to compile to efficient code on small machines with stock CPUs. Some complained that it was too large and hard to fit onto some of the tiny machines of that time. Others complained that it was too small and lacked critical features from larger Lisp implementations (like stack groups, threads, a fully integrated object system, the first version had no useful error handling, gui functionality, extensible streams, ...).

Many more users/implementors from other Lisp dialects were unhappy, because it was clear that their favorite Lisp dialect would slowly fade away - funding was going away, new users would avoid it, existing users would port their code away, ...

> This is why math functions are not generic for instance

The math functions are generic (they work for several types). But there was no machinery behind that specified. They were not generic in the sense of CLOS generic functions (or similar). Also because with CLtL1 there was no such machinery in the language, but there are (non-extensible) generic numeric functions. CLOS later added a machinery for generic functions, but there was no experience to create optimized&fast code for it. The way of a CLtL1 Lisp implementation for fast numeric functions was to specify types and let a compiler generate type specific (non-generic) code. ANSI CL left the language in that state: the generic numeric functions were not implemented by CLOS, similar to so much in the language specification avoids further integration of CLOS and leaves it to implementations to decide how to implement them: I/O, condition handling, ...

> I have no idea why ANSI CL has such a large page count.

It was supposed to be a language specification for industrial users with detailed infos. There were standard templates how to specify a function, macro, ...

The Scheme reports OTOH were made to have the smallest page count possible with 2 columns of text, leaving out much of the detail of a real language spec. Why? Because it was material for a teaching language and thus was supposed to be read by students learning the language in a semester course at the university. Thus R5RS specified a teaching language, just barely, not as a full application programming language (for example it has zero error handling and basic things were just barely specified in its behavior and implementation).

lispm··on Asterinas: OS kernel written in Rust and providing Linux-compatible ABI
> Common Lisp is an amalgamation of every lisp they could find, they slammed it all in.

Not really. It's mostly a modernized version of Zetalisp. In many cases simpler as that, with some added new stuff (like type declarations).

lispm··on Using Rust in non-Rust servers to improve performance
> The most popular lisp dialects are linked list based (Common Lisp, scheme, guix I think as well)

You may want to check the Common Lisp standard (a dialect, where its development goes back to 1982).

https://www.lispworks.com/documentation/HyperSpec/Front/Cont...

From the table of contents you can see that the language spec prominently describes: CLOS objects, structures (records), condition objects (-> errors), symbols, packages (namespaces for symbols), multi-dimensional arrays, strings, hash tables, files, streams, ...

None of these standard data structures are linked list based.

For example when I write a Lisp form do define a structure, a record-like data structure:

    (defstruct packet
      sender
      receiver
      header
      payload)
then the SOURCE is an s-expression, a linked list.

DEFSTRUCT is a macro, which defines a record data structure and a bunch of functions for it (accessors, getters, creater, type predicate, ...).

The Lisp compiler will expand the macro form into a much larger s-expression -> again a nested list.

The compiler will then process lists and a lot of other data structures (see above) and create MACHINE CODE for code defined by above record definition.

Structures themselves are by default VECTOR-like objects, with static access into its components. A getter will access the fixed offset into a record and the code for that will usually be inlined in the using code.

So we have two aspects:

* processing with linked lists on current CPUs is several orders of magnitude faster, than on the machines where Lisp was originally defined. It does not matter for most use cases on modern machines. For example any Apple Silicon is great for running Lisp.

* Lisp offers many other data structures, which are widely used in Lisp applications.

For example if I would need a bit vector, I would not use a linked list of numbers, but a real bitvector:

    CL-USER 1 > (describe #*0000010010000011000000000)

    #*0000010010000011000000000 is a (SIMPLE-ARRAY (UNSIGNED-BYTE 1) (25))


    CL-USER 2 > (sbit #*0000010010000011000000000 5)
                  ; get the fifth bit, using zero-based indexing
    1
Here the operations are written as lists, but they operate on real vectors of bits.

The result then is that optimizing Common Lisp compilers can generate code, which is fast enough for many applications.

So is in Common Lisp the linked list the "core data abstraction for your entire language"?

That's misleading. The "entire language" has many more data structures, which are not built on top of linked lists. For example arrays (strings, vectors, bitvectors, multidimensional arrays) are a part of the language, are widely used and are not made of linked lists.

lispm··on A Performance Comparison of Modern Garbage Collectors (2021) [pdf]
> for a programming language used by academia thirty years ago, rather than in one used by profit-oriented organizations for large data systems or games.

I think that's a misconception. Common Lisp was designed as a language for Research & Development (R&D) and deployment of (often complex) applications on a wide variety of hardware.

There were/are a bunch of demanding applications developed, which were/are in commercial use:

* scheduling systems used by train services, airports and airlines

* image processing applications (like analysis of satellite images)

* CAD systems for aircrafts and cars (prominent users were Boeing, Airbus, Ford, ...).

* verification of cpu designs

* databases, typically object-oriented and graph databases

Typically GCs needed to work in interactive systems with very little user interruptions by GCs (incremental GCs) and in long running applications with large data sets.

Generally Lisp has less new commercial users than years ago and Java has many times more commercial users. There has been done a lot of GC progress in the context of JVM garbage-collectors. But it's not that commercial Lisp vendors had no industry users...

Franz Inc, a commercial Common Lisp vendor, has documented its GC:

https://franz.com/support/documentation/gc.html

lispm··on Should JavaScript be split into two languages?
> Nice or not, pretending that double precision floats and arbitrary precision integers can be stacked as a tower is foolish. There are floats that can't be represented as integers, and integers which can't be represented as floats.

The numeric tower in Scheme describes general number types with above of in the tower graphic (in the Wikipedia article) meaning subtype of. double precision floats and arbitrary precision integers are representations of numbers. Both would also be Real numbers.

lispm··on Lingo: A Go micro language framework for building Domain Specific Languages
> I know some people have long used "DSL" in this way, especially among LISP fans

generally this would be called an "embedded domain specific language". Some languages are relatively flexible to change the syntax. For example Common Lisp has reader macros to change the token syntax and macros to change the Lisp syntax. With that one can create all kinds of embedded languages, incl. domain specific languages (languages which are specific to a special domain). Examples would be embedded logic languages, query languages, rule based languages, languages to describe user interfaces, etc. The Common Lisp standard has a notorious example for that, a complex LOOP construct, which uses a very different syntax: https://www.lispworks.com/documentation/HyperSpec/Body/m_loo...

There are other real-world examples out there, for example an embedded domain specific language to describe 3d objects in the domain of parametric CAD, for description of technical things like turbines or other parts of an aircraft.

lispm··on Hofstadter on Lisp (1983)
> I really feel like you are determined to misinterpret

Why post here, when you are not willing to accept feedback from other people? I get that you have trouble learning Lisp, but I have been hearing the same stuff for decades. Nothing what you tell is new. I had to deal with the same arguments 40 years ago and when you read old Lisp books from the mid 60s -> the same song. I've seen some people getting Lisp and others not. For me the question was always how to help people "to get it" - attitudes like your's, giving up early, is typically an early dead end. The mental block is the bigger problem than the actual thing to learn.

"Anyone could learn Lisp in one day, except that if they already knew Fortran, it would take three days.” — Marvin Minsky.

There is truth to that. People who already have an idea how things should work, need to let that go. Unlearn and start from a neutral position.

> international software industry of buggy, leaky, insecure C code that keeps hundreds of thousands of people in work and makes _tens of millions of dollars_ every year.

Yeah, and I have a lot of respect for that. I use software written in C everyday. It does useful stuff, independent how many problems it has.

> Some of them are the kids who couldn't get onto Computing courses but they are pro Java developers.

I work in a company, which has several hundred people developing in Java. In fact the part of the company I work with is responsible for backend work, which connects several million cars. I've met extremely bright people, doing hard work. I'm not going to try selling them Lisp.

> IMHO the Lisp industry and community needs to listen to the people trying to make easier

IMHO "the Lisp industry" does not exist as an entity and has neither the resources nor the interest to do what. Nobody is interested in CGOL, PLOT or Dylan. These were dead end. Nice experiments. I like experiments.

Lisp people worked on Dylan, when the Lisp jobs went away. Dylan went nowhere. As some former Lisp people working on Dylan, some are still thinking its a good idea and others have given up on it. Harlequin had several language offerings: Postscript RIPs, Lisp, ML, Dylan, Memory management. LispWorks survived, when Harlequin went bankrupt, because it had customers with software. Dylan did not survive. It was eventually open sourced and still has not much going on.

The non-existent "Lisp industry" would alienate its core customers. People who want a different tool.

You THINK that there it would be a way, but we have heard for decades these same ideas. The problem is not people who can give advice (I've seen lots of talks & papers about this topic) - the problem is that these people have nothing to offer, they are themselves not involved. Nobody will listen to you, because people in the IT industry get all kinds of advice, but "needs to listen" does not pay the bills.

Clojure exists, because people developed it, had a market niche and it survived. In the same original niches (enterprise consulting for web technology, ...) were and still are a zillion other offerings. Every year new and old ideas come and go.

> Recursion is trivial

Then SICP should be trivial for you, because its content is based on Scheme with lots of recursion.

> IMHO the Lisp industry and community needs to listen to the people trying to make easier, clearer Lisps, such as CGOL and PLOT and Lunar and Dylan, and engage with them, and try to understand why and embrace it, not just continually telling them they are wrong wrong wrong.

You misinterpret the Lisp community. "People are not wrong". It's just that the people in the various Lisp communities focus on their own stuff and that's their right.

I have my garden at home, I'm not responsible to sell stuff to all kinds of other garden owners. That's not my business. I'm happy with my garden.

Actually, languages like Python, Java, JavaScript, Ruby, Exlixir, OCAML, F#, Wolfram language and many others, ... they have already taken most of the Lisp features (typical argument we hear: why use Lisp, when other languages already have its most important features?).

You may not aware of it, but languages with lots of features from Lisp are in wide use already.

lispm··on Hofstadter on Lisp (1983)
Pascal, Fortran, C, ... All these languages use prefix notation for function calls.

Fortran:

    min(size(b), size(a))
Lisp:

    (min (size b) (size a))
lispm··on Hofstadter on Lisp (1983)
Basically no programming language is an infix-only-notation language. Most programming languages are using mixed notation: prefix, infix and possibly postfix. In most languages function calls are prefix. For a subset of functions there are infix operators: a + b, instead of +(a,b). For control flow many programming languages use a more elaborate syntax.

The usual mathematical notation is two-dimensional. Fractions are written a / b and

    a
    -
    b
Also think of square roots and all kinds of other mathematical notation.

When I verbalize a * (b + c) as a natural language expression then it is:

    Multiply a with the sum of b and c.
The operators are prefix.

In German:

    Multipliziere a mit der Summe aus b und c.
in Lisp:

    (* a (+ b c)) 
or

    (* a
       (+ b c))
or

    (* a
       (+ b
          c))
or

    (* a (+ b
            c))
or

         (*

            a

    (+ 

             b
        c)) 
The latter, more random layout, will not be used by Lisp programmers, because it does not follow the usual layout rules. But it is possible, since the layout of the lists is not significant in Lisp.

A pretty printer in Lisp is a function, which takes an expression and writes it in some layout. Thus Lisp can generated 2d-layouts of expressions. Most Lisp-supporting editors can indent or even layout Lisp expressions. This helps Lisp developers using a common layout of code, supported by the tools.

lispm··on The Multics Maclisp Compiler: The Basic Hackery – A Tutorial (1977)
Apple's MCL used the MMU for the stock Motorola 68020+ (M68020 + MMU, 68030/40 with included MMU, ...) processors for an efficient GC: the Ephemeral GC, using a table of changed memory pages, which was maintained by the MMU.

This idea was added by Apple to their first ARM CPUs, to get an efficient GC on tiny devices, running either a Lisp dialect or in the product, the Virtual Machine for NewtonScript.

See for some info on the ARM610 and Garbage Collection: https://wiki.preterhuman.net/A_Call_to_ARM

But today's CPUs are very very different: an example is Apples M2 Ultra SOC. We don't have a Lisp implementation which has an even remote idea how to get "full" performance out of the combination of a larger number of Efficient+Performance cores, many GPU cores, Neural processing Unit + media engine + high-bandwidth unified memory. Most current more advanced Lisp engines make only use of a (not so large) count of multiple CPUs (only a few use multiple cores for the GC), some SIMD features, none (AFAIK) make use of the rest...

lispm··on Hofstadter on Lisp (1983)
> harder to learn than other things

"harder" is relative to a reference. Even "hard" is relative.

The simple nested arithmetic code you stopped at in SICP is easy for most people working as developers. Maths from 5th year school are sufficient. Nested lists, prefix notation isn't "hard" for "most" people.

It's just lightly harder for someone who has never seen that. When they have seen XML or JSON, then it's even easier.

Actually "hard" Lisp code looks and feels different. First "harder" hurdles in Lisp are typically evaluation, recursion, macro expansion, compile-time vs. runtime, meta-notation (code as data), ...

I learned 2 years PASCAL and MODULA 2 on an Apple ][ (and i still think that was fun), before getting in contact with the Lisp alien world. I was hooked in a short time.

lispm··on Medley Loops: The Basic System (Lisp Object-Oriented Programming System) [pdf]
That's discussed in this paper: CommonLoops: merging Lisp and object-oriented programming https://dl.acm.org/doi/pdf/10.1145/28697.28700

CommonLoops was proposed by Xerox to be the OOP system of Common Lisp in the standardization process. It was then decided to design a new system called Common Lisp Object System (CLOS), starting with a merge of the features of New Flavors (MIT/Symbolics) and CommonLoops (Xerox). Xerox implemented CLOS by modifying its CommonLoops implementation, during the standardization process. Thus Portable CommonLoops (PCL) was eventually the prototype CLOS + MOP implementation.

lispm··on Medley Loops: The Basic System (Lisp Object-Oriented Programming System) [pdf]
The answer would depend on what you think "message sending" is and why you think Smalltalk does not support "message sending".
← PreviousPage 3 of 34Next →