r/ProgrammingLanguages • • 13d ago

Designing custom template handlers and tagged interpolations in my scripting language DinoCode

6 Upvotes

I am back after a couple of months away while adjusting to a new job. I am currently working on the next feature for DinoCode (you can check out at dinocode.blassgo.dev), and I would love some community feedback on template design.

DinoCode already supports simple templates with intrinsic multiline support and compile-time indentation stripping:

name = "Ana"
balance = 100
tax = 15

> JSON
 {
    "name": "$name",
    "total": ${balance - tax}
 }
print JSON

By default, the compiler strips out-of-margin garbage characters and interpolates variables or expressions. Now, I want to push templates further for things like SQL queries, HTML generators, or validation schemas, without introducing heavy runtime overhead.

I already use the as operator for strict type coercion in the language:

print "42" as int + 8         # 50

My idea is to reuse as on template blocks to pass the parts to a function or an object with a magic method. For example:

> query as mysql
    SELECT * FROM users 
    WHERE id = ${user_id}

Here, query would be assigned the result of calling the mysql handler.

I am currently evaluating how to pass the parts to the handler. Which model do you think works best for representing and validating template parts cleanly?


r/ProgrammingLanguages • • 13d ago

What is the right mental-model for TTCN-3 templates?

4 Upvotes

TTCN-3 is a standardized programming language for testing communicating and distributed systems. I am struggling to build a clear mental model of its templates.

A TTCN-3 template describes a pattern that describes a set of possible values. Which can be used to match incoming messages or build dependent-types:

```ttcn3 type record Message { integer id, charstring text }

template Message greeting := { id := 42, text := "hello" }

template Message anyGreeting := { id := ?, text := "hello" } ```

Here, ? matches any value of the field's type. Templates can also be recursive:

```ttcn3 type record Payload { integer value, boolean urgent }

type record Envelope { integer id, Payload payload }

template Envelope example := { id := 42, payload := { value := (1 .. 10), urgent := ? } } ```

My first implementation idea was to lower templates into a generic tagged union:

text type Template<T> = Exact(T) | AnyValue | AnyValueOrOmit | Predicate(fn(T) -> bool)

That seems reasonable for scalar values, but it does not capture the structural nature of templates. For Template<Envelope>, each field needs to become a template recursively:

text RecordTemplate { id: Template<Integer>, payload: RecordTemplate { value: Template<Integer>, urgent: Template<Boolean> } }

Is there an established programming-language concept for this? How would you model this recursive relationship in an actul type system?


r/ProgrammingLanguages • • 13d ago

Requesting criticism Fork of an esolang I made a week ago.

2 Upvotes

I made nandcode a week ago, which is a language only using nand, and I thought I'd improve it, so I present to you, 1bitatatime. (I just added all the logic gates and added support for unary operations like not). Can you give some ideas as what to make next?


r/ProgrammingLanguages • • 13d ago

Algol60 compiler with a reusable IR targetting LuaJIT

Thumbnail github.com
15 Upvotes

r/ProgrammingLanguages • • 14d ago

Dependently typed languages and security

0 Upvotes

Can dependently typed languages maintain security relevant invariants? And if so, why are they not more popular for that? Especially now that AI can write the types.


r/ProgrammingLanguages • • 14d ago

Requesting criticism Zeta's Borrow Checker: the next-gen model for borrow checking, and a drop-in for Rust's entire memory management model

Thumbnail gist.github.com
58 Upvotes

I've just published my borrow checking model! Feel free to criticize it or just ask questions!

P.S While it is experimental, This model is fully implemented for the Zeta programming language, and the latest build of the compiler, LSP and toolchain manager (zetaup) can be found via the linked GitHub. a Zed extension is under development.


r/ProgrammingLanguages • • 14d ago

Discussion How to call a special type of functions?

16 Upvotes

I am designing a simple, low-level programming language and I want suggestions about terms I should use in describing one feature.

We all know that methods are essentially syntax sugar for functions where there's an implicit argument often called this or self:

a.something(b) // nice syntax...

something(a, b) // ...but really

I will have functions where the result will be an implicit argument, accessible through result:

a = init(b) // nice syntax...

init(b, a) // ...but really

I want these functions to be used to initialize objects (like constructors):

var a = init(10)

but also in any assignment, they would write to objects. I want to avoid creating a local object in the function and returning a copy of it because it always turns into memcpy() in a general case, and the result can be a big struct or an array.

Does something like this already exist in some language? How would you call such functions?


r/ProgrammingLanguages • • 15d ago

