Hacker Newsnew | past | comments | ask | show | jobs | submit | GuB-42's commentslogin

And there is no need to, because we already have Wikipedia.

If we get to the more general idea of "can humans collaborate in the same way they collaborated to make Wikipedia". I see no reason why not. Collaborative projects similar in spirit to Wikipedia pop up all the time.


> similar in spirit to Wikipedia

Spirit is not sufficient. I can start a new project with the same spirit and a user base of one.

Scale is part of what makes Wikipedia. What projects are similar in spirit and scale?


The closest I can think of is OpenStreetMaps.

> And there is no need to, because we already have Wikipedia.

I became a Wikipedia editor not long after the 2nd version of the site, before they even had logins, IIRC.

I was banned from the site probably 7 years ago or so by a troll who collaborated with the admins. The review "process" was more like The Trial and the ban was quite terrible, because not only did they install some deep cookie in the browser, but they permabanned the IP address.

Wikipedia is gone. Whatever it even was, it is not now.


Exactly this. People are holding up Wikipedia as some shining light in the free world. They obviously are not aware of all the controversies there have been over the years of both rogue editors and restrictive controlling admins. It has also been called out for censorship many times before. I think everybody still has the idea that Wikipedia is free and collaborative for everyone, when in fact it has changed significantly from what it was. Your experience is testament to that.

> Wikipedia is gone. Whatever it even was, it is not now.

The title evokes a romantic sense of wikipedia as a well governed, neutral egalitarian multicultural collaboration. But anyone who has been marginalized by the cabal knows it was not most of those things.


Apparently, this is entirely subjective.

"Whatever it was[, which was really was really not all that,] it is not [even] now."


May I ask what username you used?

> because not only did they install some deep cookie

We dont use "deep" cookies, just normal cookies. If memory serves, 7 years ago Wikipedia didn't use cookies at all in the block process, it was purely ip based back at that point.


The weirdest thing I've seen about wiki nowadays is that "they" (admins? editors? chief editors? dunno) get to decide what makes a "worthy" article for wikipedia. Which is bananas, in the era of "free" storage.

I get everything about slop/spam/etc. but deciding a page about a small band in SmallTown Canada isn't "worthy" of wiki is silly beans. That's the whole point of a collaborative, anyone can contribute wiki. Having people decide what "makes the cut" or not is silly.

They could have gone with a "edu" / "core" wiki that gets to include only certain articles, and the rest are "community" or something, but literally removing articles for anything other than quality/sources/spam is not what wiki started as. And it's not what I donated for, but that's another can of worms...


Forgot to mention they deleted all of my edit history and comments on the talk page.

They provided an email address to send a message for appeal to the board, which I didn't bother.


>Collaborative projects similar in spirit to Wikipedia pop up all the time.

Name one started after 2022, with at least a modicum of success.


I can't think of any. But the thing is, but 4 years (after 2022) is not much, that's how long it took for Wikipedia to take off, most similar project I can think of: OpenStreetMap, Linux, GNU, arXiv... took longer than that. You can't judge success in 4 years.

After a quick search I stumbled upon Wikifunctions (2023), but do Wikimedia projects that are not Wikipedia count? A bit more controversial would be Anna's Archive (2022).

We have to think about the needs too. There was a need for an online encyclopedia, Wikipedia took it. What need do we have now that is currently unanswered and can be answered by a collaborative effort similar to Wikipedia?

Also, open source projects, so many come out every year that it is hard to count.


> Built really cool Photo, Video, Music editing/CAD software and released it for free

Built, really? From what I have seen, it is more like knockoffs, strictly worse than the original except that they are free, and unlike cracks, presumably legal.

I agree with the other two, though it is getting close to the cracking scene, which is certainly cool, but a bit different in sprit to what led to Linux and Wikipedia.

What we are seeing more of is "I had this specific need and I quickly vibecoded some software to do it". This is actually really cool, but it doesn't scale. These tools answer to the need of one person, they may break everywhere else but who cares, it does the job. But for a community project, it is not acceptable, everything has to work for everyone.


