/r/ProgrammingLanguages

Photograph via snooOG

This subreddit is dedicated to the theory, design and implementation of programming languages.

Welcome!

This subreddit is dedicated to the theory, design and implementation of programming languages.

Be nice to each other. Flame wars and rants are not welcomed. Please also put some effort into your post, this isn't Quora.

This subreddit is not the right place to ask questions such as "What language should I use for X", "what language should I learn", "what's your favourite language" and similar questions. Such questions should be posted in /r/AskProgramming or /r/LearnProgramming. It's also not the place for questions one can trivially answer by spending a few minutes using a search engine, such as questions like "What is a monad?".

Related subreddits

Related online communities

/r/ProgrammingLanguages

106,337 Subscribers

4

quasi-threaded code

Hi! I’m diving into building small programming languages and currently exploring how to implement interpreters. While reading about threaded-code interpreters (for example https://www.complang.tuwien.ac.at/forth/threaded-code.html ), I came up with the following idea: instead of generating bytecode, the compiler could produce an array of function references (or an array of functions-as-values, depending on the terminology of the host language), like this:

// pseudocode

instructions = [function(*VM)]{
   const(5), const(5), sum,
   dup,       // duplicate value on stack
   print(1),  // => pop 1 value from stack and print it
   const(10),
   jmpe(2),   // != 10 => jump to +2 instruction
   halt,
   const("that's all, folks!"),
   print(1)
}

for vm.i = 0; vm.i < instructions.len; vm.i++ {
   instructions[i](vm)
} 

This isn’t threaded-code, but it’s somewhat similar.

Implementing this approach is much simpler than parsing bytecode, and there’s no overhead for deserializing instructions.

However, there are a couple of drawbacks: • These instructions are hard to serialize (except maybe as source code in the host programming language). • Debugging is a bit trickier because naive implementations lack a string representation of the instructions. That said, in my experience, interactive debuggers handle this problem well.

I’m currently working on a Lisp-like language using this kind of interpreter, and so far, I’m really enjoying the results. It’s very easy to create “super-instructions,” and writing them feels simpler overall.

I’d appreciate it if you could recommend any resources on similar interpreter techniques, or share your experiences or thoughts on this approach! I’m curious if there are potential pitfalls I might have missed or ways to optimize this further.

1 Comment
2025/01/16
18:50 UTC

1

How to implement multiple variable assignment?

Sorry, my english grammar is not very good but i tried as possible to write this post understandable.

Hello and I am currently working on my new version of my programming language and after learning a lot of Parser. But I am here to ask how do I implement multiple variable assignment because the current variable assignment expression only take 1 identifier.

expr : IDENTIFIER ASSIGN expr

I want both variable assignment and object attribute editing. So I was thinking it would be like this:

expr : expr_list ASSIGN expr_list
expr_list : expr (COMMA expr)*

But I don't know how to implement like "am i just get the list of expressions by the way?" I just need some help about implementing multiple variable assignment.

I don't think this post would be all what I trying to ask so if there is something wrong please ask me to fix it!

2 Comments
2025/01/16
16:33 UTC

24

C3 0.6.6 Released

For people who don't know what C3 is, it's a C-like language which aims to be an evolution on C rather than a whole new language.

With that out of the way:

Monthly releases of 0.6.x is continuing for C3. This summer the development of C3 will turn 6 years old. When mentioned as a C language alternative, C3 is referred to as a "young" language. Just so that you other language creators can know what to expect!

By April, version 0.7.0 will be released, removing deprecated code. The plan is to have one "dot one" release each year until 1.0 is reached (and if everything goes according to plan, the version after 0.9 will be 1.0).

This release had some language changes:

  1. Enum conversions starts preferring MyFoo.from_ordinal(x) / foo.ordinal instead of (MyFoo)x and (int)foo.
  2. Ref arguments for macros are getting phased out to simplify the language, since they can be replaced (although not perfectly) by expression arguments.
  3. Allowing the main method to return void! is deprecated since it led to rather poor coding practices. This also simplifies the language. Test and benchmark functions get a similar change.
  4. Compile time $foreach now iterates over string literals, which was missing.

The standard library is also seeing some incremental improvements, including foreach-compatible iterators for HashMap.

In terms of bug fixes, it sees a fairly large amount of bug fixes, mostly on more obscure parts of the language.

For 0.6.7 compile time mutation of compile time arrays will finally be permitted. And perhaps enums might finally have the missing "enums-with-gaps" resolved (currently, enums are strictly numbered 0 and up).

More importantly though, is that C3 will see the beginning of work to prune unused features from the language, which will then eventually be removed with 0.7.0.

Blog post with the full changelog: https://c3.handmade.network/blog/p/8983-another_monthly_release__c3_0.6.6_is_here

Link to the C3 homepage: https://c3-lang.org

Finding it on Github: https://github.com/c3lang/c3c

12 Comments
2025/01/16
12:24 UTC

29

Object oriented language that is compiled to C and can seamlessly integrate with C

Object oriented language that is transpiled to C and can seamlessly integrate with C

Hey, while I love working with C sometimes i miss having some niceties like containers and async, as a joke I programmed an object oriented library in c, so I can create lambdas, interfaces, functions, etc in c and then I was getting bogged down with the boilerplate, so I decided to make a language out of it. It kinda looks like dart but has an extern keyword that allows me to implement some function, method or even an entire class (data struct + methods) in C. I already made every pass until the ir and started working on the C backend. This way I can structure my program, async stuff, etc with an high level language but perform the business logic in C + and call code from either language in either language. For the memory model I am thinking on using refcounting with either an microtask based cycle detection that checks the object pool + on allocation failure or placing this responsibility on the programmer, using weak refs. While I am making it, I can't stop thinking that it probably is fast as fuck (if I get the memory model right), and it kinda left me wondering if someone already tried something like this. Anyways, I wanted to get some feedback from people more experienced, I always wanted to make an programming language but this is my first one. Also if anyone has an idea of name, I would be glad to hear! I don't have an name for it yet and I'm just naming the files .fast

47 Comments
2025/01/15
23:45 UTC

8

Looking for people to interview exploring + designing new ~estoric HDL tensor processing features in the SUS hardware description language

Hey, I'm looking for people (ideally >= graduate level), who use HDLs or HLS somewhat regularly as part of their job/research: I'm a Masters student working on adding tensor/multidimensional array processing features to the SUS language, and as part of my project I would like to spend some time talking to you about your/an open source codebase, identifying what kinds of new features and abstractions would or wouldn't be valuable to you, in the context of the goals of the SUS language.

Although this is a Masters project, my goal here is primarily to make the experience interesting for you: this is not a survey link, but an invitation to spend an hour or so discussing some relatively weird/esoteric possible language features. The benefit to me is to draw on your experience, informing the language features I end up with.

If you're interested, please send me a DM here, and I can arrange a conversation on whatever platform you would prefer.

0 Comments
2025/01/15
13:55 UTC

13

Introducing e2e4: The Chess-Inspired Esoteric Programming Language

hello world program execution
Ever thought of combining chess and programming? Meet e2e4, an esoteric programming language interpreted and implemented in Perl.

How It Works

  • Syntax: Commands are split by new lines.
  • Commands: Place or move chess figures on an 8x8 matrix.
  • Figures: K (King), k (Knight), P (Pawn), R (Rook), Q (Queen), B (Bishop).

Example

a1K - Place King at a1.
a1b1 - Move King from a1 to b1.

Concept

  • Matrix: An 8x8 grid where each cell is initially 0.
  • Binary to ASCII: Each row of the matrix is a binary number, converted to a decimal ASCII character.Example a1K - Place King at a1. a1b1 - Move King from a1 to b1. Concept Matrix: An 8x8 grid where each cell is initially 0. Binary to ASCII: Each row of the matrix is a binary number, converted to a decimal ASCII character.

I just made it for fun after all!

source code: https://github.com/hdvpdrm/e2e4

36 Comments
2025/01/14
19:29 UTC

38

Compiling a GCed language into JavaScript vs Wasm

I'm implementing a small programming language, statically typed, but with automatic memory management (basically with a GC of any sort).

I'd like my programs to run both natively and on a browser, but the latter is the main focus. The two main backend options I see are transpiling to JavaScript (to run natively in the browser or in V8 outside of it) or compiling to LLVM and from there generate Wasm for the browser (and an elf for native binaries). The JavaScript approach would consists of mapping my values into native JavaScript ones as much as possible (I'd use JS's `Array` to implement my lists, `Object` to implement my structs, `string`, `number` etc). I don't have the energy to implement both right now.

The main points I see in favor of LLVM (and from there to Wasm) are:

  1. Smaller native binaries and faster startup time, since I wouldn't need to embed and run a JS VM.
  2. Performance might be higher since LLVM could perform lots of good compile-time optimizations.
  3. More low level control. E.g. if I want an `u16` I can have the real thing. While in JS I'd have to build it out of `number`.
  4. The binaries would be obfuscated. But I don't really care or need this.

While in favor of JS I see these points:

  1. Generated code would be much simpler to debug, using the tools built for JS and source maps.

  2. On the web it might actually run faster (the Wasm built from efficient languages with manual memory management, like C++ or Rust, is only ~30% faster than JS code, isn't it?).

  3. It would be much easier to wrap JS libraries so that my programs can use them.

  4. Transpilation and JITting would be faster and arguably simpler.

I wonder: are all my points correct? And am I forgetting anything?

Has anyone faced similar decisions? Tried both approaches?

Which way would you recommend and why?

13 Comments
2025/01/14
03:57 UTC

0

Presenting the Abstract Programming Language

So, about the language that i was talking in my last posts.
After discussing with some redditors, I understood that this sub i not the right scope to talk about what i wanted to show with my concept of agnostic language (as it is a bigger concept that refers to compiler, libraries and other tools and not simply the language), so i'm not here anymore to talk about this concept. I only need some criticism about my language syntax for now.

The language name is Abstract (don't ask me why, i just came with it it months ago and it sticks for sufficient time to just be it).
I already planned some good amount of documentation. Incomplete, but still a good amount.
The complete documentation can be found here: Abstract's documentation page (expect lots of english errors, it's not my main language but i'm trying lol)

Some pages can have syntax errors caused by changes during development so i will be very happy in explaining any doubt or confusion.

If you don't want to read it entirely, i also bring some syntax examples:

import from Std.Console
    
@public func !void main() {
    
    let i8 myByte = 8
    let i16 myShort = 16
    let i32 myInt = 32
    
    foo(myByte) # foo(i8) -> void
    foo(myInt) # foo(i32) -> void
    foo(myShort) # foo(i32) -> void
    
}

# Overloads of the function 'foo'
@public func void foo(i8 value) {
    writeln("The value is a byte and it is \{value}!")
}
@public func void foo(i32 value) {
    writeln("The value is a int32 and it is \{value}!")
}
let i32 value = 10
    
if value == 0
    Std.Console.writeln("value is exactly 0!")
elif value == 1
    Std.Console.writeln("value is exactly 1!")
elif value < 5
    Std.Console.writeln("Value is lower than 5 but greater than 1!")
elif value >= 10
    Std.Console.writeln("Value is equal or greater than 10!")
elif value > 11
    Std.Console.writeln("Value is greater than 11!")
    
    
if value == 11
    Std.Console.writeln("Value is exactly 11!")
else
    Std.Console.writeln("Value is not 11")
    
# Another option to use conditionals syntax
if (value > 30) Std.Console.writeln("Value is greater than 30!")
elif (value < 30) Std.Console.writeln("Value is lesser than 30!")
else {
    Std.Console.writeln("Certainly,")
    Std.Console.writeln("the value is")
    Std.Console.writeln("exactly 30!")
}
32 Comments
2025/01/14
01:23 UTC

0

A fully agnostic programming language (2)

After seeing some of the (really bad lol) feedback on my last post, i saw how i could not show anything that i tried to, sow now i want to contextualize a little more.

in this post i will be answering some common doubts on the last post and showing about my language and the development environment around it.

(First of all, the text will be really big so sorry for bad english, it's not my main language)

What i mean by agnostic programming language:

As a counter part of the language-agnostic programming paradigm concept, this idea should describe a language that can be used FOR everything and IN everything.
In comparison, the Java language is what is possible to be called a system-agnostic language as it can run in any system (with exceptions obviously but this is the java concept).
We cal also take C as a example of a agnostic language as a C program can be targeted for practically everything with the right compilers (native programs, kernel, web, front and back end services, etc.).

why not C#, Rust, Zig, C, C++, Lisp, OCaml or any other language that you can think can fit on this description?

(First of all, programming language is and aways will be a personal thing. I can't force you to use X or Y as you can't force me to use X or Y. Based on it, i'm ignoring any of kind of these suggestions as a "use X instead" answer as my question is how i can inprove MY programming language and not what language i should use.)

I already used some of these languages (C# and Java, Zig😍, C and C++) and tried to learn others to use in the future or just for inspiration (Runst, and really barelly List and OCaml). I personally love all programming languages, but i as everyone needs to admit that some languages are more usefull for some thing than others are for other thing.

Sometimes this isn't even a problem of the language design itself, as happens with C by being a really old program language (fuck, C is older than my mom lol) or C# and Java, that are designed mainly by big compaines (Microsoft and Oracle) that for much times diverged of their main objectives (yes i'm talking about you, microsoft >:( ).

In another side, we have the newer and better system laguages, Rust and Zig. (Yes, i know zig isn't ready yet, but it is still well structured and functional to be criticised about) Those two languages are designed and used with a basic and good reason: replace C. And yes, they do it very well. both are actually safeer and faster than C itself and are being replaced for lots of systems that used to be writen in C.

But still, both are not perfect. Rust and Zig are made for replace C and it means be used where C is used. And don't undestand me wrong, it's not a limit at all, as C is and can be used anywere, but the point is that it is still not designed to be.

C was not made for be used in web, was not made for be used in all the systems and operating systems that we have nowdays and mainly was not made to do be used on modern operating systems. C, AT MY PERSONAL VIEW, is just a extension of assembly, and Rust and Zig, AT MY PERSONAL VIEW are just extensions of C.

(disclaimer: i'm not saying Rust, Zig, C or any other language are bad languages, it's only MY view about their environment and capability and not a real criticism about their utility.)

"If you don't like 'C extension' languages, why not Python, javascript (with nodejs) or any other extremelly higher-level language?"

well, because they don't have the same capability of the languages based on C and assembly.

It's possibly to see the dilema now?

All these languages can be used for anything, but they're not designed to be used for ANYTHING. They have a scope and you need to go really further to get out of it.

Ok, but what problem i want to solve anyway?

Well, none of them. All programs are already solved with the giand plethora of languages that we have and you can use how many you want in your system to do whatever you need to do. I want do be clear here that this project is a hobbie of mine and not a big tech revolutionary project.

Clarified this, the main objective of the language is: Build complex systems with only one language instead of how much you want.

Just it, nothing much complex. i just want i language that i can use for build a kernel, as to build a website and a desktop or mobile program, don't minding the intrinsics of the language designs or having to import weird spaguetti libraries to glue everything toguether.

To make things clear, i want to explain how the idea of the project started: I, i young computer and software enginner, was trying to start with OS dev to understand better how hardware and sorftware works. As every bigginer OS dev project, i started with real mode (16-bts) and BIOS. everything was perfect, except the fact that i was spending too much time writing and reading complex things in assembly. I personally love all assembly languages and assembly probgramming in general, but i need to accept that it's not practical. So i decided to do what any other person whould do: use C instead. And here was the beggining of my main problem: not every C compiler is made to export things to raw binary. Like, obviously. no one use raw binary nowdays. modern CPUs even use BIOS anymore. but what should i do? give up mith my learning about OS dev?

And them a light came on my head: i can build a simple compiler to a language that have direct acess to inline assembly but i can also write things in a rich and good syntax. annnd this project scalated more than i actually can describle here lol.

Now that i covered the basics, let's back o the main question:

Ok, but what i want to solve anyway (v2)?

  1. Agnosticism:

I'm really tired of writing things in lots of diferent lanugages. the main problem that i want to solve is as i alread said is: One language for everything, or a "agnostic language".

  1. Memory and Resource management:

Memory management is a big problem on every low-level environment. Languages like C, C++ and Zig allow you to do whatever you want with the memory, allocating and deallocating it as your free-will, but still giving you some responsability about it, like leaks and cleanup.

Rust as a counterpart, have the famous lifetime and borrowing system. Very good for memory management, do shit and it will clean the shit for you, but also very limited. Rust don't allow (at least as default) you to fuck the memory and it is a problem. In my vision, a language should never force you to do anything, even when it can cause a bug or a complex program. So the main pseudo-philosophy for my language is: "do anything i don't care, but i will still support you to don't do it".

Also, as a fully-agnostic language, memory management can be a problem and unecessary in lots of cases (like the higher level ones), so i want to still have a automatic memory management system but that can aways be manipullable by the user (i will bring more about memory soon).

  1. Language customization:

As i said before, in my vision a programming language should never force you to do anything, and i belive this syntax is also a thing. Obviously, we need limitations. One problem that i want to don't have on my language is the macro system of C/C++ (really it's just stuppid how it work). So i want a language that allow me to do metaprogramming, overload operators and functions, shadow references and eveything, but still limiting me to don't make the language unreadable.

  1. Readability:

A readable and recognizeable syntax is what mainly makes a language good and useable. Because of this, i want to desigin the lanugage with the best syntax based on my opinion and general opinion, also with some verbosity to make sure that everything is self documented.

  1. Modulability:

The main point of a agnostic lanugage is that it should be really modular to work everywere. This is not just a thing in the language, but on the compiler and env itself. because of this, i designed to the language a way to manipulate the compiling and linking system from inside the language. It include locking and creating local and global references, static references that can be globally used by everything and as well be manipulated by the user and a compile time execution system.

Conclusion:

I think it's just it (i'm really tired of writing all of it lol). I think this can show better the view that i have about the language idea and environment and maybe help me to receive some better and usefull criticism about.

Thanks for readding :3

38 Comments
2025/01/13
19:18 UTC

13

Naive question about the data structures used at various stages in implementing a bytecode VM

Hello, I hope this question is okay for this community, but I have been trying to get an idea of the kinds of data structures typically _used_ to build parsers and interpreters for bytecode-virtual-machine languages. I hope to offer a more specific question below, but first for some background on where the question comes from...

Firstly, I've been working my way through _Crafting Interpreters_ (a book I am really enjoying), implementing the lox language in Rust. The first section with a tree-walk interpreter was relatively straightforward to implement (probably because I've done a little bit of work on interpreters operating over an AST before). However, when I got to the second section of the book, I found that I kept making fitful starts, and the thing that was pretty hard for me was that I couldn't "see" in my head the ultimate data structure the book is building out of code and evaluation objects (which makes it pretty hard for me to anticipate _where_ I'm going to need to park lifetimes for my rust data structures; I can't simply copy the C, in other words). I imagine you all will probably know this, but Nystrom has a parser which loads bytecode into `chunk`s, but those chunks form something like a linked-list (not a tree)? This section jumps around a lot, and I think I should probably be looking at finished implementations to see the whole structure and to be able to build rust data structures with lifetimes that make the most sense.

Secondly, I recorded a podcast episode a couple of weeks ago on Frances Allen, who worked at IBM and contributed research on compiler optimizations using graphs. A whole bunch of the compiler optimizations she first wrote about in the 70s are still widely used. It was super interesting, but then when I started thinking again about the data structures, it seemed like my Rust bytecode VM from _Crafting Interpreters_ is going to skip over building a graph. I am probably getting confused here between a compiler which produces LLVM IR and an interpreter which probably needs like a values stack and an some kind of evaluation context for each frame (for function calls, closures, etc.)

Lastly, I have some familiarity with CPython, which builds up a linked list of PyFrame objects (I think it's a doubly-linked list if I remember right) which include their own evaluation stacks and these point to the bytecode objects. There's a "values stack" used in CPython: before invoking a function call, it will push the args-count onto the values stack and then the function will pop them off to operate on them?

Thus, this is my confusion (and I apologize for the long question):
- What are the commonly used data structures in these bytecode VMs (stacks for evaluation, for instance, but frames that relate to each other somehow).
- What are the relationships (ex: Python has a values stack and a frame object and the code object)

If this question is too long to answer here, I'll happily take further reading suggestions or even examples to actual implementations instead. I'm really curious about the most common solutions.

11 Comments
2025/01/13
18:51 UTC

7

Cast/narrow/pattern matching operator name/symbol suggestion.

Many languages let you check if an instance matches to another type let you use it in a new scope

For instance Rust has `if let`

if let Foo(bar) = baz {
    // use bar here
}

Or Java

if (baz instanceof Foo bar) { 
   // use bar here
}

I would like to use this principle in my language and I'm thinking of an operator but I can't come up with a name: match, cast (it is not casting) and as symbol I'm thinking of >_ (because it looks like it narrowing something?)

baz >_ { 
    bar Foo 
    // use bar here
}

Questions:

What is this concept called? Is it pattern matching? I initially thought of the `bind` operator `>>=` but that's closer to using the result of an operation.

19 Comments
2025/01/13
18:36 UTC

7

Scopes and Environments

2 Comments
2025/01/13
13:28 UTC

8

Version 2025-01-11 of the Seed7 programming language released

The release note is in r/seed7.

Summary of the things done in the 2025-01-11 release:

Some info about Seed7:

Seed7 is a programming language that is inspired by Ada, C/C++ and Java. I have created Seed7 based on my diploma and doctoral theses. I've been working on it since 1989 and released it after several rewrites in 2005. Since then, I improve it on a regular basis.

Some links:

Seed7 follows several design principles:

Can interpret scripts or compile large programs:

  • The interpreter starts quickly. It can process 400000 lines per second. This allows a quick edit-test cycle. Seed7 can be compiled to efficient machine code (via a C compiler as back-end). You don't need makefiles or other build technology for Seed7 programs.

Error prevention:

Source code portability:

  • Most programming languages claim to be source code portable, but often you need considerable effort to actually write portable code. In Seed7 it is hard to write unportable code. Seed7 programs can be executed without changes. Even the path delimiter (/) and database connection strings are standardized. Seed7 has drivers for graphic, console, etc. to compensate for different operating systems.

Readability:

  • Programs are more often read than written. Seed7 uses several approaches to improve readability.

Well defined behavior:

  • Seed7 has a well defined behavior in all situations. Undefined behavior like in C does not exist.

Overloading:

  • Functions, operators and statements are not only identified by identifiers but also via the types of their parameters. This allows overloading the same identifier for different purposes.

Extensibility:

Object orientation:

  • There are interfaces and implementations of them. Classes are not used. This allows multiple dispatch.

Multiple dispatch:

  • A method is not attached to one object (this). Instead it can be connected to several objects. This works analog to the overloading of functions.

Performance:

No virtual machine:

  • Seed7 is based on the executables of the operating system. This removes another dependency.

No artificial restrictions:

  • Historic programming languages have a lot of artificial restrictions. In Seed7 there is no limit for length of an identifier or string, for the number of variables or number of nesting levels, etc.

Independent of databases:

Possibility to work without IDE:

  • IDEs are great, but some programming languages have been designed in a way that makes it hard to use them without IDE. Programming language features should be designed in a way that makes it possible to work with a simple text editor.

Minimal dependency on external tools:

  • To compile Seed7 you just need a C compiler and a make utility. The Seed7 libraries avoid calling external tools as well.

Comprehensive libraries:

Own implementations of libraries:

  • Many languages have no own implementation for essential library functions. Instead C, C++ or Java libraries are used. In Seed7 most of the libraries are written in Seed7. This reduces the dependency on external libraries. The source code of external libraries is sometimes hard to find and in most cases hard to read.

Reliable solutions:

  • Simple and reliable solutions are preferred over complex ones that may fail for various reasons.

It would be nice to get some feedback.

9 Comments
2025/01/13
07:40 UTC

0

A fully agnostic programming language

Recently i'm working on a project related to a programming language that i created.
I'm trying to design it around the idea of something fully agnostic, allowing the same language to be compiled, interpreted or shared to any target as possible.

As it's already a thing (literally every language can do this nowdays) i want something more. My idea was improve this design to allow the same language to be used as a system language (with the same software and hardware control of assembly and C) as well as a high level language like C#, python or javascript, with security features and easy memory management, abstracting the most the access to the hardware and the OS.

As my view, this is what could be a fully agnostic programming language, a language that can control any hardware and operating system as well as allows the user to build complete programs without needing to bother about details like memory management and security, everything in the same language with a simple and constant syntax.

When i try to show the image of what i want to create, is hard to make people see the utility of it as the same as i see, so i want some criticism about the idea.
I will bring more about the language in future posts (syntax, resource management and documentation) but i want some opinions about the idea that i want to share.

anyway thanks for reed :3

41 Comments
2025/01/13
04:16 UTC

18

I made an implicational-propositional-logic-proof to SKI-calculus compiler in Symbolverse term rewriting system.

Compiling an implicational propositional logic proof to an SKI calculus involves translating each logical step of the proof into a corresponding SKI combinator. In implicational logic, the axioms (such as P -> (Q -> P) and (P -> (Q -> R)) -> ((P -> Q) -> (P -> R))) are represented by simple combinators like K (which ignores its second argument) and S (which applies a function to two arguments). Each application of these combinators directly encodes the logical structure of the proof in SKI calculus. For instance, the proof of an implication such as P -> (Q -> P) would be represented by the K combinator. By systematically replacing axioms and applying inference rules, the entire proof can be reduced to a sequence of SKI combinators, yielding a program that is both a valid logical proof and an interpretable functional program in SKI calculus.

Such programs in SKI calculus offer several key advantages:

  • Deterministic Behavior: They are based on constructive proofs, which ensure that the program's execution follows a well-defined, predictable path, avoiding non-determinism.
  • Termination Guarantee: Since constructive proofs inherently avoid infinite recursion or contradiction, SKI programs derived from them are guaranteed to terminate.
  • Type Safety: The translation from constructive logic to SKI ensures that the program is type-safe, corresponding directly to logical propositions, which guarantees correct usage of types.
  • Correctness: These programs are grounded in a formal proof structure, making them reliable and correct by construction.
  • Reproducibility: Each step in the program corresponds to a logical step in the proof, ensuring that the program can be reproduced and verified based on the original proof.

In essence, SKI programs constructed from theorems are reliable, predictable, and verifiable due to their foundation in constructive logic and formal reasoning.

I made a minimal prototype of such a compiler, and you can test it as one of the examples in the online Symbolverse playground: https://tearflake.github.io/symbolverse/playground/

5 Comments
2025/01/12
17:56 UTC

37

A Simple 16-bit Virtual Computer (Update)

Hello Everyone,
I always wanted a very simple and well defined computer architecture to play around with, so I made one. SVC16 aims to bring you part of the fun of building for a retro-console without having to understand hardware from the 1980s. Don't get me wrong, old hardware is cool, but I wanted something that has no undefined behavior. There is also a benefit to being a bit different: It takes away the temptation to copy someone else's compiler or tools.
I posted about this project a month ago and received a lot of feedback, so I thought I should give an update. - The details have now been finalized.
- There is now a document that contains everything you need to know to get started.
- I built a more advanced example game.
- Improvements of the emulator (gamepad support, scaling etc.)

29 Comments
2025/01/12
14:21 UTC

36

Typechecking by "just running" the program?

Lately I've been thinking about implementing a typechecker by simply evaluating the entire program from top to bottom but with some notion on an "abstract value".

i.e most expressions will just return something like (int, *) instead of an actual (int, 10).

Expressions should still be able to catch type errors in this case.

Is there an actual name for this so I can find more literature?

24 Comments
2025/01/12
11:42 UTC

8

Compiling To Cuda/GPU, how? Guide/reference source code

Hello, i’m new to this language dev. I am trying to write a compile that will compile the program to run CUDA, how do I that?

Do i produce c++ code that uses cuda? What other options do i have? What kinda of knowledge do i need to know on top of this?

This is my first time writing a compiler and doing this generally and just wanna learn. Thank you for answering

9 Comments
2025/01/12
04:05 UTC

25

Manually-Called Garbage Collectors

Python is slow (partially) because it has an automatic garbage collector. C is fast (partially) because it doesn't. Are there any languages that have a gc but only run when called? I am starting to learn Java, and just found out about System.gc(), and also that nobody really uses it because the gc runs in the background anyway. My thought is like if you had a game, you called the gc whenever high efficiency wasn't needed, like when you pause, or switch from the main game to the title screen. Would it not be more efficient to have a gc that runs only when you want it to? Are there languages/libraries that do this? If not, why?

60 Comments
2025/01/11
17:02 UTC

15

How would you get GitHub sponsors?

This is more curiosity than anything, though Toy's repo does have the sponsor stuff enabled.

Is there some kind of group that goes around boosting promising languages? Or is it a grass-roots situation?

Flaring this as a discussion, because I hope this helps someone.

33 Comments
2025/01/11
00:39 UTC

Back To Top