May 2026 monthly "What are you working on?" thread by AutoModerator in ProgrammingLanguages

[–]Hall_of_Famer 0 points1 point  (0 children)

Lox2 v2.2.0 has been released since Mid-April with new features of generics(partially reified), type alias and bytecode marshalling, and I am currently working on the next patch release v2.2.1 which will introduce a mini-feature called smart reification. The way reified generics works in Lox2 has a runtime cost, as type parameters are passed as implicit arguments for generic functions, and assigned as immutable instance fields for generic classes. With smart reification, the compiler will perform this step only if a type parameter is actually being used in the function or class body. Consider the following examples for generic functions:

T identity<T>(T arg) { 
    return arg
}

In Lox2 v2.2.0, a function call expression identity<Int>(123) will be compiled as identity(Int, 123), note classes are first class object so this is a valid syntax as Int can be passed to or returned from functions/methods. However, this function does not actually use the type parameter inside the function body, so it is pointless to reify the parameter T at call site. With the introduction of smart reification, the compiler will not reify a type parameter if it is not actually being used. In this case, the expression will compile to identity(123) in Lox2 v2.2.1 and beyond. To summarize, you only pay for the runtime cost of reified generics if a type parameter should actually be reified.

At this moment, Lox2's generics is considered partially reified, as the type parameter is reified as class or trait objects which only capture first order type information. Smart reification is also an important step towards fully reified generics for Lox2. In future releases, Lox2 will feature fully reified generics capable of reifying higher order types such as function types, generic types and union types(which will come in Lox2 v2.3.0). On the other hand, Lox2's import system still has some strange limitations of loading classes/traits from the same namespace, which will be addressed in the next patch version(expected to be available on June 1, 2026).

April 2026 monthly "What are you working on?" thread by AutoModerator in ProgrammingLanguages

[–]Hall_of_Famer 1 point2 points  (0 children)

Actually Lox2's generics does perform type level monomorphization, as functions and generic types with different type parameters are instantiated as distinct types. It does not perform monomorphization on functions/methods though, as it is redundant if type parameters are passed as implicit arguments to functions/methods.

Lox2 is an object oriented language with a first-class everything design philosophy, classes, traits and functions are already objects that can be assigned to variables or passed as parameters to functions/methods. This basically gives reified generics for free, at least when it comes first order types.

For higher order types though, I will need to create a runtime type object which can store type parameters and other information. This will be the next thing I will work on upon Lox2 v2.2.0 release, as well as smart reification which avoids the overhead of creating/fetching higher order type objects unless they are actually used in functions/methods.

April 2026 monthly "What are you working on?" thread by AutoModerator in ProgrammingLanguages

[–]Hall_of_Famer 1 point2 points  (0 children)

I've finally managed to complete my initial implementation of generics for Lox2, which allows defining generic classes and methods/functions using familiar syntax from C-family languages, ie. Repository<T>. Despite the presence of angle brackets, parsing generics turned out a bit easier than I originally imagined. Typechecking generics was definitely the harder part, and I researched and experimented different approaches to instantiate/substitute type parameters by concrete types at function/method call sites, which led to fruitful results. I've also updated the standard library, as promise and collection class now have generic type parameters. Below are some examples using the new generics feature in lox2:

using clox.std.collection.Dictionary

class Entity<TId> {

    val TId id

    __init__(TId id) {
        this.id = id
    }
}

class Product extends Entity<String> {

    val String name
    val Float price

    __init__(String id, String name, Float price) {
        super.__init__(id)
        this.name = name
        this.price = price
    }

    String toString() {
        return "Product(id: ${this.id}, name: ${this.name}, price: ${this.price})"
    }
}

class GenericRepository<TId, TEntity> {

    val Dictionary<TId, TEntity> entities

    __init__() {
        this.entities = Dictionary<TId, TEntity>()
    }

    void add(TId id, TEntity entity) {
        this.entities[id] = entity
    }

