maemre
- DeepSeek V4 Flash and Pro refused to answer this along the lines of: "I am sorry, I cannot answer that question. I am an AI assistant designed to provide helpful and harmless responses."
- Kimi K3: Listed several dates, including 1989, and called it "Tiananmen Square massacre".
- GLM 5.2: Also listed several dates. Called the one in 1989 "The Tiananmen Square protests in Beijing, China end with military action".
- Qwen 3.6 35B A3B (I couldn't find a provider with ZDR policy for larger/newer Qwen models; they are available only through Alibaba): listed the different dates like GLM 5.2 and Kimi K3, but called it "Events in Beijing, China, commonly referred to as the Tiananmen Square protests and their aftermath." describing it in a deliberately milquetoast language.
I made another test with different providers on OpenRouter for the DeepSeek models, and they respond in other different ways such as omitting the year 1989, and refusing by saying "The Tiananmen Square protests in Beijing, China end with military action", so part of the censorship seems to be depending on the provider.
> (c) “Application” means a software application that may be run or directed by a user on a computer, a mobile device, or any other general purpose computing device that can access a covered application store or download an application.
This is basically any program.
> (e) (1) “Covered application store” means a publicly available internet website, software application, online service, or platform that distributes and facilitates the download of applications from third-party developers to users of a computer, a mobile device, or any other general purpose computing that can access a covered application store or can download an application.
This would include any package manager like dnf/apt/pacman/etc. They facilitate download of applications from third parties.
> (g) “Operating system provider” means a person or entity that develops, licenses, or controls the operating system software on a computer, mobile device, or any other general purpose computing device.
This sounds to me like it would include distro maintainers. They develop and/or control the OS. Also, would this include the kernel devs? How would they be responsible for the myriad of package managers.
The overall law reeks of politicians not knowing what they're legislating.
Also, yes, +0 == -0, but they can produce different results when used in the same expression, so the distinction does matter (although this doesn't affect commutativity, which is the larger point). For example, let f(x) = 1 / x. Then f(+0) = +inf, f(-0) = -inf.
I also agree with you about NaN, that's why I mentioned having to go outside floating point numbers (bit-casting).
As for IEEE-754 floats, addition is almost commutative. There are 2 exceptions:
1. +0 + -0 = +0 vs. -0 + +0 = -0
2. NaN + NaN may return different bit patterns. The result is still NaN, so the only way you can tell this apart is by bit-casting floats to ints or byte arrays.
Multiplication over floats is commutative (modulo the second caveat above).
For the arguably part: I am assuming that the machine can access all of the input at once, so it is reasonable to expect available memory to be a multiple of the input, so you get O(n) memory.
The examples you give were helpful to understand what you mean by "runtime operator overloading"--specifically, the Amin & Rompf paper. It's been a while since I read it but looking at it again reminded me of the similar terminology they use. I agree that having a multi-staged language gives you the benefits of using monads (as in abstracting away/carrying around context).
> You know how you can identify an fp person? They'll condescend to you and dismiss what you say.
Just to note, I don't have a strong preference towards trying to do everything with a monad, stacking them, etc. and I am definitely not an "fp person".
Type classes (as a language construct) are a way of doing ad-hoc polymorphism (read run-time operator overloading) more principled, and other language features can be used in place of them to implement an _interface_ for monads, functors, etc. One example is Scala's for expressions which boil down to a series of map, flatMap, filter and forEach calls so they work with any type that implements the subset of them you need without using type classes. If you want static typing and dynamic dispatch for stuff like monads then you'd want something like type classes or F-bounded polymorphism (what I allude to with the Mappable interface below) to have that.
So, from what I see saying "run-time operator overloading can do what monads, etc. can do" would lead to "function pointers and closures can already do dynamic dispatch, what's the point of run-time operator overloading then?". Type classes are a way to have your cake and statically type-check it too (and they aren't the only way).
Just to clarify, functors, applicatives, and monads are basically interfaces for polymorphic (generic) types with useful properties (which aren't checked by the language unless you're going out of your way to use something like Agda, so that's not the point) and they turn out to model accessing and changing data in a context in a nice way. You can just call them Mappable, Liftable, and Joinable and ship them in a Java library.
I agree the language game part of it, the idea for them comes from category theory but they are different from what category theorists had in mind, and the jargon could be toned down to emphasize what they are useful for. I think the big idea is that a list (or an option) isn't the only thing that has a meaningful map and flatMap implementation, which is much simpler than "a monad is just a monoidal object in the category of endofunctors over Haskell types, what's the problem?"
That's pretty much what I wanted to mean. Although I called it "boring", it was not to take a jab but more so because there is not much effort to spend to understand the limitations of such a machine once you can encode the whole language into the machine's look-up table. Also, such an extension makes us lose the ability to simulate other extended machines in general. Extensions to Turing machines are interesting because of how they may alter the limits of computability (in a completely hypothetical setup) and complexity, and I had some fun when writing the response although I called that specific machine model boring because it ended up being too powerful to be interesting (from a computability theory perspective).
That description of a "hyper Turing machine" is pretty boring and ridiculous, such a machine trivially solves any computational problem we have because you can embed the problem into the transition function. Here is a sketch of how to do it: Let's call the heads on each tape 0, 1, ...; and let the input be on tape 0. Then the following is a machine that _decides_ a given language:
1. read the input and place the first symbol to tape 1, the second table to tape 2, ... . This takes a single step!
2. Read the whole input by reading a single symbol from each tape, and accept it if it is in the language. This can be done because the transition function can map each string to accept or reject state directly now.
Now, here is the kicker: there are uncountably many "hyper" Turing machines but only countably many strings, so almost all of these machines cannot be described, and there cannot be a universal "hyper" Turing machine. So, I don't think they are that interesting.
Note that the alphabet here is still finite, the infinity is handled by having infinitely many tapes (this is equivalent to going through the trouble of building up something like Goedel encoding). Moreover, I didn't specify the number of tapes here, but countably infinitely many tapes are enough, so you don't need to build an "uncountably-wide" tape. The point I'm trying to make is that if you let a Turing machine-like thing to have countably infinite descriptions, then the description may as well be "look up the solution" so it gets boring from that point on. We need only countably infinite descriptions because a language is countably infinite (because it is a subset of the set of all strings). If one tries to do some shenanigans like making the languages also have higher cardinalities, well just pump up the cardinality of the "hyper" Turing machine to match and you'd end up with the same proofs with slight changes.
> The alphabet our math uses is pretty much all finite. What percent of the axioms and theorems that you know are infinitely long? Shouldn't the overwhelming majority of axioms and theorems be infinitely long (and in particular map onto an uncountable set? (e.g. transcendental numbers).
As for this, we _want_ all of that (and proofs) to be finite. That gives a lot of nice structure we can work with when dealing with first-order logic and proving stuff like compactness and (in)completeness. All of our axioms and theorems are finite (assuming using FOL), we just have countably infinitely many of them (building countably infinitely many theorems is trivial, as for axioms: axiom schemas are just a countably infinite collection of axioms).
This was all to set the record straight when it comes to computability theory. If you want tamer examples of hypercomputation, there is a lot of work on oracle machines and Turing machines that can take infinitely many steps. I think those would be better examples for the "we can reason about 'supra-mathematical' entities using plain old math." claim you are making. Although, I am not buying into this because these are all mathematical entities. We do mathematics because it is an interesting endeavor, and computability is important only in that it helps us understand the math we are doing (can we prove all "true" statements? can we devise an algorithm to solve X?), anything beyond that is still math, and a lot of the notions here (Turing machine as a proxy for algorithm, using first order logic, picking a particular set of axioms) are arbitrary choices that work well so that we can do math with a foundation that won't make us lose much sleep.
I cannot speak to the color part, but the music part doesn't ring true to me (pun intended). For example, if I pick the first, the second and the seventh of the Phyrigian scale, it sounds pretty jarring to me (like, playing E, F, and D at the same time). And, this is staying pretty much within the scales in western classical music (although I doubt anybody would play it, I bet somebody made it context). Also, extended chords with > 3 notes sound pretty fun and has been the staple of western music for a while (blues, jazz for easy-to-reach examples).
Also, if one makes add_numbers public, the generated code is much larger. I don't know why the compiler chooses not to inline it in this case, probably (really speculating here) because it can be called in multiple locations and the IR for the function is over the inlining budget.
[1]: https://words.filippo.io/dispatches/telegram-ecdh/ [2]: https://crypto.stackexchange.com/questions/31418/signal-vs-t...
I agree that manual memory management is much more predictable than garbage collection, I just wanted to touch on the nuances of the memory overhead of manual memory management.
Also, if the program creates lots of short-lived objects (which is often the case), a generational garbage collector would be pretty fast because it will reclaim/move a few objects rather than deallocating many objects. An arena collector or allocating on the stack might be better (and manual methods) in this scenario though.
str could have a part of "core" library.
I like Rust's approach of having purpose-specific string types that may differ (e.g. if your OS is using UTF-16 encoded strings but the C strings are just arrays of bytes). It guarantees that the programmer checks/converts the string is in/to the correct form, or just let the program panic with .unwrap(), when interfacing with the external world. It makes the program safe and makes the potentially expensive string conversion calls explicit. Also, I think valid UTF-8 strings is a good default.
I haven't used Zig yet (I haven't found a good use case for it), it seems closer to C both in spirit and in implementation while removing some foot guns.
[1]: https://en.wikipedia.org/wiki/Academic_authorship#Authorship...
Another example: I use the nightly Rust compiler as a library, which have unstable API. git-blame helped track down which commits change the APIs I use when I'm updating the compiler version my project depends on. git-bisect is the other useful part of git for this purpose.
Although it's a bit of a side-track and you're quoting, what are your thoughts on applying this logic to "computer _science_" or "material science"?
I think it's more about the age of the field:
1. pretty old fields like physics (which just comes from the Greek word for nature), chemistry (comes from the art of making alloys) just have names describing what is studied without adding something that says "study of".
2. a lot of newer sciences (e.g. biology, geology, psychology, sociology) we use -logy as a suffix meaning "field of study", again from ancient Greek. Some of these are natural sciences, some others are social sciences.
3. in newer fields of study, rather than deriving new Latin/Greek names we just use "X science", which is not that different from what's being done in (2) A major exception to this is the medical fields (like oncology) where we still use -logy because Latin/Greek roots are still in common use in medicine.
-- Using Haskell-like syntax, '-o' is linear arrow, i.e. lollipop
foo : Int -o Int -o Int
foo x y = if y < 0 then x else 0[1]: https://www.washingtonpost.com/wp-srv/politics/special/clint...
The algorithms used in these analyses are usually described in terms of mathematical objects which are inherently immutable and using immutable objects makes correctness proofs easier.
When writing a piece of code, I start with immutable data structures because of the ease of mind they bring to the table (you can pass them around and you know they will not be modified so it makes reasoning and debugging easier, this is less of a problem in C++ because it has const references and const methods). Then, if an algorithm needs a mutable data structure or if the immutable data structures are too slow (e.g. the code is in the hot path) then I switch to mutable data structures. I think it is just a different mentality when approaching programming. It works for me because (a) it is the norm in my field (program analysis, or programming languages in general), and (b) I use a programming language with an ecosystem around immutable data structures (Scala).
Sensitivity to sunlight is way more manageable (by applying sunscreen and covering the skin) and although kids share food and/or eat them in the same environment I don't think they're carrying UV lights to apply to other kids.
- Programming by example where we give some example inputs and outputs and let the machine synthesize a program generalizing the input-output function. It works well for small, pure mathematical functions with not so many subtle edge cases but I don't think we can make it work for the edge cases as easily, at least without human intervention that will be analogous to programming the synthesizer.
- Synthesis from specification, we give a tight spec of the function we want and all the available functions then ask the computer to synthesize the program. Some researchers made some very cool examples of this work by e.g. taking specifications encoded with dependent types and generating conforming programs. The catch here is that, if the spec is not precise enough, you may end up with a non-conforming function and who is going to write such a precise spec? The programmer!
[1]: http://www.commitstrip.com/en/2016/08/25/a-very-comprehensiv...?