Gnu Cobol is an interesting project, they support a lot of dialects. One big draw back is the generated code isn’t thread safe so cgi is about the only option for server side apps. Maybe someone more familiar with the project could comment on that?
It's kind of funny that you mention "only cgi" as a drawback on an article discussing "edge workers" - not sure if they're like "serverless functions" (new vm pr request) - but I'm assuming they're heavier than "just" new process pr request :)
Cloudflare Workers is really a Chromium "browser service worker" that runs on their servers. Since Chromium makes each browser tab isolated as possible, each instance does indeed act as a mini-VM, & AFAIK usually is created/destroyed per HTTP request.
Most deployed code uses JavaScript/TypeScript, but also can run WebAssembly, which is how they got COBOL to run there. I've also seen RUST, GoLang, & other sources run on Cloudflare Workers.
Thank you (and sibling comments)! Cunningham's Law still works wonders, it seems ;) (and no, I wasn't aware there were such a light weight primitive beneath cf workers - so I didn't make a "false"(ish) claim on purposeose ).
Ed: although for rust, and maybe go - i suppose the wasm vm does add quite a bit of overhead? Compared to just compiling to machine code.
Are there any open source application servers built around the same architecture? I gather the cf worker implementation itself isn't released as open source?
There's no separate VM; since we're using V8, it does everything. Some folks have made standalone webassembly VMs, but web browsers run wasm in the context of their existing JS vm, and we're following browser tech, even though it's "server side" in a sense :)
wasm is a bit slower than native, but it all depends. All of this is being actively worked on by folks, and so numbers change.
> Are there any open source application servers built around the same architecture? I gather the cf worker implementation itself isn't released as open source?
There's nothing exactly like workers that's open source, and yes, our implementation isn't open source either, though I would love for that to be the case. There is some stuff that's sort of similar in some senses that is open source; a lot of folks are playing around with server-side wasm. But they have different properties than Workers does. So maybe that's a comparison in one sense, but it's very much not in another sense.
So depending on if you mean green-thread/sandbox or smart edge side includes - or application server... There may or may not be some thing out there already..?
Although they do re-use the "process" between requests to further reduce the cold start time, and global variables do persist between requests (although not reliably).
I don’t recognise the name DONKEY.BAS, but I spent plenty of time in my youth with GORILLAS.BAS and have heard it mentioned from time to time since then.
This was a higher-effort post than I had expected.
The Game of Life implementation pushes itself into my Back-button browser history, which is rather annoying, but it was very cool to see some COBOL besides the obligatory Hello World.
I hardly think anyone maintaining crusty old systems will be allowed to move to Cloudflare Workers, but it is rather amazing and funny to see that it could technically now be done.
I think you’d be surprised how eager the owners of crusty mainframe systems are to stop managing ancient infra and how heavily they have been sold on serverless / “the cloud”.
I think it's important to note that this isn't an option to "get off the mainframe". Gnu Cobol doesn't support CICS, nor some other things the mainframe provides. There are "rehosting" options, both free and for pay, this isn't one.
To clarify some more, rehosting options range from "pick up and drop source files and data to the new system" to "we can do it but it's almost as much effort as rewriting the whole thing".
I've never really heard this from anyone that is actually technical. I think people with actual technical skills and joy would be quite impressed by mainframe systems.
The issue for management is you can't copy someone else's strategy like hiring random fungible devs so easily, you need to invest in some training and retaining. So if you're a stuffed shirt the easiest thing to do to explain your lack of leadership and foresight is to point to the mysterious system and point to other companies doing (x, y or z) and say you need to be more like them in a copycat way with little consideration for the difficulty or success of the existing business and systems. The evergreening that goes on in tech is extremely low dividend activity for any business but the new employees and new vendors make a lot of money until they too are out fashioned.
My impression is that the nature of mainframe systems and the applications that run on them is that they're essentially fully custom operations that could serve as full-stack object lessons in Conway's Law.
Really? My impression is that you have to scour the earth for people who know anything about those systems, and then pay them 5x what you would pay someone working on a modern system.
Did you like.. actually read my comment? Poorly run companies want the equivalent of a Scala dev with 30 years of Scala experience. It doesn't work like that. Computer systems and PLs aren't that hard to pick up.
Expecting a short announcement about adding COBOL support, I was instead treated to an educational journey about the language, amusing history and examples, technical decisions on implementation, and a practical tutorial on getting started.
This is not a joke at all. We are serious about WebAssembly in our serverless platform and showing that it can support languages like COBOL is important.
The hardest part about WebAssembly that I found is that very few projects document their ABIs. For example, I want to write a Rust WebAssembly program to do whatever with CloudFlare workers (literally anything, just to try it).
Is there a page listing all the functions I can import and call? IIRC I had only managed to find some "hello world" examples, ran them, they did indeed say hello world, and then I thought "well okay, now I know how to return stuff and nothing else" and gave up because I couldn't find documentation on other calls.
So, to take a few steps back, maybe you know some of this:
First off, you write some wasm. You export some functions from the wasm. How you do this is up to your Rust code. wasm-bindgen would be the low-level details here.
Then, in your worker, you import the wasm. This shouldn't change from the templates, really. What signatures the imported functions have depends on how you exported them.
There's no inherent restrictions about what you can call, it's about knowing what you've exported and then calling them with the appropriate stuff.
Ahh, yes, that helps a lot, thanks Steve! I missed the fact that the wrapper is what the backend communicates with, and then the wrapper calls wasm. I thought the backend would call wasm directly (and that I could just not have a JS wrapper at all).
It would be extremely helpful if this was mentioned somewhere on the starting docs (maybe it is and I missed it?).
Great question. Because I was thinking that I could use workers with just rust, I Googled for "CloudFlare workers rust" and ignored anything that had JS in it. I can tell you where I probably was when I get to my computer if you want, it was probably the CloudFlare articles about Rust and workers.
EDIT: Oops, looks like I replied to my own comment before, HN mobile app fail. Luckily, you saw the reply.
No problem! I looked again, and I think I looked around at the blog articles, wrangler and messed a bit with the examples, then didn't make much sense of it and gave up.
I would have had much better luck if I had seen what you told me, ie "you can call wasm from JS" rather than thinking I could somehow execute wasm directly on the worker. Thanks again!
Other languages may work, and we we won't stop you from using them, but you may run into problems. The main issue with getting most languages to work is that we support JavaScript and WebAssembly, which means any other language needs support for compiling to wasm before it's even possible. Once it is, we have a one megabyte limit for the size of a worker, and so many other languages won't work because their minimal wasm output is too large.
We'd like to support more in the future. It takes a lot of work.
Thanks. Official languages aside, are there plans to support protocols other than HTTP? Say, WebRTC? Or, even raw TCP/UDP sockets. From what I know, Spectrum lets one deal with L4 and MagicTransit with L3 (provided BYOAnycastIP), but will there be a way for Workers to be an origin to those?
There's a related thread about the "discovery" of the source of the Terminator COBOL from a few days ago--and the original author is still alive and well and programming mostly in CUDA/C++, Erlang and Elm according to his Twitter.
A very practical question: I am language agnostic. Lots of people have commented about COBOL and FORTRAN performance for purely mathematical problems, given the amount of man-hours that went into the libs used by these languages when computing resources were scarce.
That caught my eye. Because for what I do, every little bit of performance matters. There are no hiring constraints - I will get whoever and whatever I need, as long as it can be shown to increase performance - mostly latency, but also speed of computation on given hardware.
Can I expect practical gains in a COBOL implementation of mathematical algorithms? (mostly matrix inversion and multiplications, but not just that)
I've done some programming in Fortran in school doing computational physics. From what I can tell it isn't necessarily that the languages are super fast, compared to any other compiled language. You can get similar speed out of Fortran as C or C++ by doing the normal performance conscious practices of not allocating a lot of memory during calculations, optimizing loops, etc. Fortran has a lot of scientific packages that have been optimized very heavily, and those are linkable from other language, that is whay Scipy in Python is essentially. The Cobol I have touched isn't really that optimized I think, mostly just business code. But its fast due to no abstractions and being compiled.
I don't think you would get gains from Cobol per se, and it might not be worth it compared to just writing C or C++ in a high performance manner.
Fortran as a language had some advantages over C for high-performance numeric code (eg more restrictive aliasing rules or stack-allocated variable-length arrays). C99 addressed this.
C99 kind of addressed it, unless one manually takes the effort to properly place restrict in the correct places, and not mistakenly misuse it (possibly triggering UB), it won't match what optimizing Fortran compilers are capable of without any additional effort from the programmer.
But note that that as far as I'm aware, Fortran compilers will happily miscompile code that breaks the aliasing assumptions as well. No matter which language you use, it's the responsibility of the programmer to not break these invariants, the main difference being that Fortran doesn't force you to type out `restrict` first.
It's forbidden by the language standard, hence compilers assume no aliasing occurs, but it nevertheless may do so due to 'non-conforming' code.
In the words of the g77 manual:
> Essentially, compilers are promised (by the standard and, therefore, by programmers who write code they claim to be standard-conforming) that if they cannot detect aliasing via static analysis of a single program unit's EQUIVALENCE and COMMON statements, no such aliasing exists. In such cases, compilers are free to assume that an assignment to one variable will not change the value of another variable, allowing it to avoid generating code to re-read the value of the other variable, to re-schedule reads and writes, and so on, to produce a faster executable.
> [...]
> Unfortunately, there is no way to find all possible cases of violations of the prohibitions against aliasing in Fortran code. Static analysis is certainly imperfect, as is run-time analysis, since neither can catch all violations. (Static analysis can catch all likely violations, and some that might never actually happen, while run-time analysis can catch only those violations that actually happen during a particular run. Neither approach can cope with programs mixing Fortran code with routines written in other languages, however.)
Like in C, it will result in undefined behaviour (though the Fortran spec doesn't use the term).
Not really, because the standard is what defines the language, just because GNU Fortran does non conforming stuff it doesn't mean that for example PGI Fortran would do the same non conforming behavior.
By the same measure I can assert that C++ is a memory safe language given that Visual C++ enables bounds checking and iterator invalidation in the standard library by default.
The C language standard makes certain guarantees, such as no out-of-bounds array access, or no modification of memory accessed through a restrict-qualified expression by other means.
If such things happen during program execution, the program does not conform to the standard, and its runtime behaviour becomes undefined.
This is exactly the same situation you have with Fortran, which makes certain guarantees about, say, the aliasing of function arguments. If all such cases could be detected ahead of time, it would be impossible for programmers to write non-conforming programs. This is not possible.
I repeat, there is no essential difference between the Fortran and C situation. The best one could argue is that given that the Fortran guarantees are universal (instead of limited to restrict-qualified pointers), a Fortran programmer is less likely to write an incorrect program, but that's it.
I think the one (and only?) neat trick that COBOL has is supporting decimal datatypes as first-class citizens, which makes it very convenient for monetary stuff and other business related things where you don't want to have 0.1+0.2=0.30000000000000004
Of course (IBM) mainframes and CICS have some other tricks in their sleeves, but those are bit higher level things and probably not relevant for number crunching as such.
On commodity hardware I wouldn't expect COBOL code to perform particularly well compared to e.g. C (or indeed, FORTRAN).
At first, I thought this was a 1st April joke.
It's impressive what can be done inside the CF workers using the WebAssembly feature of V8. Now I can learn a 60 years old lang to run on the closest CF datacenter :3
88 comments
[ 2.3 ms ] story [ 160 ms ] threadfuture is now
skynet is near
Most deployed code uses JavaScript/TypeScript, but also can run WebAssembly, which is how they got COBOL to run there. I've also seen RUST, GoLang, & other sources run on Cloudflare Workers.
Shameless self-plug here: https://github.com/tomByrer/awesome-cloudflare-workers
Ed: although for rust, and maybe go - i suppose the wasm vm does add quite a bit of overhead? Compared to just compiling to machine code.
Are there any open source application servers built around the same architecture? I gather the cf worker implementation itself isn't released as open source?
wasm is a bit slower than native, but it all depends. All of this is being actively worked on by folks, and so numbers change.
> Are there any open source application servers built around the same architecture? I gather the cf worker implementation itself isn't released as open source?
There's nothing exactly like workers that's open source, and yes, our implementation isn't open source either, though I would love for that to be the case. There is some stuff that's sort of similar in some senses that is open source; a lot of folks are playing around with server-side wasm. But they have different properties than Workers does. So maybe that's a comparison in one sense, but it's very much not in another sense.
Lua and varnish https://github.com/flygoast/libvmod-lua/
Lua in nginx https://openresty.org/
And lua in haproxy - for example to verify jwt tokens: https://github.com/haproxytech/haproxy-lua-jwt
So depending on if you mean green-thread/sandbox or smart edge side includes - or application server... There may or may not be some thing out there already..?
Although they do re-use the "process" between requests to further reduce the cold start time, and global variables do persist between requests (although not reliably).
https://en.wikipedia.org/wiki/DONKEY.BAS
The Game of Life implementation pushes itself into my Back-button browser history, which is rather annoying, but it was very cool to see some COBOL besides the obligatory Hello World.
I hardly think anyone maintaining crusty old systems will be allowed to move to Cloudflare Workers, but it is rather amazing and funny to see that it could technically now be done.
Great job and great post!
To clarify some more, rehosting options range from "pick up and drop source files and data to the new system" to "we can do it but it's almost as much effort as rewriting the whole thing".
If you need the IBM Z level cryptography, security and reliability it's trying to replicate same with other hardware is very costly.
The issue for management is you can't copy someone else's strategy like hiring random fungible devs so easily, you need to invest in some training and retaining. So if you're a stuffed shirt the easiest thing to do to explain your lack of leadership and foresight is to point to the mysterious system and point to other companies doing (x, y or z) and say you need to be more like them in a copycat way with little consideration for the difficulty or success of the existing business and systems. The evergreening that goes on in tech is extremely low dividend activity for any business but the new employees and new vendors make a lot of money until they too are out fashioned.
Expecting a short announcement about adding COBOL support, I was instead treated to an educational journey about the language, amusing history and examples, technical decisions on implementation, and a practical tutorial on getting started.
Bravo!
I wonder how many other projects like this were cancelled or delayed.
Is there a page listing all the functions I can import and call? IIRC I had only managed to find some "hello world" examples, ran them, they did indeed say hello world, and then I thought "well okay, now I know how to return stuff and nothing else" and gave up because I couldn't find documentation on other calls.
First off, you write some wasm. You export some functions from the wasm. How you do this is up to your Rust code. wasm-bindgen would be the low-level details here.
Then, in your worker, you import the wasm. This shouldn't change from the templates, really. What signatures the imported functions have depends on how you exported them.
There's no inherent restrictions about what you can call, it's about knowing what you've exported and then calling them with the appropriate stuff.
So for example, https://github.com/jRiest/the-best-goats is a little Rust wasm app. This app was built before wrangler existed, so it's got some strangeness, but it does work. https://github.com/jRiest/the-best-goats/blob/master/src/lib... is the main. I am not entirely sure how jake did this, but it looks like he compiled it to wasm, and then added https://github.com/jRiest/the-best-goats/blob/master/index.j... at the bottom. Wrangler would make this a bit easier, of course. Regardless, you can see how these lines, which are the standard Worker entry point, calls into the main defined in wasm.
Does that help at all? It is certainly true that this is not as well documented as it could be. Lots of work still to do.
It would be extremely helpful if this was mentioned somewhere on the starting docs (maybe it is and I missed it?).
Where did you look for this information? I can file a bug, but knowing where to put it would be helpful.
EDIT: Oops, looks like I replied to my own comment before, HN mobile app fail. Luckily, you saw the reply.
I would have had much better luck if I had seen what you told me, ie "you can call wasm from JS" rather than thinking I could somehow execute wasm directly on the worker. Thanks again!
It was the only one I could follow and get up and running really quickly. And my go-to when I setup a new instance if I need to.
Edit: Done.
So... no PHP then? Seems like it would be a good fit, no?
PHP ships with literally hundreds of built-in functions, which I imagine makes it harder to optimize for the size constraints of Cloudflare Workers.
* JavaScript (and TypeScript)
* C and C++
* Rust
Other languages may work, and we we won't stop you from using them, but you may run into problems. The main issue with getting most languages to work is that we support JavaScript and WebAssembly, which means any other language needs support for compiling to wasm before it's even possible. Once it is, we have a one megabyte limit for the size of a worker, and so many other languages won't work because their minimal wasm output is too large.
We'd like to support more in the future. It takes a lot of work.
https://news.ycombinator.com/item?id=22857531
That caught my eye. Because for what I do, every little bit of performance matters. There are no hiring constraints - I will get whoever and whatever I need, as long as it can be shown to increase performance - mostly latency, but also speed of computation on given hardware.
Can I expect practical gains in a COBOL implementation of mathematical algorithms? (mostly matrix inversion and multiplications, but not just that)
I don't think you would get gains from Cobol per se, and it might not be worth it compared to just writing C or C++ in a high performance manner.
In the words of the g77 manual:
> Essentially, compilers are promised (by the standard and, therefore, by programmers who write code they claim to be standard-conforming) that if they cannot detect aliasing via static analysis of a single program unit's EQUIVALENCE and COMMON statements, no such aliasing exists. In such cases, compilers are free to assume that an assignment to one variable will not change the value of another variable, allowing it to avoid generating code to re-read the value of the other variable, to re-schedule reads and writes, and so on, to produce a faster executable.
> [...]
> Unfortunately, there is no way to find all possible cases of violations of the prohibitions against aliasing in Fortran code. Static analysis is certainly imperfect, as is run-time analysis, since neither can catch all violations. (Static analysis can catch all likely violations, and some that might never actually happen, while run-time analysis can catch only those violations that actually happen during a particular run. Neither approach can cope with programs mixing Fortran code with routines written in other languages, however.)
Like in C, it will result in undefined behaviour (though the Fortran spec doesn't use the term).
Nevertheless, that is like describing C semantics with something that is only possible in GNU C.
Naturally if one goes outside what the standard allows, everything goes.
It was the first relevant search result. Feel free to look for more recent resources on the topic, eg https://www.sciencedirect.com/science/article/pii/S157106610... (still a bit dated).
Naturally if one goes outside what the standard allows, everything goes.
Which makes the Fortran situation essentially the same as the C one once you've typed out `restrict`.
By the same measure I can assert that C++ is a memory safe language given that Visual C++ enables bounds checking and iterator invalidation in the standard library by default.
If such things happen during program execution, the program does not conform to the standard, and its runtime behaviour becomes undefined.
This is exactly the same situation you have with Fortran, which makes certain guarantees about, say, the aliasing of function arguments. If all such cases could be detected ahead of time, it would be impossible for programmers to write non-conforming programs. This is not possible.
I repeat, there is no essential difference between the Fortran and C situation. The best one could argue is that given that the Fortran guarantees are universal (instead of limited to restrict-qualified pointers), a Fortran programmer is less likely to write an incorrect program, but that's it.
Of course (IBM) mainframes and CICS have some other tricks in their sleeves, but those are bit higher level things and probably not relevant for number crunching as such.
On commodity hardware I wouldn't expect COBOL code to perform particularly well compared to e.g. C (or indeed, FORTRAN).
Cobol on the JVM:
MicroFocus
https://www.microfocus.com/documentation/visual-cobol/VC40/E...
Fujitsu
https://software.fujitsu.com/jp/manual/manualfiles/m150010/b...
Cobol on the CLR:
MicroFocus
https://www.microfocus.com/documentation/extend-acucobol/101...
Cobol on the CLR and Azure:
GT Software / Fujitsu
https://www.gtsoftware.com/products/netcobol/netcobol-for-ne...