1
14
submitted 2 months ago by armchair_progamer to c/programming_languages

How much progress have you made since last time? What new ideas have you stumbled upon, what old ideas have you abandoned? What new projects have you started? What are you working on?

Once again, feel free to share anything you’ve been working on, old or new, simple or complex, tiny or huge, whether you want to share and discuss it, or simply brag about it - or just about anything you feel like sharing!

The monthly thread is the place for you to engage /c/programming_languages on things that you might not have wanted to put up a post for - progress, ideas, maybe even a slick new chair you built in your garage. Share your projects and thoughts on others’ ideas, and most importantly, have a great and productive month!

Also see: https://www.reddit.com/r/ProgrammingLanguages/comments/1b3fqrz/march_2024_monthly_what_are_you_working_on_thread/

2
7
submitted 1 day ago* (last edited 1 day ago) by armchair_progamer to c/programming_languages

Another post from the creator of Vale, the last one was "Borrow checking, RC, GC, and the Eleven (!) Other Memory Safety Approaches".

This discusses Vale's higher RAII, a feature implemented using linear types. Vale has linear types as opposed to Rust's affine types: affine types prevent using a value after it's "moved", but linear types also prevent not moving a value (i.e. cannot just let it go out of scope). Additionally in Vale, one can define a set of functions that destroy a type, and in order to destroy a value of that type, one must call a function from that set; that is what Vale calls "higher RAII".

This part of the linked post contains seven examples where Vale's higher RAII enforce invariants that Rust's affine types cannot. In a language like C, you can "forget" to use a value and it will leak. In a language like Rust, the value will be properly deallocated, but you can still have "forgotten" about it, e.g. perhaps the value represents a transaction that you meant to commit (one of the seven examples). In Vale, you can't forget about a value as long as it has a linear type, because doing so will raise a compile-time error.

The rest of the post further discusses higher RAII, elaborating on what it is and why its useful, explaining why it's more general than other languages' defer and how it could be integrated into other languages, and more.

3
28
submitted 3 days ago* (last edited 3 days ago) by armchair_progamer to c/programming_languages

From the site:

We have entered a world in which we need to do more with less. If you, like us, have frowned at the difficulty and inefficiency of creating software, and wondered if there is a better way, Meta is for you. It is a descendant of the acclaimed REBOL and Logo computer languages. Logo was designed in academia to teach programming in a simple yet powerful way. It is widely used in education and influenced many newer systems and languages. REBOL extended this concept to professional programming. It was invented by Carl Sassenrath, the chief software designer of the famous Amiga computer, the first consumer multimedia system. Meta takes the next step by combining this design with the virtues of the C programming language, which has been the standard for software interoperability and performance for half a century.

meta-lang-examples (GitHub)

Try online ("console")

4
15
Exploring the c4... compiler? (registerspill.thorstenball.com)
submitted 4 days ago* (last edited 4 days ago) by armchair_progamer to c/programming_languages

c4 ("C in four functions"; GitHub)

I remember coming across c4 when it was released ten years ago. It got me excited: hey, C in four functions, that means it’s easy to understand right?

That excitement turned into “oh, I see” as soon as I scrolled through the code. c4 is dense, barely commented, and, frankly, strange. It’s unlike anything else I had come across in compiler land.

After reading through the code this week here are the other adjectives I would add to the list: clever, tricky, fascinating, cool. It’s a compiler, it’s a VM, it’s an interpreter, it’s a parser, it’s art, it’s trickshot programming.

Not to be confused with C3, "a programming language that builds on the syntax and semantics of the C language, with the goal of evolving it while still retaining familiarity for C programmers".

5
16

After getting angry at Lua for bugs reappearing after fixing them, and otherwise having issues with making it interoperable with my own language of choice (D), I decided to roll out my own VM out, with some enhanced optional features compared to regular Lua (type safety, static arrays on the stack, enhanced metatables, etc.), and also allowing the potential of other scripting languages to be ported to the VM. As I already have crafted a VM for a programmable MIDI format (M2: Docs / Implementation ; bit incomplete as of now), I thought it'll be easy, just don't optimize this time entirely around preallocation (M2 has 128 not entirely general purpose registers per pattern (musical thread) + 128 shared registers + shared arrays), add stack handling, add heap handling, add more types, etc.

