We truly need to work more towards eliminating every memory unsafe language in use today, until then we're fighting a forest fire with a bucket of water.
We truly need to work more towards eliminating every memory unsafe language in use today, until then we're fighting a forest fire with a bucket of water.
There is probably not a check Apple can write to fix this problem with memory safe programming languages. And Apple can write all possible checks. There's something profound about that.
If instead, the talent pool were incentivized to increase their ability to understand abstractions, and we selected for that kind of talent, it might not be so hard to use new languages.
Of course if they dropped all other development and told their employees to rewrite to rust, they may end up with a piece of software written in rust but no customers.
Now: rewrite 20 years worth of code.
Let's make sure we're clear: I agree --- and, further, assert that every other serious person agrees --- that memory safety is where the industry needs to go, urgently.
In that context, even a small architectural difference can be seen as a high barrier.
And a lot of that was design work that still holds, and a lot of that was code that has been obsoleted.
That decreases the amount of code to replace, doesn't it?
For code added in the past, more evolution means that for every X lines of code written, a smaller and smaller fraction of X still exists. Which means less work to replace the end product.
Languages and understanding them is not special, but decades of development of two different kernels is a huge time investment. Even though Linus Torvalds wrote the basic Linux kernel in 5 months, it was very simple at first.
I doubt writing an entire POSIX-compatible replacement for a kernel would be a small or quick endeavor, and Apple has shown resistance to adopting anything with a GPL 3 license iirc. That is why they switched to ZSH from Bash.
Still a gargantuan effort, but for them it doesn't require everyone learn Rust, just to learn Swift, which is kind of table stakes for a lot of user facing dev I'm sure there.
It'll take years to have impact, but so what? They can start now, they have the money.
> nobody disagrees with this (someone will here, but they don't matter)
There are so many people out there who don't understand the basics. HN can be sadly representative.
Rust is cool because it’s got a solid-if-slow build story that doesn’t really buy into the otherwise ubiquitous .so brain damage. Rust is cool because Haskell Lego Edition is better than no Haskell at all, and Rust is cool because now that it’s proven affine/linear typing can work, someone will probably get it right soon.
But if I can buy shares in: “shit still gets rocked constantly”, I’d like to know where.
Gatekeeping much?
I think I’ve paid my cover-fee on an opinion.
Or were you just dissing knowing things?
Rust won't solve logic bugs but it can help bring up the foundations. So long as memory safety bugs are so pervasive we can't even properly reason on a theoretical level about logic bugs. The core theorem of any type system is "type safety" which states that a well-typed program never goes wrong (gets stuck, aka UB). Only then can you properly tackle correctness issues.
> Rust is cool because Haskell Lego Edition is better than no Haskell at all, and Rust is cool because now that it’s proven affine/linear typing can work, someone will probably get it right soon.
I don't understand the condescending remarks about "Haskell Lego Edition". I do agree that Rust has shown that substructural type systems work and are useful, and that they will be a 'theme' in the next batch of languages (or I can hope).
I could just as easily throw around words like “anti-intellectual” if my goal was to distract from the point rather substantially replying.
But the attitude is an invitation to getting made fun of. It’s absurdly intellectually dishonest when Rust-as-Religion people actively hassle anyone writing C and then get a little precious when anyone mentions Haskell and then extremely precious when they step on the landmine of the guy who likes Rust enough to know the standard, the compiler, the build tool, the people who wrote the build tool, and generally enough to put it in its place from a position of knowledge.
SSH servers? Yeah, I’d go with Rust. Web browsers? In a perfect world, lot of work. Even for Mozilla who timed the fuck out on it.
Everything ever so no security problem ever exists ever again? Someone called it the “green energy of software security” on HN like this year.
It’s not the coolest look that one of my “blow off some steam” hobbies is making those people look silly, but there are worse ways to blow off some steam.
Comparisons to other languages like Haskell don't really work, since they don't fit in the same space nor have the same goals as Rust or C.
It seems you are just raging and reading subtext and drama where there is none.
Further up someone mentioned Rust and Haskell aren't similar and you go on about Rust-religion and where to use Rust. Why don't you just address the point? "Lego" is also not a synonym or metaphor for simplified.
I'm searching your posts in this topic trying to find something of value and coming up short. You assert that you know rust, and therefor your opinions have merit, but... lots of people know rust and disagree. But somehow your opinions are More Right and the others are just religious Rust shills.
I don't think you know what you're talking about honestly. If you want to pick fights on HN that's cool, we all get that urge, but you're really bad at it.
Rewriting something from scratch isnt going to magically not have bugs, and the legacy system likely has many edge cases covered that a modern new implementation will have to learn about first.
Memory unsafety allows you to change the 'category' of the bug, you become free to do whatever whereas a logic bug forces to to work within the (flawed) logic of the original program.
I think regardless, you’re right, we will still have logic bugs… but that example is also an “exception proves the rule” kind of thing.
https://news.ycombinator.com/item?id=19138602
https://www.zdnet.com/article/chrome-70-of-all-security-bugs...
- sane integers: no unsafe implicit cast, more ergonomic overflow/saturate/checked casts
- sane strings: slices with length, standardized and safe UTF-8 operations
- expressive typing preventing API misuse: monads like Optional/Result, mandatory exception handling, better typedefs, ADTs vs tagged unions
And even without the full Rust ownership model, I'd expect the following to solve a majority of the memory safety problems:
- array bounds checks (also string bounds checks)
- typed alloc (alloc a specific type rather than N bytes)
- non-null types by default
- double-free, use-after-free analysis
- thread-save std APIs
In the write-up you linked, Section 2 is a missing error check => Result<T> would surface that. The macOS case contains a relative path vs string comparison => expressive typing of Path would disallow that. DriverKit exploit is a Non-NULL vs NULL API mistake. Kernel PAC is a legit ASM logic bug, but requires a confusion of kernel stack vs. user stack => might have been typed explicitly in another language.
When you look at the percentage of security issues that derive from memory safety, it certainly makes memory safety a good place to start.
>The Chromium project finds that around 70% of our serious security bugs are memory safety problems.
https://www.chromium.org/Home/chromium-security/memory-safet...
>Around 70 percent of all the vulnerabilities in Microsoft products addressed through a security update each year are memory safety issues.
https://www.zdnet.com/article/microsoft-70-percent-of-all-se...
All code can have bugs, it's mostly just a question of how many. Rust code doesn't have to have zero bugs to be better than C. It's not like all C programmers are top-tier programmers and all Rust programmers are the bottom of the barrel.
Writing things in C correctly takes more time than in rust (once you get past the initial learning curve)
Writing things in C that appear to work may take less time.
I think we can be reasonably sure that Apple didn't introduce those image parsing bugs intentionally. But that means they thought it was correct.
Part of that is because I'm working in code where security is constantly paramount, and trying to reason about a C or C++ codebase is incredibly difficult. Maybe I get lucky and things are using some kind of smart ptr, RAII and/or proper move semantics, but if they're not then I have to think about the entire call chain. In rust I can focus very locally on the logic and not have to try and keep the full codebase in my head
For instance, in the past I worked at a sort of active directory but in the cloud company. We identified parsers of user submitted profile pictures in login windows as a privilege escalation issue. We couldn't find memory safe parsers for some of these formats that we could run in all these contexts, and ended up writing a backend service that had memory safe parsers and would recompress the resulting pixel array.
Rust parsers at the time would have greatly simplified the workflow, and I'm not sure how we would have addressed the problem except as whack-a-mole at the time if there wasn't our central service in the middle (so MMS can't do that).
Some follow-up commentary: https://marc.info/?l=openbsd-misc&m=151233345723889
1. In the video he's saying that you can't replace memory safety mitigation techniques like ASLR with memory safe languages. He notes that there will always be some unsafe code and that mitigation techniques are free, so you'll always want them.
No one should disagree with that. ASLR is effectively "free", and unsurprisingly all Rust code has ASLR support and rapidly adopts new mitigation techniques as well as other methods of finding memory unsafety.
2. The link about replacing gnu utils has nothing to do with memory safety. At all.
Even if it were related, it would simply be an argument from authority.
This is completely misleading. The vulnerabilities that exist in those languages are completely different. They often are also far less impactful.
Memory safety vulnerabilities typically lead to full code execution. It is so so so much easier to avoid RCE in memory safe languages - you can grep for "eval" and "popen" and you're fucking 99% done, you did it, no more RCE.
The C in use today wasn't written by experts either. And if it was, we can leave it alone for now, or at least until said experts get tired of maintaining it.
I'm sure someone else has already thought of this, but in case not... All you need to do is represent a pointer by three addresses - the actual pointer, a low bound, and a high bound. Then *p = 0 compiles to code that checks that the pointer is in bounds before storing zero there.
I believe such a compiler would conform to the C standard. Of course, programs that assume that a pointer is 64-bits in size and such won't work. But well-written "application level" programs (eg, a text editor) that have no need for such assumptions should work fine. There would be a performance degradation, of course, but it should be tolerable.
struct dev { int a, b; } *p; p = (struct dev *) 0x12345678;
should be able to set up p with bounds that allow access only to the a and b fields - eg, producing an error with int *q = (int *) p; q[2] = 0;
Of course, it doesn't fix logic errors, such as setting a flag to true that shouldn't be set to true.Low-level OS and device-handling code may need to do something that won't be seen as memory safe, but I expect that for such cases you'd need to do something similarly unsafe (eg, call an assembly-language routine) in any "memory safe" language.
I'm not familiar with how ASAN is implemented, but since it doesn't change the number of bytes in a pointer variable, I expect that it either doesn't catch all out-of-bounds accesses or has a much higher (worst case) performance impact than what I outlined.
You have to change the code. Whether that's by using another language annotations or through annotations like checked C is an interesting (but separate) discussion in its own right.
As for the point that programs with memory unsafety aren't standards conforming; correct but irrelevant. Every nontrivial C program ever written is nonconformant. It's not a matter of "just write better code" at this point.
[1] https://www.usenix.org/system/files/conference/atc12/atc12-f...
That's too big a performance hit for production use - much bigger than you would get with the approach I outlined.
I don't agree that any nontrivial C program is nonconformant, at least if you're talking about nonconformance due to invalid memory references. Referencing invalid memory locations is not the sort of thing that good programmers tolerate. (Of course, such references may occur when there are bugs - that's the reason for the run-time check - but not when a well-written program is operating as intended.)
ASAN was notable because
1) it was very efficient. That initial 73% was utterly fantastic at the time.
2) It was production-usable (i.e. worked on big codebases)
3) With hardware support, the performance hit is often under 10%. HWAsan on modern platforms is low-cost enough to run it all the time.
And no, I'm saying that pretty much every nontrivial C program has UB, not that they're specifically memory unsafe.
[1] https://minds.wisconsin.edu/bitstream/handle/1793/59822/TR11... [2] https://insights.sei.cmu.edu/blog/performance-of-compiler-as...
Don’t get me wrong, I often fell into this as well, but I think programmers really should get a bit of an ego-check sometimes, because (not you) it often affect discussions in other fields as well where we don’t know jackshit about.
1. I can get my ego so wrapped up in my own idea that, even once I have the necessary information to see that it's wrong, I still don't abandon it. In fact, this always happens to some extent; when I change my mind it's always embarrassing in retrospect how blind I was. But the phenomenon can be more or less extreme.
2. In a context where posturing to appear smart and competent is demanded, such as marketing, advocating totally stupid ideas puts me at a disadvantage, even if I recant later. Maybe especially then, because it reminds people who might have forgotten.
3. People who know even less than I do about a subject may be misled by my wrong ideas.
4. This approach is most productive when people who know more than I do about a subject are kind enough to take the time to explain why my ideas are wrong. This happens surprisingly often, both because people are often kind and because the people who know the most about a subject are generally very interested in it, which means they like to talk about it. Still, attention of experts is a valuable, limited resource.
5. People who know more than I do about a subject can get angry and defensive when I question something they said about it, particularly if they're mediocre and insecure. The really top people never act this way, in my experience; if they pay attention at all, either they can explain immediately why I'm wrong, as AlotOfReading did here (though I may not understand!) or they go "Hmm, now that's interesting," before figuring out why I'm wrong. (Or, occasionally, not.) But people with a good working understanding of a field may know I'm wrong without knowing why. And there are always enormously more of those in any field than really top people.
So, I try to do as much of the process as possible in my own notebook rather than on permanently archived public message boards. The worst is when group #3 and #5 start arguing with each other, producing lots of heat but no light.
My theory about why the angry and defensive people in group #5 are never the top people is that they stopped learning when they reached a minimal level of competence, because their ego became so attached to their image of competence that they stopped being able to recognize when they were wrong about things, so they are limited by whatever mistaken beliefs they still had when they reached that level. But maybe I'm just projecting from my own past experience :)
It would be nice if everything was memory safe, but making media decoding memory safe would help a lot.
Saying just make airtight sandboxes is like just write bug-free code.
JavaScript is not machine code, but still a good deal harder to make fast than a language designed for fast sandboxing. Of course there have been bugs, but mostly I think the JS VMs have done a pretty good job of protecting browsers.
Airtight sandboxing would be easier in a memory safe language prevents certain classes of bugs.
Surely we should compare tight Rust (with some 'tight' unsafe sections) against tight C?
I just think if mistakes need to be literally low as possible you’ve got a better bet than Rust unsafe.
The language spec is smaller, the static analyzers have been getting tuned for decades, and the project leaders arent kinda hostile to people using it in the first place.
&mut aliasing is a good example of running into instant UB in unsafe rust, but there are many more that you have to be aware of.
I would check out the unsafe rust "book" for yourself and see what you think. There is a section where you implement Vec and some other data structures from scratch!
Besides equivocating between a pervasively unsafe-by-default language and one with an explicit bounded opt-in is a little disingenuous. Time after time, it has been shown that even expert C developers cannot write memory safe C consistently, each line of code is a chance to blow up your entire app's security.
https://steveklabnik.com/writing/you-can-t-turn-off-the-borr...
99% of the time if you're fighting the borrow checker and just want a quick solution, that solution is `clone` or `Arc<Mutex<T>>`, not `unsafe`. Those solutions will sacrifice performance, but not safety.
I've seen unsound unchecked casts from &UnsafeCell or *mut to &mut in multiple codebases, including Firefox itself: https://github.com/emu-rs/snes-apu/blob/13c1752c0a9d43a32d05..., https://searchfox.org/mozilla-central/rev/7142c947c285e4fe4f....
And, most of the time unsafe code is not required. I think many people will just use clone too much, or Arc rather than unsafe. Additionally, I have never seen unsafe code at least where I work.
Is log4j's bug actually unique to Java/C#/gc-based languages?
Not to my understanding. It would be possible in any language with or without a GC.
Log4Shell wasn't a bug, log4j worked as expected and documented. It's just a stupid idea for a logging library to work in such a way.
It's a recurring problem in dynamic scripting languages where the language by its very nature tends to support this sort of functionality. It's actually a bit weird that Java has it because statically-typed languages like that don't generally have the ability to do that, but Java put a lot of work into building this into its language. Ruby has a very large issue with this a few years back where YAML submitted to an Ruby on Rails site would be automatically deserialized and execute a payload before it got to the logic that would reject it if nothing was looking for it. Python's pickle class has been documented as being capable of this for a long time, so the community is constantly on the lookout for things that use pickle that shouldn't, and so far they've mostly succeeded, but in principle the same thing could happen with that, too.
It would be nearly impossible for Go (a GC'd language) to have that class of catastrophic security error, because there is nowhere the runtime can go to get a list of "all classes" for any reason, including deserialization purposes. You have to have some sort of registry of classes. It's possibly to register something that can do something stupid upon unmarshaling, but you have to work a lot harder at it.
Go is not unique. You don't see the serialization bugs of this type in C or C++ either (non-GC'd languages), because there's no top-level registry of "all classes/function/whatever" in the system to access at all. You might get lots of memory safety issues, but not issues from deserializing classes that shouldn't be deserialized simply because an attacker named them. Many other languages make this effectively impossible because most languages don't have that top-level registry built in. That's the key thing that makes this bug likely.
Getting objects out of a directory services is what JNDI is all about, I'm hesitant to call it a bug.
The bug is that Java is way too keen on dynamically loading code at runtime. Probably because it was created in the 90s, where doing that was kinda all the rage. I think retrospectively the conclusion is that it may be the easiest way to make things extensible short-term, but also the worst way for long-term maintenance. Just ask Microsoft about that.
I didn't call it a bug. I called it a bit of functionality that makes the security problem possible. There are many things that result in security issues that come from some programmer making something just too darned convenient, but are otherwise "features", not some mistake or something.
It's the underlying problem. You should have to declare what classes are able to be deserialized. To the extent that it's inconvenient, well, so was the log4j issue.
Other apps are also written using the same stack with almost no bugs. I wouldn't blame the language here, but the teams working on them (or more likely their managers trying to hit unrealistic deadlines).
So with regard to C, I would say it is not objectively inferior like QWERTY became, it's actually pretty well designed. It does produce fast code. I use it myself sometimes, not a bad language for simple algorithm prototypes of under 60 lines. But it's based to a huge degree on characters, the difference between code that works and code that fails can come down to characters, C is about characters, pretty much any character, there's no margin of error. Whereas with Lisp, you have parentheses for everything, you have an interpreter but you can also compile it, I am actually able to trust Lisp in a way that is out of the question with C. There's just so incredibly many gotchas and pitfalls, buffer overflows, it's endless, you have to really know what you're doing if you want to do stunts with pointers, memory, void types.
I guess the bottom line is if you're want your code to be perfect, and you write it in C, you can't delegate to the language, you yourself have to code that code perfectly in the human capacity of perfection.
Clarifying that what I mean by this is that it's not realistic to expect large C codebases to be perfect. Bug-free, with no exploits. Perfect. Same thing.
1. You start off by saying you can't just blame the team or their manager if you're dissatisfied with a product, then instead of explaining why the people who made a piece of software aren't responsible for its faults you go off on a long non-sequitur about QWERTY.
2. Your rant on QWERTY just isn't true. You namedrop Peter Thiel and his book, so if he's your source then he's wrong too. QWERTY is not terrible, not obsolete, it was not designed to slow down typists, and there's no record of salesmen typing "typewriter quote" with just the top row. It's true that it was designed to switch common letters between the left and right hands, but that actually speeds up typing. It also does not take weeks for someone to type "the" ; and if you mean learning touch-typing, I don't know of any study that claims that alternative keyboard layouts are faster to learn.
The various alt. keyboard layouts (dvorak, coleman, workman) definitely have their advantages and can be considered better than QWERTY, sure; people have estimated that they can be up to ~30% faster, but realistically, people report increasing their typing speeds by 5-10%; or at least the ones who have previously tried to maximize their typing speeds... If learning a new layout is the first time they'd put effort into that skill, they'd obviously improve more. It's probably also true that these layouts are more efficient in the sense that they require moving the fingers less, reducing the risk of RSI (though you'd really want to use an ergonomic keyboard if that's a concern.)
QWERTY is still used because it's not terrible, it's good enough. You can type faster than you can think with it, and for most people that's all they want. There's nothing wrong with any of the alternative layouts, I agree that they're better in some respects, but they're not order-of-magnitudes better as claimed.
3. Your opinions about C are asinine.
"not objectively inferior like QWERTY" - So, is C good or not? We're talking about memory safety, C provides literally none. Is this not objectively inferior? Now, I would argue that it's not, it's an engineering trade-off that one can make, trading safety for an abstract machine that's similar to the underlying metal, manual control over memory, etc. But you're not making that point, you're just saying that it's actually good before going on to explain that it's hard to use safely, leaving your readers confused as to what you're trying to argue.
"not a bad language for simple algorithm prototypes of under 60 lines" - It's difficult to use C in this way because the standard library is rather bare. If my algorithm needs any sort of non-trivial data-structure I'll have to write it myself, which would make it over 60 lines, or find and use an external library. If I don't have all that work already completed from previous projects, or know that you'll eventually need it in C for some reason, I generally won't reach for C... I'll use a scripting language, or perhaps even C++. Additionally, the places C is commonly used for its strengths (and where it has begun being challenged by a maturing Rust) are the systems programming and embedded spaces, so claiming C is only good for 60-line prototypes is just weird.
"C is about characters" - Um, most computer languages are "about characters". There are some visual languages, but I don't think you're comparing C to Scratch here... You can misplace a parentheses with Lisp or make any number of errors that are syntactically correct yet semantically wrong and you'll have errors too, just like in C. Now, most lisps give you a garbage collector and are more strongly typed than C, for instance, features which prevent entire categories of bugs, making those lisps safer.
4. You kinda lost the point there. You started by saying that the people who wrote Apple Music "could very well be capable and well-minded, likely personally capable of coding", i.e., they're good at what they do. Fine, let's assume that. Then, your bottom line is that in C "you have to really know what you're doing" and "you yourself have to code that code perfectly in the human capacity of perfection". What's missing here is a line explaining that humans aren't perfect, and even very capable programmers make mistakes all the time, and having the compiler catch errors would actually be very nice. Then it would flow from your initial points that these are actually fine engineers, but they were hamstrung by C.
And the tangent on QWERTY just did not help at all.
One might make the argument that Oberon, with its System module, provides the same memory control abilities but few of the disabilities of C.
> so claiming C is only good for 60-line prototypes is just weird.
That seems like a misrepresentation of the claim above?
> Um, most computer languages are "about characters". There are some visual languages, but I don't think you're comparing C to Scratch here... You can misplace a parentheses with Lisp or make any number of errors that are syntactically correct yet semantically wrong and you'll have errors too, just like in C.
Well, not really. Lisp is actually about trees of objects. The evaluator doesn't even understand sequences of characters. That you can enter it as a sequence of characters is purely coincidental, but there have been structured syntactic tree editors (sadly they went down for being proprietary and expensive at the time).
Sure, and that would be a good argument, there are several interesting languages out there that do various things better than C. I'm not intimately familiar with the Wirth languages, but I thought Oberon provided garbage collection?
> [...] misrepresentation [...]
Fine, they never claimed it was only good for that, but I still find it weird to claim that "it's fine, it's great for X" where X is a thing that the language is not particularly good at, while ignoring Y, the thing it's well known for.
> [...] trees of objects [...]
I just don't think that "about characters" or "about trees of objects" is an interesting way to differentiate between programming languages, and I think that this discussion is actually confusing between two different properties. First, is how the source code is represented and edited. It's almost always as a plain text file. Some languages have variants on the plain text file: SQL stored procedures are stored on the RDBMS, Smalltalk stores source code in a live environment image. There are other approaches, such as visual editing as-in Scratch, or Projectional Editing (https://martinfowler.com/bliki/ProjectionalEditing.html) as in... um... Cedalion? I don't actually know any well-known ones.
The other property is how the language internally represents its own code. Sure, Lisp has the neat property that its code is data that it can manipulate, but other languages represent their code as (abstract) syntax trees, too. Basically every compiler or interpreter for a 3rd generation language or above, i.e., anything higher-level than assembly language, parses source code the same way: tokenization then parsing into an abstract syntax tree using either manually-coded recursive descent, or a compiler generator (Bison, Yacc, Antlr, Parser combinators, etc.) So your point that the Lisp evaluator doesn't even understand sequences of characters is true for any compiler, they all operate on the AST.
I think that there's a point to be made somewhere in here that one language's syntax can be more error-prone than another's, but that wasn't the argument being made... Not that I understood, anyway.
Lisp does not really operate on an AST. It operates on nested token lists, without syntax representation. For example (postfix 1 2 +) can be legal in Lisp, because it does not (!) parse that code according to a syntax before handing it to the evaluator.
Lisp code consists of nested lists of data. Textual Lisp code uses a data format for these nested lists, which can be read and printed. A lot of Lisp code, though, is generated without being read/printed -> via macros.
What you say about Lisp code being generated without being read or printed is of course true, and while Lisp takes that idea and runs with it, it's not exactly unique to Lisp either; Rust's macro can do the same thing, without S-expressions. In other languages you usually generate source code, for example Java has a lot of source code generators (e.g., JAXB's XJC that used to come with the JDK).
There are lots of language with code generators. Lisp does this as core part of the language and can do it at runtime as part of the evaluation machinery.
The constitutents of the list are not "tokens" in Common Lisp. ANSI CL makes it clear that the characters "postfix", in the default read table, are token constituents; they get gathered into a token until the space appears. That token is then converted into a symbol name, which is interned to produce a symbol. That symbol is no longer a "token".
I'm not quite sure that this is what actually happened: https://repository.kulib.kyoto-u.ac.jp/dspace/bitstream/2433...
Or given how new it is, it's likely majority written in Swift when presenting a native app
Also backwards compatibility is a feature many wouldn't give away for extra security, at least not now.
https://medium.com/@tinocaer/how-microsoft-is-adopting-rust-...
https://preettheman.medium.com/this-is-what-apple-uses-rust-...
- Add reference counting to ObjC to get rid of a lot of use after free bugs (still of course possible because it's just a language suggestion and not strictly enforced like Rust or Swift)
- push for adding ObjC notations to let the tooling help catch some set of bugs. Still not perfect by any means but helps a little.
- created an entirely new memory safe language as Swift.
Cyber security is national security is the people’s security. Ever since my aunt was doxxed and had her online banking money stolen I’ve become a cyber security hardliner.
let’s kill bytes. :P