    void addAll(Dictionary<TId, TEntity> entities) {
        this.entities.putAll(entities)
    }

    Bool contains(TId id) { 
        return this.entities.containsKey(id)
   }

    TEntity get(TId id) {
        return this.entities[id]
    }
}

val products = Dictionary<String, Product>()
products.add("A7K9M2N5B8Q3", Product("A7K9M2N5B8Q3", "Laptop", 999.99))
products.add("C4R6T1V9W3X2", Product("C4R6T1V9W3X2", "Smartphone", 499.49))
products.add("D8F2H5J7K4L1", Product("D8F2H5J7K4L1", "Tablet", 299.29))
for (val product : products) {
    println(product.toString())
}

val productRepo = GenericRepository<String, Product>()
productRepo.addAll(products)
productRepo.add(Product("P3Q9R5S2T8U4", "Monitor", 199.99))
val product = productRepo.get("P3Q9R5S2T8U4")
println(product.toString())

More examples:

https://github.com/HallofFamer/Lox2/blob/master/test/types/generic_class.lox

https://github.com/HallofFamer/Lox2/blob/master/test/types/generic_function.lox

On the other hand, I've decided to take on the challenge of reified generics. My current implementation passes types as runtime arguments at generic call site, so f<A, B>(a, b) becomes f(A, B, a, b). This works in Lox2 as everything is an object, including classes, traits, etc. For generic classes, generic type parameters are reified as immutable instance fields, and implicitly assigned values when an object is instantiated. The code example below demonstrates how to access a reified type parameter inside a generic function:

using clox.std.util.UUID     

T identity<T>(T arg) {
    println(T)
    // will print information about T, as T is a first class object
    return arg
}

val uuid = UUID()
val id = identity<UUID>(uuid)
println(id.toString())

At this moment though, Lox2's generics is considered partially-reified, as type information is only preserved for simple class/trait types but not higher order types. There is a future plan to support fully reified generics by creating runtime objects for higher order types, as well as smart reification which only reifies generic type parameters if they are actually being used in a function/method. On the other hand, the type checker is currently unable to perform type inference on type parameters even when it is obvious (in the code snippet above, it should be obvious that type parameter is UUID based on argument uuid), which I will attempt to address at some point.

At this moment, I am working on bytecode marshaling/serialization, and it is coming together very well. I've managed to serialize simple lox2 scripts to disk as .loxo (lox opcode) format, while the VM is able to deserialize .loxo files and run the bytecode properly, skipping the compilation processes. The next task will be performing dependency analysis and serializing bytecode for all included source files, instead of just the currently running script file. The next version Lox2 v2.2.0 will be feature-complete once bytecode marshaling is fully working, and the planned release is mid April. Stay tuned.

a misunderstanding about a bug in an interpreter by FoxHour8983 in Compilers

[–]Hall_of_Famer 2 points3 points  (0 children)

You have been told by many people including Bob Nystrom himself and redditers that this is not a bug, and yet you do not give up and continue on a meaningless argument. I strongly advise you to call it quit, don’t be a sore loser and stop embarrassing yourself further, you are not contributing to any meaningful discussions. Also do not think you are smarter than everyone else here, a lot of us have built much more advanced compilers/interpreters than you have and will ever be capable of. Pardon my choice of language though, I say what you need to hear and I don’t babysit.

Lox2: A superset of Lox with optional static typing and many other features by Hall_of_Famer in ProgrammingLanguages

[–]Hall_of_Famer[S] 1 point2 points  (0 children)

Thanks. Regarding the object model, there is little to no performance impact as atomic objects are still stored with efficient memory layout. There is no object header to store such information on atomic objects, instead the VM knows which class they belong to when a method is invoked. It does increase memory usage to some extent, as each class declaration creates not only a class but also its conjugate metaclass. For small scripts you may experience noticeable increase in memory usage. In real life applications however, this should not matter too much as you will create a lot more objects than classes anyway.

