[HN Gopher] Show HN: W++ - A Python-style scripting language for...
___________________________________________________________________
Show HN: W++ - A Python-style scripting language for .NET with
NuGet support
Hey HN 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.
Author : sinisterMage
Score : 78 points
Date : 2025-05-30 14:58 UTC (8 hours ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| airstrike wrote:
| _> if you've ever said "I wish Python ran on .NET"_
|
| Isn't that IronPython?
| sinisterMage wrote:
| You're absolutely right -- IronPython does run Python on .NET.
|
| 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.
| giancarlostoro wrote:
| I lowkey want someone to make the Clojure of .NET which is a
| Lisp / Scheme like language but that takes full advantage of
| .NET I do like that yours does this with Python however. My
| two main languages for a while have always been Python and
| C#.
|
| 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.
| sinisterMage wrote:
| That's a really cool idea -- a "Clojure of .NET" would
| definitely fill a unique niche. W++ kind of stumbled into
| this space by aiming to make .NET feel more like Python for
| scripting -- but yeah, I'd love to explore where it could
| go if more folks want something expressive but tightly
| integrated with .NET.
|
| Also, totally agree -- bridging Python and .NET ecosystems
| more deeply (like Django with NuGet access ) sounds wild
| and fun. Appreciate the thoughts!
| grzm wrote:
| I'm not familiar enough with the CLR or .Net to know
| whether this fits your needs, but there is ClojureCLR:
|
| https://clojure.org/about/clojureclr
| Nelkins wrote:
| There's the original/current implementation:
| https://github.com/clojure/clojure-clr
|
| And the newer reimplementation:
| https://github.com/dmiller/clojure-clr-next
| actuallyalys wrote:
| I'm a little confused; it "looks like Python" but basically every
| snippet has elements that _don't_ look like Python. Ignoring the
| semicolons, which you do call out as a difference, I see let for
| introducing variables, new for creating objects, and a completely
| different lambda syntax.
|
| 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.
| sinisterMage wrote:
| You're totally right to ask -- W++ borrows Python's general
| feel (like significant indentation and dynamic typing), but its
| core is rooted in a C-style heritage due to the .NET
| foundation. So while let and semicolons aren't Pythonic, the
| language avoids boilerplate, supports clean control flow, and
| aims for the readability people love about 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!
| umanwizard wrote:
| .NET by no means requires languages to be C-like, certainly
| not in trivial ways like having semicolons. F# for example
| (or for that matter, IronPython) is very unlike C. So
| whatever you're trying to say here is still confusing.
|
| 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).
| sinisterMage wrote:
| Totally fair point -- W++ isn't meant to be a direct Python
| clone, just inspired by its simplicity and clean syntax
| (like indentation and dynamic typing). The goal was to make
| scripting on .NET feel lighter and more approachable.
|
| I'll tweak the README to make that clearer. Appreciate the
| honest feedback!
| smt88 wrote:
| I think this project is incredibly cool and lots of people
| will use this, but...
|
| > _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).
| sinisterMage wrote:
| Thanks! Totally fair -- I know significant indentation and
| dynamic typing aren't for everyone.
|
| 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
| dontlaugh wrote:
| I have the opposite opinion, having written Python for many
| years. Dynamic typing is almost never better or necessary,
| but significant whitespace makes for excellent syntax with
| no downsides.
| pansa2 wrote:
| There's at least one downside: only having lambda
| expressions instead of full anonymous functions.
|
| 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.
| sinisterMage wrote:
| Yep, W++ lambdas are statement-level on purpose My high
| school teacher once told me lambdas are "university-
| level," so I made them the default function syntax in
| W++. It's my way of saying: "nah, these aren't scary --
| they belong in scripting too."
|
| 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.
| dontlaugh wrote:
| It works just fine for F#, for example. It's doable, but
| it's too late for Python.
| const_cast wrote:
| > but significant whitespace makes for excellent syntax
| with no downsides.
|
| 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.
| noworriesnate wrote:
| This is very cool! Do you have data flow analysis implemented
| anywhere? I've been thinking about building my own Python
| interpreter to help understand how info flows around inside a
| script generated by an LLM and data flow analysis would probably
| be a good place to start. I'm very familiar with the dotnet
| ecosystem so this could be something I'd be interested in
| contributing to.
| sinisterMage wrote:
| Thanks! That means a lot
|
| 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!
| frabert wrote:
| https://boo-language.github.io/ The Boo language comes to mind as
| something similar
| sinisterMage wrote:
| Oh wow, I actually hadn't heard of Boo until now -- thanks for
| sharing it! Just took a quick look and yeah, I can definitely
| see some parallels. W++ wasn't directly inspired by it, but I
| guess we both arrived at similar goals: a Python-style language
| that plays well with .NET.
| debugnik wrote:
| This was by the same author as UnityScript, wasn't it? IIRC the
| latter was mostly just Boo in a JS trenchcoat, which is why
| both were supported along with C#.
| bob1029 wrote:
| I think this is fun stuff. I always enjoyed building things like
| this.
|
| 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
| giancarlostoro wrote:
| > 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.
|
| I'm a little jealous ;) As someone who codes in both Python and
| C# mainly, never had to touch IronPython for an employer yet.
| waldrews wrote:
| It's sad that IronPython is effectively dead, but PythonNet
| is now very stable, complete, and friendly to recent Pythons.
| e-master wrote:
| pythonnet works, we use it in a pretty large (Python)
| codebase, but I'm much more excited about
| https://github.com/tonybaloney/CSnakes, which allows using
| Python in a proper statically typed language - C#.
| sinisterMage wrote:
| Thanks! I really appreciate you taking the time to write this
| up -- super insightful.
|
| 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.
| 90s_dev wrote:
| > Memory leaks were probably the most difficult thing to reason
| about. Object lifecycles are already pretty tricky without the
| hosted language on top.
|
| I thought the whole point of these high level langs was that
| you don't have to worry about that?
| sinisterMage wrote:
| Totally fair question -- most high-level languages do take
| care of memory for you, especially with garbage collection.
|
| 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
| make3 wrote:
| Are you saying that IronPython in general has memory leak
| issues? or just because you were trying to add support for an
| old .NET framework
| giancarlostoro wrote:
| The only immediate feedback I have is the name. I feel like
| languages and projects underestimate good naming, like Go has a
| nice name, but its awful to google for, hence everyone tacks on
| "lang" to it.
|
| 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!
| sinisterMage wrote:
| Haha yeah, fair point on the name! I actually chose "W++" from
| a gaming mindset -- in games, W = Win, so W++ was my way of
| saying "keep stacking wins." It's not meant to compete with
| Rust or Zig -- it's more of a light, expressive scripting
| language that happens to be built on .NET.
|
| 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!
| zerkten wrote:
| Does this start up quickly on the first execution? IronPython and
| other languages have problems with JIT resulting in minor delays
| to execution which are frustrating for quick scripts. There was a
| change in IronPython to interpret and not JIT on the first run to
| avoid this delay. Anything you use to remove JIT delays for quick
| scripts will increase the likelihood of adoption. Running JIT on
| repeat runs is a beneficial feature so you don't want to kill it
| entirely.
|
| 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.
| sinisterMage wrote:
| Thanks for the thoughtful feedback -- you raised a few great
| points I hadn't fully considered.
|
| 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.
| pansa2 wrote:
| Why does this post say "Python-style syntax", but "SYNTAX.md"
| shows a "clean syntax inspired by JavaScript and C-like
| languages"?
| sinisterMage wrote:
| You're totally right to catch that -- I'll update it for
| clarity!
|
| 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!
| hoistbypetard wrote:
| > This repo contains the full source code of W++ after it reached
| over 33,000 downloads on the VSCode Marketplace -- and was
| mysteriously flagged and removed.
|
| Any insight into why that is?
| sinisterMage wrote:
| Yeah, so here's the full story: when I first uploaded the W++
| VSCode extension to the Marketplace, it took off faster than I
| expected -- over 33,000 downloads in under 2 hours. A few days
| later, it was suddenly removed.
|
| 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.
| hoistbypetard wrote:
| I hope it catches the attention of someone who might be able
| to find out.
| jarrell_mark wrote:
| Semi colon is a non starter for me personally.
|
| All the best and I'm sure many others will find this useful.
| sinisterMage wrote:
| Totally fair! I know semicolons aren't for everyone -- W++
| leans into a mix of familiar C-style syntax with some Python-
| style simplicity, but it's definitely not a perfect fit for all
| tastes.
|
| Appreciate the kind words regardless -- and who knows, maybe
| I'll experiment with optional semicolons in a future version.
| eddythompson80 wrote:
| For me, having semi colon be a non-configurable default is a
| non starter. Languages like Go or C take it too far. I prefer a
| typescript like language where semi colons are configurable
| through a config file or tool.
|
| 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.
| e-master wrote:
| A bit of off topic, but recently I started learning F# because my
| new team at work uses it heavily, and even though I love writing
| in C# and even though the latest C# features are really nice
| (especially love patter matching), I wish now C# didn't have the
| curly braces and semicolons at all, and used instead indentation
| based grouping like F# and Python does. That is practically all I
| wish I had in C#... and discriminated unions, but let's be
| honest, what are the chances of that happening? ;)
___________________________________________________________________
(page generated 2025-05-30 23:00 UTC)