Software is not building a bridge; trying to peddle the effort as akin to 996 in a textile sweatshop is one of the cheesiest tropes of the IT industry

The amount of artisanal code slop expertly crafted by hand I have cleaned up suggests to me the human effort is just as big a mess; see all the unknown unknown security issues being spotted by LLMs


We would have inefficient and polluting engines, leaded gasoline, steam engines burning coal, no high performance plastics, and probably more even wars around oil and gas and slower economy leading to less resource to fund battery research...

I mean, batteries and solar panels are cool, but thinking about the future doesn't mean we should forget the present. The advance we could have gotten by diverting funding away from fossil fuels and towards renewables and batteries is to balance with the damage caused by using outdated fossil fuel technology before the transition.

Cities are breathable now thanks to all the progresses modern engines have made. They will be even more breathable with zero emission cars, but I prefer to wait a bit more in these conditions than waiting a bit less in a smog filled city.


So progress is in burning fossils because otherwise we cant >get it<?

Progress is in doing more work with less impact. Burning fossils more efficiently and burning less of them because we have an alternative are both progress.

These labs had one thing in common: they were funded by monopolies. Xerox with copy machines, Bell with the telephone, General Electric is also known for its monopolistic practices.

And you probably heard about these little things called LLMs, that's Google research, yup, another quasi-monopoly. And it wasn't product centric, in fact, Google turned out to be pretty bad at making a product out of their research, that's how OpenAI took over.

Monopolies are bad for consumers, but there is also some good. Because they make tons of money and don't have to worry about competitors, they can invest a lot into fundamental research with a long term perspective. A competitive industry rewards shorter term strategy, because companies can't afford to wait 20 years for the next big thing if their competitor takes over after 2 years with the next small thing.


But moving faster and without accountability is generally worse.

In a perfect world, we would move at a steady pace, as to keep up with the world but without rushing, and people would be accountable without a heavy bureaucratic processes.

Unfortunately, that's not how it works in practice, at least not for long, so between the two, we usually favor the slow and bureaucratic process when safety and reliability matter.


Security works by layers.

The physics makes the rowhammer impossible to fix in practice, but you can add various mitigations: scrambling, ECC, detection and response, etc... On the application level, you can also make it so that it is not possible to do a rowhammer in the first place. Fix everything that can be fixed and mitigate what can't be fixed.

And there is another security issue that can't be fixed, and is much worse than rowhammer: people. But we can't remove people, just like we can't remove DRAM for the performance level we need, so we mitigate the risk. It is not game over because we have other layers of security.


How do you decide what risks you can just leave open? Because that's what you're doing. The only thing that protects us from targeted rowhammer exploits for your hardware is our ability to research and write exploits ...

I don't decide, doing anything involve some risks, some of them can't be eliminated. Or, I guess I can decide to not do anything, but it won't get me anywhere.

To go back with the human analogy. I have a server in a datacenter, there is a weakness in that someone can go to the machine physically and do nasty stuff, including hitting it with a literal hammer. This is a risk, but I can't do anything about it. Someone has to do the maintenance. But it can be mitigated with access control to the datacenter, among other things.

If the door to the server room can be opened with a toothpick, that's a vulnerability and it has to be fixed, because to "real" solution of not letting anyone in is not viable. I didn't chose to let people in the server room, it is just impossible not to.


You can't decide to stop being black, but you can choose to not buy an iPhone. That's why race is a protected category and your smartphone is not.

And it is not "braindead". EncroChat was a "privacy service", selling phones featuring E2E encryption, disabled cameras and microphones, etc... Even though it wasn't marketed as such, it was mostly a service for criminals. And they effectively searched everyone using these devices (they hacked the firmware), and maybe a few people who weren't criminals got searched, as it happens in many investigations, most people turned out to be. The result was many arrests of people you really want to get arrested, with weapons, murder, torture, etc... being involved.

