HackerTrans
TopNewTrendsCommentsPastAskShowJobs

maemre

no profile record

comments

maemre
·5 tháng trước·discuss
The law is written so broadly, I think it applies to them already: https://leginfo.legislature.ca.gov/faces/billTextClient.xhtm...

> (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.
maemre
·3 năm trước·discuss
You're right, producing +/- 0 depends on the rounding mode and it is commutative, I forgot about that completely. I edited my comment to fix that claim.

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).
maemre
·3 năm trước·discuss
Integer overflows/underflows don't affect commutativity, unless you refer to undefined behavior, which is...undefined and found only in C and C++ among common languages. 2's complement integer arithmetic is commutative for both addition and multiplication.

Thanks to BeetleB for pointing out that addition in IEEE floats is indeed commutative (I originally claimed "+0 + -0 = +0 vs. -0 + +0 = -0" which is incorrect).

As for IEEE-754 floats, addition is commutative as long as you don't care about exact bit patterns:

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 also commutative modulo the caveat above.
maemre
·3 năm trước·discuss
Space complexity helps characterize this: real-world computers can (arguably) emulate a linear-bounded automaton, so anything in DSPACE(O(n)) is fair game if you can wait long enough.

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.
maemre
·3 năm trước·discuss
I misinterpreted what you said then, sorry about that.

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".
maemre
·3 năm trước·discuss
I think this is more in the lines of mixing up concepts (the language features that enable implementing functors etc. in Haskell with functors as used in programming). I liked the JavaScript monad example in the grandparent, even if it was underwhelming. It is similar to Douglas Crockford's presentation of monads (using JavaScript, but with more interesting examples like promises).

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?"
maemre
·4 năm trước·discuss
I like this reading of the story a lot (although I didn't read it this way when I read the book originally). It reminds me of how Camus approaches to making peace with the absurd: recognizing the absurd and creating a personal meaning in order to get free from the meaninglessness (I might be totally off base with this interpretation of Camus).
maemre
·4 năm trước·discuss
> even if you made an alphabet (strings whose characters had decimal places or something) that was bigger, then it would still be kinda boring cuz the hyper hyper turing machine would still be a lookup table (though maybe even the machine in my example could still just be a lookup table for an uncountably large language on account of having uncountably many tapes/heads).

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).
maemre
·4 năm trước·discuss
I am nerd-sniped with the computability claims here. The last paragraph sums up what I think about what you wrote more broadly.

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.
maemre
·4 năm trước·discuss
> Pick any three musical notes, even on a microtonal scale, and they form a pleasing chord.

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).
maemre
·4 năm trước·discuss
I think the answer is a combination of both and inlining. With Rc, the compiler can inline the reference count increment/decrements as well as the non-public function add_numbers and the surrounding code is simple enough that it can do dead code elimination as well as other optimizations to remove the unobservable behavior. If you switch to use Arc (which is a better equivalent of shared_ptr as it also does locking/unlocking), the generated code is more comparable (funnily enough, part of the code for drop in Arc is deliberately not inlined so it prevents this optimization [1]).

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://doc.rust-lang.org/src/alloc/sync.rs.html#1088