The Red Programming Language
red-lang.org
red-lang.org
Despite the promising description, the language design looks pretty... quirky.
To me, its type system and parsing nature are one of a kind, to be able to label everything as what it is
[money!] is $12.53
[tuple!] is 5.5.5.5
[date!] is 16-Jul-2023/21:00:17
means the parser immediately parses and type checks everything, all while looking as human readable as possible.1. default compile mode was shared, so all executables relied on a "libred.dll" or similar
2. compiling "libred" was really slow (1 minute), but after that its done and skipped in the compile stage, making compile much faster (but still with the limitation of #1)
3. you can compile static, but then the static "libred" needs to be compiled EVERY TIME, making every single static compile, even "hello world" take one minute EVERY TIME.
I posted multiple issues about #3, but they were closed each time as "wont fix" or "working as intended" or similar. So OK fine, I just moved onto Go and Rust, even C, plenty of other languages that dont have this issue.
If so, that sounds reasonable to me.
Which issue? This one?
>>> but from what I remember the problem was this:
>>> 1. default compile mode was shared, so all executables relied on a "libred.dll" or similar
Don't all the above languages, besides Go, rely on a library for runtime? Ever got the error `missing msvcrt110.dll` when distributing binaries of your application on Windows?
The only difference here that I see is that you can choose to recompile the runtime; with C, C++, et all on Windows, you don't get that choice - you have to use the dlls that the language specifies whether you like it or not.
You shouldn't need to recompile the runtime to statically link it.
Red might not have a way to store intermediate static linking files and so is forced to do a full compilation everytime.
Caching at the output file level is simplest but can result in these kinds of weird performance issues.
(Shipping a precompiled library is standard to avoid this pain point, MSVC includes four versions of its standard library, Debug/Release and Static/Dynamic in the various combinations)
1. there are no objects, so when you switch from Python, instead of chains of methods, like `my_dataframe.groupby(...).aggregate(...).groupby(...).aggregate(...)` you need either (a) a lot of poorly readable nested calls, or (b) ugly "pipes", where the left side is implicit first param of the function on the right side: ` my_df |> groupby(...) |> aggregate(...) |> groupby(...) |> aggregate(...)`. (Writing them, you feel insecure of what is happening -- in this case, what gets passed to the function.)
2. You can't make it a CLI script, because it compiles the whole code WITH dependencies every time, and as soon as you import some serious libraries, compile times will skyrocket. I quickly hit 40 seconds of compilation with just geospatial lib and dataframes. These 40 seconds turned out to be A LOT when you develop interactively. And you can't build everything in a Jupyter Notebook, because eventually you'll have to switch to a CLI script.
I think I could put up with pipes, but the compilation times were the final argument against Julia.
These are not ugly pipes. These are a very common feature in a lot of functional languages. Once you've used them, you want them everywhere :)
And of course you know exactly what is passed to the function. You wrote it yourself: left side is passed as the first param of the function on the right side.
Pipes are fine, but methods and traits with a strong type system reduce any ambiguity there.
Doesn't mean you can't use pipes reasonably! But in Julia that seems like it could be harder to unpack.
This has nothing to do with pipes, this is a matter of namespacing.
" hello world "
|> String.trim()
|> String.split()
|> Enum.map(fn char -> String.uppercase(char) end)
|> Enum.join()
#=> "HELLO WORLD"
I'm sure some will think that is too verbose but I love it. Otherwise pipes are far more flexible than method chaining just because you aren't constrained to one "type". You don't always want to do this, but as per the example above, it's pretty handy. You also don't have to rely on a method you don't own returning an instance of itself.but for example in pike import is only useful as a shortcut, and not needed if you use fully qualified function calls. and like you i never saw the point of import. using the fully qualified function calls makes the code more readable because i can quickly recognize library functions from custom code.
with pipes i have no experience at all. but they certainly look useful. a()|>b()|>c() looks better than c(b(a())) but i can see the confusion because there are now two ways to pass an argument. but even then a(i,j)|>b(x,y)|>c(z) is still more readable than c(b(a(i,j),x,y),z). now i want this feature in all my favorite languages
The only ML language I have any experience with is OCaml which is statically typed and has pipes.
EDIT: re-reading your last comment it looks like I totally ignored the first part of what you said, but I guess I'm confused. This thread is also probably nested enough, lol.
I really like pipelines but know people who try and make everything a pipeline.
What do you mean by that?
> methods and traits with a strong type system reduce any ambiguity there.
Strong type system does not preclude pipes.
And no, in many cases, it's absolutely not clear what gets passed, because you may have a vector of scalars, and the function accepts... what? Is it restricted in input types at all? If it takes a scalar and then gets passed a vec of them (but you don't call it's vectorized equivalent), what happens?
Yes, I can go check the function, check if I have a vec and check if I call the function the proper (scalar or vectored) way,.. but this escalates the complexity and choices you should make, towards Rust language. And still it can run and try doing something implicitly. When I coded it, I wasn't sure I can't mess things up somewhere in the middle of the pipe.
Don't get me wrong, I liked many features of Julia. I made one project in several languages just to compare, and Julia was easy to learn and worked pretty well. The main issue that stopped me from using it was the above mentioned cold start time.
or is there an implementation where a pipe takes a vector and applies it to the next function as multiple arguments?
it's a dynamic language with optional compilation, so complaining that the compiler is slow isn't very fair.
The compiler is written in Rebol (language Red is based on) which is dynamic language also, so that's why it's slow. Rebol itself is written in C and its scripts can't be compiled. You can of course bundle the script with the interpreter which is ~1-2MB with OS dependencies only.
(I used to work for Red and use Rebol in my job daily)
The home page of Rebol, which it says it's derived from, seems to do a much better job at stating its purpose: http://rebol.com/
Call it the Rebol curse, I guess.
All I could find were 32-bit binaries on a couple sites compiled a decade ago, and a lot of focus on Red, which is in a weird limbo as well.
From poking at the project, it looks interesting but not ready to really try out yet.
"compiled a decade ago"
Listen here, kid. Two and a half decades ago I had Windows 95 and I could browse the Web, send and receive email (or fax!), play music, play videos (or movies), play games, use instant messaging, program in multiple languages, use databases, run a mail or Web server on my desktop, read and edit documents in formats such as doc, rtf, xls, ppt, pdf, xml, desktop publishing, view and edit images including high re photos, including porn of course, make international phone calls, and a few other things.
And every single Tcl/Tk script (cli or gui) I wrote two decades ago still run 100% unchanged.
If you refrain from using anything just because it was "compiled a decade ago" then you are a fool. Sadly, you are not alone. Far from it.
The problem with abandonware languages like Rebol is that it's often impossible to use, find documentation for if not learn, and the commercial story and lack of any sense of open source of this probect is the reason why I just moved on. It seemed no one cared to look into it in the past decade, so I was content with what I had found, and stopped short of actually using the thing. I was wrong, but in my defence the active fork was doing its best to hide under a rock.
But I guess it feels good to call someone a kid and a fool over the Internet.
I am really looking forward to learn more about this language when 1.0 comes out, especially because of its ambitious feature list [3] (programming across the low/high-level spectrum, etc.), Lisp influences and the Logo-like syntax inherited from Rebol.
- [1] https://www.red-lang.org/2022/07/the-road-to-10.html - [2] https://www.red-lang.org/p/roadmap_2.html - [3] https://github.com/red/red
> 2 - Open a GUI, read web page, send it as email:
view layout [u: field "user@rebol.com" h: field "http://" btn "Send" [send to-email u/text read to-url h/text alert "Sent"]]https://www.red-lang.org/2023/06/dynamic-refinements-and-fun...
Maybe a consequence of them walking their path to 1.0?
Crappy design when a common typo silently and slightly alters the functionality of your program.
Makes me interested in learning more about Red to see more example of what to not do
You got eg. prin1 in Clisp which should be hard to distinguish in some fonts.
* the philosophy of zig in terms of simplicity
* the thread and memory safe nature of Rust - without Rust's kitchen sink approach to adding sub languages and complexity
* the simplicity and straightforwardness of TypeScript
Zig does have some memory safety, but not as much as Rust of course. I think Zig made the decision to add as much safety as they could, without crossing the complexity boundary. any further memory safety and you're about in Rust land. maybe some middle ground language is possible, but not one that I know of.
That's not quite true. We have GC using languages (some allow it to be turned off), and for many or in many use cases, that would be enough. Other languages like Lobster, Vlang, Vale, etc... are developing/putting out easier to use alternatives.
I love rust but I think it's fundamentally complex
https://en.wikipedia.org/wiki/ATS_%28programming_language%29
To my mind, BTW, Typescript is not that "straightforward" or "simple", but it has a pretty powerful type system, and I like that.
I get the practical reasons why it’s useful, but I’m surprised it’s anyone’s choice for the design of a high level language. Is Python or Ruby not a much better choice?
Ruby, idk, never used or even encountered it. Python was my main language for a while.
I could see fully modern JS, without any transpilers, being an ok scripting language, I guess that's why React Native works well in that way.
For standard library, NodeJS keeps things pretty simple server-side. It's messier client-side with browser standards, but it's getting better, and Python can't even run in-browser. I like how JS evolves more gradually than Py which had the hard 2->3 transition.
I have to say I really prefer TS.
I know Python has types now but it doesn’t feel as good as TS.
This is a bit of a headscratcher. TS is a kludgy attempt at adding type safety to a dynamically-typed and expressive language.
It’s SO easy.
All programming languages should be this easy.
TypeScript has more than enough complexity even without the npm ecosystem.
Red is a really promising language. It, like Lisp, gets flak because of the syntax but that really becomes a non-issue pretty quickly once you start using it and the productivity gains you see from using it all but eliminate any reservations you might have about the syntax.
Perhaps such things sounds trivial, but in a language where they claim that programming should be fun, hard to type things are a bit of fun-killers. I also disslike both visually and if I would to type all those operators #,%,$,?,:,! etc. We humans are used to raede txet adn cna prase text even when mistyped without barely stopping, but the punctuation is a bit harder to read and type, and that for a reason. That becomes especially annoying if those signs are overloaded or combined, as in Perl or C++, which is probably one of the reasons that gives those languages "write-only" epithet.
I have seen the video: https://www.youtube.com/watch?v=-KqNO_sDqm4 by Nenad, but it is from 2015. If they are still 4x slower than C for the compiled code, than I am very hard to believe they are a serious contender to become a systems programming language as they claim to be. Compare to sbcl (Common Lisp) where speed is almost approaching C in some cases. Having built-in toolchains and DSLs is nice, but it can also be a curse and made things harder to evolve and modernize.
While I sound like a very negative person, I do like some of the ideas in Red definitely. Built-in tasks, concurrency and homoiconicity sounds like a very nice features to start with.
Not Found
The requested URL was not found on this server.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.
Not odd at all, in fact, just another consequence of the ridiculous fragmentation in Linux scene
https://en.m.wikipedia.org/wiki/Carl_Sassenrath
Sadly, they (Red) seem to have gone the crypto-funding way a few years ago.
Until a major backer steps up and funds a project with amounts that is comparable to what MS or Apple spends on their GUI, the Linux on desktop is not happening.
My bet is on QT if anyone is listening.
However, I found debugging to be very difficult, once I wrote a more complex application. Are there good debugging tools for Red?
An application, as a mass of code, will contain code that works at different abstraction levels.
take a look at their roadmap:
*v0.7 : Full I/O with async support.
*v1.0b : (beta) completed self-hosted Red with 64-bit support.
For reaching the 1.0-beta milestone, we target 12 months of intensive work, so that will bring us to Q3 2023.
so that was written in june 2022 before 0.7. there is no announcement for 0.7, but then they changed the versioning so i can't tell if the goals for that have been reached. but it's pretty clear that self-hosting is the next big target.
I thought about another multiplatform, homoiconic, highly compact language: https://janet-lang.org/ (takes 803 kb on my machine).
It has no types though.
Red is based on Rebol, which was created by Carl Sassenrath, the creator of the pre-emptive multi-tasking Amiga OS. When he left Commodore, he wrote Amiga Logo and the created Rebol.
https://www.red-lang.org/2017/12/leaping-into-future-red-goe...
https://www.red-lang.org/2018/01/answers-to-community-questi...
Sarcasm aside, while I think striving to be better is great, sometimes I wish there was just a standard language for programming.
I realize it depends on the context (mobile, web, desktop application, different platforms) but it can feel overwhelming when in the end, they all pretty much do the same thing: tell a computer to do things.
Red is not a new language.
Five-ish years ago they were aiming for a 1.0 within a year while still having major milestones like adding actors (and re-writing half of internals to support actors) on the roadmap.
Also, worth reading Paul Grahams "Blub Paradox" article from decades ago... http://www.paulgraham.com/avg.html (hopefully you know who he is given you are here on HN)
Approved by a Central Planning Committee, I suppose?
Good news, there is such a standard, and you can buy it here: https://webstore.ansi.org/standards/incits/ansix3531976r1998
Some choice quotes from the Wikipedia page ( https://en.wikipedia.org/wiki/PL/I ):
> PL/I (Programming Language One) is a procedural, imperative computer programming language initially developed by IBM. The PL/1 ANSI standard, X3.53-1976, was published in 1976. It is designed for scientific, engineering, business and system programming.
> IBM wanted a single programming language for all users.
> The language is designed to be all things to all programmers.[vague]