That's also the reason why mainstream apps like Signal are important for privacy, if only criminals use an app, having that app is a legitimate reason for being suspected. If most people using the app don't really need privacy and it is mostly used to talk about what to eat for dinner, that protects those who really need that privacy. And yes, it includes criminals, unfortunately, so it is actually a good thing for society when criminals use their own communication channels instead of using mainstream ones, good thing most of them are not so smart.


> You can't decide to stop being black, but you can choose to not buy an iPhone. That's why race is a protected category and your smartphone is not.

There are protected categories which person can choose to belong to. In USA these include for example religion. In EU political beliefs as well. So would it be okay to start suspecting anyone who is Christian if some Christian committed crime? Or anyone who supports AfD if AfD supporter committed crime? You can always choose to stop being Christian or AfD supporter.


EncroChat wasn't illegal. It was hacked by the government and used to catch crimes. Its creators are not in jail.

Anom is one where the creators were in jail, but only after they were caught directly participating in drug operations.


And it failed at it too.

People who buy trucks as a status symbol want to be "tough". And Tesla clearly intended to appeal to "tough guys", it is big, powerful, and supposedly indestructible. Elon even twitted at some point that it would destroy the other car in a collision, a morally questionable comment, but the implications are clear, a though vehicle for people who don't give a fuck about others.

And then, they managed to break the unbreakable window during the presentation, followed by the rusty trucks, and most importantly, the whole fiasco with glued panels that came off. So, you market a tough vehicle, but it falls appart. Who is going to buy that?


I doubt that replacing painted regular steel with fancy stainless steel is going to be cheap. Paint is expensive, but so is stainless steel. I also can't imagine the "origami" technique to be cheaper than stamping, the reason they suggested that is because their fancy stainless steel can't be stamped. And in the end, Tesla couldn't even do it, so they glued the parts on...

I don't know any item where the unpainted stainless steel version is cheaper than the painted steel version, thinking about kitchen appliances for instance. For cars, the most famous car with a stainless steel body is the DeLorean DMC-12, which was notoriously expensive, even without the time circuits.


In this particular case, it is type safe. NULL, by the C standard does not refer to an object. It means that every pointer in C is effectively an option type, which mean that a function that returns a pointer can return NULL for "no result", which, in the case of crypt() is perfectly adequate.

It is the opposite that is unsafe, that is, when the returned value can't be NULL, but it stills returns a pointer. C++ has references in an attempt to fix this problem.

Because C tends to prioritize performance over safety, a NULL pointer dereference is considered undefined behavior and the compiler can invoke nasal demons if it makes the code go faster, but with the right options, you can have it checked and invoke what in other languages would call a panic handler, but on UNIX is the SIGSEGV signal. You can then attach a debugger or read the core file and see what went wrong.

Note: I am not talking about "char *" for strings, that one is unsafe, but NULL is not. It is just a special case of an option type, or a result type, or an error union. Modern languages just extended this idea to objects other than pointers, and with more than one type of error.


> the compiler can invoke nasal demons if it makes the code go faster

I had never heard that phrase, and was delighted at the answer when I googled it its origin, thank you:

http://www.catb.org/jargon/html/N/nasal-demons.html

> “When the compiler encounters [a given undefined construct] it is legal for it to make demons fly out of your nose” (the implication is that the compiler may choose any arbitrarily bizarre way to interpret the code without violating the ANSI C standard)


However this is limited by the compiler's actual abilities and code. The C standard doesn't forbid nasal demons, but the compiler isn't programmed to invoke nasal demons and isn't running on hardware with that capability, so it won't happen.

I've heard nasal demons invoked as a literal possibility. No they are not a literal possibility.