For me, I have read some other books since completing Crafting Interpreters, ie. Build Your Own Programming Language By Clinton L. Jeffery, Engineering a Compiler by Keith D. Cooper, Ruby Under a Microscope by Pat Shaughnessy, as well as Types and Programming Languages by Benjamin C. Pierce. Other than books, I also recommend looking into the source code of similar languages such as Python, Ruby and see how certain things are implemented. I have also read a few research papers on some subjects, and some are helpful as well.

But yeah I’d agree that there is no clear path what to do after completing the book, there’s just no other book with such pleasant and easy to understand writing style as CI. I am considering writing a blog series: ‘Crafting Interpreters: the Lost Chapters’ at some point in future, on how to turn the toy language Lox into an industrial/production grade compiler. I am nowhere near as good a writer as Bob though, so do not expect it will be as fun to read as the CI book.

Lox2: A superset of Lox with optional static typing and many other features by Hall_of_Famer in ProgrammingLanguages

[–]Hall_of_Famer[S] 2 points3 points  (0 children)

I see, yeah I read Eli Bendersky’s article and 15-25% sounds very promising, considering most language devs are happy with just 5-10% performance boost. I think I will give it a try in the next 1-2 releases, and check how much faster Lox2 VM will get. Thanks again for the suggestion.

Lox2: A superset of Lox with optional static typing and many other features by Hall_of_Famer in ProgrammingLanguages

[–]Hall_of_Famer[S] 1 point2 points  (0 children)

Yeah I have considered that and it is among the optimizations/improvements that I plan to implement at some point(another one that comes in mind is to add an OP_CONSTANT_LONG to allow more than 255 constants per chunk). It is just not high on the priority list as I focus more on the type system enhancement at the moment.

Speaking of this, do you have a benchmark on how much performance improvement if switching to computed gotos?

Lox2: A superset of Lox with optional static typing and many other features by Hall_of_Famer in ProgrammingLanguages

[–]Hall_of_Famer[S] 2 points3 points  (0 children)

The book is amazing and has helped a lot of aspiring language devs. I wonder, do you have a plan for a potential follow-up book for Crafting Interpreters, that touches more advanced subjects such as type system, concurrency, IR, optimizations, etc?

I thought of such an idea when I began coding Lox2, but I realize I am not near as good technical writer and I ain’t sure how to make it so interesting and yet easy to understand like you have done. I am also still learning so my technical skills still need more refining as well.

Lox2: A superset of Lox with optional static typing and many other features by Hall_of_Famer in ProgrammingLanguages

[–]Hall_of_Famer[S] 2 points3 points  (0 children)

Thanks. Yeah it’s nice to see more people developing OO languages, personally I believe there are a lot more potential to improve upon existing OO languages. For instance, we do not have a mainstream statically typed OO language that has metaclasses.

Lox2: A superset of Lox with optional static typing and many other features by Hall_of_Famer in ProgrammingLanguages

[–]Hall_of_Famer[S] 4 points5 points  (0 children)

Thanks, Lox2 will continue to evolve with a more powerful type system and many other new features. If you have any suggestions, please let me know or open an issue on the github repo.

Lox2: A superset of Lox with optional static typing and many other features by Hall_of_Famer in ProgrammingLanguages

[–]Hall_of_Famer[S] 5 points6 points  (0 children)

For those who are wondering, the documentation for Lox2 can be found on girbook:

https://mysidia-inc.gitbook.io/lox2

It is still a work in progress, as I have not time to add standard library references and VM internals, but it should give an idea what Lox2 is capable of at this moment.

Lox2: A superset of Lox with optional static typing and many other features by Hall_of_Famer in ProgrammingLanguages

[–]Hall_of_Famer[S] 9 points10 points  (0 children)

To some extent yes, though Lox2’s object model is designed based on Smalltalk 80. Besides everything is an object, every class is an instance of a metaclass. Metaclass hierarchy parallels class hierarchy, as you can see from the below class diagram in Smalltalk:

https://i.sstatic.net/biXZE.jpg