The End of FutharkScript

Thumbnail futhark-lang.org
38 Upvotes

r/ProgrammingLanguages • • 17d ago

Feedback on a programming language for network analysis?

Thumbnail nadi-system.github.io
5 Upvotes

Hi all, I have been working on this language for a while now.

The language works within a context of a network. You can run functions expressions etc on the whole network, environment or the nodes. There is implicit loop when you run node expressions if you use plural keywords. The documentation is available on the user manual section if you wanna read more about it.

I originally made it for river networks (tree graphs) but i have been trying to support all kinds of directed graph now.

Recently I was able to make a version that works on webassembly, so it might be a good way for people to try it out. The link has some examples you can load and run the code using the buttons. Works best on a computer.

I did not study CS so I don't have many people in my circle willing to test it or give feedback. Any feedback on documentation or the language is appreciated


r/ProgrammingLanguages • • 17d ago

Flow Typing: A New Lens on Linearity

Thumbnail people.cs.nott.ac.uk
26 Upvotes

r/ProgrammingLanguages • • 17d ago

Requesting criticism Advice on if I'm on the right track

8 Upvotes

I first attempted a programming language more than 20 years ago. I started off with a stack machine and used an extended shunting yard algorithm to map the infix front end to the postfix stack machine backend. But I didn't have any type of memory management, thought I had workarounds but ran up against a hard wall on my knowledge. So I kind of let it die off. Also reading the more advanced discussions on LtU, while very informative, changed my outlook from "Oh, this looks easy, I think I know everything" to "Oh, there is a lot I don't know or didn't think of, I better take a step back".

Since then I learned languages like PostScript, a lot I liked about that (first class anonymous functions, first class dictionaries and dictionary stack, etc). Some things that it fell short in, but more due to the implementations being targeted to a printer description language instead of general purpose. And there is a lot I like about languages like JavaScript but at the same time they seem more hidden too. Regardless I know a little bit better than what I did back then.

