Thinking like a C programmer while writing Eiffel: no collection coding

50 views
Skip to first unread message

Finnian Reilly

unread,
Aug 20, 2026, 5:54:32 AM (7 days ago) Aug 20
to Eiffel Users

Hi all,

for the purposes of making the Xpact XML parser compete with the eXpat parser written in C, I have had to think more like a C programmer while writing Eiffel.

It's been an interesting challenge to turn off the garbage collector temporarily during a parse and then discipline myself to create as few new objects as possible, and recycle objects kept in a pool . Turns out I am not the only developer using a GC language who is thinking like that. I came across this interesting video recently.

Trading Firms Run Java Without Ever Letting It Collect

High-frequency trading firms write their hot path in Java — then engineer it so the garbage collector never runs. Here's how zero-allocation Java actually works. In a world where a few milliseconds of GC pause means a missed trade, the fastest firms on earth didn't make Java's garbage collector faster. They starved it. This is a breakdown of the low-latency techniques that let HFT systems run Java in the hot path without ever pausing to collect: object pooling, off-heap memory, the old sun.misc.Unsafe path (now the Foreign Function & Memory API and MemorySegment), and pre-market JIT warmup. It's also an honest look at what that costs — not in hardware, but in the rare engineers who can hold the whole fragile machine in their heads. This is mechanical sympathy taken to its most extreme conclusion, and a clear argument for why almost nobody should copy it.


-- 
SmartDevelopersUseUnderScoresInTheirIdentifiersBecause_it_is_much_easier_to_read
(Eiffel = Security by Contract + C Speed)

Eric Bezault

unread,
Aug 20, 2026, 7:01:20 AM (7 days ago) Aug 20
to eiffel...@googlegroups.com
Note that the Gobo Eiffel compiler is also designed so that
it can be run without the GC.

--
Eric Bezault <er...@gobosoft.com>
Eiffel expert - available for freelance work
https://www.gobosoft.com


On 20/08/2026 11:54, Finnian Reilly wrote:
> Hi all,
>
> for the purposes of making the Xpact XML parser compete with the eXpat
> parser written in C, I have had to think more like a C programmer while
> writing Eiffel.
>
> It's been an interesting challenge to turn off the garbage collector
> temporarily during a parse and then discipline myself to create as few
> new objects as possible, and recycle objects kept in a pool . Turns out
> I am not the only developer using a GC language who is thinking like
> that. I came across this interesting video recently.
>
> Trading Firms Run Java Without Ever Letting It Collect <https://
> www.youtube.com/watch?v=goQgk3iE4jw>
>
>> High-frequency trading firms write their hot path in Java — then
>> engineer it so the garbage collector never runs. Here's how zero-
>> allocation Java actually works. In a world where a few milliseconds of
>> GC pause means a missed trade, the fastest firms on earth didn't make
>> Java's garbage collector faster. They starved it. This is a breakdown
>> of the low-latency techniques that let HFT systems run Java in the hot
>> path without ever pausing to collect: object pooling, off-heap memory,
>> the old sun.misc.Unsafe path (now the Foreign Function & Memory API
>> and MemorySegment), and pre-market JIT warmup. It's also an honest
>> look at what that costs — not in hardware, but in the rare engineers
>> who can hold the whole fragile machine in their heads. This is
>> mechanical sympathy taken to its most extreme conclusion, and a clear
>> argument for why almost nobody should copy it.
>
>
> --
> SmartDevelopersUseUnderScoresInTheirIdentifiersBecause_it_is_much_easier_to_read
> (Eiffel = Security by Contract + C Speed)
>
> --
> You received this message because you are subscribed to the Google
> Groups "Eiffel Users" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to eiffel-users...@googlegroups.com <mailto:eiffel-
> users+un...@googlegroups.com>.
> To view this discussion visit https://groups.google.com/d/msgid/eiffel-
> users/366a043c-dc76-479e-a94a-e530c140071d%40eiffel-loop.com <https://
> groups.google.com/d/msgid/eiffel-users/366a043c-dc76-479e-a94a-
> e530c140071d%40eiffel-loop.com?utm_medium=email&utm_source=footer>.