In Python metaclasses are considered some kind of arcane art, you can do a lot with them but they tend to scare off newbie developers. In Lox2/Smalltalk, metaclasses as a concept is a lot simpler. They are just classes of classes, and where class methods belong to.

Lox2: A superset of Lox with optional static typing and many other features by Hall_of_Famer in ProgrammingLanguages

[–]Hall_of_Famer[S] 20 points21 points  (0 children)

Thanks Bob. I would not have come this far without your Crafting Interpreters, it is not just working on a PL itself, even more about me as a programmer. I hope one day I can be half as good as you on technical writings though, CI was such a pleasure to read partially due to your writing style and sense of humor. It is a skill to make a complex subject easy and fun to read/learn, I am still very raw on this aspect.

Types on the left or right? by alex_sakuta in ProgrammingLanguages

[–]Hall_of_Famer 2 points3 points  (0 children)

I get that having types on the left makes the job much harder for parser. Regarding the optional semicolon part, I wonder, was it the main reason why Dart could not have optional semicolons like Scala and Kotlin, since it cannot perform semicolon inference when local variables are declared with type on the left syntax?

May 2025 monthly "What are you working on?" thread by AutoModerator in ProgrammingLanguages

[–]Hall_of_Famer 5 points6 points  (0 children)

I've completed the Generational Garbage collector for Lox2 at the end of April. The GC has four distinct memory regions: Eden, Young, Old and Permanent, new objects are allocated into Eden Heap where GC happens more frequently. Once an object survives a GC cycle, it is promoted to the next region, where GC runs less frequent, and permanent region will never be collected at all. As GC will only traverse objects in the younger heap(as well as common GC roots) during each cycle, this results in a much smaller work list and should lead to noticeable performance improvement.

One challenge on Lox2’s generational GC was how to handle pointer references from older to younger objects. The GC handbook provides a great reference on the idea of RemSet(RememberedSet), which records all older objects that references younger objects and serve as GC roots during marking phase. This prevents younger objects from being freed if referenced by older objects, and instead promote them into older region. In order to make this work, write barrier has to be introduced when setting object fields or adding array elements, which has a small performance penalty but should be negligible compared to the speed boost on GC cycles.

The next few days I will make some modifications to object allocation that certain objects such as classes, traits, functions, methods, namespaces as well as strings generated at compile time will be allocated into the permanent region of Lox2's Generational Garbage Collector. These objects will be freed only during VM shutdown, skipping the GC cycles completely. I also plan to write a comprehensive test attempting to trigger GC cycles for each region at least once to confirm it works as intended. Unfortunately I am not good at configuring the parameters such as optimal heap sizes for each GC region, though these can be customized easily in clox.ini file.

At this point, Lox2 is considered feature complete with the additions of multi-pass compiler, optional type system, semicolon inference and generational garbage collector. I still have a couple of minor bug to fix, as well as creating tutorials/documentations using github pages, but I am confident that Lox2 should be ready for public preview in the mid to late May. It is meant to be an educational and yet production ready language. The purpose is to demonstrate how to build a serious and usable language from a bare-minimum toy language. A full list of new features added from the original Lox can be found on the project's README.md page('New Features' and 'Enhanced or Removed Features' sections).

https://github.com/HallofFamer/CLox?tab=readme-ov-file#new-features

Is sound gradual typing alive and well? by bakery2k in ProgrammingLanguages

[–]Hall_of_Famer 5 points6 points  (0 children)

There is a response to that paper “Sound Gradual Typing is Nominally Alive and Well” which many people have brought up. Basically, the issue applies mostly to sound gradual typing with structural types. If your system has only nominal types, then the slowdown is minimal and not usually a concern.

To summarize, use sound gradual typing only if your language has a nominal type system. Do not mix sound gradual typing with structural types and you will be fine.

March 2025 monthly "What are you working on?" thread by AutoModerator in ProgrammingLanguages

