Show HN: W++ – A Python-style scripting language for .NET with NuGet support
I’ve been building *W++*, a scripting language that looks like Python but runs on the .NET runtime. It started as a fun side project, but it evolved into something surprisingly powerful — and potentially useful:
Key Features:
- Python-style syntax with semicolon-based simplicity
- Compiles to .NET IL with experimental JIT support
- Can run interpreted or compiled
- Built-in CLI for managing projects, running, and building
- Supports importing NuGet packages and converts them to .ingot modules automatically - MIT licensed and fully open-source
You can even do things like:
wpp
import Newtonsoft.Json
let person = new JObject()
person["name"] = "Alice"
print person["name"];
Use Cases:
Game scripting (Unity, OpenTK support in progress)Education (gentle intro to .NET without C# syntax)
Blazor scripting
Embeddable scripting engine for .NET apps
GitHub: https://github.com/sinisterMage/WPlusPlus
I’d love feedback, ideas, and thoughts. Thanks for reading — and if you’ve ever said “I wish Python ran on .NET,” this might be for you.
That said, in 2025 if I was already willing to utilize C#/.NET, I would probably prefer an "internal" DSL approach [0] - i.e., one that leverages the host language directly and builds the abstractions on top.
Examples of this would be fluent interfaces and methods like ConfigureDomainServices(Action<DomainServiceBuilder>). I know some developers frown on this approach, but I've embraced it as the least terrible way to go about handling things like AspNetCore web server configuration and setting up complicated data transformation pipelines. If these techniques are good enough for configuring a modern, production grade web server, they are probably good enough for configuring your domain too.
I spent a solid 3 years building & supporting an IronPython stack on the old 4.x .NET Framework and I learned a lot of lessons about how bad things can get when you begin coloring outside the lines. Memory leaks were probably the most difficult thing to reason about. Object lifecycles are already pretty tricky without the hosted language on top.
[0]: https://martinfowler.com/dsl.html
I'm a little jealous ;) As someone who codes in both Python and C# mainly, never had to touch IronPython for an employer yet.
I definitely get the appeal of internal DSLs, especially with how powerful C#’s fluent APIs have become. W++ takes a bit of a different path: more like “what if .NET had a native scripting layer that felt expressive and lightweight,” even if that means giving up some safety or flexibility of the host language.
And wow — 3 years with IronPython is no joke. Totally agree on how tricky it can get once you step outside the intended boundaries. I’m keeping W++ focused more on smaller, experimental scripting for now, but your point about memory and lifecycle management is a great reminder for anything that gets more ambitious.
Cheers for the link to Fowler’s DSL article too — gold.
No comments yet
I thought the whole point of these high level langs was that you don't have to worry about that?
But in hosted scenarios like IronPython or W++ (where the language is layered on top of .NET), things can get trickier:
You're managing your own object model inside a host runtime.
If you're not careful, it's easy to create long-lived references (like global caches or circular structures) that the GC won’t clean up.
In IronPython's case, hosting decisions (like how objects interop with .NET classes) can leak unintentionally if lifecycle logic isn't airtight.
So yeah — you usually don't think about memory... unless you're writing the language
I think it stays niche because it’s targeted at people knowing the dotnet ecosystem but most of those people reason a lot in OOP/imperative because well, they work with C#.
But it’s amazing to me that F# is still evolving and cutting edge after more than two decades of being extremely niche. You’d think Microsoft would abandon it or let it rot but no. Though I think F# is in fact the laboratory for new language features for C#.
As others have stated, the use of semicolons while stating this is "like Python" is weird. Use language which avoids the direct Python comparison. It seems like your language is intended to be succinct. Just state that because it'll avoid negative reactions. I'm a C# and Python dev, so I'd rather you avoided this in-between state.
Killing semicolons and braces to embrace indentation would be my preference for a scripting language that is intended to appeal to my Python-side. If the intention is to appeal purely to C# devs, then don't mention Python at all because they often jump to "indentation, ugh" without considering your language.
You're absolutely right about JIT startup time. Currently, W++ doesn't do any caching or ahead-of-time work, so there’s a delay on the first run. I’ll explore ways to keep it snappy for quick scripts — maybe a pure interpreter fallback for single-run use cases would help.
Also appreciate the insight on the Python comparison. That “in-between state” you described is exactly where I’m at — trying to blend Python’s simplicity with .NET’s power. But you’re right, the messaging could be cleaner. I’ll adjust the README to better reflect that W++ is its own thing and not a direct clone or pitch to Python devs.
This kind of comment is gold, seriously. Thanks for taking the time.
Maybe the “looks like Python” means it uses significant whitespace? In that case I think the README should have an example demonstrating that.
To be clear, you can diverge from Python syntax all you want. I think you just need to be clearer about what you mean by “looks like Python,” maybe by providing an example that highlights the features that particularly resemble Python.
I’ll make the README clearer with a side-by-side W++ vs Python snippet to highlight the similarities better. Thanks a lot for pointing it out!
Honestly I think you’re leaning too hard into the “Python” marketing. Python is not just a byword for “easy-to-learn dynamically typed language”. It is its own, specific thing, and your language is not the same. You could say something like “inspired by Python” (in certain ways), but claiming to target people who “wish they could write Python on .NET” strikes me as an exaggeration (especially since you can already do that).
I’ll tweak the README to make that clearer. Appreciate the honest feedback!
> significant indentation and dynamic typing
are absolutely the worst parts of Python. I can understand dynamic typing for scripting purposes, no real qualms there, but significant whitespace is on its face absolutely insane (significant characters that are literally invisible).
Biggest downside: copying and pasting code breaks in a lot of apps.
Jira, Teams, and probably some others, eat whitespace for breakfast. So if a coworker gives me a code snippet they have to manually edit it (often not even possible) OR I have to, or it won't even run. And since the whitespace is significant, it can't be auto formatted.
Whereas with C# you can copy the most fucked up snippet, put it in your editor and boom - auto-formatted and compiles.
Python’s grammar works great for expressions-inside-statements (and expressions-inside-expressions), but it can’t do statements-inside-expressions. Every attempt to support the latter turns out really ugly, at least in corner cases.
That said, I totally agree that full anonymous functions would be useful (especially for more complex logic). Might explore adding those later, but I love the message the current model sends.
It might not be a highly visible downside, but it's there nonetheless. It's better to be honest about that than pretend there is no cultural tradeoff that comes with making such a (IMO) terrible design decision in a language.
There are plenty of people that feel the same way about sigils (like `$foo` in Perl) and semi-colons. I've never understood it -- and likely never will, at this point -- but I don't pretend that there isn't a real demographic effect that these choices bring with them.
W++ leans that way just to reduce boilerplate and keep the syntax clean for smaller scripts, but it’s not trying to be the “one true way” to write .NET code. Honestly, it’s all about exploring what a lightweight .NET scripting layer could feel like.
Appreciate you checking it out
Any insight into why that is?
Only later did I find out it had been labeled as malware by Microsoft — no details, no warning. I emailed their support to clarify what triggered the flag, but I never got a response.
Since then, I’ve made the entire source public here, including the VSCode extension, so folks can inspect and use it freely. If anyone has experience navigating these kinds of takedowns, I’d definitely appreciate insights.
https://github.com/sinisterMage/WPlusPlus/blob/master/SYNTAX...
I drew from multiple languages — Python, JavaScript, even a little C-style flavor — to make something that’s readable, expressive, and beginner-friendly, especially for quick scripting in .NET.
Appreciate the suggestion! I’ll make sure the SYNTAX.md is linked more clearly from the README.
The idea was: W++ aims for a syntax that feels lightweight like Python (minimal boilerplate, indentation structure), but it also borrows C-style flow and expression flexibility. So technically it’s a bit of a hybrid:
Block structure + minimalism = inspired by Python
let, const, switch, and lambdas = more JS/C-style
I’ll clean up SYNTAX.md and the description to better reflect that. Appreciate you pointing it out!
W++ doesn’t have full-blown data flow analysis (yet!) — the current interpreter walks the AST in a fairly straightforward way, and the JIT just compiles expression trees without SSA or optimization passes. But your idea of analyzing LLM-generated scripts is super interesting. I'd love to explore basic flow inference or a visualizer in the future.
Feel free to open an issue or discussion if you’re curious — would be awesome to collaborate!
All the best and I’m sure many others will find this useful.
Appreciate the kind words regardless — and who knows, maybe I’ll experiment with optional semicolons in a future version.
Typescript itself is a non starter because of non-configurable "brackets around if conditions" behavior. I pretty much write any language I wanna use these days depending on the task. Use the right tool for the right job. I do generally target perl 5.8 as a backend though. Seemed simpler and most widely supported backend across all systems I came across. Has been super stable since '02.
I don't think the name "W++" conveys what it is, it makes me think this is a systems language that competes with Rust, D, C++, C and even Zig. Maybe calling it based on a different snake species would convey that it might be related to Python? Calling it Cobra or something else might make sense.
Otherwise, I look forward to experimenting with this project!
But you’re totally right that naming is tricky. I might reconsider down the line if it ever gets serious traction — “Cobra” does sound kinda slick
Appreciate the feedback!
Isn't that IronPython?
W++ takes a different approach: it's a custom scripting language that looks like Python but is designed for tight integration with .NET itself, including:
Native JIT compilation (via IL emission)
NuGet package import support (via .ingot wrapping)
Familiar syntax (like print, let, for, if) with static structure
IronPython is about bringing Python to .NET. W++ is about making .NET scripting feel more like Python.
Think of it as IronPython’s minimalist, compile-time-powered cousin.
I do think theres some interesting value in something like IronPython becoming more compatible with regular Python code in that in theory you could take advantage of both .NET and Python libraries. I'm thinking maybe Django with access to any .NET library.
https://clojure.org/about/clojureclr
And the newer reimplementation: https://github.com/dmiller/clojure-clr-next
Also, totally agree — bridging Python and .NET ecosystems more deeply (like Django with NuGet access ) sounds wild and fun. Appreciate the thoughts!