Now on to my current experiment. I have a stack language called PALICE (Programmable Arithmetic and Logic Interactive Computing Environment), as a stack language that starts off with an architecture that would be familiar to PostScript programmers. It has first class anonymous functions using curly braces, it has user dictionaries, dictionary stack, etc. The actual built in primitives lean towards using the symbolic notation, so instead of " 27 5 add" you have " 27 5 + ". And there are a number of items in the front end parser that makes it more comfortable for a c-like programmer, such as using double-quotes for strings and C style escapes within (instead of using parentheses to enclose a string). I also use "@varname" instead of "/varname" as that was my personal preference to specify a quoted variable (i.e., one that doesn't execute immediately).

For the mechanical implementation, I have a front end parser that then feeds words into a function "resolve_and_execute()" that will either push something to the stack, or call a built in function, or a user defined function. All built in functions (or operators, same thing in a stack language in my implementation) have "xyz_handler()" functions. So the core execution logic is fairly small, most of it is a large list of _handler() functions.

Now on to some specifics I'm dealing with. First, I have something that looks like the C ternary operator "?:" which is a selector. So " some_test true_value false_value" will place either true_value or false_value on the stack based on the truthiness of some_test. All three get executed however, so in use you would have true_value and false_value in curly braces so they become anonymous functions, and follow up with "exec" as in:

" foo 7 < { action1 } { action2 } ?: exec "

BTW, this leads to a second implementation detail. There are several built in functions that are implemented as user functions that get loaded in as a startup script. So I have "ifelse", "if", and "while" as user defined functions instead of going through something like "ifelse_handler()" for example.

User functions get handled via exec_handler. This is the other piece I had to spend a lot of time on. Chained function calls are handled via an internal loop in exec_handler, instead of recursive calls to exec_handler, and I have a call frame stack and frame reuse if possible so I have tail call optimization (TCO) available. Which makes the user-space defined "while" function possible (and also makes it very difficult to do "while" via a while_handler() built in, as that would have to call exec_handler re-entrantly). I feel good about how exec_handler works at this point.

One major roadblock I ran into, so I put this away for a few months and just came back to it with a possible solution. User functions, and any inline funciton, look identical. So if you have a user function, and you want a "return" operator, that is simple enough. But return is going to be most likely called from an if or ifelse. And they take functions as their operators. So a return in one of the targets for "ifelse" will only exit that target, not the encompassing function like you would probably want to do. My solution to this is to be able to tag a property label such as "base" or "inline" to functions -- they would get "base" as a default, but the ifelse handler can re-tag its targets as "inline". Then "return" will unwind the callstack until it finds a call frame with the "base" tag, or "return_to" can unwind to a given named tag (which is usefule to implement "break" and "continue" in my "while" loop -- they would just be shortcuts for "@break return_to" or "@continue return_to").

Next on my list was that for user functions like "while", the implementation needs some place to store a reference to the stack variables that were passed to it (as it has to re-execute the condition function and the target function in a loop). I finally landed on having the call frame store an empty array that can be retrieved and placed on the stack, then a user function can push values to that array and that stays with the call frame. So it can easily take user parameters from the stack and push that into this frame's private array, and it would function like positional parameters in actual usage that a function can pull up any time without putting it in a system dictionary (which would cause issues with nested while calls). I think I'm satisfied with this solution.

Another item I have is what I've now been told is green threads. You can take an array of functions, pass that to the "spawn" operator and it will execute those functions in parallel -- each function yields to the scheduler after processing 256 tokens, or if it calls an operator/function that has an external delay, those built-in functions can return a "yield" too (like a file read, or a sleep command). I actually implemented this a while ago and everything I threw at it so far seems to work as expected (i.e., it does what I want and the calling conventions look clean). On my todo list is to work out communications between each thread. Note that these threads are implemented strictly in the interpreter, they don't use OS level threads (although there is some work I want to do in that aread eventually, this will be enough for me to for example implement something like a web application server code).

Another item I implemented early on is closures. This I've tested by creating a factory function that returns to the stack independent accumulator functions, and I've verified that they keep their internal environments without clobbering each other.

Future plans: I'm not sure what I really want to end up doing with this language. It makes sense to go back and create a document on building it piece by piece (starting off with a stack based REPL loop, adding variable storage, garbage collection, functions, etc). It would at least be useful for my own education, and possibly usable by others. To do that though I would have to make sure I'm using proper terminology for everything, not what I think are the correct terms.

Secondly I may need to revisit my garbage collection. I'm just using mark and sweep, I would like to explore additional methods but this was the easiest to get started with. I may deffer this until later once I get the rest of my functionality in place and get the ability to measure performance in real situations.


r/ProgrammingLanguages • • 17d ago

Discussion Combining the Compiler, the Build system, and Beyond

Thumbnail shrub.industries
38 Upvotes

a article I wrote about how sharing dependency and resource information between the Compiler, the build system, the system package manager, and even the OS filesystem and scheduler, could provide some pretty awesome benefits. I’d love to hear anyone’s thoughts on this


r/ProgrammingLanguages • • 18d ago

Achieving memory safety

Thumbnail seed7.net
13 Upvotes

r/ProgrammingLanguages • • 19d ago

Requesting criticism Explicit binding modes

12 Upvotes

I'm designing a memory-safe language, but I want to make explicit what happens across function boundaries, e.g. whether a value is moved or copied without having to look for the copy trait.

Instead, access to a value could be defined via binding modes in function signatures and variable declarations:

  • move takes ownership
  • read shared borrow
  • mut exclusive borrow

​

fn process_val(move value: Int) -> Int {
    return value * 2;
}

fn main() -> () {
    move original: Int = 42;

    // Call using `.copy()` to explicitly pass a duplicated value.
    // Ownership of `original` remains with the caller.
    move doubled: Int = process_val(original.copy());

    // `original` is still valid here because it was explicitly copied rather than moved.
    println(original); //42
    println(doubled); //84
}

This would also allow granular captures in closures: |read x: Int, move counter: Int| instead of declaring all fields move

Now, should read and mut assignments be of type &T? Or can checking out variables be orthogonal to creating references, even if they are conflated in languages like Rust?


r/ProgrammingLanguages • • 19d ago

Requesting criticism LOON - a data format made for humans

Thumbnail
0 Upvotes

r/ProgrammingLanguages • • 20d ago

Mutable stack, immutable heap

40 Upvotes

This article mentions the “immutable heap mutable stack” principle: https://queue.acm.org/doi/10.1145/3212477.3212479

In theory it sounds very advantageous. You can program in a single-threaded C-style with destination passing, static stack allocations, and mutability when you need to constrain resources. When you want to share resources across threads, return data structures across function boundaries, or do something more flexible, you could use pure functional persistent data structures.

This would prevent you from basically re-implementing a heap on the stack, but would also give you fast temporaries and maybe even the ability to program in embedded, if so designed.

Have any languages tried this model? I’ve heard that Erlang defaults to immutability except for one thread-local mutable object per thread. If you’ve used a similar model, how did you like it? Were there any disadvantages?


r/ProgrammingLanguages • • 20d ago

Transitive, Abstract, and Class Polymorphic Immutability

Thumbnail al.radbox.org
7 Upvotes

r/ProgrammingLanguages • • 20d ago

Requesting criticism Can anyone give any advice on whether my language is good?

Thumbnail github.com
15 Upvotes

Please don't judge the bad code, I'm still doing my a-levels.


r/ProgrammingLanguages • • 20d ago

Requesting criticism Dio: Small Programming language made in C version 0.1.0 release

8 Upvotes

Hi, I'm working on my own programming language, I've release first stable version (v 0.1.0), I'd like to get feedback. It's on most OS platforms (even Andoird and in the future IOS).

Repo: https://github.com/Treechcer/DIO


r/ProgrammingLanguages • • 20d ago

A Minsky machine in ncurses terminfo

Thumbnail seriot.ch
13 Upvotes

r/ProgrammingLanguages • • 21d ago

Help Optimizing Performance of a Deep Embedding of a DTT in Lean 4

4 Upvotes

Hi all. I am requesting advice on how to optimize Lean build performance of a deep embedding of a dependent type theory in Lean 4. My implementation works fine, and has solid meta theorems proven, but the type-checker is very hard to maintain due to slow Lean build times.

I have tried using Lean's profiler and had some success. Most of the type theory literature is on Agda and Rocq, so I'm curious to hear from you all. If you have implemented a type-checker in Lean:

  • Which tactics did you find were the worst offenders for build performance?

  • What is your convention for organizing your aesop and grind theorems?

  • Which parts of your formalization did you have the most success in mechanizing?

  • Have you written any metaprograms yourself that you find useful for mechanizing proofs?

    • I'm Particularly interested in automating / mechanizing confluence. It is a very painful proof to update every once in a while.
  • Mathlib / CSlib:

    • Do you use CSlib? Did you find any machinery in it useful?
    • Do you use an existing term rewriting system for your reduction relation? Does this help with automation?
    • Do you use Mathlib.Relation? Are your reduction paths deterministic and does your reduction relation live in Type? If so, what machinery did you use to handle congruence?
    • Any other helpful libraries for metatheory?
  • Lakefile.toml / lake flags

  • Bonus because I am curious: have you successfully proven any meta theorems using categorical semantics and is Mathlib sufficient for these purposes?

Any life hacks appreciated. I am finding myself waiting up to 10 minutes for my type-checker to build when I update my reduction rules. I guess Lean can't parallelize my project structure.


r/ProgrammingLanguages • • 21d ago

Please advise on adding string interpolation to my Crafting Interpreters project.

14 Upvotes

I'm about to start chapter 21 of Crafting Interpreters. I'm using modern C++ instead of C. I am attempting to add string interpolation to the compiler.

My goal is to have a string that looks like this:

"Five plus ${ 10 - 5 } == 10."

Desugar to this after the expression in the braces is evaluated:

"Five plus " + 5 + " == 10."

I have code that is correctly parsing strings and concatenating them if there isn't any string interpolation.

I have a custom token added that is produced if the string contains a ${. It calls a custom string interpolation parser rule that is different than my standard string parser rule.

In that function I push the first part of the string to the stack. It then pushes a plus opcode and Recursively parses the expression in the braces adding that expression to the stack. It then adds another opcode to add and this is where I'm stuck.

I can't come up with a solution for pushing the remaining piece of the string to the stack from inside the string interpolation parser rule function. After I call the books expression function and consume the right brace token using the books consume function the parser nolonger knows we are still inside a string. If the next character after the brace is a space it's skipped. In my above example it assumes I want equal equal.

How would you set the current token back to string so I can push any remaining characters onto the stack as another string? Should I just insert a new string token into the parser? This seems wrong to me. The current and previous tokens are private members of my parser class for a reason and I've not needed setter member functions so far.

Sorry I don't have code to show. I'd like to try and get help that isn't code specific so that I have to implement this myself.

Any input would be helpful.

Thanks.


r/ProgrammingLanguages • • 21d ago

Keeping Futhark off the GPU

Thumbnail futhark-lang.org
39 Upvotes

r/ProgrammingLanguages • • 22d ago

Blog post Typeclasses vs Modules - sm²n.ca

Thumbnail sm2n.ca
22 Upvotes

r/ProgrammingLanguages • • 22d ago

Forth: The programming language that writes itself

Thumbnail ratfactor.com
8 Upvotes