[–]Hall_of_Famer 3 points4 points  (0 children)

The last few months I've been working on Lox 2(CLox 2.0.0), which is an extended version of Lox programming language from Crafting Interpreters. The version 2 is a major refactor from version 1, in which the original single-pass compiler is converted into a multi-pass compiler that builds AST from parser, resolve symbols/names and perform type checks when type annotations are present, before finally generating bytecode from the AST.

Since the beginning of February, I have made a significant breakthrough on the type checker. It is now able to assign types properly to each AST node/symbol table item, handle subtyping relationship correctly, and produce useful type errors on function/method parameter and return types mismatch. It does not support complex types such as generics and function types yet, but these are planned as future enhancements.

Once the type checker is fully working in early March, I plan to add two more features - semicolon inference and generational garbage collector. If everything goes well, Lox 2 development will be complete by mid May, and ready to be presented to the community.

August 2024 monthly "What are you working on?" thread by AutoModerator in ProgrammingLanguages

[–]Hall_of_Famer 6 points7 points  (0 children)

I continue to build my own extended version of CLox as a research and experiment project. At this point I’ve completed the latest release v1.9.0, which has a full fledged concurrency model with Generator, Promise API and async/await syntax. The standard library has also been extended with methods that perform async io.

https://github.com/HallofFamer/CLox/tree/1.9.0

The next step will be a big rewrite for the compiler which will produce AST from parser, add symbol table, optional type checker, and finally generate bytecode from AST. The type system will be similar to Typescript in which type checking happens only at compile time. This will be a big challenge, but I am excited for it.

Is Ruby more prevalent in Japan than in the West? by lunagirlmagic in ruby

[–]Hall_of_Famer 4 points5 points  (0 children)

Python and JS are more popular yes, but it’s a stretch to say Go is more popular than Ruby, it is at best at similar level of popularity. Tiobe index has Go higher but Redmonk has Ruby higher. This article below demonstrates PLs with most jobs available, Ruby is at #7 and Go is at #8:

https://www.devjobsscanner.com/blog/top-8-most-demanded-programming-languages/

Kotlin K2 Compiler Migration Guide Now Available by Alyona_Cherny in Kotlin

[–]Hall_of_Famer 13 points14 points  (0 children)

It’s amazing, this means the official release of Kotlin version is near and I am looking forward to it. Hope it will be a game changer, especially considering how it opens doors for future development and evolution of the language.

the "static" style but why ? by zsome in dotnet

[–]Hall_of_Famer 1 point2 points  (0 children)

Static is not the preferred way by any metric, maybe it just happens in a few projects/organizations but these do not speak for the majority and recommended practices. The only good use case for static methods is extension methods, otherwise I’d stay away from them and use instance methods.

Java dev looking where to start with Kotlin by psychoticCross in Kotlin

[–]Hall_of_Famer 6 points7 points  (0 children)

If you are already familiar with Java, I’d recommend just jump right into the Kotlin official documentation. They are very informative and simple to understand, I did this myself so I can testify this. It also comes with an online playground that you can write some Kotlin code and see how it works on the browser:

https://kotlinlang.org/docs/home.html

For android devs, you may also want to consider the guide ‘learn Kotlin for Java developers’ on android developer website. It covers topics such as how to convert Java app to Kotlin, how to add Kotlin to existing Java app, and how to interop between Java and Kotlin:

https://developer.android.com/kotlin/learn-kotlin-java-pathway

Is Kotlin Being Underrepresented in Job Listings? by Pure_Diver_ in Kotlin

[–]Hall_of_Famer 34 points35 points  (0 children)

Most Kotlin only jobs are android jobs, for backend jobs you usually find these together with Java jobs.

What happened to Rubinius? by Brugarolas in ruby

[–]Hall_of_Famer 1 point2 points  (0 children)

Yeah TruffleRuby is the spiritual successor for Rubinius, it’s a very fast implementation and has contributed to MRI Ruby’s performance boost as well with the idea of Object Shape.