Maybe your compiler isn't, but GCC is designed to summon every nasal demon it can. It especially loves to elide null pointer checks. There was a PR that almost made it to Linux mainline that did some weird stuff in kernel space where memory mapped to address 0 is valid and contains important stuff. It got a pointer, read data from it, then checked if pointer is null before giving root permissions for some operation. Reading the code, everything seems alright. Even stepping through it with debugger shows that it works. But when compiled with -O2 or higher, GCC removed the null check and now everybody got root permissions unconditionally - because reading from null pointer is UB regardless of circumstances, and GCC treats UB as dead code even if it is reachable.

> GCC is designed to summon every nasal demon it can.

Which is zero, to be clear. There's not even a standard USB device class for a nasal demon releaser

A null check elision is not a demon up my nose - it's a null check elision.


Sure, and char[] is no string because you can't tie anything with it. And don't get me started on the insects that allegedly live inside digital source files - that's an absurd concept, no self respecting computer specialist should be talking like that.

Having made devices for other human holes, you can just use the standardized HID class. It can be adapted for nasal demons incoming and outgoing.

Wait, so if you're running on embedded, you're not allowed to store anything at address 0, requiring you to waste that little bit of RAM?

That's... a bizarre choice, considering how religious C is about not making any assumptions about what a machine can and cannot do, even going to the trouble of working with non-IEEE floats and int types that are not a multiple of 8 bits.


No. IIRC, you’re just not allowed to use a constant expression evaluating to 0 as a pointer to construct a non-null pointer to address zero.

Runtime pointer arithmetic resulting in a zero-valued pointer, is not a null pointer m, though it is also nonportable and could have the same effect (but hopefully not nasal demons, as I believe this falls under some catagory of nonportable behavior other than “undefined”).

There’s no requirement that the in-memory representation of a null pointer be all-zeroes, only that constant 0 represents a null pointer in source code.

Regardless, I agree that it’s a bizarre choice.


Unfortunately yes. ISO/IEC 9899:1999 footnote 83: "Among the invalid values for dereferencing a pointer by the unary * operator are a null pointer".

The implicitness is exactly the problem. The workaround that caused this vulnerability was done because people assumed that crypt() would never return null.

You don't even need a fancy result type. A simple Option<String> would've forced downstream users to consider the failure case, avoiding this situation in the first place.


The workaround was correctly designed: two error string tokens are used so that one can always be chosen that is not equal to the second argument.

Someone coded a defense against long inputs which ignored this important principle.

What turned the bug into a security disaster is that Musl stupidly chose two symbols such that one of them is exactly the same as a convention for disabled logins. So that the moment someone makes a change to the function which allows crypt("something", "*") to return "*", you have an incident.

If the same bug were made in Glibc, it would have limited impact because crypt("long .... string", "*0") returning "*0", while incorrect, wouldn't do anything in a system that doesn't use *0 in password files. *0 does not correspond to any widespread password field convention.


.unwrap()

Now what?


I think the argument would be that in C people will look at a char* and think "string" rather than "string or null". Thus consumers of the library not checking the result and the maintainer trying to be helpful by putting a "safe" value in there for the error case.

Whereas if the library returns something that is unambiguously an option type, consumers unambiguously call unwrap at their own risk.

Of course you do have a point (assuming I'm picking up what you're suggesting correctly) that all pointers in C are option types. But I think there's a cognitive ergonomics aspect to this where an option type more clearly relays the library authors' intent.


First you shouldn't have unwraps in prod code, and you can verify that in your CI/build process/whatever. Second, now you have a crash of the SSH server, which is arguably much better than some random logging in as root.

This isn't about "you", it's about whether any consumer of your code is using unwrap on the result, which currently is perfectly safe to do. The equivalent in C is returning NULL, which would also have caused a crash. They decided not crashing was preferable, which is how we ended up here.

"you shouldn't have unwraps in production code" is exactly the same form of argument as "you shouldn't be assuming crypt returns a valid non-null pointer in production code".

Absolutely not. Unwrap is a language rule, so everyone knows unwrap is not a safe thing to do and writing it even once is an explicit dismissal (and you should document it). On the other side, knowing that crypt does not necessarily return a hash is easily overlooked and forgotten, there is no code smell that can hint you that you are doing things wrong.

