HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
mrakgr
The-Spiral-Language
Python2018–2023
mrakgr / The-Spiral-Language

The-Spiral-Language

Functional language with intensional polymorphism and first-class staging.

12Distinct people
19Mentions
1Explicit recommenders
947GitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

Functional language with intensional polymorphism and first-class staging.

GitHub

Where it is used

No documented product use was verified in the last source check.

What people are saying

https://github.com/mrakgr/The-Spiral-Language/commit/1dee010... That one is really in the "mad scientist" mindset. I love it, I wish him and this project good luck.

s3m4j used a recommendation phrase. One indexed comment matches. This is a phrase match, not a verdict.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

No other repository is repeatedly linked in the same discussions.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 5:04:57 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year19 dated mentions

Observed mentions: 2018-07-12 22:27:23 UTC to 2023-01-14 11:01:05 UTC.

02468102018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 10 mentions; 1 submissions, 9 comments20182019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 3 mentions; 0 submissions, 3 comments2020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments20202021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 2 mentions; 1 submissions, 1 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 1 mentions; 1 submissions, 0 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 1 mentions; 1 submissions, 0 comments2023

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC1019
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC303
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC202
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC211
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC110
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC110

What Hacker News says

19 sources

Ask HN: How do I make my PL beneficial to the largest amount of people?

I originally started work on [Spiral](https://github.com/mrakgr/The-Spiral-Language) back in late 2016 because I wanted a functional language in which I could program novel AI hardware that hadn't existed at the time, and still doesn't, but it won't be long before it arrives. It took 3 years of full time work to get it to its current standard of quality, and I'd really feel comfortable programming new hardware devices in my favored functional style. I've designed Spiral so it is both extremely powerful, easy to use while being efficient enough to program devices like GPUs that can't even use heap allocation for their objects. I am not really concerned about what I'll do when I get access to Tenstorrent chips in six months; my personal needs for the language are met. But I would like it if I could spread the language more broadly, make it
Read the rest
useful for people other than myself and get people to sponsor my work on it. Here is the value proposition of Spiral. It is a high-level functional PL that has some features that other languages don't, but that isn't really the point. On mainstream devices like the x86 ones there are a lot of programming languages that are good, and it would be tedious to use Spiral to compile to such platforms compared to using such languages directly. It is a bit how ReasonML compiles to JS. Back when I tried it I found using Typescript easier to deal with. So that is not where I'd like to go into, though using Spiral would have benefits in certain areas. Rather, while reading the [CNX blog](https://www.cnx-software.com/) I realized that while consumer facing AI chips are not here yet, there is a lot of hardware development in the embedded space. They are heterogenous architecture. They have GPU and TPUs in addition to CPUs. And these cross platform interactions within the same system is something that existing languages are really poor at tackling. If you look at Python or C#, for example, you can't really program the GPU on them directly. They are CPU focused, and don't have the right semantics and would be too inefficient to program devices like GPUs directly. The way I've designed Spiral is that you can program the CPU and the GPU and whatever else from within the same language. It is not suitable for just GPUs, check this [demo out](https://github.com/mrakgr/PIM-Programming-In-Spiral-UPMEM-Demo). I recently did a backend for UPMEM devices, which are the first commercialized Process-In-Memory chips. I've posted the link to this on HN yesterday and on the Reddit embedded sub, but I got zero interest. And this is really a pity because that map kernel I've demoed is actually a big deal. Back when I first started working on Spiral, it took me 1.5 years of full time work to get to the point where I could write a program like that in the language. And without backend nesting of the kind that Spiral offers, it is impossible to write those kinds of programs no matter how skilled one is as a programmer. The kind of backend nesting I've demonstrated is not something you can do in F#, Python or any of the languages that I know of. I could easily create such backends for many kinds of hardware. And people would benefit from that because unlike the mainstream computing devices, the hardware coming down the pipeline will have poor language support, nothing on the level of what Spiral offers. For the kinds of heterogeneous architectures I am envisioning, the language designs that are good in the CPU-dominant era, will simply not be suited in the heterogeneous era. I need chances to demonstrate how good Spiral is, but I am not sure how to get them. If I do not get them, the future of computing will be a lot worse off. I wasn't there when Cuda was incumbent so I missed the boat on that, but I'd like it if Spiral became dominant on future computing devices. Not because I was the one who made the language, but simply because no other design is as suited for them.
5 points · Open discussion
Yeah I like this technique too. To put a name on it, it's a form of metaprogramming that could be called "staged programming" or "multi-stage programming", and there are a bunch nascent systems that do things like it: https://scala-lms.github.io/ -- Scala LMS is similar in that you replace type T in your algorithms with Ref<T>, and you get a code generator (compiler) rather than an interpreter. This links to a CACM article by the authors of Scala LMS: https://cs.stackexchange.com/questions/2869/what-are-staged-... https://andrewkelley.me/post/zig-programming-language-blurs-... -- Zig has a code generator for printf using compile-time metaprogramming. http://terralang.org/ -- You can write arbitrary Lua to generate Terra code, sort of like he's writing Python to generate LLVM code. I think this is more general and doesn't necessarily wor
Read the rest
k by retaining the structure of say solve_linear_system(). I'm not quite sure. But the problem domains they tackle are very similar to this (numerical code). TensorFlow also has two stages of computation -- you define a graph of objects in imperative Python, using Python operator overloading in the same way that LLVMCode in this example does. And then later the separate TensorFlow language is evaluated in parallel / distributed on GPUs. In one case you're defining an SSA graph of ops in LLVM; in the other case you're defining a graph of TensorFlow ops. Note that the semantics of TensorFlow language are distinct from the semantics of Python, e.g. https://ai.google/research/pubs/pub46196 One interesting language in the same vein is Spiral, with "first-class staging" for machine learning: https://github.com/mrakgr/The-Spiral-Language You can also do a lot of this with constexpr / templates in C++, although the syntax is horrible. As you allude to, these staged programming systems can have TWO languages or one. In the case of Scala and Zig it's one language, but in the case of Lua/Terra it's two. Arguably in the case of C++, it's two languages and not one. Another thing to search for is "partial evaluation". I still have to understand the difference more precisely, as alluded to in the link above. https://en.wikipedia.org/wiki/Multi-stage_programming The Python/RPython language pair in PyPy is also related: https://morepypy.blogspot.com/2018/09/the-first-15-years-of-...
In Outperforming everything with anything: Python? Sure, why not?
> As a matter of fact, it's what the compiler devs keep recomending. I definitely agree with them in this matter. Macros might have a role in language development, but they should not be a stand in for compiler optimizations. For safety and speed, the type system should be there. https://github.com/mrakgr/The-Spiral-Language/blob/0741959ac... Here is how the example you've shown could be done in Spiral. Maybe I should add express support for literal testing in pattern matching, but it is not a pattern that comes up too often by itself. > I feel like what Julia does is just more low level right now - And you get pretty far with just multiple dispatch! What you say is exactly right as pattern matching compiles down to those low level operations, so there no reason at all why those low level operations should be done by hand. Pattern matchin
Read the rest
g does not depend on a particular type system or whether the language is dynamic or static. There are only so many good ideas in programming languages and this is one of them. Though there is some overlap between pattern matching and multiple dispatch, the roles are different. The purpose of multiple dispatch is extensibility, but the purpose of pattern matching is destructuring. https://stackoverflow.com/questions/2502354/what-is-pattern-... Note the great disparity in the F# examples that do pattern matching and the C# examples that do manual reflection. https://github.com/mrakgr/The-Spiral-Language/blob/0741959ac... Here are a few very simple examples of it in action in Spiral. I use them as compiler tests. https://github.com/mrakgr/The-Spiral-Language/blob/0741959ac... Here is quite a complex example of how it is used in action. I won't go into detail of this here, but you can see how I repeatedly match on the contents of a module at different times in order to get more generic functionality for the kernel. The particular kernel shown here is the most complex one that exists in the library right now - I am yet to get to things like generic matrix multiplication and convolution, but I'll get there eventually. > I see how it sounds nice, but I can't really imagine right now how it would improve my life. Let me just say that it is really difficult to know ahead of time how a particular language feature would affect your programming life. I could have said the same thing about first class functions back in 2015. I am sure in the future there will be such features I can't even imagine right now. > And if we don't get it as part of the compiler, we can definitely do things like that with https://github.com/jrevels/Cassette.jl/ I'll have to watch the talk on this. Thanks for the link.
In The Spiral Language
> With your linked spiral code, I can't even really tell where the algorithm starts and where the setup code ends - which of course might easily be attributed to my unfamiliarity with Spiral ;) Heh, I've noticed that the setup code tends to come out longer than the actual kernels. It is inside `kernel = cuda`. Spiral is indentation sensitive like Python and F#. The stuff inside {} is just module creation, think of it like tuples with named fields. > Do you have any benchmarks for the softmax kernel? If that kernel has optimal performance, it would be quite interesting. If it's sup par, it looks much longer than a simple version. No, I've yet to actually benchmark it. It really depends on how good of a job NVCC does with the generic sequential reduce kernel. I'll do an in depth analysis when I am done with all the neural network work that
Read the rest
I am doing currently which might take a while. https://github.com/mrakgr/The-Spiral-Language/blob/7ecd30bdf... You can see how it is implement here for the forward and backward parts. https://github.com/mrakgr/The-Spiral-Language/blob/7ecd30bdf... In the actual cost function, it is a bit different since I fuse the forward and the backward parts. It is a bit ugly because of all the type checking for whether the argument is a dual, but that is all done at compile time. > https://mikeinnes.github.io/2017/08/24/cudanative.html This is actually loop unrolling example that I had in mind when I said that Julia needs macros for. https://github.com/mrakgr/The-Spiral-Language#3-loops-and-ar... You can in fact get loop unrolling with just standard functions in Spiral. I go into it in the context of this chapter. It is achieved by pattern matching over tuples and recursion. > If you can make concrete examples of how things can be simpler than this, I'd be delighted to hear them :) Yes, by replacing meta programming with intensional polymorphism and inlinining guarantees. Also reflection should be done using pattern matching. I think this last one could be taken entirely seriously as it would not involve a replacement of the entire type system. All the claims in the article about inlining and specialization that make it sound like magic is what in general makes me dubious about languages pretending to be speed kings. Yes, I am aware that GPU kernels do not require optimizers capable of having monads for breakfast and that in the context of GPU programming where they were made they are probably true, but inlining is the sort of thing that matters more the more high level a language is. For very high level languages that desire speed, there isn't much choice but to make them a part of language semantics despite the added burden it puts on the user. Since we are still at it, I have a question I need to ask. Recently I've been informed that Julia is capable of GCing GPU memory. If this is fully integrated that would be a major feature which is not possible in say .NET or Racket. I really wanted this in Spiral and could not get it in .NET. By fully integrated, I mean much like for regular memory for which the GC takes note of the state of the system for when to do collection and defragmentation. If it can only make a thin wrapper with a finalizer (much like in .NET) around an unmanaged resource then it is not a big deal. Is it fully integrated or is it a wrapper style memory management? If it is the later, then that is too bad, but I'd suggest to Julia devs that they work on making it fully integrated as it would be a really good feature. Obviously, I can't do it in Spiral as I would need to write my own VM and I have only so many years in my life.
In The Spiral Language
I like how the broadcasting comes out in the end in Julia. Besides that Julia has quite many niceties that I could only wish Spiral had and I do think that they matter significantly even if they are not vital. This is definitely praiseworthy work. Since I haven't done so and I really should have, if you or anyone else still looking at this thread are curious how GPU programming without macros looks like then take a peek at this: https://github.com/mrakgr/The-Spiral-Language/blob/3a94ca644... Comparing Spiral and Julia code that has been linked so far, I feel that no one would ever guess without knowing ahead of time that Spiral is a static language and Julia dynamic based on these examples. As an example of this in action, here is how layer normalization is implemented using the 'seq_broadcast' kernel which does a sequence of reductions a
Read the rest
nd broadcasts in registers. It is also used to implement softmax for example. https://github.com/mrakgr/The-Spiral-Language/blob/3a94ca644...
In The Spiral Language

Showing the 15 most recent of 19 sources. Enable JavaScript to search and browse every indexed mention.

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.