The memory management model is automatic reference counting, with some optimizations, such as perseus for compile time reference counting where possible, and copy-on-write at runtime.
Yes, it's python-inspired. Some notable differences are:
- no return keyword
- match/if are expressions
- it's functional
- =? is used for early returns or binding, depending on the variant of an Option or Result that is returned
There's a lot of other differences -- it's a smaller language surface than Python overall.
Yeah, this is the idea. This chaining is exactly the same as the pipeline operator in some some function languages, except that it hopefully reads in a more familiar way to programmers of non-functional languages.
Yes, blorp does that. And it also allows local mutation and loops inside pure functions, so performance doesn't need to be left on the table in most cases.
Hi, maintanier of blorp here. I think you mean that [1,2,3].map(func(x): x *2).filter(func(x): x > 5) would iterate twice, correct? Under the hood blorp optimizes that away for the functions we can. It constructs a loop and combines logic into a single iteration where possible.
Of course, blorp also allows local mutation in loops (even in pure functions, so long as the logic is contained to the function), so if there's a specific algorithm you'd rather express in a loop, you can.
Hey - I'm the creator of Blorp, and like a lot of the ideas you have in Roc! Did you consider having opt-in purity? Or some other means of conveying impurity other than "!"?
Hey... I'm the maintainer and had no idea this was posted. The reason pure is required is because it's clear and opt-in. There's a CLI subcommand called purify that will help identify pure functions that haven't been deemed so if that's desired.
But there can be many (small) applications where pure doesn't even matter, so I don't really want to force someone to write "impure" for the main function, for example.
Working on something kinda similar. No GC, Python feel, managed memory, performance approaching C. It's here: https://blorp-lang.org if you want to compare approaches.
Yeah, concurrency in blorp doesn't allow shared mutable references, so deadlocks aren't really a concern. Otherwise it's meant to be simple-ish -- virtual threads, channels, no async/await. Pure functions allow safe parallelism naturally, so that's fairly straightforward, though the API is still incomplete, for example the "Parallel" section here: https://blorp-lang.org/docs/lists/. It's still under heavy development (working on it right now).
1) I want to minimize global complexity, which by definition maximizes local reasoning.
2) I want to make the vast majority of bugs simply unrepresentable - taking it past Rust, and even past Pony - WHILE allowing shared mutable memory, but without requiring a PhD to use.
The goal is in EASY mode, it's barely harder to use than Ruby or Python (just the occasional pedant compiler error that has automatic options to fix itself most of the time). You don't even have to supply types or compile. It has a REPL, etc.
When you bump to DEFAULT mode and then to STRICT mode, all the annotation is automatic - your code just might look "ugly" if you like having no types anywhere etc.
But DEFAULT & STRICT mode give people and LLMs everything they need to know to understand the effects of an individual function.
I have some similar goals. Have you considered leaning more into inference than gradual typing? One pattern I like is allowing the compiler to develop a more complex mental model, but keeping it straightforward for users -- you can do that with inference, ownership, purity, effect types, etc. What I actually think is really tantalizing is using tooling to fill in some of those gaps -- for instance, the editor could know types, required capabilities etc, without the user ever needing to type anything, but when the user needs it, they can find it, query it, test against it.
Cool - it sounds pretty similar. It's interesting that it looks so different. I'll have to investigate more.
WRT to inference, yes. I infer everything in EASY mode.
And the compiler give the user autofix via choice when a type is ambiguous (I don't default to huge union types - I assume no one wants to do that and make them choose a type - may potentially allow AutoUnion to allow that).
I couldn't tell if you're using affine ownership, but I assume so if you don't have a GC. If they try to create an alias - they get a use after move error, and the compiler tells them they need to either COPY (auto-fix) or create a RefCount (usually auto-fix) - they pick.
No, blorp doesn't use affine types (one or zero uses). In blorp, ownership is not explicitly controlled by users at all, so it's opaque. Under the hood, it's perceus for compile-time ownership and borrowing and automatic reference counting with copy-on-write optimizations for the runtime. This is made reasonably easy for the compiler to reason about in blorp because semantically it doesn't _really_ have in-place mutation -- `var` really means "re-bindable" to a new value; and then under the hood we'll mutate in place where we can.
If you want some feedback, I'd recommend putting some concurrent benchmarks on your home page (and if you have some already - I'd clearly separate them).
When I originally scanned it, I just assumed this was another predominately sequential language with no good concurrency story.
If you're actually competitive with Rust/Tokio/Crossbeam and Go on the most common concurrent patterns, then you've got a really compelling project!
I suspect if you don't cherry-pick benchmarks, you're going to run into some performance problems with not allowing shared mutable memory - though maybe you can avoid most of that if you have some type of built-in actor pattern.
But if you're actually competitive across the board with Go & Rust/Tokio/Crossbeam - I'd love to take a deeper look, because that is NOT easy to accomplish.
I didn't see any of that from a cursory look at the language, though.
Still incomplete there. But yeah performance should be decent. Not aiming for parity either rust or go entirely but in the same ball park is the expectation.
How is compiling to zig? I considered doing it but chose C instead because of how much zig is still changing. I've considered using it's C compiler for targeting multiple platforms locally.
Comptime is very powerful and awesome to use for a transpilation target.
Also, Io and how Zig handles allocation and gives you full control of the allocator make it super easy to do things you probably want to do in your language.
reply