> the errors I get at runtime are almost never type-based
That surprises me, but everyone's experiences are different. I've been in the statically typed language space for so long and enjoyed it so much, I find it pretty irritating to go back to Python (my long-ago favorite) but many people are in the exact opposite frame of mind. I'm curious: what kinds of errors do you classify as a type-based error? I think that varies from person to person.
For example, null references. A C programmer would say dereferencing a null is not a type-based error, because it's not feasible to encode non-nullable pointers in the C type system. A Haskell programmer would say it is a type-based error because Haskell makes it difficult not to encode this in the type system, you really have to go out of your way to create a runtime null dereference error.
A C# or TypeScript programmer could answer differently depending on who you ask, because both of those languages make it possible to leverage the typechecker to prevent null-deref at compile time, but neither one makes it required (you can turn those checks off or make them warnings if you like), so it depends on the programmer's build settings and how much typechecking they personally have chosen to use.
It should also be remembered that while the industrial revolution netted humanity enormous wealth and eventually a higher average standard of living, it also kinda sucked for the generations of working class living through it, prior to labor reform. Millions of people lived entire lives where the industrial revolution was nothing but bad for them and never saw the upside. So anybody opposing a new industrial revolution is not necessarily acting out of irrationality.
Kind of. I think the history is interesting here and complex.
One of the hard things to grasp is that the industrial revolution was preceded by an environmental collapse. Part of the reason there was a switch to coal (despite being seen as inferior to wood at the time) was massive depletion of wood in England and the high cost of importing not just timber but even just firewood.
Add this in to the enormously expensive wars England was fighting all through this period and stressed everything from labor and food supplies (which also triggered demand for steel and copper and brass) The industrial revolution happened against a backdrop of national crisis so it's hard to know what was being caused by the revolution and what the revolution was helping paper over.
And on top of this, when Engels and Marx wrote about the squalor and desperation of their time (which was very real), nearly a hundred years had passed and something much different was happening. Massive amounts of peasantry were being dispossessed of lands and forced into urban slums. Cities grew something like 10x in a single generation. This wasn't really the fault of the industrial revolution but because of really bad policy.
The contract behind open source was something like (GPL):
"If you copy my work, you should share your work too."
or at minimum (MIT):
"If you copy my work, you should credit me."
I think it is no longer under dispute that the legal contract is satisfied by LLMs. The AI companies won and will continue to win.
But we are talking about a social contract, which is not quite the same thing. The social contract is what leads some devs who previously enjoyed publishing their work openly to no longer feel the same way. What did the authors mean by "copy"? Did they mean literally CTRL+C, CTRL+V or something broader?
This is a matter of opinion which only each individual creator can answer. For me, copying meant something like:
"To reproduce the function of my work, dependent on my having published it, without effort nor understanding of your own"
Ten years ago this basically required doing a CTRL+C, CTRL+V so there was no need to be more specific. Anybody who did enough work to, say, rewrite in another language (with that language's idioms), met the bar of clause 3. Now AI enables a form of "copying" that matches my definition, without the user even being aware of whose works they are copying. It perfectly launders the origins of its output. It can write an FFmpeg clone in Rust for you that would appear to be a novel work.
Of course, I cannot say that my own little bits and pieces of open source code would make a scratch in AI's capability, were it removed.
But I do strongly believe that if all the code that was published by authors with the same mindset was unavailable, Claude would be a far weaker developer.
> But we are talking about a social contract, which is not quite the same thing. The social contract is what leads some devs who previously enjoyed publishing their work openly to no longer feel the same way.
Perhaps this illustrates a fissure that was always lurking under the surface, then. The social contract that I've personally always attributed to FOSS communities was that attempting to restrict how people downstream of you use code is illegitimate, and that licenses like the GPL were meant to use copyright law to achieve something that resembles the state of affairs that might exist if copyright didn't exist in the first place. That's what the whole concept of "copyleft" always seemed to imply.
Now we have a new class of technologies that is admittedly fraught with a wide range of risks and pitfalls, but also a lot of promise to enable people to actually put the "four freedoms" into practice in ways they couldn't before, and we're seeing people who have normative opinions about AI derived from other, unrelated principles trying to circle the wagons and exclude those use cases. That is what seems like a breach of the social contract as I've always understood it.
> Did they mean literally CTRL+C, CTRL+V or something broader?
Given that FOSS licenses were always constructed to function within applicable copyright law, I don't see how they could mean anything else. "Literal CTRL+C, CTRL+V" is the only thing copyright has ever applied to, and the whole point of "copyleft" was to lessen the restrictions on even that.
> "Literal CTRL+C, CTRL+V" is the only thing copyright has ever applied to
This is extremely false. Copyright additionally grants you exclusive control over the production and distribution of derivative works.
A "derivative work" is a work based upon one or more preexisting works, such as a translation, musical arrangement, dramatization, fictionalization, motion picture version, sound recording, art reproduction, abridgment, condensation, or any other form in which a work may be recast, transformed, or adapted. A work consisting of editorial revisions, annotations, elaborations, or other modifications which, as a whole, represent an original work of authorship, is a "derivative work".
A training set is just an anthology, and the training process is condensation. That makes the weights a derivative work of every work in the training set.
Now, there's a separate discussion to be had about whether that derivative work meets the criteria for fair use, but that's it's own tangent.
> This is extremely false. Copyright additionally grants you exclusive control over the production and distribution of derivative works.
A derivative work is a work that itself includes copyrighted content from the original work.
That is to say that for something to be a derivative work, some measure of its content must be "CTRL-C, CTRL-V" from the originating work.
Something that's merely inspired by another work, or draws underlying themes or factual knowledge from it, is not a derivative work.
> A training set is just an anthology,
Which might make the training set itself a derivative work, but works created by using the model trained on that anthology are a different matter.
> and the training process is condensation.
No, it isn't. It's the creation of a new work that represents patterns extrapolated or interpolated from the data set, without the resulting model actually including any of the copyrighted elements of the work.
The underlying ideas and facts in the original work were never protected by copyright. Only the specific fixed form of expression is copyrightable.
Someone who looks at a dozen code examples in public repos to learn how to do e.g. a quick sort, then upon understanding the logic flow of the quick sort algorithm, writes his own quick sort implementation is not creating a derivative work of the code in the repos he exampled. And the way LLMs work is much more similar to that process than to the "compressed anthology" concept you're describing.
> A derivative work is a work that itself includes copyrighted content from the original work.
If you put a GPL C program through Emscripten to run in a browser the output doesn't include the original C code but it's surely a derivative work.
> Someone who looks at a dozen code examples in public repos to learn how to do e.g. a quick sort, then upon understanding the logic flow of the quick sort algorithm, writes his own quick sort implementation is not creating a derivative work of the code in the repos he exampled. And the way LLMs work is much more similar to that process than to the "compressed anthology" concept you're describing.
This is undoubtedly the core of the disagreement. Humans can learn from what they have seen, appreciate it, understand it, and draw on that experience in what they create. They do this without being considered ripoff artists, so why not machines that simulate the "same" thing automatically?
To me the answer is simply that humans are special. Human thought and human effort makes it creativity when a human does it, copying when a machine does it. It's a double standard I am perfectly willing to accept. I am unabashedly biased in this regard.
That may seem remarkably unfair to the machines, or like a cop-out. I just carved out a hardcoded special case for humans, and my whole philosophical reasoning is "because I said so". But how fair do we want to be? After all, if you want to treat a machine exactly like a human who learns from prior art to create new art, then the ownership of the new art would also belong to the machine. Not to the person who prompts it.
> If you put a GPL C program through Emscripten to run in a browser the output doesn't include the original C code but it's surely a derivative work.
Because it does include content from the original work -- this is just a translation, and isn't comparable to how LLMs work.
> To me the answer is simply that humans are special.
I don't disagree, but I also view LLMs as tools that extend human capacities and not autonomous entities unto themselves. LLMs are still just software, and can't really be regarded as anything other than instruments that humans use to broaden their capacity to see, appreciate, understand, and draw on that experience in what they create.
> That may seem remarkably unfair to the machines, or like a cop-out.
No, it's unfair to the humans. The machines are just tools that they use. The "double standard" is really a set of inconsistent standards applied to the same underlying moral agents.
> After all, if you want to treat a machine exactly like a human who learns from prior art to create new art, then the ownership of the new art would also belong to the machine. Not to the person who prompts it.
No, it always belongs to the person who prompts it. The machine is not a conscious entity, bears no intentions, and has no capacity to act on its own initiative. The machine is always just a tool that extends human capacity, as all machines always have.
For a good comparison here, we've never not credited a photographer as the author of a photograph. But the photographer is in a sense merely prompting the camera by framing the shot, selecting the exposure, adjusting the lighting, etc. -- the hard work in actually creating the photograph is being done by the camera itself, with the photographer playing no role in directly constructing the final image, and with the many of the qualities of the final image being determined by pre-existing features of the camera's functional design and components that the photographer also played no role in defining, apart from choosing which camera to use.
LLMs are like cameras in this way. And the fact that they rely on external data for model training no more disclaims the user as the author of the resulting work than looking things up in a dictionary or encyclopedia does the same for the author of an essay.
The camera analogy is a good one but I have never had a camera that had every great picture somebody else had taken, plus every work of art, baked into it. They only captured what they were aimed at directly by the user. Well, maybe next time I upgrade my phone that will not be the case since they now have built in AI "enhancement" of photos.
I agree with the framing of the AI as a tool not an autonomous entity. The thing is, to me, it is exactly that framing that makes it so the use of that tool means "copying" more than it means "learning and taking inspiration and creating new art", because who is doing the learning and being inspired? The person who types "make me a 3d arena FPS" certainly didn't do any learning from the Quake source code. The AI itself, being just a program, can't take credit.
I think of a trained AI like a lossy, highly compressed copy of its training data set. AI companies charge access to decompress targeted pieces of that copy and the lossiness makes that decompression interesting and "new". But normally I can't charge for access to other people's stuff even if the access is highly lossy, like a camcorder bootleg.
> The camera analogy is a good one but I have never had a camera that had every great picture somebody else had taken, plus every work of art, baked into it.
I've never had an LLM that had any of that baked into it either. LLMs just have token correlations trained on those works. Trying to get an LLM to output the data it was trained on verbatim is something I'd expect to be heading into monkeys-on-typewriters territory. "Write something in the style of Shakespeare" and "give me the original text of Hamlet" are two very different things.
> I agree with the framing of the AI as a tool not an autonomous entity. The thing is, to me, it is exactly that framing that makes it so the use of that tool means "copying" more than it means "learning and taking inspiration and creating new art", because who is doing the learning and being inspired?
It's not learning or taking inspiration, though. It's just making statistical inferences based on token correlations. Whether or not that's analogous to how humans learn is something I think is a metaphysical question that is of little practical relevance. The fact remains that LLMs are not human, have no intentions of their own, do not exercise any kind of agency despite how often people employing the misnomer "agentic", and are ultimately glorified statistical models.
The LLM is a tool that extends human capacities in the same way as any other mathematical framework or technological device.
> I think of a trained AI like a lossy, highly compressed copy of its training data set.
I've seen a few people in this thread make that argument, but I just can't agree with it. It's not compression, lossy or lossless, which aims to deterministically encode a representation of the specific input data. The training data is analogous to the sample set used in a regression analysis to generate a polynomial function -- it's not valid to treat the output from any application of that polynomial as a copy of the original sample data.
> Perhaps this illustrates a fissure that was always lurking under the surface, then(...)
Yes, I do think there has always been such a fissure. People publish OSS code for many reasons, often a blend of multiple reasons. There are selfish reasons such as the desire for one's work to be recognized, or even the hope of getting better employment through showing ones' skill or making something companies will pay for support on. There are social reasons like the desire to collaborate with others. There are altruistic benefit-of-all-mankind reasons like Richard Stallman said "...restrictions reduce the amount and the ways that the program can be used. This reduces the amount of wealth that humanity derives from the program."
It sounds like your view of things is limited mostly to that last version of FOSS, the copyleft style. But even adherents of that style, I think, are not too happy with AI consumption of their code. For one, it allows laundering of the copyleft license so their work goes into closed-source products that are never shared. And for two, if your idea of OSS is that we all put our contributions into the great shared river of human achievements to benefit the world, it is disappointing to see that river funneled into a giant waterwheel of profit for a half dozen trillion dollar companies charging rent for its bounty.
> Given that FOSS licenses were always constructed to function within applicable copyright law, I don't see how they could mean anything else.
I agree from a legal standpoint. I cannot enforce my personal definition of copying nor do I expect that to become possible. It was just conveniently aligned with the reality of how copying software worked in the past, and no longer is and never will be again. That doesn't mean I will be writing OSS software with a new made-up unenforceable license. It just means, like OP, I'll weigh differently whether I want to bother releasing stuff at all.
> It sounds like your view of things is limited mostly to that last version of FOSS, the copyleft style.
No, I'm well aware of the different motivations for and approaches to FOSS. I'm mostly focusing on the copyleft/GNU GPL side of the discussion here because that's the side of the house where most of ideas of a social contract and desire to see a specific ecosystem develop have been located. People on the MIT/BSD side of things, which has always had a much more direct "do whatever you want" ethos, are not the ones I'd expect to be making these arguments in the first place.
> For one, it allows laundering of the copyleft license so their work goes into closed-source products that are never shared.
I'd agree that someone using an LLM to create a deterministic transcription of someone else's work is indeed violating the license. But I think the argument goes beyond that, into using LLMs in any way at all.
> That doesn't mean I will be writing OSS software with a new made-up unenforceable license. It just means, like OP, I'll weigh differently whether I want to bother releasing stuff at all.
That's a reasonable position, and from the perspective of examining whether the current LLM climate is sapping motivation to participate in FOSS, I can understand where you're coming from.
But to that point, I'd argue that if your motivation was to gain recognition, participate in a community, etc. then you're going to lose those things by keeping your code private anyway, whereas you won't necessarily lose those things just because an LLM was trained on your code. If you contribute to a popular project, people were almost certainly already using your work to do things you don't approve of -- if that didn't take away your motivation, why would LLMs do much worse?
> The social contract that I've personally always attributed to FOSS communities was that attempting to restrict how people downstream of you use code is illegitimate,
That's wrong. What on earth gave you that impression when the licenses specifically set constraints on what downstream can do (from "release derivatives as open" to "put me in the credits").
Which part of which open source licenses gave you the impression that there were no restrictions?
> That's wrong. What on earth gave you that impression when the licenses specifically set constraints on what downstream can do (from "release derivatives as open" to "put me in the credits").
These are restrictions on redistribution, not use. And they're there to make sure that derivative works can't themselves impose restrictions on use.
> "If you copy my work, you should share your work too."
Not exactly. The GPL way is that you should share my work under the same terms if you want to share it, even if modifying it.
You are not required to share anything if you don't actually share anything, and just run it yourself. That's where all the criticism towards cloud providers who freely use FLOSS is directed.
> But we are talking about a social contract, which is not quite the same thing. The social contract is what leads some devs who previously enjoyed publishing their work openly to no longer feel the same way.
There is clearly a misalignment in expectations from some FLOSS enthusiasts. The main FLOSS licenses focus exclusively on distribution, but their expectations somehow extend well beyond distribution. We hear those FLOSS enthusiasts criticize and attack companies for using software exactly according to their terms, and somehow that is framed as abuse if said users happen to be bigger than some arbitrary boundary.
> Static types are, in a real sense, a compensation for the gap I just described - the gap between the description and the running thing. When you can't easily inspect or reshape the live system, you want the compiler to tell you as much as possible before you cross that gap.
I think this underrates static typing. For me the biggest value add of a static type system is that while doing a big, breaking-change refactor, I can near-instantly see all the places I need to update callers. Getting the code to work in the place I was actually working on is easy, I was already focused there. Static types pay off by helping me know when my change broke other parts of the system I wasn't even thinking about.
I'm not underrating static typing and I'm not saying static types have no value for refactoring - they absolutely do. But the "I can't refactor safely without types" argument tends to assume a codebase structured the way typed codebases are structured. Idiomatic Clojure has a different shape, and the refactor pain you're describing almost never materializes.
What the static typing camp can't acknowledge is that not all dynamically typed languages are equal. I agree with your sentiment e.g., on Python codebases - it's legit pain, but PLs like Clojure and Elixir are a different story.
Data-orientation flattens the call graph. Most Clojure functions take and return plain maps/vectors/seqs. A "breaking change" to a data shape doesn't ripple through type signatures across the codebase the way it does when every layer has its own nominal type. You change the shape at the edges (parsing, validation via Spec/Malli) and most intermediate code keeps working.
Fewer, more general functions. map, filter, reduce, get-in, update, etc. replace dozens of bespoke typed methods. There's just less surface area to break. But then again, I would say `(map)`, and someone familiar with Javascript's `map()` would have some wrong assumptions.
You really just can't evaluate ANY language by picking a single aspect of it without wholly understanding the holistic picture in practical, battleground scenarios. Yes, Clojure is dynamic, but it doesn't mean it's harder to maintain or to more difficult to build with, or you just can't write robust software in it. It genuinely has qualities that shine in some domains.
My claim wasn't "static types are useless for refactoring" - it was that they're a compensation for the gap between description and running system. Your refactor scenario fits that exactly: you need the compiler to tell you about distant breakage because you can't cheaply ask the live system "who calls this, and does it still make sense?"
In a live image, that question is answerable directly. find-usages, instrument the function, exercise the path, watch what flows through. The "places I wasn't thinking about" announce themselves the moment they're touched, with real data in hand - not as a list of locations I now have to go read and reason about cold.
I'm prepared to excise the word "genuinely" from my vocabulary after working with Claude.
One of my biggest fears with using AI at work is that I will subconsciously start talking and writing like a bot, despite making conscious efforts to do the opposite. Just like how when you read a lot of books by one author, their style infects your own writing style.
Suppose the image resize service has some caching, and due to a bug in the caching, under certain circumstances it will respond with an already-cached resized version of a different source image.
Let's say for example it caches on something stupid like the CRC32 of the input image -- good enough that the couple dozen images in your test dataset don't collide, you don't see it in smoke testing your app, but real world data has collisions on a daily basis.
This gets into production and customer A sees a resized version of customer B's document for a thumbnail. Now customer A is wondering how many other customers are seeing resized versions of their private documents in thumbnail images. They are very very mad.
If the image resize service was built by "another team" then that other team is responsible for the bug and will take most of the heat for it. If it was built by an "agent swarm" or "gas town" or whatever under my direction then I'm 100% responsible for it and rightly deserve the heat.
That is why I cannot understand any approach that doesn't involve reading the code at all. Testing alone is not sufficient. MTTR is not sufficient because you can't make a customer less mad about a data privacy bug by fixing it.
1. You can treat software like a black box when other people developed it for you because they can stand behind it. They have their own reputations to uphold. You can't when AI developed it for you because YOU are responsible for 100% of the bugs in it. If you take this trendy stance of "I never read or write code, just specs", you are just rolling the dice on what you stamp your name on.
2. Just because you have unit tests and you've tested the software by clicking through the app doesn't mean you've found every bug. There have always been bug types, like the example checksum collision, that are easier to detect by reading the code than by running the code because it will work most of the time even though the approach is wrong.
But I'm already responsible for the bugs in my software. Also, who cares if someone else is responsible? And how does that align with OSS's "no warranty provided"?
> There have always been bug types, like the example checksum collision, that are easier to detect by reading the code than by running the code
AI seems radically, insanely more qualified to not write bugs like that. I doubt that if you polled developers 99% would be able to tell you what a CRC32 even is, let alone why it's insufficient as a cache key.
> But I'm already responsible for the bugs in my software. Also, who cares if someone else is responsible? And how does that align with OSS's "no warranty provided"?
The original example from Simon Willison referred not to pulling in a 3rd party library, but working "at larger organizations" where "another team hands over something". In other words we area all working on the same product for the same company, they have been assigned another part of it and I'm expected to use their code.
In that scenario of course I care that someone else is responsible! It may affect whether I get fired or not!
It's different if you're a solo founder of a startup and for everything you ship, the buck stops with you. But proportionally many many more devs are in a situation where they are a cog in a machine.
> AI seems radically, insanely more qualified to not write bugs like that. I doubt that if you polled developers 99% would be able to tell you what a CRC32 even is, let alone why it's insufficient as a cache key.
I actually do agree that AI generally writes pretty good code. Doesn't mean I'm not gonna check. Sometimes it is too clever for its own good, such as re-implementing from scratch something that already exists and is well-proven.
The whole example is kind of contrived in the first place (how many environments don't have an excellent "image resizing" solution to reach for off the shelf?), so I hope you don't mind my bug example is also contrived.
Object-oriented polymorphism (interfaces, inheritance) is for when you have a fixed set of methods to implement but an unbounded set of types that may want to implement them.
As a consumer, you cannot change the methods, but you can add a subtype. When you subtype an abstract class or an interface, the compiler does not let you proceed until you have implemented all the methods.
Discriminated unions are for the exact opposite situation, when you have a fixed set of subtypes, but unbounded set of methods to implement on them. As a consumer, you cannot add a subtype, but you can add a new method. When you write a new method, the compiler does not let you proceed until you have handled all the subtypes.
Good languages should support both!
The best example is abstract syntax trees, the data types that represent expressions and statements in a programming language. "Expression" breaks down into cases: integer literal, string literal, variable name, binary operations like add(expr1,expr2), unary operations like negate(expr), function call(functionName, exprs), etc.
Clearly all of these expression subtypes should belong to a base type `Expression`. But what methods do you put on `Expression`? If you're writing a compiler, you have to walk this syntax tree many times for very different purposes. First you might do a pass on it where you "de-sugar" syntax, then another pass where you type-check it and resolve names in the code, then another pass where you generate assembly code from it. Perhaps your compiler even supports different backends so you have a code-gen path for x86, another for ARM, etc. You'll likely want a pretty-printer so you can do automatic reformatting, maybe you want linting support, etc.
If you look at all those concerns and say that each subtype of `Expression` must implement methods for each one, then you end up with untenable code organization. Every expression subtype now has a huge stack of methods to implement all in one file, dealing with stuff from totally different layers of the compiler. It's a mess.
It's much cleaner to have the "shape" of the expression defined in one place without all that clutter, and then in each of those areas of the code you can write methods that consume expressions however they need, so each of those separate concerns lives in its own silo.
If you're an old hand at OO you may be familiar with its actual answer to this problem, the "Visitor" pattern. See System.Linq.Expressions.ExpressionVisitor. However, once you've used a language with good union and pattern matching support, this feels like a clunky hack. Basically the mirror image of a language without real object orientation imitating it by passing around closures and structs-of-closures.
------------------------------------------------
It doesn't just have to be compiler stuff. A business app data model can use this too. Instead of having:
public class DbUser
{
public EmailAddress Email { get; set; }
public PasswordHash? Password { get; set; } // null if they use SSO
public SamlEntityProviderId? SamlProvider { get; set; } // null if they use password auth
}
You could have:
type UserAuth =
| PasswordAuth of PasswordHash
| SSOAuth of SamlIdentityProviderId
The implementation details of those different auth methods, the UI for them, etc. don't have to be part of the data model. We do have to model what "shapes" of data are acceptable, but "doing stuff" based on those shapes is another layer's problem.
Even though the degree really didn't teach you what you'd do on the job, it was a signal to employers that 1. you were capable of learning stuff when needed, 2. you didn't give up on doing hard things, and 3. they wouldn't have to explain to you what a loop or a class is.
With rampant AI cheating it's no longer a guarantee of any of those.
I do not think I had a single university course that was not ultimately assessed through supervised written tests. That matters, because homework was never a reliable anti-cheating mechanism. Even before AI, you could just pay someone smarter to do your homework for you, or ask older students for their assignments (and sometimes even their test questions, there's even a pg essay on this [0]).
You can cheat as much as you want on homework, but it won't help you on supervised written tests. At some point you have to sit down, unaided, and show that you can solve the problems yourself. So I do not see how AI substantially weakens the signaling value of a degree, at least in systems where the degree is backed by in-person written assessment. It may make take-home coursework less meaningful, but that was already the weakest part of the signal.
I don't know, I went to a pretty well regarded CS program but some of the people I graduated with are definitely not people I'd want to work with. They might have hypothetically known what a loop is but I wouldn't expect them to put one to good use.
That surprises me, but everyone's experiences are different. I've been in the statically typed language space for so long and enjoyed it so much, I find it pretty irritating to go back to Python (my long-ago favorite) but many people are in the exact opposite frame of mind. I'm curious: what kinds of errors do you classify as a type-based error? I think that varies from person to person.
For example, null references. A C programmer would say dereferencing a null is not a type-based error, because it's not feasible to encode non-nullable pointers in the C type system. A Haskell programmer would say it is a type-based error because Haskell makes it difficult not to encode this in the type system, you really have to go out of your way to create a runtime null dereference error.
A C# or TypeScript programmer could answer differently depending on who you ask, because both of those languages make it possible to leverage the typechecker to prevent null-deref at compile time, but neither one makes it required (you can turn those checks off or make them warnings if you like), so it depends on the programmer's build settings and how much typechecking they personally have chosen to use.
reply