Hacker Newsnew | past | comments | ask | show | jobs | submit | greggirwin's commentslogin

1) I'm part of Team Red. 2) You can like, dislike, embrace, or discount a language (or anything for that matter) for any reason that's important to you. 3) I'm not here to convince anyone of anything, just to provide some information and my own thoughts and opinions. 4) I'm not going to justify or argue the state of things in Red today. It is what it is. Lots of high level things are easy to talk (or complain) about, while some other really cool tech lives in the shadows, but is also important. 5) In Red we call embedded DSLs "dialects", just for clarity in what I write.

Red is more different than you may think, just by looking at it. It is designed such that things that look familiar may work very differently under the hood. That's good for making people comfortable, but also means you can't judge a book completely by its cover.

Red is a data format first. That's very Lisp-like, but Red goes further with the large number of datatypes that have a lexical form. e.g. email, url, pair, point, file, date, time, money, etc. Where Lisp* says code is data and data is code, we tend to say "Everything is data until it is evaluated." Rebol was only interpreted, but Red (not all Red however, as some things are too dynamic and require JiT, which we don't have yet) can be compiled.

Red compiles to Red/System (R/S) code. R/S is a static dialect (DSL) of Red, which compiles directly to machine code. No external compiler or C code gen. So you can write DSLs in Red, and those DSLs can be higher or lower level. We call this Metal to Meta programming. Compile a small R/S program, and you will see it's fast, and fully standalone. Compile Red in Dev mode, where the runtime isn't rebuilt, and it's also fast (after the first time). Compile in encap mode and...more to explain. Compile for release and it takes time, but gives you a standalone EXE. It's slow for a number of reasons. Just the current state of things. Compilation speed has not been a priority.

On APIs vs DSLs, a key distinction for me is that API don't have a natural way to enforce the order of operations. That's where a grammar adds value. And because Red is often self-consuming data, the ability to write grammars (`parse` rules) that are very BNF/PEG like, it makes data handling quite powerful. I also think it's easier than most other systems, but that's me, and I've been in the Redbol (Red+Rebol) world for a long time. Two related notes on that. 1) `parse` is, itself a dialect of Red. 2) You can parse not only at the character/string level, but at the value and datatype level, including literal values and typesets. Typesets are a way to express datatypes that are related. e.g. the `number!` typeset matches `[integer! float! percent!]` types. All that said, Red is a multi-paradigm language, including functional (though not pure functional), so you can absolutely build things in an OOP/lib/API manner if you prefer.

Infix came up, and the model is simple. Infix ops have a higher precedence than func calls, but there is no other operator precedence. Strictly left to right for ops. And, yes, operators are a datatype and you can make your own from most 2-arity funcs.

Func args are not enclosed in parens or brackets. This is a fundamental aspect that takes some getting used to. Once you do, at least from what I've seen through the years, it feels natural. We call this "free ranging evaluation" and it's a powerful aspect of Red. It also plays into dialect design. Red is sufficiently flexible that you could hack around this if you want, but then you're fighting the language, rather than working with it.

Red is high level and garbage collected, but it is not "safe" by some standards. Mutability is the default, values are strongly typed but variables are not, you can mix Red and Red/System pretty much however you want, and R/S is basically a C-level language. We talk about these tradeoffs a lot, and how to find a balance. Nothing comes for free.

One of the main dialects in Red, along with `parse`, is the `VID Visual Interface Dialect`. This is how you describe GUIs for Red's cross platform GUI system. You could also build a tree of faces manually, or write your own GUI dialect or API.

Another cross-platform note. Yes, we are 32-bit only at the moment. It hurts us as much as it hurts you. But Red can cross compile from and to any system it runs on. No other software or compilers needed; just a command line switch.

One of our primary goals is to "fight software complexity". That doesn't mean Red will look like C, or JS, or Python. It doesn't mean any one thing. It means a lot of things working in concert. We also hope to keep Red small and easy to set up. Today you can still just drop the EXE somewhere and go. The toolchain (interpreter+compiler) is ~1.5M and the REPLs (text mode and GUI mode, separately) are just over ~2M. We may offer more options at some point, ideas like using LLVM come up a lot. While they solve some problems, they create others. So far, the costs have been deemed unacceptable, and we don't have any showstoppers (other than time). But since Red is open source, with a permissive license...

Happy Reducing!


Thanks @9214. I must have blocked it from my memory.


Did you notice a) that the ticket is closed, and b) it was a bad ticket to begin with? See this comment in there: https://github.com/red/red/issues/3412#issuecomment-39595136...

