Threads for jado

  1. 4

    One reason I like parametric polymorphism so much is that it needs neither effort to use it nor guidelines for using it. :)

    1. 2

      nor guidelines for using it

      Everything in programming gets guidelines eventually…

      1. 5

        Parametric polymorphism is a type system feature that allows functions not to require any specific type if that type is irrelevant.

        There’s definitely a class of use cases that require knowing the type or interface of values and there are only two options there: code duplication or some form of ad hoc polymorphism (generics, interfaces, ML functors…). However, there’re also lots of use cases where logic for different types is exactly the same.

        For example, most collections (lists, trees etc.) don’t care about the values they contain.

        Consider this function for calculating the length of a linked list (pseudocode):

        function length list =
          case list of
           | [] → 0
           | (head : tail) → 1 + (length tail)
        

        The head variable—actual item—is not used by that function at all and could be omitted. If the language knows that and can express a “list of anything” type, both length [1, 2, 3] and length ["foo", "bar", "baz"] will type check. The type of such function would be like length : α list→int where α is a type variable that can be substituted for anything.

        The cost of this kind of polymorphism is always zero, both at compile time and at execution time, so there are no possible reasons to force a naturally polymorphic function to a concrete type.

        1. 5

          The cost of this kind of polymorphism is always zero

          Depending on the implementation, the compiler may have to do monomorphization, which can take a lot more time (see C++ template compile times). That would also expand the size of the final binary, which could result in more L1 cache misses (depending on the usage of the function). Everything has a cost!

          1. 1

            The cost of monomorphization is identical to the cost of having a separate implementation for each type — since that’s what it is.

    1. 3

      $freeTime = Finishing Categories for Quantum Theory and starting Deep Learning on Graphs. It always seems like there are other variables in my life that take priority over the things I really want to learn.

      $school = I’m taking a graduate course in Deep Learning which has been very useful. My prof heavily focuses on the math (since he’s a stats phd), making us do things like train a neural network by hand on tests. I’ve seen a lot of people (read: randos on twitter) who say you “don’t need the math” to learn DL, but I find it very helpful in building up an intuition.

      $work = Somehow I managed to make a 40,000+ line PR and I also somehow convinced management that this was useful enough to go into production soon. After 9 months of parallel development, I am probably going to merge it in the next week or two. Pray for me.

      1. 2

        Going to repeat the author’s praise of ggplot2 here - it is a very simple library to use! You can stack layers on top of each other and generally manipulate your graph to display pretty complex data. My prof last semester used it heavily for ML graphs, and even made a fork for animated / web hosted plots.

        The Python adaptation is also simple to use: https://plotnine.readthedocs.io/en/stable/

        1. 1

          something something use a language that mitigates this class of errors something something

          1. 2

            I’ve never understood this question. It seems very obvious to me that software engineering is solving engineering problems in the domain of software. You could use some equivalent definitions, but I think the divide between casual software development and professional software engineering is bigger than most people think.

            I can teach anyone how to write a TCP server that connects to a PostgreSQL database. They could probably do it in an hour or two. Having them scale that server to 200,000 concurrent users is an entirely different problem.

            Much of the math that mechanical engineers use is continuous math. This is where we work over a continuous domain, like real numbers. Things like calculus, trigonometry, and differential equations are in this category. … In software, we don’t use these things, leading to the conception that we don’t use math. But we actually use discrete math, where we deal exclusively with non-continuous numbers.

            No, you don’t use continuous math in your software. Plenty of people do! Do any rendering and you’ll at the least be doing a good chunk of linear algebra.

            Software development is all about the unknown. The production process for software is trivially easy—just copy a disk or CD. The software engineering metaphor fails because we understand production, a mechanical task, much better than we understand design, an intellectual task. - Software Craftsmanship

            This screams ignorance. Packaging software is far from trivial. I’m sure the book has more context, but the ability to copy/paste our final files doesn’t contradict software engineering being a field of engineering. Have you ever copied an executable from a Windows machine to a macOS machine and had it run fine?

            Most people don’t consider a website “engineered”.

            If that website is serving a country’s worth of people, you can confidently assume there were engineering problems being solved.

            1. 1

              I primarily work in C# so I use Visual Studio. When Jetbrains Rider was in beta I tried it out just out of curiosity (I find it hard to be fanatical about microsoft products, both vs and vscode have glaring flaws in my opinion). It was amazing. The price tag was the only thing that has stopped me getting a license. I will probably fork out for it at some point though.

              1. 2

                If you’re a student you can get (almost?) all Jetbrains IDEs for free!

                1. 1

                  Great, and then when you graduate you have to migrate everything to some other IDE. Not really worth the effort. Either way it does not matter to me, I am not a student. I can get almost all Jetbrains IDEs for like 10k a year.

                  If you are a billionaire you can get pretty much any software your want for an insignificant amount of money.

                  If you are a unicorn you can don’t really need software.

                  1. 3

                    What a strange comment.

                    The “All Products Pack” is $249 for yr1, $199 in yr2, and $149/yr onwards. It includes a perpetual fallback license (you keep what you’ve got when you cancel). Not $10k.

                    You don’t need to be a billionaire to afford that. Most software developers can. And those that can’t almost all fall into categories of people Jetbrains will give a discount to.

                    You’d think software developers would have more sympathy with having to charge money for software but every discussion of Jetbrains (whose products I don’t use) seems to have one person complaining about the totally reasonable price.

                    1. 2

                      Sorry for this, I just guessed based on some vague memory of what individual products cost. I guessed there might be an all products pack but I didn’t check it. Having said that I was not trying to criticise jetbrains for charging money, more I was frustrated with the post I replied to which felt like an advertisement and was totally not helpful to me. I am sorry for this too however, as the comment was likely directed at readers in general and not at me directly. I guess I was just having a grumpy day.

                      1. 1

                        Don’t worry, we all have such days. Big of you to admit that. Cheers, mate.

              1. 13

                I think this vulnerability is getting a lot of recognition because of how ubiquitous the disdain is for these kinds of “features”. Every post I see repeats how plainly bad this idea is. I couldn’t imagine letting anything like this through a code review.

                My job is in the Minecraft modding space and we were notified of the issue immediately. I maintain our platform that boots Minecraft so I was coincidentally one of the first people to patch it. My “patch” being, like with most vulnerabilities of this caliber, ripping out the bad code completely. I think that was a much better patch than the original one for 2.15.0 (which I saw in 2.15.0-rc2, the latest rc tagged on GitHub, when the vulnerability dropped) and better than the additional mitigations for 2.16.0. No way I’m letting a logger have network access, or even code that could access a network.

                1. 2

                  What features are you talking about? Asking because I don’t program in Java so don’t know.

                  1. 3

                    https://issues.apache.org/jira/browse/LOG4J2-313 is the original ticket.

                    JNDI is a Java API abstraction over any kind of lookup services (DNS, LDAP, Consul etc.). The ticket authors wanted to look up certain parts of the logging config from such a service. I don’t think it’s so impossible to imagine how such functionality would be desired to quickly tweak a certain logging parameter across multiple microservices, for example. But yes, enabling it by default was a really bad choice.

                1. 7

                  I feel like most of the code reviews I’ve been doing recently include me saying “Instead of return null values here, we can make this an Optional so users of this method know they have to handle the empty case”. Sometimes my coworkers grumble but the amount of NPEs we’ve had in production has definitely gone down. Extra boilerplate up front saves time in the future!

                  1. 4

                    The good news is that “instead of returning a null value, make it Optional” is one and the same in Python: If the value can be None, then its type is already effectively Optional and should be marked as such (or equivalently, Variant[None, …]). I don’t think there exists anything to disagree about.

                    As for reviewing code when tradeoffs exist (such as in strongly typed languages, where Optional actually does something – it adds a machine word to the size of the type), I’m glad you say “can” and present it as a tip with a certain reason. In code review, “considerate” is more helpful than “holder of popular opinion”!

                  1. 5

                    Thinking about using this as an obfuscation technique in the future… I have really been liking the posts from netmeister.org. The writing is very welcoming and explores topics that don’t have much documentation.

                    1. 3

                      I’ve printed his entry and there are some neat tricks I learned, but ‘stage 3’, where, according to his comments, a bytecode interpreter is used, is still beyond my understanding. Also not sure why this helps, a bytecode interpreter sounds like a lot of overhead to me…

                      1. 3

                        The overhead of interpreting the bytecode is compensated by the bytecode instructions not taking up much memory and the interpreter using SIMD instructions to do the calculations.

                        Some comments that highlight the reasoning for this:

                        32 bytes of bytecode can be loaded from memory, interpreted, and have its output stored back into memory using just four machine instructions

                        the same CPU instruction [is used] to output digits from multiple different line numbers, because the bytecode is being interpreted in a SIMD way

                        Using bytecode also allows you to specialize / unroll individual parts of the total executed code, which you can see in the thirty_bytecode_lines subroutine.

                      1. 4

                        It looks like clang outputs this in an ELF metadata section (and this change was originally made by the PS4 team) which could be read by whoever is trying to run the program. I wonder if the best way for you to make your app the most portable™️ would be to provide many different versions using different max stack sizes.

                        quoting the linked article by Ariadne,

                        …or the developer fixes their program to behave correctly only for the Alpine case, and it remains silently broken on other platforms.

                        If I have to special case your platform, then your platform is the one making my app not portable. I’m all for platforms choosing what is best for them (macOS deprecating OpenGL caused many months of work for me) but

                        it is my opinion that if your program is crashing on Alpine, it is because your program is dependent on behavior that is not guaranteed to actually exist

                        is a bit of a stretch. It effectively was guaranteed by being the same for the majority of platforms, or at least the majority of Linux distributions. Is there a reason to change the “default” here? I can see how in some applications a smaller thread stack size could increase performance, but I would have assumed the default is every thread has the same stack space as the main thread. Maybe I’m a little too optimistic with how many threads people are spawning in their applications.

                        1. 5

                          This is beautifully presented! The diagram of half-precision floats communicates the internals super well. Are self driving cars using genetic algorithms in the real world and crashing into everything for a few generations? I would imagine they would take an unsupervised approach so you’re not required to have every kind of stop sign and car labeled.

                          1. 7

                            Thanks for the feedback! Yeah, I don’t think that the Genetic Algorithm would be a real-world solution for self-driving cars. I was using it in this side project just to get some intuition about how the algorithm works and to check whether the cars will actually evolve into something interesting or not.

                          1. 4

                            Because graduating with an undergraduate computer science degree doesn’t require mathematics at all. At least not so much that you can’t temporarily memorize some general mathematical techniques for an exam and forget it all the next day. They won’t be used outside of an exam setting; trust me.

                            I know every university is different, but for me I’ve had to take Calc 1, Calc 2, Discrete Math, Linear Algebra, & Set Theory. I don’t know of any friends at other schools who are doing CS and don’t have to do the “real math” mentioned in the article. I’ve never really understood the mindset of “CS doesn’t need Math” which, while true for Web Programming, doesn’t hold true once you reach advanced CS fields. Most of the Unsupervised Machine Learning course I’m taking now is understanding the linalg. Advanced CS definitely requires advanced math. That intersection is where all the fun CS topics are!

                            I’m looking at you proofs. But even proofs aren’t really mathematics. Students do proofs because instructors ask them to do proofs; they’re not actually proving anything novel.

                            This is an interesting take. Immediately I think “how can you prove novel things if you don’t intuitively understand previously proven things?” There is a part of me that believes if Software Engineers were forced to write F* we’d have fewer planes falling out of the sky.

                            Tangentially, the pictures shown in the article look like they’re straight out of my Algorithms textbook (notably not a math course but a CS course). While exploring various new avenues in math, specifically Homotopy Type Theory & Higher Category Theory, I think I’ve formed a better picture of what “math” really is. I wish the syntax was as easy to read as those pictures. Sadly mathematicians don’t write their math in pseudocode.

                            1. 2

                              I’ve attended advanced CS courses that required a ton of math. E.g.:

                              • Program analysis: Required Galois connections and other abstract algebra topics
                              • Computationally hard problems: Required good background in logic and discrete math
                              • Data logic: Required high order logic and term rewriting background
                              • Real-time systems: Required automata theory
                              • Numerical methods: Required real analysis and linear algebra
                              • NLP: Required a bit of type theory for understanding Montague grammars
                            1. 8

                              I’m not too convinced it has been misnamed. When referring to engineering with tools given to us by Computer Science, I’ve heard most people just say Software Engineering. Keeping “science” in the name highlights all of the (very much non-engineering) theoretical scientific parts of CS: automata theory, type theory, PLT, etc. that of course have their applications within Software Engineering (do Set Theory & Category Theory fit here? I usually throw them together with the “theoretical CS topics” I study).

                              1. 3

                                If anything, I think the discipline has been misnamed for the very opposite reason than what the author of the article suggests. There are of course exceptions, because that’s how language works, but I generally interpret “science” as describing a discipline that seeks to develop increasingly accurate models of empirical phenomena via experimentation. Those theoretical constructs you mention don’t require any reference to the empirical, because like any purely mathematical object, their development proceeds according to the implications and constraints of logic. Something like “computational mathematics” seems more apt as a descriptor of that line of study, and the study of how those objects inform the development of real systems of computers seems best described as “engineering,” a field of inquiry that’s clearly related but has distinct aims in terms of which kinds of investigation it prioritizes.

                                I wonder if the semantic ambiguities here might be due to some latent sense among practitioners that being an “applied” discipline makes that discipline lesser, which I think is an easier fiction to maintain when even the engineered artifacts of software seem to exist without recourse to the physical world (of course they do in practice, since some hardware needs to store and run that software, but it’s easy to pretend that that’s not the case).

                                1. 3

                                  The question of P and NP is, on its own, enough to justify the word “science”. We have only the barest idea of how to approach the problem mathematically, and most of our progress has been empirical. Quoting Aaronson:

                                  I like to joke that, if computer scientists had been physicists, we’d simply have declared P ≠ NP to be an observed law of Nature, analogous to the laws of thermodynamics. A Nobel Prize would even be given for the discovery of that law. (And in the unlikely event that someone later proved P = NP, a second Nobel Prize would be awarded for the law’s overthrow.)

                                  1. 1

                                    I dunno, man, that doesn’t feel very convincing. Asking earnestly: how is the question of P/NP (non-)equivalence as it stands now any different in that respect from the Poincaré conjecture before its having been proven? The latter spent a long time seeming intuitively true, bolstered by a number of exemplary spaces, but it was only by a process of deduction subject only to the constraints of logical inference that it was finally proven. It seems evident to me that, should any definitive answer concerning the relationship between P and NP ever be discovered, it will only ever be discovered in a similar way, only ever bound by logical constraints and not empirical ones. Aaronson’s position on the matter seems entirely consistent with that outlook, since I read his “joke” as precisely that: a joke. Computer scientists are clearly not physicists, and so the means by which they establish “laws” must necessarily differ. Computer “scientists,” then, are mathematicians after all, which is neither a benediction nor an indictment, just a statement of fact.

                                    1. 1

                                      The choice of algorithms and data structures for daily work, including everything we’ve ever built, would be influenced by the relationship between P and NP in ways which we haven’t yet discovered how to imagine. It’s also influenced by the relationship between P and BPP, which could alter when Monte Carlo algorithms would be useful. This is (a portion of) what makes it distinct from the other prize problems.

                                      I don’t have a list handy, but register allocation and concurrent scheduling are two common situations where a low-effort greedy algorithm empirically handles typical cases of NP-complete problems well. I would empirically point out that every backpack a human is carrying in the wild is an instance of a solved knapsack problem, despite all formal evidence suggesting that even average attempts to fill a backpack should be hard. This is worth investigating further.

                                      1. 1

                                        Sure, I don’t by any means reject the idea that resolving the question of P equaling NP or not would have many concrete ramifications, but my point is that I think its having many practical applications is orthogonal to the question of its epistemological nature: as a proposition, it has the possibility of being proven correct (or its negation does, depending), which is fundamentally not possible for theories that model physical phenomena.

                                        1. 1

                                          I will defer to Aaronson again for a serious survey. The takeaway I want to highlight is that computational complexity theory is interested not just in the relationships between P, NP, BPP, BQP, etc. but also in which complexity classes accurately describe which physical machines. Recall that quantum logic was created as a theory which explained why some empirical observations did not agree with classical physics; if this is science, then so is our description of the class NP in response to finding thousands of NP-complete problems in the wild. (And just like how quantum logic was required to justify the work which led to the observation of the Higgs boson, analysis of NP was required in order to formulate BQP, leading to quantum computers.)

                              1. 1

                                One of my favorite features of Koka is the Perceus reference counting that lets you write code in a functional, immutable style while maintaining performance by reusing unique references.

                                1. 1

                                  I just bought the HoTT book! I’m very excited to read it. There is a HoTT library for Coq and the Arend Theorem Prover by JetBrains which has HoTT built in for those that want something other than Agda.

                                  1. 1

                                    Tangentially related is an amazing optimization for virtual calls in Android ART 8.0 which devirtualizes calls if only one implementation exists (and then possible inlines it!). I’m unsure if OpenJDK has a similar optimization, but the space for optimizing JVM implementations is still very open.

                                    1. 2

                                      Single implementation devirtualisation has been standard practice for all Java JITs for all time - because of the “everything is virtual by default” decision at the core of the language.

                                      Even .NET does it despite virtual dispatch not being a default in the primary languages as there are enough high frequency calls that are technically overridable but are not overridden in practice.

                                    1. 1

                                      I wonder how this compares to XLA which uses the same LLVM NVPTX backend but also supports compiling to CPUs. On top of that, is it feasible to target GPUs other than Nvidia’s or is everything else really too slow to care about?

                                      1. 8

                                        It’s nice to see languages using QBE, and even better to see it’s still in slightly active development. I’m hoping for more projects like QBE to pop up, or for more languages to follow Zig’s footsteps and make LLVM an optional dependency by rewriting things for the language’s specific use, which I believe for Zig will help with cross compiling and is already helping with linking

                                        1. 1

                                          There are a lot of people theorizing that this is directly related to recent changes in the Minecraft codebase.

                                          For many people working in the Minecraft ecosystem, these changes are long overdue! The game has been stuck on an old build of Oracle JRE 8 for years to maintain compatibility with older systems. Many projects have already stated they’re upgrading to Java 11 (Paper, Velocity) for the coming Minecraft release.