this is a pretty common observation and yeah it sure is inspired by rust's syntax a bit because i have been a rust dev since quite a long time so i'm much more in favor of it's design philosophy as well
Your README and docs don’t describe any of the interesting or unique things here. You cover `if` in README but not choreographic programming or perceus. Did i miss some big link?
Why would they? The only thing the readme says about RESEARCH.md is "if you want to contribute to the language please read RESEARCH.md". The OP doesn't want to contribute, they want to see an example of choreographic programming. This shouldn't be hard. What is hard is guessing which of the random markdown documents to click to find an example.
i poked around in there, under choreographic programming there’s one example of something not in the language as a discarded idea.
if you claim X and Y make us cool and different, then you should document X and Y in your readme. don’t tell me something is the star, and then hide it away. this is baffling to me.
First of all, the syntax is very generic and conservative. I’m extremely positive about that. It just looks like C or Typescript or Java to me and I don’t see mysterious diacritical marks.
The next thing is, I need more examples. Read me documents can scroll forever and that’s fine. Add examples for every concept your language wants to cover to it. This is your chance to think things through and make the read me and the language astonishing.
And your AI disclaimer (or your AI’s disclaimer) makes sense.
i'm actively working on the documentation without AI because it has been an awful experience with it , i've also restricted AI from contributing to it in any way except for helping the developer write their commit messages (Refer to AGENTS.md) properly which is pretty much useless anyways, the language is in it's early stages as well and things might change a lot
I would like to see an examples directory with a diverse set of example programs. What would be most interesting to me is programs with non-trivial memory usage and data structures, because that's where differences in the memory model would matter. I want to know what's possible and what's not allowed in this language. What makes this different and better than Rust's borrow checker.
Please don't take this personally, trying to offer this as constructive criticism. I don't find this to be a very interesting example of the language. If the main feature is a unique approach to memory/multithreading/network safety, I would like to see an example of a multithreaded networking program that uses dynamic allocations, not a ~100 line a procedure that uses static buffers and terminal IO.
docs.wyzer-lang.org doesn't resolve for me, and it's prominently linked from https://wyzer-lang.vercel.app/. Since I'm not familiar with wyzer or perceus, how would one write, say, a doubly linked list in wyzer?
maybe wait until you have something to share before Show HN? overall your work seems like a cool thing that i’d like to look at in a few months once there’s more substantial education stuff to read about it.
Great. I'm also writing a new language with the same memory management idea (Perceus-style reference counting / ownership). My language [1] is not functional and currently lacks multi-threading and networking, so there are big differences. But I really like the moto "easy to use memory safety without tracing GC".
One thing I don’t understand is how you can guarantee the lack of a distributed deadlock. I’m sure it’s covered in the underlying research, but just conceptually it’s hard to picture.
What stops a choreography where Claire send a message to Bob but Bob is waiting for Alice and Alice is waiting for Claire?
Is it like Rust memory safety where not all valid programs are accepted but all invalid programs are rejected?
I think some examples of the distributed code in action on a trivial and non trivial distributed example is more compelling than a 3d donut render
The protocol doesn't describe "Claire sends" and "Bob receives" as two independent actions that wait for each other, it describes them as a single communication in the global program/state.
When it gets executed into code, every send already has a corresponding receive by construction, so you can't write something like "Claire sends to Bob while Bob is actually waiting for Alice" unless the protocol itself allowed that execution.
So the cycle you're describing can't just accidentally appear because of sync issues, because the assumption is a communication is represented correctly at each turn.
So yeah it kinda does limit the set of all possible programs since I would expect not everything can be encoded this way also seems hard to resolve this in practice without only allowing communication b/w Wyzer systems.
I am not very familiar with this topic in practice so OP would be the best person to answer this, I am quite intrigued by how it works in practice as well.
This question is in fact core to research in the paradigm. Let me first address how it works and then the expressivity question.
A choreographic programming language features programming abstractions for programming communication intent. For example, often they have a primitive like:
Alice.expr -> Bob.x
read 'Alice communicates the evaluation of expr to Bob, which stores the message in its local variable x'. (In fact, we discovered that we can extend any mainstream language to have this kind of high-level primitives by extending data types with locations, see choral-lang.org).
This makes it impossible to write mismatched communication actions, because you're expressing both the send and receive actions in a single atomic instruction: they are well-matched by construction. You then build a compiler (typically called 'projection') that generates distributed programs for Alice and Bob -- the former doing the send to Bob and the latter doing the receive from Alice. We like making formal models of these compilers and mathematically proving them correct. A compiler that respects the choreography then automatically entails deadlock-freedom of the compiled code without the need for complex checks, because the source choreography cannot syntactically express deadlocked terms.
Consequently, there are no deadlocked distributed programs that we can compile from choreographies. It's an application of the neat trick of designing high-level languages for 'guiding' programming: instead of programming a distributed system with low-level primitives and then attempting the generally very hard task of checking for deadlocks, we use a high-level language where deadlocks cannot be written (or are at least easy to check against).
The above hopefully explains the intuition of how choreographic programming works. But then, as you did, one naturally asks: What can we express in choreographic programming languages? Are there fundamental limitations?
We do not know exactly yet; this is an area of very active exploration. Over the years, people have developed more and more clever choreographic programming languages that capture more and more interaction patterns.
What's perhaps surprising is that, for some theories of distributed languages (or interaction patterns, if you like), we know that choreographic programming is complete, in the sense that it can capture all deadlock-free systems that can be modelled in those theories. The first result of this kind was about capturing all interaction behaviours that can be described in linear logic (in the Curry-Howard interpretation of it with process calculi), but there are also works that can deal with recursive behaviour and even process spawning (fork). That's encouraging.
I think that investigating what the paradigm precisely can and cannot do is fascinating (but I'm very biased here..), not least because using a mathematically-modelled compiler lets us optimise the generated code aggressively (e.g., adding more asynchrony, as in Ozone). From the state of the art already out there, it looks like choreographic programming is 'expressive enough' for many different purposes. Hopefully it's gonna be the typical situation with high-level abstractions, whereby for most cases and most people the high-level language is gonna be good and low-level communication actions will be necessary only in niche scenarios. In the meantime, there are choreographic languages that can be integrated with middleware and foreign APIs to cover up for deficiencies (like Choral, HasChor, etc.).
Very interesting. Maybe this would benefit from concrete examples, of things that are difficult or impossible in other languages, but well supported in Wyzer? I see there's a few high level examples, but I'm thinking concrete scenarios with code snippets might be helpful.
isn't there a way to infer that from context? like if the variable is declared with the Comptime role. Some guy said that the const keyword was a mistake C made that is then blindly followed by its successors.
I like the ideas a lot. The Readme needs some polish (I think it’s great that it reads as hand-written; an LLM could make suggestions that make it just 10% easier to read).
Is choreographic programming the same as session types?
nice Rust-inspired syntax, although if the main selling point is choreography here, that isn't featured enough on web page or README. Needs more examples/explanation of how that works.
Promising insofar as all of the essentials seem to be right (for me): compiled, good type checker, no garbage checker etc.
examples aren't updated yet some guy who mocked me earlier for the language on discord deleted his statements and walked away blocking me after giving me his hacker news credentials, now here i am answering to your questions
I love the ambition and the fact that this is not just another "state of the art in 2015" language like I see so often. It's trying to do something genuinely different. The field of "taking stuff out of academia and making it work" is a rich and underharvested one.
However, your light is hidden under a basket, to use an old metaphor. I'm having to go digging to find the genuinely new things going on. I suggest recalibrating the entire documentation with a focus on the new stuff. People on HN often complain about not having syntax examples front and center but I would say for you, the very first thing I you should be hitting your new visitors with is the choreography idea.
Set up a simple example of doing something like a concurrent remote counter that is atomically safe by the construction of your language and immediately dive in to what that means. Forget even educating us on the rest of the mundane syntax of the language, immediately dive in to what that is and what that means. I see in the docs/ dir that it probably hurts your programmer mind to cover the choreography before covering sections 1-8, but you can safely assume that if you intrigue with the choreography that they'll hang around to learn about the rest, whereas you can't safely assume that a new reader will wade through all the rest of the relatively mundane details to get to the really interesting stuff.
A modern language with a modern take on compiling a "program" that takes a unified view of the world at the programming language level, and then emits a "server" and a "client" (and perhaps other roles) as separate executables is a pretty nifty idea. Hit it early and hit it hard.
This is hands down some of the most constructive feedback we’ve received. You hit the nail on the head.
We definitely fell into the author’s trap of structuring docs "bottom-up" (Prerequisites -> Basic Syntax -> Advanced Concepts) rather than leading with our actual core innovation: choreography.
We are restructuring the main README/docs front page right now to lead immediately with a concrete example of choreographic execution (e.g., atomic multi-node orchestration / client-server emitting) before getting into standard syntax.
Really appreciate you taking the time to dig into the docs/ dir to pull this out it’s a huge help for our presentation.
Yes, strong agree, normalcy resumes at some point. But you want the hook in first.
I mean, I'm phrasing that in marketing terms, but in this case it's in harmony with what your users want anyhow. We want to know ASAP why we should care about this language. So it works for everyone. Of course when it comes time to deliver the promise, normal programming language documentation is the way it is for a reason.
They did the right thing highlighting a working example front and center.
Nothing worse than PDFs full of theory and no working examples of the thing you’ll actually be doing all day.
I get that it’s important to show what abstractions and methodologies can arise out of using it, but with a good example that would be obvious. It’s the developer community using the language that will come up with the best abstractions (libraries) that - if it has an active community - helps shape what those novel developer experiences are.
A good analogy is the development of the skateboard - released first as a scooter - until someone knocked the handle off a started “surfing” down the street. Just show me the thing. I’ll tell you if it’s cool and how to use it
> Go, Java, C#, and Python use garbage collectors. This makes them easier to use but slower and less predictable.
It does not. The term "garbage collectors" covers a whole spectrum of algorithms, some might slow you down (though not for the reason you may think) while others were invented to speed up memory management beyond that of C++, in exchange for other tradeoffs. Python's (mostly) refcounting GC is actually closer to C in its memory management overhead than to either Go or Java. It's also not what makes Python slow. Go uses a mark-and-sweep collector to find a balanace between speed, FFI, and footprint. Java uses moving collectors, which are faster - and some of which are even more predictable - than memory management in C++. That's because Java aims to offer better performance than C++ in large concurrent software, where low-level languages tend to suffer from various overheads due to their requirement for low-level control (Java trades off some performance in smaller programs, but mostly it trades of startup time and footprint). Moving collectors (but not refcoting collectors or mark-and-sweep collectors) are an optimisation over free-list approaches, not a compromise for convenience.
So it is true that slow programming languages tend to use some kind of GC, but that's not what makes them slow, nor does it make the super-fast languages that also use a GC (often of a very different kind) any slower. The range of languages that use GCs covers everything from the super slow to the super fast.
The quoted text says "slower". It does not claim that GC makes those languages slow overall.
Are you arguing that GC is not inherently slower than other memory management strategies (e.g. the Rust approach)? Or just that the cost is not worth optimizing away?
Of course GC is not inherently slower than other memory management strategies. Not only because GC is not a "memory management strategy" but a wide spectrum of them, but also because some GCs are used to speed up memory management compared to low-level languages. Dynamic heap allocations in low-level languages is often minimised because it is slow; some GCs are used to solve this problem.
I don't understand how you can claim that using a GC does not make a language slower and less predictable.
Running a GC takes time, pollutes the cache, and is often run at an unpredictable time. Sure, the GC is not necessarily the SLOWEST thing about the language (python), but it's not helping, either.
Yes, but for a moving collector that's less time than it takes to run malloc and free. The interaction of a moving collector with most object is bump allocation when they're allocated (similar to stack allocation) and... that's it. The GC never sees them again, scans them again, or is even aware of their existence (moving collectors don't have a free operation). Overall, moving collectors (but not other kinds of GC) reduce the work of memory management compared to malloc/free.
In low-level languages we try to avoid doing a lot of malloc/free not because heap memory management is slow in general, but because that approach to memory management is slow. Moving collectors are an optimisation designed to make heap memory management fast, but it requires that (nearly) all pointers be movable, something that low-level languages can't do because they have constraints that are more important to them than speed (you can't interact with the OS or hardware directly, i.e. without an FFI API, if your pointers are movable, and such direct interaction is the point of low-level languages).
That moving collectors (NOT the GC Python has; NOT the GC Go has) can, in principle, make heap memory management cheaper than stack allocation has been well known since the eighties. But until recently they had excellent throughput (somewhat similar to arenas) but potentially long pauses. It was only recently that they were made "pauseless".
> and is often run at an unpredictable time
How much work malloc and free need to do is also unpredictable, and a modern pauseless moving collector like ZGC spreads the work needed for memory management more evenly than malloc and free.
> Sure, the GC is not necessarily the SLOWEST thing about the language (python), but it's not helping, either.
There is very little resemblance between CPython's GC and Java. Python's memory management is closer to C's than to Java's. GCs cover such a wide spectrum of algorithms that it doesn't make sense to talk about them as a single category as far as performance tradeoffs are concerned.
> see a new programing language
> look inside
> it's rust
asking out of my own ignorance, what's so hard with rust that you cannot convince people and contribute to that directly instead of going on your way? i remember so few of these projects survived over the years. do you think it'll really become something other than your pet project?
The pitch is "one ownership rule for memory, threads, and networks," but I think there are two rules in here and they pull against each other.
The resource rule as stated is linear: once you use a resource, you can't use it again. Perceus is not that. Perceus exists precisely because values are shared — it inserts dup/drop and then reuses the allocation in place when the count happens to be 1. If everything in the language were genuinely use-once, you wouldn't need refcounting at all; a linear type system gives you the frees statically. The fact that Perceus is in the design implies aliasing is allowed, which means "one owner" is a description of the socket/interrupt layer, not of memory.
That's fine as a design — but then the elevator pitch is "two rules that rhyme," and the FAQ's central claim ("you only need to learn one rule") is the thing I'd expect to break first under contact with real programs.
Related, and more concrete: Koka and Lean get away with RC partly because their data is overwhelmingly acyclic by construction. Your README shows var bindings and mutable struct fields. Mutation plus refcounting gives you cycles, and cycles leak. What's the plan — a cycle collector, weak references, a type-level acyclicity restriction, or accepting the leak? DESIGN.md would be a good place to state it outright, because it's the first question anyone with RC experience will ask.
Simplicity in the tag line but uses Result<T, E>. Should've followed Zig's direction for error handling. With that out of the way looks like a fun little language.
Zig's way is "simple" but not elegant, specifically since it hard codes how error handling is done. Algebraic data types are more elegant, since it can be used not just for error handling, but also other kinds of data modeling.
Ocaml was very simple to program in to be honest, and has very minimal rules as well so i can be productive with the development of the language, Rust also used ocaml in it's early versions for bootstrapping
The tests I could find for ‘choreographed programming’ were 1-2 lines long and demonstrated absolutely nothing, certainly nothing as elaborate as the research text is stating.
This looks cool! Memory safety beyond Rust with simpler code is a strong claim. Something I'd love to see is examples that mimic issues Rust borrow checker would catch as well as ones only wyzer would catch.
Too bad the github readme doesn't explain how the choreographic side of Wyzer works, or even what it looks like (please correct me if I'm wrong, couldn't find it after a quick skim).
It would be worth writing examples of the resource ownership model (especially network wise), this is the rare feature here it seems.
ps: were you looking at efforts such as clojure electric (https://github.com/hyperfiddle/electric) ? they aim to represent computation on different hosts as one expression.
I skimmed so I may have missed it, but nowhere in the README do I actually see a description of what "choreographic programming" is, or an example of it.
New? It stretches back industrially to the WS-* stuff in the early 00s (this is where the term originated), and on the academic side has roots in process calculi from the 90s and session types from the late 00s and early 10s.
As someone working on a language in this space, I think your README could be much better.
Most of the important stuff is in this section:
```3. What's Actually New About It?```
But you don't really go into any details about what's actually happening, have any honest conversation about any trade-offs, mention anything about why this is memory safe & correct now (highly skeptical), or why you have a clear path towards that in the near future.
From the VERY brief examples you show, it looks like it's just Rust without a borrow checker. The borrow checker gives Rust a bad reputation, but it's only a very small part of why Rust is hard. You didn't give any insight into how you're solving the rest of the problems.
wow it is great to see that there is still life in distributed programming languages. I would like to know what are the differences to MPI programming, chapel and PGAS languages like Co-Array Fortran and the rust extension ChoRus?
Can you you give a hello world example in each of them and show where your languages shines?
> Memory (Section 5): You write functional code that does not change data. Behind the scenes, if a piece of data has only one owner, the compiler changes it directly in memory. This makes it as fast as C without a garbage collector or lifetime rules.
What happens if the piece of data has multiple owners? Do you get sudden performance bugs which are hard to debug?
Far too often I see projects on HN where, on a casual skim, I just can't figure out "the point." This is clear and concise.
---
One of the issues with "Writing one network rule that creates code for every computer. We borrowed this from academic research" is that often it's hard to have the same language on every computer. For example, for a web application, you're either going to have to transpile to Javascript or target WASM. (And WASM has a lot of overhead compared to Javascript.)
Congratulations your language is trying to solve an hard problem.
But .. your language mostly hide when you're doing an 'inside' function call or an 'external' function call.
I'm not sure I like this;
1) the latency of both operation is very different so you want to minimise the number of 'external' function calls
2) what happens in case of 'timeout' for external function calls?
I didn't see it in the doc, did I miss it?
vsilent | 15 hours ago
[OP] v0id_isgood | 15 hours ago
jitl | 15 hours ago
Where’s the cool stuff?
[OP] v0id_isgood | 14 hours ago
derdi | 14 hours ago
jitl | 14 hours ago
if you claim X and Y make us cool and different, then you should document X and Y in your readme. don’t tell me something is the star, and then hide it away. this is baffling to me.
polymer8563 | 13 hours ago
IsTom | 12 hours ago
andai | 14 hours ago
hyperhello | 15 hours ago
The next thing is, I need more examples. Read me documents can scroll forever and that’s fine. Add examples for every concept your language wants to cover to it. This is your chance to think things through and make the read me and the language astonishing.
And your AI disclaimer (or your AI’s disclaimer) makes sense.
[OP] v0id_isgood | 14 hours ago
gitgud | 4 hours ago
[OP] v0id_isgood | 14 hours ago
snek_case | 13 hours ago
mightyham | 11 hours ago
manithree | 14 hours ago
[OP] v0id_isgood | 14 hours ago
jitl | 14 hours ago
thomasmg | 14 hours ago
[1] https://github.com/thomasmueller/bau-lang/tree/main
vlovich123 | 14 hours ago
What stops a choreography where Claire send a message to Bob but Bob is waiting for Alice and Alice is waiting for Claire?
Is it like Rust memory safety where not all valid programs are accepted but all invalid programs are rejected?
I think some examples of the distributed code in action on a trivial and non trivial distributed example is more compelling than a 3d donut render
minraws | 13 hours ago
The protocol doesn't describe "Claire sends" and "Bob receives" as two independent actions that wait for each other, it describes them as a single communication in the global program/state.
When it gets executed into code, every send already has a corresponding receive by construction, so you can't write something like "Claire sends to Bob while Bob is actually waiting for Alice" unless the protocol itself allowed that execution.
So the cycle you're describing can't just accidentally appear because of sync issues, because the assumption is a communication is represented correctly at each turn.
So yeah it kinda does limit the set of all possible programs since I would expect not everything can be encoded this way also seems hard to resolve this in practice without only allowing communication b/w Wyzer systems.
I am not very familiar with this topic in practice so OP would be the best person to answer this, I am quite intrigued by how it works in practice as well.
fmontesi | 9 hours ago
A choreographic programming language features programming abstractions for programming communication intent. For example, often they have a primitive like:
Alice.expr -> Bob.x
read 'Alice communicates the evaluation of expr to Bob, which stores the message in its local variable x'. (In fact, we discovered that we can extend any mainstream language to have this kind of high-level primitives by extending data types with locations, see choral-lang.org).
This makes it impossible to write mismatched communication actions, because you're expressing both the send and receive actions in a single atomic instruction: they are well-matched by construction. You then build a compiler (typically called 'projection') that generates distributed programs for Alice and Bob -- the former doing the send to Bob and the latter doing the receive from Alice. We like making formal models of these compilers and mathematically proving them correct. A compiler that respects the choreography then automatically entails deadlock-freedom of the compiled code without the need for complex checks, because the source choreography cannot syntactically express deadlocked terms.
Consequently, there are no deadlocked distributed programs that we can compile from choreographies. It's an application of the neat trick of designing high-level languages for 'guiding' programming: instead of programming a distributed system with low-level primitives and then attempting the generally very hard task of checking for deadlocks, we use a high-level language where deadlocks cannot be written (or are at least easy to check against).
The above hopefully explains the intuition of how choreographic programming works. But then, as you did, one naturally asks: What can we express in choreographic programming languages? Are there fundamental limitations?
We do not know exactly yet; this is an area of very active exploration. Over the years, people have developed more and more clever choreographic programming languages that capture more and more interaction patterns.
What's perhaps surprising is that, for some theories of distributed languages (or interaction patterns, if you like), we know that choreographic programming is complete, in the sense that it can capture all deadlock-free systems that can be modelled in those theories. The first result of this kind was about capturing all interaction behaviours that can be described in linear logic (in the Curry-Howard interpretation of it with process calculi), but there are also works that can deal with recursive behaviour and even process spawning (fork). That's encouraging.
I think that investigating what the paradigm precisely can and cannot do is fascinating (but I'm very biased here..), not least because using a mathematically-modelled compiler lets us optimise the generated code aggressively (e.g., adding more asynchrony, as in Ozone). From the state of the art already out there, it looks like choreographic programming is 'expressive enough' for many different purposes. Hopefully it's gonna be the typical situation with high-level abstractions, whereby for most cases and most people the high-level language is gonna be good and low-level communication actions will be necessary only in niche scenarios. In the meantime, there are choreographic languages that can be integrated with middleware and foreign APIs to cover up for deficiencies (like Choral, HasChor, etc.).
pgt | 9 hours ago
hmokiguess | 14 hours ago
In there it says you started this journey when you were 8 years old and that you are a 14 year old programmer
I'm not sure how I feel about this to be honest, I need to process that.
[OP] v0id_isgood | 14 hours ago
DoesntMatter22 | 6 hours ago
REDA_MAH | 14 hours ago
andai | 14 hours ago
steeleduncan | 14 hours ago
[OP] v0id_isgood | 13 hours ago
bramadityaw | 11 hours ago
pmarreck | 14 hours ago
It's "pretentious."
(said pretentiously, lol)
Hey, at least we know AI didn't write it, lol
tosti | 11 hours ago
https://www.microsoft.com/en-us/research/wp-content/uploads/...
(wait what is that WordPress?)
kazinator | 13 hours ago
Made an error? Hold your beer, Bud's got your back: the Bud Wyzer compiler!
pjmlp | 13 hours ago
bckr | 13 hours ago
Is choreographic programming the same as session types?
netniuq | 13 hours ago
Promising insofar as all of the essentials seem to be right (for me): compiled, good type checker, no garbage checker etc.
phplovesong | 13 hours ago
reactordev | 13 hours ago
Is mut a thing? looks like rust.
[OP] v0id_isgood | 12 hours ago
reactordev | 11 hours ago
slifin | 13 hours ago
jerf | 13 hours ago
However, your light is hidden under a basket, to use an old metaphor. I'm having to go digging to find the genuinely new things going on. I suggest recalibrating the entire documentation with a focus on the new stuff. People on HN often complain about not having syntax examples front and center but I would say for you, the very first thing I you should be hitting your new visitors with is the choreography idea.
Set up a simple example of doing something like a concurrent remote counter that is atomically safe by the construction of your language and immediately dive in to what that means. Forget even educating us on the rest of the mundane syntax of the language, immediately dive in to what that is and what that means. I see in the docs/ dir that it probably hurts your programmer mind to cover the choreography before covering sections 1-8, but you can safely assume that if you intrigue with the choreography that they'll hang around to learn about the rest, whereas you can't safely assume that a new reader will wade through all the rest of the relatively mundane details to get to the really interesting stuff.
A modern language with a modern take on compiling a "program" that takes a unified view of the world at the programming language level, and then emits a "server" and a "client" (and perhaps other roles) as separate executables is a pretty nifty idea. Hit it early and hit it hard.
[OP] v0id_isgood | 12 hours ago
We definitely fell into the author’s trap of structuring docs "bottom-up" (Prerequisites -> Basic Syntax -> Advanced Concepts) rather than leading with our actual core innovation: choreography.
We are restructuring the main README/docs front page right now to lead immediately with a concrete example of choreographic execution (e.g., atomic multi-node orchestration / client-server emitting) before getting into standard syntax.
Really appreciate you taking the time to dig into the docs/ dir to pull this out it’s a huge help for our presentation.
chime | 11 hours ago
jerf | 11 hours ago
I mean, I'm phrasing that in marketing terms, but in this case it's in harmony with what your users want anyhow. We want to know ASAP why we should care about this language. So it works for everyone. Of course when it comes time to deliver the promise, normal programming language documentation is the way it is for a reason.
bramadityaw | 11 hours ago
adastra22 | 11 hours ago
byson94 | an hour ago
Jabbles | 10 hours ago
winfredJa | an hour ago
byson94 | an hour ago
irq-1 | 10 hours ago
You should put these up front also.
valorzard | 9 hours ago
arcrevenant | 7 hours ago
This is not an LLM talking but a kid who is learning to write with them, if you look closely. Still concerning
arcrevenant | 9 hours ago
Nothing worse than PDFs full of theory and no working examples of the thing you’ll actually be doing all day.
I get that it’s important to show what abstractions and methodologies can arise out of using it, but with a good example that would be obvious. It’s the developer community using the language that will come up with the best abstractions (libraries) that - if it has an active community - helps shape what those novel developer experiences are.
A good analogy is the development of the skateboard - released first as a scooter - until someone knocked the handle off a started “surfing” down the street. Just show me the thing. I’ll tell you if it’s cool and how to use it
bitwizeshift | 9 hours ago
The choreography stuff is actually really cool! Definitely agree this should be front and center
pron | 12 hours ago
It does not. The term "garbage collectors" covers a whole spectrum of algorithms, some might slow you down (though not for the reason you may think) while others were invented to speed up memory management beyond that of C++, in exchange for other tradeoffs. Python's (mostly) refcounting GC is actually closer to C in its memory management overhead than to either Go or Java. It's also not what makes Python slow. Go uses a mark-and-sweep collector to find a balanace between speed, FFI, and footprint. Java uses moving collectors, which are faster - and some of which are even more predictable - than memory management in C++. That's because Java aims to offer better performance than C++ in large concurrent software, where low-level languages tend to suffer from various overheads due to their requirement for low-level control (Java trades off some performance in smaller programs, but mostly it trades of startup time and footprint). Moving collectors (but not refcoting collectors or mark-and-sweep collectors) are an optimisation over free-list approaches, not a compromise for convenience.
So it is true that slow programming languages tend to use some kind of GC, but that's not what makes them slow, nor does it make the super-fast languages that also use a GC (often of a very different kind) any slower. The range of languages that use GCs covers everything from the super slow to the super fast.
allknowingfrog | 10 hours ago
Are you arguing that GC is not inherently slower than other memory management strategies (e.g. the Rust approach)? Or just that the cost is not worth optimizing away?
pron | 5 hours ago
jesse__ | 6 hours ago
Running a GC takes time, pollutes the cache, and is often run at an unpredictable time. Sure, the GC is not necessarily the SLOWEST thing about the language (python), but it's not helping, either.
xigoi | 6 hours ago
Isn’t this only the case for tracing garbage collectors? (And even then, not all of them are stop-the-world.)
pron | 6 hours ago
Yes, but for a moving collector that's less time than it takes to run malloc and free. The interaction of a moving collector with most object is bump allocation when they're allocated (similar to stack allocation) and... that's it. The GC never sees them again, scans them again, or is even aware of their existence (moving collectors don't have a free operation). Overall, moving collectors (but not other kinds of GC) reduce the work of memory management compared to malloc/free.
In low-level languages we try to avoid doing a lot of malloc/free not because heap memory management is slow in general, but because that approach to memory management is slow. Moving collectors are an optimisation designed to make heap memory management fast, but it requires that (nearly) all pointers be movable, something that low-level languages can't do because they have constraints that are more important to them than speed (you can't interact with the OS or hardware directly, i.e. without an FFI API, if your pointers are movable, and such direct interaction is the point of low-level languages).
That moving collectors (NOT the GC Python has; NOT the GC Go has) can, in principle, make heap memory management cheaper than stack allocation has been well known since the eighties. But until recently they had excellent throughput (somewhat similar to arenas) but potentially long pauses. It was only recently that they were made "pauseless".
> and is often run at an unpredictable time
How much work malloc and free need to do is also unpredictable, and a modern pauseless moving collector like ZGC spreads the work needed for memory management more evenly than malloc and free.
> Sure, the GC is not necessarily the SLOWEST thing about the language (python), but it's not helping, either.
There is very little resemblance between CPython's GC and Java. Python's memory management is closer to C's than to Java's. GCs cover such a wide spectrum of algorithms that it doesn't make sense to talk about them as a single category as far as performance tradeoffs are concerned.
thechao | 12 hours ago
But why!? You know what'd be cool? If we started supporting control statements that were a bit more sophisticated!
``` do { } while (c) { if (x) break foo; } else { case foo : ...; default : ...; } ```
[OP] v0id_isgood | 12 hours ago
gokaygurcan | 12 hours ago
asking out of my own ignorance, what's so hard with rust that you cannot convince people and contribute to that directly instead of going on your way? i remember so few of these projects survived over the years. do you think it'll really become something other than your pet project?
999900000999 | 12 hours ago
It takes the fun out of this. I like JavaScript and Python. If I need to type system, there’s always type script and C#.
I don’t care about a bunch of memory management details, and if I ever want to I might as well use C++ and become a quant.
I learn a new programming language for one of two reasons, there’s a framework or engine that requires it. For example, Godot with GD script.
Or to make more money.
Python was a very happy mix of both, I learned it to work with ML libraries as a hobby and later found it pays a lot more.
DoesntMatter22 | 6 hours ago
imthenitto | 12 hours ago
The resource rule as stated is linear: once you use a resource, you can't use it again. Perceus is not that. Perceus exists precisely because values are shared — it inserts dup/drop and then reuses the allocation in place when the count happens to be 1. If everything in the language were genuinely use-once, you wouldn't need refcounting at all; a linear type system gives you the frees statically. The fact that Perceus is in the design implies aliasing is allowed, which means "one owner" is a description of the socket/interrupt layer, not of memory.
That's fine as a design — but then the elevator pitch is "two rules that rhyme," and the FAQ's central claim ("you only need to learn one rule") is the thing I'd expect to break first under contact with real programs.
Related, and more concrete: Koka and Lean get away with RC partly because their data is overwhelmingly acyclic by construction. Your README shows var bindings and mutable struct fields. Mutation plus refcounting gives you cycles, and cycles leak. What's the plan — a cycle collector, weak references, a type-level acyclicity restriction, or accepting the leak? DESIGN.md would be a good place to state it outright, because it's the first question anyone with RC experience will ask.
Myzel394 | 12 hours ago
nirbendavid | 12 hours ago
khat | 12 hours ago
[OP] v0id_isgood | 12 hours ago
bramadityaw | 10 hours ago
taolson | 12 hours ago
[OP] v0id_isgood | 12 hours ago
dwroberts | 12 hours ago
This is just slop
rrook | 12 hours ago
https://hale-lang.org/articles/claims-in-hale/
mring33621 | 12 hours ago
pmkary | 12 hours ago
beckford | 9 hours ago
pmkary | 9 hours ago
bryzaguy | 12 hours ago
rbr94 | 11 hours ago
Too bad the github readme doesn't explain how the choreographic side of Wyzer works, or even what it looks like (please correct me if I'm wrong, couldn't find it after a quick skim).
tristanMatthias | 8 hours ago
DauntingPear7 | 11 hours ago
xyzsparetimexyz | 11 hours ago
jnpnj | 11 hours ago
ps: were you looking at efforts such as clojure electric (https://github.com/hyperfiddle/electric) ? they aim to represent computation on different hosts as one expression.
adastra22 | 11 hours ago
lostbean | 11 hours ago
bramadityaw | 11 hours ago
tpoacher | 10 hours ago
Are we just straight up inventing buzzwords now?
Hey guess what, I'm more into symphonic opus programming, none of that backyard dance-club programming for me thanks.
/s [no hate, just laffs]
jwolfe | 10 hours ago
tpoacher | 10 hours ago
Nothing like establishing a new buzzword in a field to get them citations rolling.
tonyg | 9 hours ago
srean | 10 hours ago
https://felix-tutorial.readthedocs.io/en/latest/intro_corout...
Note this is for cooperative threading.
onlyrealcuzzo | 10 hours ago
Most of the important stuff is in this section:
```3. What's Actually New About It?```
But you don't really go into any details about what's actually happening, have any honest conversation about any trade-offs, mention anything about why this is memory safe & correct now (highly skeptical), or why you have a clear path towards that in the near future.
From the VERY brief examples you show, it looks like it's just Rust without a borrow checker. The borrow checker gives Rust a bad reputation, but it's only a very small part of why Rust is hard. You didn't give any insight into how you're solving the rest of the problems.
nicoburns | 9 hours ago
Definitely a cool idea. I guess time will tell whether lifting it into the language proves itself as worth it.
fxj | 9 hours ago
Can you you give a hello world example in each of them and show where your languages shines?
whateverboat | 8 hours ago
What happens if the piece of data has multiple owners? Do you get sudden performance bugs which are hard to debug?
gwbas1c | 7 hours ago
> 1. What Wyzer Is, In One Paragraph...
> 2. Why Make a New Language At All?...
Far too often I see projects on HN where, on a casual skim, I just can't figure out "the point." This is clear and concise.
---
One of the issues with "Writing one network rule that creates code for every computer. We borrowed this from academic research" is that often it's hard to have the same language on every computer. For example, for a web application, you're either going to have to transpile to Javascript or target WASM. (And WASM has a lot of overhead compared to Javascript.)
NetMageSCW | 7 hours ago
renox | 6 hours ago
But .. your language mostly hide when you're doing an 'inside' function call or an 'external' function call. I'm not sure I like this; 1) the latency of both operation is very different so you want to minimise the number of 'external' function calls 2) what happens in case of 'timeout' for external function calls? I didn't see it in the doc, did I miss it?