Yes, if you rebuild the runtime when you compile, it's slow. If you use dev mode, because you're not changing anything in the runtime, it's fast.


Did you notice, that pretty much every single major language today offers static compile? C, Go, Rust, D, Nim. Why does Red think its special to not offer a static compile?


So you're changing your argument now, that's fine.

Let's see. Java? Python? Ruby? JS? PHP? Any .NET lang?

Go is on the rise, yes. As is Rust. But D? Nim? Do you really consider those major languages?

Enough silly arguments though. We think it's special to offer options, because one size does not fit all, but we hope a common syntax can fit most. So you have the option to 1) use an external runtime, which makes all your EXEs tiny (say they run in a common system, even against a custom Red runtime you build); 2) compile to native code and get a single, no dependencies, EXE; 3) "encap" your code with the compiled runtime so you can leverage all dynamic features of Red, some of which can't be compiled; 4) compile the runtime so it can be accessed from other languages and environments. 5) Write in pure Red/System, which is basically like writing in C. Maximum control, no high level features. Tiny EXEs, no runtime, fast compilation.

- https://www.red-lang.org/2017/03/062-libred-and-macros.html (please note the Excel+Red Pong demo)


argument hasnt changed. Red requires a compile of the entire runtime every single time someone wants a static compile. Even if you change one line of code, that another 30 second wait


Have your read p.1 in the message you are replying to? Red does not support static linking, that's true, but you can link to a dynamic runtime library instead, without slow recompilation times... or use the interpreter, or encap the script, or fallback on Red/System. There are options to compensate for the lack of your preferred workflow.


and people who want static compile have to wait 30 seconds to recompile, even if its one line code change


EDIT: i just read up on this. only the first time the static build is slow. later rebuilds are fast. just like every c/c++ program. the first time it has to build everything, all following times it only needs to rebuild the parts that changed.

this has already been explained, and i am only repeating it here for the casual HN reader, so they can follow along.

old comment, that makes no sense because getting a fast static build isn't even a problem. left here because that is what was responded to:

why do you need a static build after every change? isn't a dynamic one sufficient for testing?


why do you need a dynamic build after every change?


As someone naive to Red myself, I just read through the 5 different compile methods mentioned in the parent comment, and while that's quite a bit more than other languages offer, it seems to offer an interesting set of tradeoffs that balance the needs of different real-world scenarios against the language design.

It sounds like you're describing an edge case. To better understand it, what's the actual context around your requirement of static builds?

To be clear about my question, I am genuinely curious - perhaps there are workarounds that could be used, or optimizations that could be considered in the long term.

However (and critically), there is not nearly enough semantic detail in your arguments as currently presented for developers to potentially extract actionable work items from. This is why everyone else is annoyed.


[flagged]


whoops, you are right, i missed that detail: https://github.com/red/red/issues/3412#issuecomment-39593686...

i am watching red on the sidelines as i am waiting for it to become usable for my interests, so i am not tracking every detail.

though i'd appreciate if you could use a less adversarial and demanding attitude. this is not appropriate for a Free Software and Open Source project, and it only serves to annoy the developers which reduces their motivation to work on the project.

your complaints, even if they were acceptable, won't help your cause. at best they will be ignored. at worst they will slow progress down as developers are less motivated.

it has been explained that the current compiler is not the final version, and as such, speedy static builds are simply not a development goal. and they should not be, because the goal is to rebuild the compiler, at which point this issue may be addressed if it is important enough. when that happens, then it is time to make a case for static builds. until then things will go faster if you could stay out of the developers ways.


So don't compile statically while in the dev phase, then switch and sacrifice one gigantic 30-second chunk of your life for release.

Any reason this wouldn't work?


64-bit is high on our list, but also a huge task, so needs a large block of time where other things won't get done. We have some big features we're pushing on now, and will update our roadmap accordingly.


Automated builds are the way to go. We're revamping our release process to avoid stale-binary syndrome. If you don't follow us on Gitter, where you'll see active chat every day, you can look at https://progress.red-lang.org/ to see what's been done. Or just look at github graphs of commits.

We absolutely lost some focus with the blockchain aspect, and are rolling with all the punches as best we can. Sustainability is key, so we're also working on commercial products to that end. Got our first one out last year, and the next one is in the planning stages.

Our first product is https://www.redlake-tech.com/products/diagrammar-for-windows..., and all features are enabled for free. The only limitation is that exported images are watermarked. We also sponsor licenses for other FOSS projects.


The problem with going off of commits is that if someone doesn’t follow every week, they are likely to miss what is happening.