Eric Bezault

unread,
Aug 20, 2026, 7:12:00 AM (7 days ago) Aug 20
to Eiffel Users
Here is some documentation explaining the design used in
gec/gelint to be able to run faster with no GC:

https://gobo-eiffel.github.io/gobo/tool/gelint/doc/technology.html

--
Eric Bezault <er...@gobosoft.com>
Eiffel expert - available for freelance work
https://www.gobosoft.com


> an email to eiffel-users...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/eiffel-
> users/bae9964d-2940-4bab-9abf-e5340b7dcb82%40gobosoft.com.


Finnian Reilly

unread,
Aug 20, 2026, 12:06:56 PM (7 days ago) Aug 20
to eiffel...@googlegroups.com
That sounds very interesting and worthwhile trying out. For maintaining Eiffel-loop I have one monolithic test project that has a reference to every class. I have many lines like this to include everything. Have everything compiled is useful for pan-library scale refactoring.

	date_time: TUPLE [
		EL_DATE, EL_DATEABLE,
		EL_QUANTITY_INCREASE_RATE_CALCULATOR
	]
		do
			create Result
		end

	initialization: TUPLE [
		EL_MAKEABLE_TO_SIZE_FACTORY [EL_MAKEABLE_TO_SIZE]
	]
		do
			create Result
		end

But with gelint I could perhaps also test classes that are not compilation targets on the current platform.


    
Here is some documentation explaining the design used in
gec/gelint to be able to run faster with no GC:

https://gobo-eiffel.github.io/gobo/tool/gelint/doc/technology.html


-- 
SmartDevelopersUseUnderScoresInTheirIdentifiersBecause_it_is_much_easier_to_read
(Eiffel = Security by Contract + C Speed)

Eric Bezault

unread,
Aug 20, 2026, 12:49:40 PM (7 days ago) Aug 20
to eiffel...@googlegroups.com
If you want to compile all your classes without using gelint, just put
that line in your ECF file:

<root all_classes="true"/>

For the Gobo project, I also have an ECF file which points to all
Gobo Eiffel libraries:

https://github.com/gobo-eiffel/gobo/blob/master/library/common/config/ecf/integration.ecf

with different targets depending on the compilation mode I want to
test (e.g. SCOOP, no thread, etc.). This is this ECF file that I
use with gelint because I know that all classes included in the
Gobo package are reachable from it.

--
Eric Bezault <er...@gobosoft.com>
Eiffel expert - available for freelance work
https://www.gobosoft.com


> --
> You received this message because you are subscribed to the Google
> Groups "Eiffel Users" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to eiffel-users...@googlegroups.com <mailto:eiffel-
> users+un...@googlegroups.com>.
> To view this discussion visit https://groups.google.com/d/msgid/eiffel-
> users/130008a3-2116-4ac1-91a8-3aa92a63dee1%40eiffel-loop.com <https://
> groups.google.com/d/msgid/eiffel-
> users/130008a3-2116-4ac1-91a8-3aa92a63dee1%40eiffel-loop.com?
> utm_medium=email&utm_source=footer>.



Ulrich Windl

unread,
Aug 20, 2026, 1:08:28 PM (7 days ago) Aug 20
to eiffel...@googlegroups.com
Ideally I would expect that the compiler or runtime does this kind of optimization. Doing low-level programming using a high-level language seems strange to me.

Eric Bezault

unread,
Aug 20, 2026, 3:57:18 PM (6 days ago) Aug 20
to eiffel...@googlegroups.com
The compiler can do low-level optimizations, and it does. But sometimes
high-level design decisions may also help to optimize the program. For
example some trade-offs about speed and/or memory usage can be made by
those who design the program based on its specification. Depending on
the expected input, it might be better to use a linked-list or an
arrayed-list, to use a quick sort or a bubble sort, etc. A human or
an AI may have enough information in the specification and context to
decide which one to use to get the most optimized program. I'm not sure
that a compiler will be able to decide whether a linked-list usage
should be replaced with an arrayed-list implementation, or vice versa,
in the generated binary because it thinks that the resulting program
will be more optimized.

In my opinion, making the decision to design the program in such a way
that it can fit its entire representation of a possibly huge input in
memory instead of caching it on disk should not necessarily be seen as
low-level programming. Realizing that in doing so, almost no "garbage"
is created, and with a couple more design decisions (e.g. using the
visitor pattern to avoid to have some temporary objects being created
again and again) that the work of the GC would be useless, why not
unplug it to avoid its overhead (traversing the object graph again
and again as memory usage grows, hoping to find and reclaim garbage
which does not exist). I can imagine an AI fed with a well defined
specification figure that out. I have more difficulties to imagine
a compiler being able to figure out that it could perform such huge
redesign on the fly to optimize the generated binary. So even if the
optimizations might look low-level programming, the design decisions
to make these optimizations possible are high-level programming. It
would require much more efforts to implement such design in a low-level
language like C than it took to do so using a high-level language
like Eiffel.

--
Eric Bezault <er...@gobosoft.com>
Eiffel expert - available for freelance work
https://www.gobosoft.com


Ian Joyner

unread,
Aug 20, 2026, 5:04:32 PM (6 days ago) Aug 20
to eiffel...@googlegroups.com
Hello Finnian,

Be interesting to know what you think thinking like a C programmer actually is?

To me it invokes Alan Kay’s comment (which I took straight from the OOPSLA talk he gave (1997?)

“This is the most pernicious thing about C++ and Java in that they think they’re helping the programmer by looking as much like the old thing as possible but in fact they’re hurting the programmer terribly by making it difficult for the programmer to understand what is really powerful about this new metaphor.”

Ian

Sent from my iPad

On 20 Aug 2026, at 9:54 pm, Finnian Reilly <fin...@eiffel-loop.com> wrote:


--
You received this message because you are subscribed to the Google Groups "Eiffel Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to eiffel-users...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/eiffel-users/366a043c-dc76-479e-a94a-e530c140071d%40eiffel-loop.com.

Finnian Reilly

unread,
Aug 21, 2026, 2:50:19 AM (6 days ago) Aug 21
to eiffel...@googlegroups.com
Hello Finnian,

Be interesting to know what you think thinking like a C programmer actually is?

Hi Ian

in the context of Eiffel thinking like a C programmer means thinking about what the C is doing that is generated by the compiler.

Without going into too much detail  I can give a couple of examples for a hot path:
If I am thinking like an Eiffel programmer I write this:

scan_start_tag_name (buf: SPECIAL [CHARACTER]; start_index, end_index, lead_count: INTEGER): INTEGER
   -- After consuming name-start char(s); scan rest of start tag name.
   local
      index, name_lower, name_upper, byte_count, bt_code, l_last_colon_index: INTEGER; done: BOOLEAN
   do
      index := start_index; name_lower := start_index - lead_count; name_upper := Unset
      from until index >= end_index or done loop
         bt_code := Byte_type_table [buf [index].code]
         inspect bt_code

But if I am thinking like a C programmer I write this

scan_start_tag_name (buf: SPECIAL [CHARACTER]; start_index, end_index, lead_count: INTEGER; bt_table: SPECIAL [INTEGER]): INTEGER
   -- After consuming name-start char(s); scan rest of start tag name.
   local
      index, name_lower, name_upper, byte_count, bt_code, l_last_colon_index: INTEGER; done: BOOLEAN
   do
      index := start_index; name_lower := start_index - lead_count; name_upper := Unset
      from until index >= end_index or done loop
         bt_code := bt_table [buf [index].code]
         inspect bt_code

The latter had greatly improved performance across many such routines

Or a very literal example of  using C data structs in an Eiffel program

   process_content (
      buf: like buffer; start_index, end_index: INTEGER; bt_table: SPECIAL [INTEGER]
      attributes: XT_ATTRIBUTE_BUFFER_INTERVALS; names: like name_cache
      a_context: XT_ELEMENT_CONTEXT; parse_data: POINTER; a_source_type: NATURAL_8
   ): INTEGER

parse_data is a pointer to the data defined by class XT_C_PARSE_DATA_STRUCT (github link). I could have passed the MANAGED_POINTER reference that allocates the memory, but thinking in C terms, I pass a raw pointer instead.

Also as an Eiffel programmer, you would not want to have such a long argument list, you would put some or all of that data in another object.

but for C coder, if it gets you the performance you want, then why not.

Also Eiffel coders might prefer bt_table: ARRAY [INTEGER] but a C coder would  definitely want bt_table: SPECIAL [INTEGER]

regards

Finnian

Finnian Reilly

unread,
Aug 21, 2026, 3:09:07 AM (6 days ago) Aug 21
to eiffel...@googlegroups.com
On 20/08/2026 18:08, Ulrich Windl wrote:
Ideally I would expect that the compiler or runtime does this kind of optimization. Doing low-level programming using a high-level language seems strange to me.

The Xpact XML parser is 98% written at the level of Eiffel, and only 2% at the level of C (using arbitrary figures)

I’m using Eiffel for the things Eiffel is good at:

  • abstraction
  • classes and inheritance
  • Design by Contract
  • type safety
  • genericity
  • readability
  • memory safety
  • rapid development
  • high-level application architecture

I’m deliberately applying low-level performance techniques only to a very narrow hot path where they matter.

That's actually one of the interesting advantages of having a high-level language: I can choose the level of abstraction appropriate to each part of the program.

The alternative isn't necessarily:

Eiffel + GC or C.

It can be:

Mostly high-level Eiffel + a small amount of deliberately low-level Eiffel.

And that's essentially what my experiment demonstrates.

There is also a subtle misconception about what the compiler can do

A compiler cannot generally infer that I should pool objects instead of allocating them.

Suppose I have something conceptually like:

create {SPECIAL [CHARACTER_8]}.make_empty (buffer_size)

The compiler cannot simply decide:

"Ah, this object could be reused from a pool."

because that potentially changes observable program behavior.

The compiler has to preserve the semantics of my program. Object identity, creation procedures, references held elsewhere, invariants, attachment status, etc. can all matter.

Similarly, "don't allocate anything during this operation" is often an architectural decision, not merely an optimization that a compiler can safely discover.

The developer might know:

"These parser objects have a lifetime bounded by this parse and can be recycled."

The compiler generally doesn't have that semantic knowledge.

Ulrich Windl

unread,
Aug 22, 2026, 7:37:35 AM (5 days ago) Aug 22
to eiffel...@googlegroups.com
Hi!

Let me expand on this: In GNU C you can attribute an if whether it's "likely", or not. You can also "profile" program executions. With AI I would expect that an SI could make specific proposals for optimizing code based on profiling data. Maybe a future compiler or IDE can do that even.

Ulrich

Ulrich Windl

unread,
Aug 22, 2026, 7:41:42 AM (5 days ago) Aug 22
to eiffel...@googlegroups.com
Hi!

I think a good programmer can implement an abstract high -level code in efficient low-level machine language. However that's a LOT of work, especially after changes. But what is wrong is assuming that a future compiler can do that also?

Ulrich

Ulrich Windl

unread,
Aug 22, 2026, 7:47:24 AM (5 days ago) Aug 22
to eiffel...@googlegroups.com
Hi!

Isn't using "SPECIAL" instead of ARRAY already thinking like a C programmer? If SPECIAL is like a base class for ARRAY, why can't a compiler actually reduce features of ARRAY to those of special, effectively changing ARRAY to SPECIAL automatically? Or is it that SPECIAL is actually implemented in C?

Ulrich

21.08.2026 08:50:09 Finnian Reilly <fin...@eiffel-loop.com>:
> /parse_data /is a pointer to the data defined by class XT_C_PARSE_DATA_STRUCT[https://github.com/finnianr/Xpact-core/blob/main/library/source/support/xt_c_parse_data_struct.e] (github link). I could have passed the MANAGED_POINTER reference that allocates the memory, but thinking in C terms, I pass a raw pointer instead.
>
> Also as an Eiffel programmer, you would not want to have such a long argument list, you would put some or all of that data in another object.
>
> but for C coder, if it gets you the performance you want, then why not.
>
> Also Eiffel coders might prefer /bt_table: ARRAY [INTEGER]/ but a C coder would  definitely want /bt_table: SPECIAL [INTEGER]/
>
> regards
>
> Finnian
>
> --
> SmartDevelopersUseUnderScoresInTheirIdentifiersBecause_it_is_much_easier_to_read
> (Eiffel = Security by Contract + C Speed)
>
> --
> You received this message because you are subscribed to the Google Groups "Eiffel Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to eiffel-users...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/eiffel-users/07c47122-bf44-4dce-b2fc-dcc8575eeee4%40eiffel-loop.com[https://groups.google.com/d/msgid/eiffel-users/07c47122-bf44-4dce-b2fc-dcc8575eeee4%40eiffel-loop.com?utm_medium=email&utm_source=footer].

Ulrich Windl

unread,
Aug 22, 2026, 7:54:38 AM (5 days ago) Aug 22
to eiffel...@googlegroups.com
Hi!
>
>
> Eiffel + GC *or* C.
Isn't it "Eiffel - GC, or C" or "Eiffel, or C + GC"?


> The compiler generally doesn't have that semantic knowledge
Isn't that a bit like "the compiler cannot prove the correctness of a program"? What if we tell the compiler about the semantics?

Ulrich

21.08.2026 09:09:02 Finnian Reilly <fin...@eiffel-loop.com>:

> On 20/08/2026 18:08, Ulrich Windl wrote:
>
>> Ideally I would expect that the compiler or runtime does this kind of optimization. Doing low-level programming using a high-level language seems strange to me.
>>
>
> The Xpact XML parser is 98% written at the level of Eiffel, and only 2% at the level of C (using arbitrary figures)
>
> I’m using Eiffel for the things Eiffel is good at:
>
>
> * abstraction
> * classes and inheritance
> * Design by Contract
> * type safety
> * genericity
> * readability
> * memory safety
> * rapid development
> * high-level application architecture
>
> I’m deliberately applying *low-level performance techniques only to a very narrow hot path* where they matter.
>
> That's actually one of the interesting advantages of having a high-level language: I can choose the level of abstraction appropriate to each part of the program.
>
> The alternative isn't necessarily:
>
>
> Eiffel + GC *or* C.
>
>
> It can be:
>
>
> *Mostly high-level Eiffel + a small amount of deliberately low-level Eiffel.*
>
>
> And that's essentially what my experiment demonstrates.
>
> There is also a subtle misconception about what the compiler can do
>
> A compiler cannot generally infer that I should pool objects instead of allocating them.
>
> Suppose I have something conceptually like:
>
> create {SPECIAL [CHARACTER_8]}.make_empty (buffer_size)
>
> The compiler cannot simply decide:
>
>
> "Ah, this object could be reused from a pool."
>
>
> because that potentially changes observable program behavior.
>
> The compiler has to preserve the semantics of my program. Object identity, creation procedures, references held elsewhere, invariants, attachment status, etc. can all matter.
>
> Similarly, *"don't allocate anything during this operation" is often an architectural decision*, not merely an optimization that a compiler can safely discover.
>
> The developer might know:
>
>
> "These parser objects have a lifetime bounded by this parse and can be recycled."
>
>
> The compiler generally doesn't have that semantic knowledge.
>
>
>
> --
> SmartDevelopersUseUnderScoresInTheirIdentifiersBecause_it_is_much_easier_to_read
> (Eiffel = Security by Contract + C Speed)
>
> --
> You received this message because you are subscribed to the Google Groups "Eiffel Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to eiffel-users...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/eiffel-users/215fd82e-7a0f-4418-a180-1364d3081050%40eiffel-loop.com[https://groups.google.com/d/msgid/eiffel-users/215fd82e-7a0f-4418-a180-1364d3081050%40eiffel-loop.com?utm_medium=email&utm_source=footer].

Finnian Reilly

unread,
Aug 22, 2026, 11:29:26 AM (5 days ago) Aug 22
to eiffel...@googlegroups.com
On 22/08/2026 12:54, Ulrich Windl wrote:
> Isn't it "Eiffel - GC, or C" or "Eiffel, or C + GC"?
Yes  GC.opposite is probably more correct.
>
>
>> The compiler generally doesn't have that semantic knowledge
> Isn't that a bit like "the compiler cannot prove the correctness of a program"?
Exactly
> What if we tell the compiler about the semantics?
That I think is the essence of programming

Finnian Reilly

unread,
Aug 22, 2026, 11:32:24 AM (5 days ago) Aug 22
to eiffel...@googlegroups.com
On 22/08/2026 12:47, Ulrich Windl wrote:
> Hi!
>
> Isn't using "SPECIAL" instead of ARRAY already thinking like a C programmer?
Yes, exactly.
> If SPECIAL is like a base class for ARRAY, why can't a compiler actually reduce features of ARRAY to those of special,
ARRAY has a lot of contract code and ability to reallocate, and change
the base etc.
> effectively changing ARRAY to SPECIAL automatically? Or is it that SPECIAL is actually implemented in C?
Yes SPECIAL calls a lot of C built-ins
> Ulrich

Ulrich Windl

unread,
Aug 22, 2026, 12:45:31 PM (5 days ago) Aug 22
to eiffel...@googlegroups.com
What I meant was: If the compiler detects that the features used in ARRAY are all available from SPECIAL, can't it optimize? For example ARRAY allows non-zero-based indexing by doing extra index arithmetic relativ to SPECIAL. If the ARRAY is zero-based the extra arithmetic can be avoided.
I know that this is beyond what compilers can do currently, but aggressive optimization would make such high-level languages more attractive.
Dome years ago I wanted to demonstrate argument passing to functions as done in C when I realized that the compiler optimized "printf("%s\n", "Hello")" to "puts("Hello")", so a different function had been called, and only one actual parameter being passed. I didn't expect that level of optimization at that time...

Ulrich

--

Mit freundlichen Grüßen
Ulrich Windl

22.08.2026 17:32:20 Finnian Reilly <fin...@eiffel-loop.com>:
> --
> You received this message because you are subscribed to the Google Groups "Eiffel Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to eiffel-users...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/eiffel-users/1dd9b659-ee86-44dd-ac07-bfdb24f20cc8%40eiffel-loop.com.

Finnian Reilly

unread,
Aug 22, 2026, 1:29:02 PM (5 days ago) Aug 22
to eiffel...@googlegroups.com
What I meant was: If the compiler detects that the features used in ARRAY are all available from SPECIAL, can't it optimize? For example ARRAY allows non-zero-based indexing by doing extra index arithmetic relativ to SPECIAL. If the ARRAY is zero-based the extra arithmetic can be avoided.
I know that this is beyond what compilers can do currently, but aggressive optimization would make such high-level languages more attractive.

I see what you mean. Yes, in theory this could definitely be done. It gave me the idea to ask Claude the question below.

That said, I'm happy enough with Eiffel as it is. In my experience it's not that inconvenient to decide the appropriate optimization level for each part of a program yourself. Most of the time ARRAY is perfectly fine as-is. There's also likely a tradeoff: a smarter compiler doing this kind of analysis would probably be slower, and I'd rather have a compiler that's fast.

Dome years ago I wanted to demonstrate argument passing to functions as done in C when I realized that the compiler optimized "printf("%s\n", "Hello")" to "puts("Hello")", so a different function had been called, and only one actual parameter being passed. I didn't expect that level of optimization at that time..

Question to Claude

Including languages that don't compile to C but perhaps to VM language or even assembly, what are the top 10 most optimized languages ?

Broadening the net to include VM-targeted and directly-native-compiled languages changes the picture a fair bit, since some of the most sophisticated optimizers on Earth live in JIT tiers (V8, HotSpot, JVM's C2/Graal) rather than ahead-of-time compilers. Here's a top 10, ranked more by "sophistication and number of distinct optimization techniques employed" than by raw benchmark speed — those aren't the same thing, and a couple of entries here aren't even the fastest in absolute terms but are the most technically interesting.

1. Common Lisp (SBCL) / historically Stalin (Scheme)
SBCL is the practical entry: a dynamically-typed, GC'd, high-level language whose native compiler does full type inference when you give it declarations, unboxes floats and integers, eliminates bounds checks, and inlines generic arithmetic dispatch away entirely — all while remaining a fully interactive, dynamic language the rest of the time. It's the best living proof that "high-level and dynamic" doesn't have to mean "unoptimizable." Stalin (mentioned last time) is the research-extreme version of the same idea for Scheme.

2. Glasgow Haskell Compiler (GHC)
Rewrite-rule-driven stream fusion, strictness analysis, worker/wrapper transformation, unboxing, and a core language (System FC) specifically designed to make aggressive whole-program transformation sound. Probably has the largest number of distinct, formally justified optimization passes of anything on this list.

3. MLton (Standard ML)
Whole-program monomorphization and defunctorization — it refuses separate compilation specifically so it can see everything at once and specialize polymorphic/modular code into flat, monomorphic, heavily inlined output. The closest realization of your friend's original ARRAY/SPECIAL idea.

4. Java (HotSpot JVM, and Graal)
This deserves a much higher spot than people expect. C2's speculative optimization — inlining through virtual calls based on observed call-site monomorphism, escape analysis to stack-allocate objects that never leave a method, and deoptimization when a speculative guard fails — is genuinely one of the most sophisticated optimization systems in production use anywhere. Graal extends this with partial escape analysis and more aggressive speculation. This is the JIT/guard-and-deoptimize philosophy mentioned last time (in the Self/Smalltalk lineage), industrialized at massive scale.

5. JavaScript (V8, SpiderMonkey)
Similar philosophy to HotSpot but for a far more dynamic language: hidden classes (shapes) turn duck-typed property access into fixed-offset struct access when the shape is stable, inline caches speculate on call-site types, and TurboFan compiles hot speculative paths down to near-native code with deopt guards. Remarkable given JS has essentially no static type information to start from.

6. Rust
Monomorphization of generics per-instantiation, zero-cost abstraction as a language design constraint rather than an optimizer afterthought, and LLVM's full optimization pipeline underneath. Its trick is pushing as much proof (aliasing via the borrow checker) into the type system so LLVM can optimize as aggressively as it would hand-verified C.

7. Julia
Type-specializing JIT via multiple dispatch — every generic function gets compiled to a specialized native version per concrete argument-type combination the first time it's called, via LLVM. Interesting because it gets C-like performance from code that reads like Python.

8. OCaml (with Flambda)
Cross-module inlining and specialization added on top of OCaml's already-fast baseline native compiler; closes much of the gap to GHC/MLton while staying closer to "practical systems language."

9. Ada / SPARK (GNAT, native code generation)
Included again here specifically for check-elimination: contracts and range types are fed to the prover/optimizer and verified statically, so bounds and overflow checks that other languages pay for at runtime are simply proven unnecessary and dropped.

10. Self
Historically essential rather than practically relevant today: pioneered polymorphic inline caches and speculative type feedback for a language with no static types and no classes at all (pure prototype-based objects). Nearly every JIT on this list (V8, HotSpot, Graal) is a direct intellectual descendant of Self's optimization techniques from the late '80s/early '90s at Sun.

If it's useful, I can go deeper on any one of these — in particular, HotSpot's speculate-and-deopt cycle or GHC's fusion rules would probably be the most directly instructive reading for thinking about what a more aggressive EiffelStudio backend could borrow.

Ulrich Windl

unread,
Aug 24, 2026, 12:17:50 PM (3 days ago) Aug 24
to eiffel...@googlegroups.com
Hi!

IMHO Claude's answer reads more like a summary of marketing material, than something really useful. And as we all suspected: Eiffel doesn't optimize at all (it's missing in Claude's list), so let's go back to LISP 😉

Ulrich
Reply all
Reply to author
Forward
0 new messages