Thus I begun working on PingusVM, to contribute to the problem of ever growing number of standards.

However, as time went by, I had to realize (just like every time I've added another engine feature) that it's way more complicated, especially as I have realized mid-development that I had a lot of oversight on design. Not only that, I have a lot of other projects, such as the game engine I've originally intended the VM for. My main issue is, potential candidates either lack integer support, or are very bloated (I don't need a second XML DOM parser, etc). Lua kind of worked, but after I fixed an issue (which was hard as every tutorial implied you just wanted to load a file directly instead of having the ability of loading the text directly) a very similar one reappeared, while following every tutorial possible. Others would lead me to introduce some C-style build system, as they would need "hard linking" to my engine, and that "hard linking" is why I had to halt development of my image library, as I would have needed to introduce a build system into my project for the LZW codec (required for GIF files).

6
10
submitted 5 days ago by armchair_progamer to c/programming_languages

Implementing first class functions in a bytecode interpreter is trivial.

But how do compilers that generate machine code (or lower to C, or SSA) implement higher order functions? Back in 2021, I found an answer when contributing closures to the Pallene compiler.

Today I was researching something loosely related, and found yet another neat trick called defunctionalization in this paper.

Defunctionalization is a transform -- a way to re-write the original program without using higher order functions such that it can be trivially compiled to a flat IR in subsequent compiler passes.

The paper uses an OCaml example, and I'll be porting the same program to Haskell. Our implementation will assume that the language being compiled supports GADTs, though it's certainly possible to defunctionalize without them.

7
16
submitted 1 week ago by armchair_progamer to c/programming_languages

For the last year and a half, I and my recently-added collaborator Jane Losare-Lusby have been working in secret on a safe systems language that could be learned about as quickly as one can learn Go. I think we might have something worth exploring.

June (programming language) GitHub

8
18
submitted 1 week ago* (last edited 1 week ago) by armchair_progamer to c/programming_languages

From the homepage:

Thinking in services

Jolie crystallises the programming concepts of service-oriented computing as linguistic constructs. The basic building blocks of software are not objects or functions, but rather services that can be relocated and replicated as needed. A composition of services is a service.

Tailored for microservices and APIs

Jolie is a contract-first programming language, which puts API design at the forefront. It supports both synchronous and asynchronous communication. Data models are defined by types that support refinement [...], and DTO (Data Transfer Objects) transformations are transparently managed by the interpreter.

From vision:

Our vision is to design a programming language with a different trade-off: instead of optimising for computation, the aim of Jolie is to offer native abstractions for the creation and composition of services.

By shifting the focus on services from libraries and frameworks to the programming language, we can change significantly how programmers manage their knowledge regarding service programming. The key idea is that the important abstractions for service programming should be crystallised in the programming language, translating to an easier learning curve for new service developers and less knowledge to be managed.

9
4
submitted 1 week ago* (last edited 1 week ago) by armchair_progamer to c/programming_languages

This was a conference at MIT that was held 2 days ago. The presentations are all recorded here, and there are summaries and links to the presented papers on the main site.

The mission of the MIT PL Review is to highlight recent developments that we believe have significant potential to shape the future direction of PL research and/or industry practice. We aim to select papers that may substantially transform the PL community and beyond, with a focus on emerging trends rather than established lines of research. We favor papers whose contributions are broadly accessible (and likely to be appreciated) across the PL community, but we do not limit the papers to those published at PL venues. Our selection process is not meant to provide an objective evaluation of works but rather to highlight and celebrate works that resonated with our committee members.

See also: PL Review 2023

10
7
submitted 1 week ago* (last edited 1 week ago) by armchair_progamer to c/programming_languages

Algebraic Subtyping is a type system devised by Stephen Dolan in 2016, in his dissertation. It extends Hindley-Milner with subtyping, in a way that preserves decidability and principality. Over the past few years, I have implemented Algebraic Subtyping in my language Pinafore (omitting record types). Pinafore is, as far as I know, currently the only language to implement this type system besides Dolan's own MLsub prototype.

See also: Pinafore and Sixteen Unusual Things about Pinafore

11
14
submitted 1 week ago by ChubakPDP11 to c/programming_languages

These toolchain are created for experts to create industrial-level compilers. Even if you think you got a syntactic design concept that is such hot shit that you can't wait to get it bootstrapped, even if hell, it proves Rice's theorem wrong, please, write a simple interpreter for it to prove your syntax works. In fact, I think one way you can test your language's design is to have it mooch off an established VM like JVM, CPython's VM or CLR.

But if you wanna 'learn' compiler design, I beg you to roll your own backend. You don't need SSA or any of that shit. You don't need to super-optimize the output at first try. Just make a tree-rewrite optimizer and that's that.

Same is true with LP generators. From Yacc to ANTLR, they just make the experience harder and less rewarding. I know hand-rolling LP is hard in a language like C, in which case, don't fucking use it lol. There's honestly no inherent worth in using C in 2024 for compiler design.

But there's still use for C in being the subject of your compiler. It's a very simple, straightforward and more importantly, standardized language, you don't need to write a runtime for it, because when it comes to both UNIX and Windows, runtime is OS itself! Just make sure you add a syscall interface and then C runtimes like glibc and CRT can be easily strapped.

I'm going to do exactly this. I named my C compiler 'Cephyr'. I have started over several times now. I am using OCaml.

I know my point about using LP generators is preaching to the choir and most people despise them


but I just don't understand why people love to use IRs/ILs when doing so teaches you shit.

I recommend beginning to design your language with the IR -- your IR.

I don't just wanna focus on Cephyr. There are other stuff I wanna do, like Nock, a PostScript interpreter in Rust (because GhostScript had made me hard-reset 4-5 times. GhostScript is just un-secure, leaky garbage).

Anyways tell me what you think about my 'take' on this. Of course I am not saying you are 'less knowledgeable' for using LLM or MLIR, I'm just saying, they don't teach you stuff.

Still, some people just use LLVM and MLIR as a final 'portable' interface, having done the optimization on graphs and trees. i think there should be some sort of 'retargatble assembly' language. Like something with fixed number of registers which.. oh wait that's just a VM!

Also you don't need to necessarily translate to a super super low-level language. Just target C. GNU C to be exact. Cyclone does that, in fact, I am planning to bootstrap my functional language, which I named 'Xeph', based on Zephyr ASDL, into GNU C as a test. Or I might use JVM. I dunno. JVM languages are big these days.

PS: Do you guys know any cool VMs I can target beside CPython and JVM? Something with AoT perhaps?

Thanks.

12
10
submitted 2 weeks ago* (last edited 2 weeks ago) by armchair_progamer to c/programming_languages

From the GitHub:

Cognition is a fully introspective system designed so that the syntax and hierarchy structure of the language is fully public; that is, a file that contains cognition code can alter the way that it is being parsed, in real time. Cognition allows for this because the language is completely postfix with extremely minimal syntax, and what exists of the syntax can be changed at will. Because the language never reads more than it has to, and because the language allows for metaprogramming (talking about symbols as if they are data, as well as code), the syntax of the language is made fluid. This allows for the advanced manipulation of how the next token is tokenized, and how these tokens are arranged into something like the AST without having to explicitly program a rigid syntax.

The linked post introduces Cognition and the philosophy behind it, while guiding the reader though an example Cognition program. The program starts out like gibberish, but using Cognition's metaprogramming capabilities, gradually adopts a more readable syntax to build something useful (a Brainfuck interpreter).

13
23
Borgo (language) (borgo-lang.github.io)
submitted 2 weeks ago by armchair_progamer to c/programming_languages

GitHub

Image from the site

Borgo is a new programming language that compiles to Go.

use fmt

enum NetworkState<T> {
    Loading,
    Failed(int),
    Success(T),
}

struct Response {
    title: string,
    duration: int,
}

fn main() {
    let res = Response {
        title: "Hello world",
       duration: 0,
    }

    let state = NetworkState.Success(res)

    let msg = match state {
        NetworkState.Loading => "still loading",
        NetworkState.Failed(code) => fmt.Sprintf("Got error code: %d", code),
        NetworkState.Success(res) => res.title,
    }

    fmt.Println(msg)
}
14
5
submitted 2 weeks ago by armchair_progamer to c/programming_languages
15
3
submitted 2 weeks ago* (last edited 2 weeks ago) by armchair_progamer to c/programming_languages

Befreak is a purely reversible two-dimensional programming language. It was inspired by the Chris Pressey's Befunge programming language. Like Befunge, all Befreak instructions are written as a single character, and execution can flow north, south, east, and west.

The thing that makes Befreak special is its reversibility. Every instruction in Befreak is by its very nature reversible. At any point during execution, if you'd like, you can pause the system, toggle the "reverse" flag, and then upon resuming, the program will run itself backwards from its current state, eventually ending up at the very beginning, where it started. This feature is not accomplished by keeping a history of past states, but simply by virtue of the fact that each individual instruction is reversible. This means that Befreak contains no instructions that can destroy information; this can make programming in the language both challenging and interesting.

Example program (prints prime numbers):

    /1)@(1\         
    >)1=1(<         
    \'(v?)/         
       >'%s(\       
     ^ >*s)=/       
     >=<            
     (              
/s'0v^?w23(v`s]:(48\
[   (      )       +
)   =      =       4
0   c      c       8
1   =      =       )
%   )      (       w
\01(^      ^)01*01(/
16
8
submitted 3 weeks ago by armchair_progamer to c/programming_languages

*Lattice is a high-performance visual scripting system targeting Unity ECS. Read more here.

I wanted to write a few posts on the design of Lattice as a language. Today, let's focus on “composability”. This is intuitively something we desire in programming languages. Some systems feel like they are effortlessly reconfigurable, recombinable, and then others.. just don’t. Some languages seem to actively reject our efforts at organization.

17
23
submitted 3 weeks ago by armchair_progamer to c/programming_languages

The author of this blog is also the creator of Vale, an experimental language with generational references (which is one of the named approaches).

Another one of Vale's unique features is higher RAII, which forces the coder to call a function on a value to destroy it (a sort of linear type).

18
20
submitted 3 weeks ago* (last edited 3 weeks ago) by armchair_progamer to c/programming_languages

Today I am pleased to announce Beatrice, which is a finally tagless, dependently typed, self-aware functional programming language that I have been working on for quite a while. In this short blog post, I will demonstrate its most prominent features and contrast them to those of mainstream programming languages.

The "self-aware" is referring to homoiconicity:

Beatrice can represent its typed abstract syntax within itself. This allows us to manipulate Beatrice programs within Beatrice.

GitHub

Longer overview

19
3
submitted 3 weeks ago by armchair_progamer to c/programming_languages

One of my research group’s major goals is to create technologies that enable self-improving compilers. Taking humans out of the compiler-improvement loop will make this process orders of magnitude faster, and also the resulting compilers will tend to be correct by construction. One such technology is superoptimization, where we use an expensive search procedure to discover optimizations that are missing from a compiler. Another is generalization, which takes a specific optimization (perhaps, but not necessarily, discovered by a superoptimizer) and turns it into a broadly applicable form that is suitable for inclusion in a production compiler.

Together with a representative benchmark suite, superoptimization + generalization will result in a fully automated self-improvement loop for one part of an optimizing compiler: the peephole optimizer. In the rest of this piece I’ll sketch out an expanded version of this self-improvement loop that includes dataflow analyses.

20
5
Parsing and all that (blog.jeffsmits.net)
submitted 3 weeks ago by armchair_progamer to c/programming_languages

A longer article on the different types of parsers and how they work, with a lot of state machine diagrams and some Rust code samples.

21
10
submitted 3 weeks ago by armchair_progamer to c/programming_languages

For the past few months I’ve been mulling over some things that Russell Johnston made me realize about the relationship between effect systems and coroutines. You can read more of his thoughts on this subject here, but he made me realize that effect systems (like that found in Koka) and coroutines (like Rust’s async functions or generators) are in some ways isomorphic to one another. I’ve been pondering the differences between them, trying to figuring out the advantages and disadvantages of each.

A few weeks ago, Will Crichton posted something on Twitter that helped bring the contrast into sharper focus for me:

The entire field of PL right now: what if it was dynamically scoped…. but statically typed…………..? (effects, capabilities, contexts, metavariables…)

I’m just a humble language designer (and not a theorist of anything, especially not PL), so my focus is the difference in user experience and affordance. But this seems like a cutting insight and this property of effect handlers - static typing but dynamic scoping - seems to me to be a good jumping off point for understanding the difference between effect handlers and coroutines from a user perspective.

22
4
submitted 3 weeks ago by armchair_progamer to c/programming_languages

Project has been dead for several years but the idea seems interesting.

Abstract from the original paper:

ML is two languages in one: there is the core, with types and expressions, and there are modules, with signatures, structures and functors. Modules form a separate, higher-order functional language on top of the core. There are both practical and technical reasons for this stratification; yet, it creates substantial duplication in syntax and semantics, and it reduces expressiveness. For example, selecting a module cannot be made a dynamic decision. Language extensions allowing modules to be packaged up as first-class values have been proposed and implemented in different variations. However, they remedy expressiveness only to some extent, are syntactically cumbersome, and do not alleviate redundancy.

We propose a redesign of ML in which modules are truly first-class values, and core and module layer are unified into one language. In this "1ML", functions, functors, and even type constructors are one and the same construct; likewise, no distinction is made between structures, records, or tuples. Or viewed the other way round, everything is just ("a mode of use of") modules. Yet, 1ML does not require dependent types, and its type structure is expressible in terms of plain System Fω, in a minor variation of our F-ing modules approach. We introduce both an explicitly typed version of 1ML, and an extension with Damas/Milner-style implicit quantification. Type inference for this language is not complete, but, we argue, not substantially worse than for Standard ML.

An alternative view is that 1ML is a user-friendly surface syntax for System Fω that allows combining term and type abstraction in a more compositional manner than the bare calculus.

23
5
submitted 3 weeks ago by ChubakPDP11 to c/programming_languages

Hey. I have made some DSLs before, and for all of them, most of which were in C, I have used Flex and Bison. But this time I wanna use Scheme, Cyclone Scheme to be exact. I can potentially use Flex/Bison this time too, because Cyclone has a strong FFI to C.

But I'd rather innovate. I have been writing down the language's grammar in EBNF:

https://gist.github.com/Chubek/bd54df78fe1f71f46cb262ba990a209b

And my thinking is, why not turn this into a parser? Not something like BNFC that translates BNF (not EBNF) into several parser and lexer specifications plus an AST, I want it to translate EBNF into Scheme.

But if you read the grammar, you will realize that there are some places where it's not very descriptive and machine-friendly. For that reason, I think an LLM can help.

Now, I need your help. I am mostly active in systems programming. Like Assembly, C stuff. I don't know much about LLMs and this whole AI revolution. I did some work as an 'ML-engineer guy' (not an ML engineer, an ML-engineer guy, there's a difference!), so I know how this whole thing works. I have also read MITs standard book on mathematical optimization.

But I definitely need to use a pretrained model here. My knowledge of mathematical optimization is useless when you need like 28 million to train a model that would aide you with this?

I don't want to use an API. I wanna own my software. I do use ChatGPT as a search engine, but that's about it, I never owned Google anyways!

I know about HuggingFace. What model there do you think would help me?

Also, how do these weights work? If I bind one DNN framework to Cyclone, will the weights trained by another DNN framework work in it too? Do people use frameworks not written in C, so I would have to like triple-bind it? I know both Google's and Facebook's are in C. However they are in 'garbage c'. Well let's deal with that later.

Anyways, thanks for your help.

TL; DR:

I need an LLM that would be used in an EBNF -> Scheme parser generator.

24
5
submitted 3 weeks ago by armchair_progamer to c/programming_languages

This article sketches out the syntax for a small language and explains the design decisions.

Also see author's other posts, particularly Notes on Compiler IRs which summarizes the IR designs of various new-ish languages.

25
4
submitted 4 weeks ago by cli345 to c/programming_languages

This is just a very naive execution model for concurrency.

What do you think about it?

view more: next ›

Programming Languages

1013 readers
5 users here now

Hello!

This is the current Lemmy equivalent of https://www.reddit.com/r/ProgrammingLanguages/.

The content and rules are the same here as they are over there. Taken directly from the /r/ProgrammingLanguages overview:

This community 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 the right place to ask questions such as "What language should I use for X", "what language should I learn", and "what's your favorite language". Such questions should be posted in /c/learn_programming or /c/programming.

This is the right place for posts like the following:

See /r/ProgrammingLanguages for specific examples

Related online communities

founded 11 months ago
MODERATORS