Skip to content

[Final Project] Bristle#639

Open
pedropontesgarcia wants to merge 1 commit into
sampsyo:2025fafrom
pedropontesgarcia:fp-helen-pedro
Open

[Final Project] Bristle#639
pedropontesgarcia wants to merge 1 commit into
sampsyo:2025fafrom
pedropontesgarcia:fp-helen-pedro

Conversation

@pedropontesgarcia

Copy link
Copy Markdown
Contributor

Closes #605.

@sampsyo sampsyo left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work, y'all. It's great that you got something working end to end.

Your writeup has a few good high-level outlines here, but there are a couple of missing pieces:

  • A high-level catalog of exactly what your compiler does, outside of the defunctionalization step (which you have covered in more detail). Can you say anything about how it works in a way that would, for example, be helpful for someone trying to do a similar project?
  • Details about your correctness evaluation.

Would you be willing to add a few details on both fronts? When you're ready, use GitHub's "request review" button to let me know to take another look.


We did not include the tuple or array features of MinCaml, as we felt these would be annoying and less relevant to implement in Bril. Nonetheless, arrays could be implemented relatively easily using the Bril memory extension.

We also implemented the basics of a “function reference” extension in Bril. Since it isn’t always possible to know which function will be called at compile-time, we implemented this functionality on top of the Brili interpreter and the associated TypeScript Bril library. Since we wrote our compiler in Rust, we also updated the Bril-rs library to handle our extension.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would y'all be interested in merging this stuff in to the Bril monorepo? I can imagine this extension being useful for future students. I would probably be interested in extending to have precise function types, but I'm happy to help work on that as part of the merge process if you're interested.


We built a compiler for a typed non-Lisp language, and wanted to minimize modifications to Bril (after all, it is technically supposed to be an IR, not an interpreter). We encountered a lack of documentation around our case and skill level.

There don’t seem to be many resources which detail in depth what components are necessary for compiling a functional language, so we had to figure these out on our own. The MinCaml reference implementation was somewhat helpful, but is actually too specific—it targets machine code, which permits, for example, looser forms of handling closures and memory, which we were not interested in doing in Bril. It also proposes converting the input code into K-normal form, for which there is a lack of documentation around on the internet. Information around ML-family languages was also difficult to find due to the abundance of machine learning content.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it would be possible to distill a list of things your compiler does do in the end? As you say, there are not many clear references out there for what is entailed in compiling a language like MinCaml to a target like Bril. Therefore, your blog post here could be really valuable for other people wondering about this! Could you provide a bulleted list of the phases the program goes through, where defunctionalization is just one of the phases? That could help clarify exactly what the "recipe" is for a compiler like this.


This leads into one of the hardest tasks for us: properly supporting first-class functions within the constraints of Bril. We went down multiple rabbit holes about lambda lifting and closure conversion, only to find information that was often confusing and misleading. We found very disparate notions of what these two concepts meant. Literature around these topics was somewhat sparse, very advanced, and again often applied to different languages targeting a different set of constraints. The terminology for “lambdas”, “closures”, etc. was also used very loosely.

To make the work more manageable, we chose to focus on what outcomes we wanted to support. We wanted to support some form of closure (which we define as functions that take in state from the scope in which they are defined) and function references (assigning a function, without inputs, to a variable). We also added the function reference extension to Bril, which keeps the spirit of the language in supporting a minimal version of functionality we needed. We used the original lambda lifting implementation described in Johnsson 1984, to aid in defunctionalisation, rather than using conflicting definitions of closure conversion. It is able to lift some closures to the top level, such as in the [`cls-bug.ml` benchmark](https://codeberg.org/pedropontesgarcia/bristle/src/branch/main/test/cls-bug.ml).

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide a link to Johnsson 1984.


## Were we successful?

We’d say so, yes! Our compiler supports a surprisingly large amount of the MinCaml specification, and we were able to run some worthwhile programs—for example, a square root approximation—using the result. While we didn’t get as much optimization in as we had hoped for, we encountered enough complexity in the core task of converting a functional language with first-class functions and lexical scope to Bril. We think that, given the unexpected challenges, accomplishing this task is sufficient.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you provide a little more detail about your evaluation? For example:

  • Where did you get the benchmarks?
  • How many benchmarks?
  • How diverse were they? How long?
  • How did you get the expected output?
  • How did you compare your implementation to the expected output?

@sampsyo sampsyo added the 2025fa label Dec 23, 2025
@mercure67

Copy link
Copy Markdown
Contributor

i've applied some of the relevant changes to pedro and i's google doc. they will most likely be PRed after break.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Project Proposal: broil ( a lisp in bril)

3 participants