I don't really care about the form of the argument when the concrete results are that (i) “no unwrap in prod” is trivial to ensure through the toolchain, (ii) even though, its consequences are “damn it crashed” instead of “welp I guess this guy is root now”.

In this situation, the decisions to make crypt implementations stop returning null in favor of a string error token were made not because C programs that misuse crypt are difficult to fix, but because they are in the form of unknown binaries in the wild that you cannot fix.

And that analogous situation can happen in the safer language where crypt returns an Optional(String) which some bad programs assume is always present. You don't know where all such programs exist, and people use them who don't have the code and cannot fix them.

Returning an error token which is carefully different from crypt's second argument was an attempt to fix programs that cannot be hunted down, patched and recompiled, even if fixing them would be easy to do.

Of course the tooling for C pointers being null or not is not comparable to optional types; that's not debatable.


> And that analogous situation can happen in the safer language where crypt returns an Optional(String) which some bad programs assume is always present.

Once again, no, because these unknown programs would just crash on the `.unwrap()`; not get in a silently corrupted state. Same causes, different effects.


OK, so you are talking about running crypt() on bare metal microcontrollers or other small systems that don't have MMU support for trapping null pointers. Everywhere else, dereferencing an undisplaced null pointer is a instant CPU trap, even though it be formally undefined behavior in ISO C.

Note that even on systems that don't have hardware support for trapping null pointers, it can be implemented in the compiler as a code generation option.

For instance, in 1987, Microsoft Quick C introduced the /Zr option for doing this, as well as a #pragma check_pointer({on|off}).

If you're interested, BitSavers has the documentation: https://bitsavers.trailing-edge.com/pdf/microsoft/msdos_c/qu... Look for section 8.1.4.4 and also /Zr.


Now you have an easy way to discover the bug

In theory, having newtons and pounds force be represented as `float` is type safe. In practice, it destroyed a multi-million-dollar NASA spacecraft because of human error.

If NASA were to use the equivalent of `pub struct Newtons(f32); pub struct PoundsForce(f32);`, where the types Newton and PoundsForce were not interchangeable, this would never have happened[1].

[1] I'm aware that that story is a bit more complicated than that, that CSV files were involved (which are, again, not type safe), and that, in that particular scenario, more would have to be done to preserve type safety across formats, vendors and codebases, but my point still stands.


I think related to your caveat is:

https://lexi-lambda.github.io/blog/2020/11/01/names-are-not-...

> The newtype is opaque, so the only way to observe it is to convert it back to a [f32].


You might consider it type safe according to C's rules, but it is not type safe according to contemporary opinion because the success type and error type are the same.

> [...] because the success type and error type are the same.

That's a bit weird? In Rust, if you have an thing that returns Result<String, String> that's still type safe, even though success and error types are the same.

I think I understand what you want to express, maybe. You might say it's in-band vs out-of-band error signalling?


> In Rust, if you have an thing that returns Result<String, String> that's still type safe, even though success and error types are the same.

These types are not the same:

    Ok<String>
    Err<String>

Those are not types at all. Ok and Err are type constructors for the Result<A, B> type that take arguments of type A and B respectively.

> type constructors

Nit: the type constructor is `Result`: given two types `A` and `B` (not instances of those types, but actual types) it gives you a new type `Result<A, B>`.

`Ok` and `Err` are called "variants" and can be used to construct a new _instance_ of `Result<A, B>`.


Ah, thanks! I'd remembered the term "data constructor" from Haskell and called it a type constructor instead.

Ok and Err are "thingies" which are in the type system, which give rise to distinctions that allow for compile-time diagnostics. They are part of the type.

Ok and Err are not just type constructors because they appear on the left hand side in pattern matching: they "do" matching and destructuring also.


The success and error types are not the same, because they are in different positions in the type, and so distinguished by different patterns.

If you have literally the above convention where a valid result is a String, and an error result is also a String (e.g. error message) that is still type safe.

  match (whatever()) {
    Ok(s) => println!("good result string: {s}"),
    Err(s) => println!("error string: {s}"),
  }
The success type and error type having to be different is not a good way to express the idea; rather that success and error cases are distinguished by type (even if the success and error data units are of the same type).

In other words, the "Ok" and "Err" entities are an ingredient of the type and that effectively makes the result and error be distinguished at the type level.

But we could also argue that Rust still allows you to write an integer-returning function such that -1 means error.


Basically, you need the whole 'success and error types are different' in a language like Python if you make the return type something like "int | string", where 'string' stands for your error message.

Of course that breaks down, when the success type is also an error message, eg when you are looking up something in a catalogue of error messages.

Rust has no trouble with this, for exactly the reasons you line out.


Contemporary opinion among who? Words mean things, and "type safe" simply does not mean "agrees with my preferred style of error reporting"

Papers on type soundness from the last 30 years usually explore the domain further than C semantics.

Soundness means that the program behaves in accordance with what its types express. You're right that C may be unsound due to undefined behaviour, but I don't think this is about soundness. What you're saying is that papers on types show how you can use types to express more constraints.

There can be other valid perspectives and definitions of that word than yours.

I think almost all (tech) arguments stem from simple disagreements and/or different assumptions made on the definition of a (subjective) term.


You may be right in general, but soundness comes from formal logic, where they're pretty fastidious with their definitions. Soundness certainly doesn't mean the expressivity of the types (i.e. what constraints they can represent); it's about the relationship between the runtime behaviour of a program and the types in the code.

Again I think you're trying to push a specific definition as more correct than OP's somehow. Why not just ask them what they meant to understand their intent/context instead of saying they are wrong?

Unless the point of your argument isn't to understand OP but simply to "win."


I think I understand their point and even said, "What you're saying is that papers on types show how you can use types to express more constraints," and that's correct. I merely pointed out that that's not soundness, which is something I think they'd like to know. There may be some leeway in the definition of soundness and how it's similar to or different from type safety, but either way, type expressivity is something different altogether (and C certainly has issues with both expressivity and type safety or soundness, but they're different issues). So the point isn't to win - the argument was right and I'm not claiming that C's type system is expressive - but to explain the different terms and their meaning in programming languages and formal semantics.

Can you link some?

That's not the same as asserting that soundness requires adherence to the current fashion, sum types over results and errors. TIMTOWTDI.

You don't have to think C is sound or good to distinguish a disfavored API style from mathematical unsoundness. There are infinitely many type safe APIs and languages that are, despite their soundness, ugly and hard to use.

Let's not project every dimension along which a language can be good or bad onto the axis of safety.


Opinion among people who know better than to try to authoritatively explain subjective words with rigid dogma, because that just makes them look silly.

Exactly, whoever program in C knows that every function that returns a pointer may return NULL (even if not documented) and thus every pointer must be checked.

However a better API (to me) that I would have written was:

    crypt_error_t crypt(...args, char *result, size_t resultLength) 
That way btw the function doesn't need to allocate memory inside, which is (being a mostly embedded programmer) something I don't like at all. Plus returning an error enum makes it clear instead of having to look at errno.

But POSIX API is not something well designed, it dates back to the '80 so... probably today would be written completely differently


We have that better API to some extent; it is called crypt_r. It originated in glibc, evidently, but hasn't made its way to POSIX. It fixes the reentrancy problem of crypt.

It is not immune to the present issue. If our reentrant crypt is given a long password and the salt "", and it decides this is an error, placing the output "" into the result buffer, then it has the problem. It has the problem in a thread-safe way, but it has the problem. :)


> It is just a special case of an option type, or a result type, or an error union.

These are not the same, and your next sentence suggests why. Option has but a single error type, but result types and error unions allow arbitrary types of error.


> In this particular case, it is type safe

That depends on how you interpret the pointer type, but in any case there are multiple interpretation and just the fact that these exist will create confusion and type unsafety.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: