Show HN: Winglang – A new cloud-oriented programming language
github.comWinglang looks really cool. I'm really curious how Winglang will evolve their language syntax and semantics to make cloud development more expressive (I assumed `bring` and `inflight` keywords are just the beginning?).
At Shuttle[0] we've built something similar but instead of building a language from scratch we've built on Rust using metaprogramming and the type system to achieve the same effect. For now we haven't hit any limitations that would warrant a new compiler as metaprogramming allows us to express cloud development quite naturally inside the language.
It's a coincidence I just went through the getting started guide yesterday. It would be nice to have a two-way sync between the simulator diagram and the generated code. I'm also curious how Winglang handles existing infrastructure and what it looks like to introduce Winglang to a project that already uses CF or TF.
I've used CF, and TF and was an early adopter of CDK. I'm curious how this compares with Pulumi (never tried it). I liked the idea behind CDK but was shy about going all in because it was AWS-specific. Looks like this is the natural progression.
[I'm on the Wing team]
Nice coincidence :)
There is no plan currently to add a two-way sync between the simulator diagram and the code, and there could be technical difficulties to do it since the code is not generated but written by developers (only the JS + TF compilation artifacts are generated). But you are welcome to open an issue about it and it and it will be prioritized if it gets enough votes.
Since Winglang generates CF/TF for the parts of the app that are defined in the language, it should be possible to add these parts to the ones that already exist in the app, but it depends on the app's architecture. One can also convert the existing codebase, or at least the infra part to Wing pretty easily in some cases. If you have a particular use case in mind we'd be happy to talk and see how we can help.
Yes, this is a cloud agnostic language, which is one of the differentiating factors from Pulumi where the code you write is cloud specific. Also, unlike Pulumi, Winglang is not an infrastructure language but can be used for both the infra and application code. Its compiler takes care of the cloud mechanics (IAM policies, networking) that IaC tools like Pulumi and the CDK require you to configure manually. More info here:
Thanks for the reply.
My question about how to integrate with existing code is more of a curiosity rather than a specific use case. It seems like adoption will be an uphill battle because you're asking devs to learn a new language AND port all existing infrastructure code to Wing.
One other thought: It would be cool to see Wing shine by demoing a full-blown distributed system. Perhaps with a couple of microservices and some supporting infrastructure.
You can use CDK with other providers using https://github.com/hashicorp/terraform-cdk
In my experience, CDK is far better than Pulumi, especially if you're mostly going to be using AWS.
forgive my ignorance, what is CF?
Cloud Formation (https://aws.amazon.com/cloudformation/)
I guess AWS CloudFormation
Sorry, yes. CF=CloudFormation, TF=Terraform
Why a whole language rather than a library that could just as well abstract the cloudy infrastructure and expose its data structures as "first class citizens" ?
The short answer is that there are things we cannot do with existing languages, such as our inflights and their connection to preflights. The full version is here: https://www.winglang.io/docs/faq/why-a-language
> Why a whole language rather than a library that could just as well abstract the cloudy infrastructure and expose its data structures as "first class citizens" ?
"Very cool, but what here cannot be done by a library or compiler extension?
In existing languages, where there is no way to distinguish between multiple execution phases, it is impossible to naturally represent this idea that an object has methods that can only be executed from within a specific execution phase (or within certain scopes of the program). You are welcome to read more about it here (including code samples that show the same app built in Wing vs. other solutions)."
https://github.com/winglang/wing#very-cool-but-what-here-can...
I'm not convinced one "cannot" do it with an existing programming language, as the link states.
I agree that the ergonomics of a languaged planned for that is better. But the argument that it's *only* possible with a purposeful language doesn't hold, in my opinion.
Afaik, the AWS CDK allows to express both preflight and inflight in JS, Python, and others, and it works well. Again, the CDK gives an arguably worse experience, but not "impossible"...
Pulumi has the Automation API [1] which is a step in that direction.
[1] https://www.pulumi.com/docs/using-pulumi/automation-api/
I've been following the Unison lang [1] for quite some. Wing seem to set similar goals? From the first glance Wing looks more polished, but there's "The Big Idea" behind Unison - is there something similar?
Unison is a pure functional language. That's important because it allows the whole "big idea" to work: you can change code, commit it to your Unison database and synchronize with your cloud without it ever breaking due to things like "different versions of a type" for example.
This language OTOH looks like TypeScript with seamless access to cloud resources, which while neat, is not comparable to what Unison brings to the table (it may, however, be what people actually want... time will tell).
Given that it's built as a whole language, I'm curious about the choice to make no obvious distinction between 'preflight' and 'inflight' functions.
It's not obvious at a glance that you can only call inflight functions in an inflight scope, because the syntax for calling them is identical to calling a preflight function on the same object.
Do you just compile it and see where it fails?
(engineer on the Winglang team here)
Your observation is partially correct. The language does make a distinction when you're defining new functions: you must use the "inflight" keyword annotation to define an inflight function, and most un-annotated functions are assumed to be "preflight". (The top-level scope of every Wing program has a preflight phase).
But at _call sites_ no distinction is made. We don't have have a different calling convention between calling preflight/inflight functions because the compiler uses type checking to enforce that inflight functions can only be called in inflight scopes, and preflight functions can only be called in preflight scopes. Scopes are lexical, meaning you can automatically assume when you see `inflight () => { ... }` or `inflight foo() { ... }` that all code inside that block is executed inflight, i.e. at runtime.
The neat thing here is if you're writing code to access a method on a class (typing `obj.`), your IDE's auto-completion will only show you the methods available to you based on the scope you're in. There's a short 10 second clip showing this here: https://twitter.com/rybickic/status/1720168675641102803
We've prioritized LSP support while designing the compiler to help out with this.
> In existing languages, where there is no way to distinguish between multiple execution phases, it is impossible to naturally represent this idea that an object has methods that can only be executed from within a specific execution phase.
I'm sure I'm getting the wrong end of the stick but isn't this possible to ensure using typing? Very simple dependent typing/phantom types/bog standard normal types?
The current type system is designed around the experience of writing code like the example below where objects can have two kinds of methods:
Importantly, if you try calling bucket.put() outside of one of these "inflight" scopes or try calling api.get() inside one of these "inflight" scopes, you'll get compilation errors - not runtime errors.let bucket = new cloud.Bucket(); let api = new cloud.Api(); // api.get is a preflight method - it generates cloud infrastructure api.post("/hello", inflight (req) => { // bucket.put is an inflight method - it performs data plane operations, at "runtime" bucket.put("data.txt", req.body ?? "empty"); });Could this style of API be achieved in an existing language? I think it's an open ended question - I'm not sure. But I reckon it gets into complex framework territory (or may require injecting modifications into existing compilers, which presents other challenges). But I'd love to see more exploration into this direction.
Okay, I partly take back what I said in my sibling post. Your "(req) => {..}" lambda has to be constrained only to contain inflight methods.
Yes, it can be done by either building the contents of the lambda in some truly horrid way (you'd effectively be building an AST at runtime). The alternative is to get hold of the AST/parse tree at runtime (which I believe.NET can do if you ask it nicely, but that is very specifically .NET) which you can then analyse.
The first way is utterly vile though workable and language agnostic, the second way is definitely tied to one platform. If there's third way I can't think of it ATM.
What I was getting at is that it seems to depend on the compiler to know the difference between preflight and inflight because the calling convention is identical.
I personally don't think it's intuitive that function calls using the same syntax either emit terraform code or JS. It's like mixing compile time macros and code into one.
With respect, and also with the understanding that I do not comprehend your domain very well so I may be talking out of my but with static typing I think it is possible, perhaps if a bit less pretty.
I can try and put something together in C# but not right now I'm afraid (it would be a good exercise for me as I've only read up on these, not actually use them personally, although I plan to start very soon for my own personal work). There was some examples going round here https://old.reddit.com/r/programming/comments/zm7f9/phantom_... which may help.
Again, I may be misunderstanding your domain completely, so bear it in mind please.
> infrastructure and runtime code in one language
This is fertile ground for new languages, apparently they call this the "Construct Programming Model" but there appears to be no meat to the theory. If programming language theory was leveraged properly I think they'd really be on to something. See the success of Rust for example.
I just did some cursory research and came across a paper on "ABS: A high-level modeling language for cloud-aware programming" which would give a much stronger foundation for such an effort than JavaScript.
Hey, I'm part of the Wing team, funny you mention the construct programming model as it comes from the CDK, which is Elad's (Wing's creator) previous project. Wing is also built around this concept.
I will read the article you mentioned, sounds interesting
Been hacking together a new entrant in this space as well, looking forward to competing :)
:)
I think it's an interesting idea, but I feel like creating a whole new language has too much overhead for adoption. You would need to create a language server and extensions for every editor you want to support.
A language-specific DSL (Pulumi, CDK, etc) just works in any editor that already supports your language.
This is a similar reason to why I dislike most docblock-based infra tools as well. If wing is confident in their ability to maintain editor tooling, more power to them, but it isn't maintenance I would want to manage.
[I'm on the Wing team] I get what you mean about adoption and maintenance overheads.
On the adoption front, we are aware it takes time for languages to get adopted. We also plan to release the Wing SDK to other languages soon, but the best DX is still provided by using Winglang itself simply because we are not constrained by what other languages support.
The language server is actually the same one for different editors, but we do need to create and maintain different editor extensions. The best supported one at the moment is VSC.
> We also plan to release the Wing SDK to other languages soon
Awesome! I agree that your intended experience is likely to be more curated, but supporting other languages might really help. This is really cool to hear.
Also, I realize I might have phrased it poorly, but I meant exactly that about the language server. Language server once, but each editor needs its own extension. Even the extension wrappers around the language server could quickly eat up a lot of maintenance time because there is no true standard. Open VSX is pretty nice for cross editor extensions, but not too many editors use it, yet.
Yea, no good way around IDE extensions. Hopefully if Wing gets popular enough the community will create extensions where there is demand for them.
Also, thanks for taking the time to give us feedback
I looked through the docs and I don't see any async methods, is that built into inflight like this code snippet I found?
queue.setConsumer(inflight (body: str): str => { let next = counter.inc(); let key = "myfile-{next}.txt"; bucket.put(key, body); });
Yap, all inflight code is async by default.
Ok, thanks for clarifying. That is pretty slick
>In existing languages, where there is no way to distinguish between multiple execution phases, it is impossible to naturally represent this idea that an object has methods that can only be executed from within a specific execution phase
My category theory is pretty rudimentary, but isn’t this a good use case for a monad?
Look interesting but my first thought is I don't see any error case code.
Given this language is really about abstracting network calls to external services as objects/methods wouldn't it make sense to have return values be maybes and then be able to pattern match on that given that these are not local calls and networks/services do fail?
My guess is an actor pattern where you are sending messages to these services and waiting for responses instead of faking a local call would surface the error conditions in a much cleaner way, ala Erlang or Elixir.
This may be helpful: https://www.joelonsoftware.com/2002/11/11/the-law-of-leaky-a...
This seems to be in roughly the same space as the radius project[1] out of Microsoft. They are a data structure rather than a language, but the idea of merging the application and infrastructure seems similar. Is there a place for one application/infrastructure model that includes integration details in the manner of Apache Camel[2] that we can all get behind? [1] https://radapp.io [2] https://camel.apache.org
I need an elevator pitch on this (which is currently in my "yet another terraformy thing" mental bucket right now, rightly or wrongly!).
I am interested, but when I look at the comparison with Pulumi - https://www.winglang.io/docs/faq/why-a-language, they have 4 lines of code in Wing, but the long Pulumi example sets up permissions. So how did the permissions get set up in Wing? The great thing about Pulumi is if you are trying to comply with company security policies which in turn are for SOC2 etc. then this explicit setup as code is great. I think Pulumi also has a policy system but I haven't explored it yet.
So what I am saying is more code != bad (think of the raison d'etre of the Go programming langauge) but I am not saying Wing is bad ... I am saying I would like to know more.
I find it hard to believe that there is a semantic deficiency in JS/Go/C# etc. that means you need a new languages. And if you use Typescript, OCaml or Haskell (most likely Typescript for popularity) you can probably make the Type system do as much static heavy lifting as possible. Of course some checks need the current state so need runtime. But happy to be persuaded we need a new language.
[I'm on the Wing team] The elevator pitch is that there are things we cannot do with existing languages, such as our inflights and their connection to preflights. This is because that if we used an existing language we'd have to support its legacy code and could not impose new limitations that are needed to execute the inflight system well. It doesn't mean that you cannot come close with existing languages, and there are nice projects that do that, it just means that you cannot go all the way.
The full version is here: https://www.winglang.io/docs/faq/why-a-language
> […] they have 4 lines of code in Wing, but the long Pulumi example sets up permissions. So how did the permissions get set up in Wing?
As it says on the page: "Wing allows developers to write very few lines of code and let the compiler take care of IAM policies and other cloud mechanics."
Basically it auto-generates least-privilege IAM policies.
> Basically it auto-generates least-privilege IAM policies.
Nice!
Show me a complex use case.
Show me making it more complex and what that costs.
Show me the performance benchmarks.
Syntax is cool but the older I get the more I care about productivity and speed.
[I'm on the Wing team] Wing is still in early days so we can't show very complex use cases yet, but as time passes developer use to build more and more complex things with it.
Our aim is to improve productivity and speed by enabling developers to develop against a local simulator and visualization console, giving them instant feedback and much shorter iteration cycles. By allowing them to work at a higher abstraction level we aim to reduce complexity, which should also lead to greater productivity.
I hope that in the future, as more developers use Wing, we can show case studies and benchmarks that prove our hypothesis are correct.
> dev against a local simulator
But can’t you already do this today with GCP and AWS and more generally a wealth of Docker images and Kub/Knative?
Furthermore, I wonder how you guys plan to encourage users to jump ship from (node/go/Java/.NET) to winglang, all of which have a rich package ecosystem?
> can’t you already do this today with GCP and AWS and more generally a wealth of Docker images and Kub/Knative?
not really.. as soon as you need cloud resources that are not in your k8s cluster, you end up with the cloud in your development loop.
> what about the package ecosystem?
wing has interoperability with the npm ecosystem, so basically any node package can be used quite easily from winglang code.
on the infra side, there’s interoperability with the CDK for terraform ecosystem.
> not really.. as soon as you need cloud resources that are not in your k8s cluster, you end up with the cloud in your development loop.
https://github.com/localstack/awscli-local
https://github.com/fsouza/fake-gcs-server
https://cloud.google.com/sdk/docs/downloads-docker
I’ve used all of these locally to great success.
Glad to hear you guys want to interop with npm.
Related:
Wing Cloud Raises a $20M Seed to Build a Programming Language for the Cloud - https://news.ycombinator.com/item?id=36864816 - July 2023 (6 comments)
Wing: A cloud-oriented programming language – request alpha access - https://news.ycombinator.com/item?id=34051325 - Dec 2022 (148 comments)
Wing programming language: A cloud-oriented programming language - https://news.ycombinator.com/item?id=33762969 - Nov 2022 (1 comment)
Can you explain the idea behind a cloud-oriented programming language? How does it works?
I'm not affiliated, but I'd guess that things like "object storage" are a first class citizen, similar to a "string" or "float" in other languages.
Hey, I'm on the Wing team, yes you are correct, cloud services, like object storage, are indeed first class citizens and you can use them as naturally in Wing as you would use basic data structures or OS services in traditional languages. The idea behind Wing is that the cloud is the computer that it targets. By having a compiler that sees the entire application, including infra and runtime code, we are able to delegate cloud mechanics (IAM policies, network topologies, etc.) to it instead of leaving these details for developers to take care of and reduce their velocity.
I could see this useful for prototyping, but I worry about losing finer control. for instance when I make a lambda, I like to have the lambda execute a container rather than write the function in place
(engineer on the Winglang team here)
Hi there! Being able to break through the abstraction to apply these non-functional requirements is a MUST in our opinion.
That is why we introduced Wing Custom Platforms that allow you to customize how resources are provisioned (as well as some other things). Giving you as much or as little control as you need.
More on platforms here: https://www.winglang.io/docs/concepts/platforms
> In existing languages, where there is no way to distinguish between multiple execution phases, it is impossible to naturally represent this idea that an object has methods that can only be executed from within a specific execution phase (or within certain scopes of the program).
What about algebraic effect based languages like koka? Would it make sense to make "inflight" methods and effect and have appropriate effect handlers in scopes like queues or functions?
Is the goal to let this work with something like sveltekit? Like how do I use this with a full flown web app?
Very cool! What's the difference between WinLang and Serverless?
The way I read it is that Winglang combines your IaC and your runtime logic/code. In theory it's pretty neat, I haven't given it a serious try though. I'm not totally convinced that I want my infrastructure definition intermingled with my business logic though.
Hey, I'm part of the Wing team, I see where you're coming from regarding intermingling business logic with infra definitions. If it makes sense, these infra definitions are the functional part of the infrastructure (declaring that you want a bucket and pre-populating it with objects during deployment for instance). The non-functional parts (encryption, redundancy, others) can be taken care of separately on the platform side
Hey, I'm part of the Wing team, Winglang is a general purpose programming language, not a framework, so there are less limitations on how far it can take the development experience. It let's developers work at a higher level of abstraction, is fully extensible and is cloud and provisioning engine agnostic. It comes with a local cloud simulator, allowing you to get instant feedback and enjoy very short iteration cycles. It also comes with a visualisation console to interact with the local app and debug and test it.
One is a programming language, the other is the accepted name for the concept of "pay as you go" PaaS services.
This is pretty cool! I've had my eye on Wing for a while, as a avid fan of Pulumi. I was fortunate enough to have the freedom to use Pulumi in a past role, and it revolutionized the way I thought about infrastructure.
My current org has been slow to adopt IaC, and Bicep has been all for which I've managed to drum up appetite. I was surprised somewhat to enjoy the simplicity, but eventually I think we'll outgrow it. My hope is by the time we're ready to graduate, things like Wing, or radius will be more mature and easier to weave in.
On a side note, it feels disingenuous or at least inaccurate for a project to brand itself "new". I feel like I've seen this posted to hn a few times, how long will it be "new"? There's at least one 8-month old post.
The word "new" scares away certain types, who happen to be in leadership or decision-making roles.
[I'm on the Wing team] Thanks for the feedback. We call it new because it is only a year old, and for programming languages its pretty young. It is just now getting mature enough to be able to build real world applications with. Hope it makes sense
I understand your point, and I sincerely wasn't sniping. Since you took the time to reply, I'll share a little of my reasoning in case you might find it valuable.
I think using a subjective term is meaningless, at least in the context of an introduction. "New" is far too relative, and means something entirely different for one person to the next.
I personally think it makes more sense to provide an objective fact, such as "started in 2022" and let readers determine whether that qualifies as "new" or not.
I wouldn't have mentioned it, and may not have even noticed if it weren't literally the first piece of information presented to me in the repo.
In any case best of luck with the project. It looks very promising and I am excited to see where it goes!
Thanks, and I agree with your reasoning, makes sense to provide objective data
Which clouds are supported by winglang?
[I'm on the Wing team] We currently support AWS, Azure and GCP with varying degrees of maturity. Since it's an open platform one can add any other cloud. More info here: https://www.winglang.io/docs/faq/supported-clouds-services-a...
Does it work on/against GCP?
[I'm on the Wing team] Yes, but it's still in early days, you can see our support matrix here: https://www.winglang.io/docs/standard-library/compatibility-...
oh boy -- lot's of work ahead for you folks, best of luck! I'll be watching this project. We do a ton with GCP so when this matures we'll be looking at it more.
How do you compete with -- if at all -- with Ballerina lang? https://ballerina.io/
Yes lots and lots of work, but we enjoy doing it :)
About ballerina, there are similarities to wing, but at a high level it is focused on simplifying networking whereas Winglang is about simplifying the use of cloud services.