The only place I go to see updates for projects is Releases (or a changelog file).

Maybe a nice middle ground is simply writing more blog posts? I believe this comment from the blog sums it up very well:

> The last post here was April 20 and on Twitter Red-lang, Oct 20, of last year. Never feel like the teams posts must be somewhat ground breaking or totally exciting to the general reader/supporter. We and new interested parties must see you are still supporting your own vision or like a slow loading web page they'll be forced to move on.

https://www.red-lang.org/2020/08/redsystem-new-features.html...


Diagrammar looks interesting. Is there enough demand for it though? Wish y'all the best!


That's what we're trying to find out. :^) In many ways it is a guinea pig, and something we wanted for ourselves. Very niche, to be sure, but if you've ever had to write grammars, the alternatives are EMACS/VIM + YACC/Bison or XText if you're in the Java world and can be locked in and handle the weight.

It's funny to me what a tough sell it is, but that's true for all new dev tools. While the main purpose is to help anyone, whatever grammar they choose (ABNF, EBNF, etc.), it all compiles down to Red `parse` internally, so if you use Red, your parser is already done. If you use the native `parse` rules to begin with, you can even include actions. Testing in it is cool too. But really it's to try and get people to see that documenting your design (meaning you have a design to begin with), is valuable.


It seems pretty similar to this free one

https://github.com/GuntherRademacher/rr


They generate the same type of syntax diagram, but are otherwise...quite different. If you read the product page it should hit the high points.



Those are the same project.


Of course we have to define "new". And consider that it was new when that was written. :^)

It shares syntax with Rebol, 95% of it anyway, but many other "new" languages share syntax with older languages. In any case, there are many new things about it, including being a from-scratch implementation.

- Native GUI system (non-native in development for those who want to go that way) driven by a GUI DSL, with full reactivity built in. - Reactivity and ownership features are built into the core object datatype, so they can be used for more than GUIs. - System level DSL. Red/System is a C level language, but is a dialect of Red. It compiles directly to machine code, not ASM or C. Cross compilation is built in as well. Again, no external tools needed. - Android is out of date, but it also requires no JDK or other IDE.

So there are at least some things that make it new-ish.


I've done this quite a bit in Rebol and more recently in Red. The reason these languages work well for this is that you can dynamically build the GUI layout in their DSL for that, which is easy and concise. But you can also build the tree of faces directly (as the DSL does internally), if you need more control.

https://gitter.im/red/red/help is a good place to ask for ideas and examples.

Full disclosure, I'm on the Red team so my biases are pretty strong. ;^)


One of our team summed it up very nicely: Pragmatically, this design notion comes from Red being a data format first (code is data and data can be used as code). To mimick scoping at data level, context has to be implicit. As a consequence, any block of code e.g. [take the spoon] can be passed around, evaluated on demand in any place, used in user-defined custom loops, without losing the original meaning even if all it's words `take`, `the` and `spoon` were defined differently in those loops or other functions.

Rebol's designer called this "definitional scoping". What it means is that where a word (variable) exists is important. The "where" part leads to https://github.com/red/red/wiki/%5BDOC%5D-Why-you-have-to-co... and is one of the big things that messes with your head when you come to Red from other langs. :^) For many people this stays invisible forever and things just work. But it doesn't take much for people to step off the ledge and into deep water, because things look so easy and it seems like you should be able to just pass blocks around and have everything work magically. It's internally consistent in how it works, but that's hard to see without tooling we have yet to build.


Oh, so it's like Rust's `macro_rules!` identifier rule?

Rust's `macro_rules!` macros operate on ASTs, so the `x` inside a macro definition is different to the `x` in the scope where the macro is used, even though the textual representation of the identifier the macro inserts into the place it's used might be identical. This means that:

  macro_rules! add_two {
      ($i: ident) => {
          let x = 2;
          $i += x;
      }
  }

  fn main() {
      let mut x = 5;
      add_two!(x);
      println!("{}", x);
  }
appears to become:

  fn main() {
      let mut x = 5;
      let x = 2;
      x += x;
      println!("{}", x);
  }
but it still prints 7, not 4, because they're two different `x`s. (Of course, Red has first-class metaprogramming, so it's a lot better.)


Something like that, yes. Red has macros as well, with a key difference being that at compile time, for all macros, there is no runtime context to bind to. Sometimes this helps, sometimes it's a limitation. For example, interpolation at runtime can be tricky, but isn't as flexible if done with macros.


Rebol2 was closed source, and is no longer maintained. Red has a non-restrictive license.


I hadn't seen docopt before, but am curious why you think it's such a bad design.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: