Red Programming Language
A few years ago I revisited Racket after a long hiatus, and that was maybe the biggest thing I noticed. I really don't like syntax macros as much as I did back in the day. Once I decide to use `define-syntax` I've then got to decide whether I also want to wade into dealing with also implementing a syntax colorer or an indenter as part of my #lang. And if I do decide to do that, then I've got a bunch more work, and am also probably committing to working in DrRacket (otherwise I'd rather stay in emacs) because that's the only editor that supports those features, and it just turns into a whole quagmire.
And it's arguably even worse outside of Racket, where I might have to implement a whole language server and editor plugin to accomplish the same.
Versus, if I can do what I need to do with a reasonably tidy API, then I can get those quality of life things without all the extra maintenance burden.
None of this was a big deal 20 years ago. My expectations were different back then, because I hadn't been spoiled by things like the language server protocol and everyone (finally) agreeing that autoformatting is a Good Thing.
Standard math syntax is a DSL. I understand math a lot more quickly than I understand the same thing written in 20 lines of code.
I think the language we use to express ourselves influence the quality of the product. If your language encapsulates complexity, then you can build more complicated things.
I’m not arguing in favor of specific (“pointless”) DSLs, but there’s a nice paper about making a video editing language in Racket[1] that makes a DSL seem pretty convincing.
user_part = re.repeat(re.alnum | re.chars(".-_+"))
domain_segment = re.repeat(re.alnum)
domain = re.list(domain_segment,separator=".",minimum=2)
email_address = user_part + "@" + domain
Where, in a real program, `domain` would be defined in a "standard library of constructions" that you can just import and re-use in more complicated regexes.Something like this can be implemented in any language with operator overloading, no DSL required. Without operator overloading, the syntax would be a bit more awkward, but still nicer than the current regexp madness.
I get that the meaning of the operators is not clear unless you're already familiar with regex, but neither is the meaning of !, ?, %, &, |, ^, ~, &&, ||, <<, >>, *, //, &, ++ (prefix), ++ (postfix), and so on. You learn these because you need them once, and then they're burned into your mind forever. Regex was similar for me.
The more orthogonal or flexible the language is, the less there tends to be a distinction between redefining syntactical elements and defining functions or methods.
GP is right. Don't make DSLs, make APIs, which are:
* More composable
* More reusable
* More simple to reason about
* More natively supported
* More portable
* More readable
* More maintainable
Those are things that spring to mind that I think are unequivocally DSLs, but if you’re willing to consider markup languages as DSLs, the list could get a lot longer.
https://martinfowler.com/books/dsl.html
https://martinfowler.com/dsl.html
Also see:
https://en.m.wikipedia.org/wiki/Domain-specific_language
including the References section.
Or see C#'s LINQ.
This might be one of the rare times it's worth it. The C# team alread has the experience and tooling to maintain a language. Maintaining a DSL might be a reasonable choice for them.
It's rarely a good idea for app or library devs to make a similar decision.
In languages where the grammar is sufficiently flexible, the distinction all but disappears, but even in languages where the grammar is rigid and API's stand out like a sore thumb, the API itself still creates a new rule-set that you need to learn.
You can choose to not call that a new language all you want, but the cognitive load is still there.
Just grouping things together in a particular order and giving the group a name does not make a DSL.
Metaprogramming comes in handy when ordinary programming results in a lot of complex, hence unmaintainable, code or can't achieve something due to how the language is implemented. It can vastly simplify how you express application logic, e.g. when interfacing with foreign programming languages such as SQL or generating code from data.
Any sane metaprogramming regime allows you to do something like macro expansion, i.e. look at the code the metaprogramming is compiled into in the current context.
Not long ago, i had to work with a coworker’s mini language and function runner engine, which was basically a mini programming language. Except without a debugger or type checker or stack traces or any of the other million niceties we’d have had if we just used the host language to execute things ‘natively.’
That said, while the level of tooling for big languages goes up, the bar for creating yesteryear’s tooling is going down, with all the LSP tooling we have now, for example. Maybe someday we’ll get languages with tools where libraries have nice tooling without crazy dev effort, and then we’ll change our tune on DSLs.
send friend@rebol.com read http://www.cnn.com
`read` knows that it takes one argument, and `send` knows that it takes two, so this ends up being grouped like (send friend@rebol.com (read http://www.cnn.com))
(which I think is valid syntax; that AST node is called a 'paren').Weirdly, the language also has some infix operators, which seem a bit out-of-place to me. I have no idea how the 'parser'[1] works.
[1] 'parsing' happens so late that it feels funny to call it that. The thing that knows how to treat an array as a representation of an evaluatable expression and evaluate it.
Weirdly, the language also has some infix operators, which seem a bit out-of-place to me. I have no idea how the 'parser'[1] works.
There are no keywords or statements, only expressions. Square backets ("blocks") are used for both code and data, similar to a Lisp list. The main language (called the "'do' dialect") is entirely polish notation with a single exception for infix operators: Whenever a token is consumed, check the following token for an infix operator. If it is one, also immediately consume the immediately following one to evaluate the infix operator.
This results in a few oddities / small pitfalls, but it's very consistent:
* "2 + 2 * 2" = 8 because there is no order of operations, infix operators are simply evaluated as they're seen
* "length? name < 10" errors (if "name" isn't a number) because the infix operator "<" is evaluated first to create the argument to "length?"
I made an infix parser in which certain prefix operators (named math functions) have a low precedence. This allows for things like
1> log10 5 + 5 ;; i.e. log10 10
1.0
But a different prefix operator, like unary minus, binds tighter: 2> - 5 + 5
0
I invented a dynamic precedence extension to Shunting Yard which allows this parse: 3> log10 5 + 5 + log10 5 + 5 ;; i.e. (log10 5 + 5) + (log10 5 + 5)
2.0
Functions not registered with the parser are subject to a phony infix treatment if their arguments look like they might be infix and thus something similar happens to your Red example: 4> len "123" - 2
** -: invalid operands "123" 2
"123" - 2 turns into a single argument to len, which does not participate in the infix parsing at all. log10 does participate because it is formally registered as a prefix operator.The following are also the result of the "phony infix" hack:
4> 1 cons 2
(1 . 2)
5> 1 cons 2 + 3
(1 . 5)
Non-function in first place, function in second place leads to a swap: plus the arguments are analyzed for infix. print tostring 5 + cos pi
Works a bit like a shift/reduce parser, with heavy use of fexprs (blocks in Rebol parlance)I know you enjoy Lisps, so you might like this toy Rebol evaluator written in Scheme: http://ll1.ai.mit.edu/marshall.html
I have no idea how the 'parser'[1] works
I think parsing there depends on the actual value of the current token. So if you assign send to another variable and use that the "parser" will still recognize that it takes 2 parameters.
It's an interesting design, definitely not something one sees frequently.
Even things that are normally keywords and statements in other languages (like conditionals and loops) are actually just functions that conform to the exact same parsing rules.
This is like the only programming language I could never learn.
Wait till you hear of Urbit and see this: https://developers.urbit.org/overview/nock
I've looked it a few times over the years. It's neat. I've never written a single line of it, though.
In 1988, Sassenrath left Silicon Valley for the mountains of Ukiah valley, 2 hours north of San Francisco. From there he founded multimedia technology companies such as Pantaray, American Multimedia, and VideoStream. He also implemented the Logo programming language for the Amiga, managed the software OS development for CDTV, one of the first CD-ROM TV set-top boxes, and wrote the OS for Viscorp Ed, one of the first Internet TV set-top boxes.
What a legend!
Sites which do this well (just from the top of my head):
https://odin-lang.org/
immediate code sample visible
"See the Full Demo"
"See More Examples"
https://ziglang.org/
immediate code sample
scroll down a bit, "More Code Samples"
Here on red-lang.org... I can barely find a consecutive meaningful chunk of code... ? "Getting Started" Nope
"Documentation" Nope
"Official Documentation" link to github
https://github.com/red/docs/blob/master/en/SUMMARY.adoc
"Home"
merely a chronologically sorted blog
newest entry links to 50 line "script" by chance
showing off multi-monitor support
(doesn't seem like a super helpful sample)
?
There are at best two people working on the language, and they both don't have the time and have a very weird approach to docs (like posting extensive google docs or pastebin explanations, but never actually having any proper documentation)
But no one has bothered to write a complete manual like Carl did for Rebol, and the language is a partial implementation in Rebol which has a hybrid Rebol/Red syntax that must ultimately be bootstrapped in Red. In short, you have the scaffolding around it and if you are not a total fan or a dev of the project it is not even worth it.
The website has posts from 2025:
https://www.red-lang.org/2025/04/multiple-monitors-support.h...
Unless you mean the theme, thats probably just a standard Google Blogger/Blogspot theme, which has been around for 25 years.
I don't take any new language seriously unless it's memory safe, free of UB, able to interoperate with what already exists including optional shared libraries (because static linking the world every time in everything is memory and disk wasteful), and assists formal proofs of correctness. Otherwise, what already exists seems preferable for serious use and hobbies can remain fun distractions.
red-lang.org is blocked!
Phantom believes this website is malicious and unsafe to use.
This site has been flagged as part of a community-maintained database of known phishing websites and scams. If you believe the site has been flagged in error, please file an issue.
Ignore this warning, take me to https://www.red-lang.org/p/about.html anyway.
I also got to know about Red early, followed it and tried it out for a bit.
but as others have said, that move to crypto, to fund the dev work and make the devs money, put me off for good. nothing wrong with making money, let them make plenty, I just didn't jive with crypto as a way of doing it.
sad about it going that route
The idea between having the red system language, regular scripting language, cross platform gui, and native executables was really cool though. I remember being interested back in ~2015, so my question is...what's going on as it's been a decade. I know the project is crazy ambitious of course, but how close are we to where this is at a stage where most would consider it production worthy.
Then the roadmap slipped, and then never mentioned again.
But I haven't looked at the language or discussions around it for a long while now.
Edit: found some old discussion here. In 2018 they were at version 0.6.4 https://news.ycombinator.com/item?id=18864840
In 2025 they are at version 0.6.6: https://github.com/red/red/releases
I thought maybe someone had put the DoD's Red language spec online.
And yes, someone has: https://iment.com/maida/computer/redref/
It's very elegant! I can't fully grasp everything that's happening but the visual appearance of the syntax alone is interesting.
[0] https://github.com/red/code/blob/master/Scripts/clock.red
I would assume it does, because I assume I be able to know these things in a comparable JS or Python example. But if that assumption is correct I really like the ‘look’ of Red.
If it's robust it seems rather neat.