While this is trivially true, the question is if these remaining use cases that separate frontier models from non-frontier models bring in enough revenue to offset the massive spending of the frontier labs.
3,120 karma · joined December 27, 2011
While this is trivially true, the question is if these remaining use cases that separate frontier models from non-frontier models bring in enough revenue to offset the massive spending of the frontier labs.
The European Council does nominate the candidate and infamously in 2019 overrode the informally agreed on spitzenkandidaten process, by which the nominee of the political group (EU Parliament equivalent of parties) with the most seats should have gotten the nomination.
That said, the EU Parliament is not bound by the nomination. It can very obviously reject any candidate it doesn't like, though of course the dynamics of candidate selection are heavily influenced by the European Council's nomination power.
But yes, there's nothing per se undemocratic about it and I'm a bit bewildered by people asking for direct election of the President rather than cleaning up the existing process, given that most EU member states elect their heads of government indirectly.
1. Identifying the cause of poor performance. 2. Implementation. 3. Architectural impact (performance is a classic case of a cross-cutting concern)
(I am specifically leaving out the case of realtime systems, hard or soft, where additional factors come into play.)
But the article seems to focus entirely on the second aspect, while largely ignoring the other two.
Most performance bugs are not difficult to fix [1, 2], but can sometimes be hard to identify. Implementation effort is not the driving limitation in those cases.
Conversely, other performance improvements may affect the overall design, e.g. 27% of all bugs identified in [3].
Having an obvious, self-contained optimization target with a benchmark where algorithmic optimization within a module is also the key problem seems to be the exception, not the rule.
Also, not all performance issues are created equal. Many have trivial cost.
In contrast, some of the most challenging performance issues are the ones that affect the design and architecture of the system. After all, the hard part of software engineering is not writing a small, self-contained application. It's managing system complexity, while maintaining (in the words of Fred Brooks) conceptual integrity. Fixing performance issues is at least in this regard not fundamentally different from fixing other software defects.
Unfortunately, this is an area that is also full of trade-offs, such as performance vs. architectural simplicity, or performance in one part of the system vs. performance in another part, all of which requires judgement.
For example, you may need to bypass an abstraction boundary or reorganize abstraction boundaries to improve performance. Or you may have to special-case something while keeping duplicated code at a minimum and easy to maintain.
This is not to say that agents cannot help here, too. In fact, agents can be very helpful at e.g. identifying bottlenecks that are not directly visible in a profiler or can be used quickly do comparative evaluations of the various options for an architectural change. But solving these issues is not, like with the regex example in the article, about hillclimbing towards better performance, but involves a combination of puzzle-solving and design skill, IMHO.
And finally, even a self-contained algorithmic improvement may come with an increased maintenance burden, especially around edge cases and through increased code complexity.
[1] Jin, Guoliang & Song, Linhai & Shi, Xiaoming & Scherpelz, Joel & Lu, Shan. (2012). Understanding and Detecting Real-World Performance Bugs. Sigplan Notices - SIGPLAN. 47. 10.1145/2345156.2254075.
[2] Selakovic, Marija & Pradel, Michael. (2016). Performance issues and optimizations in JavaScript: an empirical study. 61-72. 10.1145/2884781.2884829.
[3] Zhao, Yutong & Xiao, Lu & Bondi, André & Chen, Bihuan & Liu, Yang. (2023). A Large-Scale Empirical Study of Real-Life Performance Issues in Open Source Projects. IEEE Transactions on Software Engineering. 49. 924-946. 10.1109/TSE.2022.3167628.
Not necessarily. Even near the frontier, we don't really have a total ordering of capabilities, but a partial order. And even frontier models make plenty of mistakes. Combined with the randomness inherent in searching large codebases for vulnerabilities or correctness issues, it is entirely plausible that even much weaker models (and GLM-5.2 isn't even weak) can stumble upon issues that stronger models missed.
My current hypothesis – for which I have only limited evidence, unfortunately – is that it is better to have multiple reasonably powerful (but not necessarily frontier) models looking for issues than just one very powerful one. And even then you're likely to miss out on some issues.
You have to consider that having an LLM scan for vulnerabilities is hardly infallible. It is a search guided by heuristics and given a large enough codebase, it is unlikely to identify all vulnerabilities.
Personally, I've had Fable 5, GPT 5.6 Sol, and GLM 5.2 all looking for correctness issues in an old abandoned WIP codebase of mine and all of them found some that the others hadn't discovered. Now, correctness issues aren't the same as vulnerabilities, but the same principle about using heuristics to find defects applies.
"(1) It is prohibited to possess, manufacture, make available on the market, import, or otherwise bring within the territory to which this Act applies, telecommunications equipment that, by its appearance, purports to be another object or is disguised as an object of everyday use and that, because of these circumstances or because of the way it functions, is particularly suited and intended to intercept, without that person’s knowledge, the non-publicly spoken words of another person or to record images of another person without that person’s knowledge."
IANAL, but this sounds like it's directly applicable.
Violations can be punished with up to two years in prison or a fine.
What makes this analysis tricky is disposable vs. discretionary income. The US clearly comes out on top when it comes to disposable income (labour is taxed too much in Germany compared to capital income and wealth).
The picture gets more complicated when you look at discretionary income, which also accounts for regular bills, such as rent, college tuition, out of pocket expenses for health care, childcare, and such. All the taxes you pay in Germany do also pay for something, after all. There is unfortunately very little data for this type of comparison.
I used to think that also, probably because FAANG salaries had skewed my perception, but after looking at the data, this does not seem to be actually true, at least not in general.
For example, Germany has a somewhat higher annual median gross salary for full-time employees than the US (PPP-adjusted, BLS/DESTATIS salary data, OECD PPP values).
Of course, this is the median salary. America absolutely offers higher salaries at the top end (and I mean much higher, often by a factor of 2-3 for highly qualified professionals, such as software engineers and doctors). But that also means correspondingly lower salaries at the low end. And of course, labor is taxed heavily in Germany, so discretionary/disposable income may look different in the end on a case-by-case basis.
It is still very worrying and the unfortunate result of a lot of things going wrong at the cabinet level.
This does not change with agents doing the coding. Coding agents make mistakes also. Not very often nowadays, but neither do competent human programmers. And without a methodology to keep problems in check your agentic code will also accumulate software defects over time and result in code that becomes less and less maintainable, because you have no mental model of the software.
Antirez is correct in pointing out that slop existed before we started to use LLMs for programming; I've worked with my share of really ugly legacy code myself. But the problems do not magically disappear in the LLM age, no matter how good your model is. They remain, as every model is ultimately a heuristic (albeit a very powerful one), and no heuristic is 100% accurate.
This does not mean that coding agents are useless; used correctly, they can be enormously powerful accelerators for the software development (and validation!) process, because combining your strengths with those of a modern LLM is generally a substantial net gain. But that must still happen as a part of an approach that results in maintainable software with minimal defects.
Personally, I primarily use agents as virtual pair programmers these days, which I find very useful. This is an iterative process with relatively small and contained changes, where "looking at the code" is just part and parcel of following along and building a mental model of the resulting piece of software.
No, this is exactly the definition I am talking about. The problem is that while theoretically you could work with Var(G)/Var(P) even if Cov(G, E) ≠ 0, studies are not designed to capture that.
In fact, the standard ACE model [1] used in twin studies explicitly assumes among other things that there is no gene-environment correlation. This means that it gets silently added to one or more of the ACE components; not because of any ill intentions, but simply because if you included covariance, the resulting system of equations would be underdetermined and could not be solved [2].
But to make matters worse, gene-environment correlation/interaction itself is disproportionately absorbed by the A and C components rather than E. All this can lead to inflated heritability estimates.
And to clarify, I am not making any pronunciations about how much relevance or magnitude that effect has; for all I know, this could in the end be a minor effect. My point here is that there is a lot of mathematical handwaving going on with very limited testability of the modeling.
[1] https://en.wikipedia.org/wiki/ACE_model
[2] If you want to be precise, you need to actually distinguish between gene-environment correlation and interaction and use P = G + E + (G x E), but that makes the system even more underdetermined, because now we have both Cov(G, E) and Var(G x E) to worry about.
The unintuitive part is that in quantitative genetics, heritability is defined in terms of variance in traits at the population level, not as the passing of traits from parents to offspring (that would be heredity [1]). Of course, I may have misinterpreted what you said in your OP when you cited the wiktionary definition of "[g]enetically transmissible from parent to offspring", and if so, I apologize, but at the time it seemed to me that you were talking about heredity.
> Uhm, no. That is exactly what I (and I think most people) would expect the answer to be.
What the article is talking about is that if you fix Var(E) = 0, then Var(P) = Var(G) in the standard heritability model, i.e. all phenotypic variance is explained entirely by genotypic variance (because in that model, Var(P) = Var(G) + Var(E)).
Fun fact (even if only tangentially unrelated): In Western countries, wearing glasses is a highly heritable trait, because wearing glasses is a strong proxy variable for refractive error [2], such as nearsightedness, which is highly heritable. It is often brought up as another example of how the quantitative genetics definition does not match conventional use of the word.
That said, there are plenty of critiques of this definition of heritability, and not just because it is different from what a layperson would expect it to mean.
For example, the way it is used also usually has a big problem in that the standard formula assumes that Cov(G, E) = 0 (or at least is negligible), whereas in practice that is not actually true [3, 4].
This definition of heritability is also mathematically flawed in that it assumes (without evidence) that P = G + E, or at least can be reasonably approximated this way. Given that human development is the result of a feedback loop involving genetic and environmental factors, one would expect a model closer to something like a Markov chain. Proposed justifications of a simple additive model as an approximation (e.g. via the central limit theorem for highly polygenic traits) have to my knowledge never been tested.
More recent genome-wide association studies [5] have actually shown a considerable gap between heritability estimates from genotype data and heritability estimates from twin studies, known as the "missing heritability problem".
[1] https://en.wikipedia.org/wiki/Heritability
[2] https://en.wikipedia.org/wiki/Genetic_variance
[3] https://en.wikipedia.org/wiki/Gene%E2%80%93environment_inter...
[4] https://en.wikipedia.org/wiki/Gene%E2%80%93environment_corre...
[5] https://en.wikipedia.org/wiki/Genome-wide_association_study
[1] https://www.europarl.europa.eu/legislative-train/
[2] https://www.europarl.europa.eu/legislative-train/theme-a-new...
Some git subcommands are implemented in these. git filter-branch is a shell script, git cvsimport is a Perl script, and git p4 (perforce interop) is a Python script. There are not too many left these days (git add -p/-i also used to call a Perl script), but they exist.
What specific example are you thinking of where additional power was handed to Brussels through an amendment of the treaties?
> That's in addition to the constant Commission push for more power...
If you are worried about the executive trying to expand its power (and something that should be kept in check), may I suggest that the US is not actually a great example right now for how to avoid that?
Actually, the EU has the same concept of enumerated powers (called "competences" in the case of the EU). They are listed in articles 2-6 TFEU [1]. You may argue over whether the EU has too many competences or (in some areas) too little, but it's the same principle. The EU cannot legislate outside areas where power has been expressly conferred to it by the treaties.
This is in fact one point of contention over the "chat control" legislation. It is supposed to be enacted under the "internal market" competence, but similar to the US commerce clause, there is a legal debate over whether that competence is actually sufficient to enable such legislation or whether it is legal cover for encroachment on competences reserved to the member states.
This would of course be up to the ECJ to decide, just as the US Suprement Court would have to decide if any given US federal legislation is covered by the commerce clause.
In addition, there is the Charter of Fundamental Rights, and the ECJ could also strike down EU legislation (as it has done before) if it violates the rights protected by the Charter.
[1] https://en.wikisource.org/wiki/Consolidated_version_of_the_T...
I'll also note that nothing here is per se undemocratic. Both the Parliament and the Council are made up of elected members. The members of the Council (as members of the national governments) are indirectly elected, but elected all the same. Direct election is not a requirement for a democracy (see election of the US president or the US Senate prior to the 17th amendment or the Senate of Canada right now).
That does not mean that there isn't plenty of valid criticism of the EU's current structure, but claiming that it is not "actually democratic" falls far short of a meaningful critique.
- First class, fully functional closures. - Non-abstract classes and methods are final by default. - Named parameters. - Easy to write iterators via sequence { ... } - First class support for unsigned types.
In addition, there are plenty of cases where memory usage is unbounded or excessive, not because of allocator behavior, but because of programming mistakes. In fact, memory can sometimes blow up just because of large user inputs and very few systems are prepared for properly handling OOM conditions that happen legitimately.
Case in point: Both CRuby and Apple's JavaScriptCore have garbage collectors that use conservative stack scanning and are widely used in production systems without the world ending.
That said, you're probably not going to use conservative stack scanning because of collection speed alone. There are other trade-offs between conservative stack scanning and precise stack scanning that weigh more heavily.
I'll add the caveat that I would be very cautious about using a conservative GC on 32-bit systems, but on 64-bit systems this is about as much of a concern as memory fragmentation.
The actual functionality is then provided by the coroutine system, though a lot of the heavy lifting is done by the optimizer to eliminate all or most of the runtime overhead.
Personally, I see Kotlin as the closest thing to a statically typed Smalltalk that we have among major languages, and that's a major draw.
A key part here is that Kotlin closures are fully-featured equivalents of Smalltalk blocks (up to and including even non-local returns [1]), whereas in many other languages that falls short. Java does not allow mutation of local variables and Python restricts lambdas to normal expressions.
I find code whose behavior can be parameterized by code to be an essential feature of modern-day programming and this should be as frictionless as possible.
This is also a situation where syntax matters, and while it isn't quite as nice as Smalltalk, Kotlin's syntax (esp. with trailing closures) make such code as readable as possible in a brace-style language with minimal additional syntactic noise.
In a similar vein, the functionality of Smalltalk's cascades is offered through scope functions [2], especially `.run {}`.
But ultimately, fully-featured closures (and the fact that they are widely used in the standard library) power a lot of the things that people seem to like about Kotlin.
That does not mean that there aren't downsides. The limitations of running on the JVM are one (e.g. while Kotlin has workarounds for the JVM's type erasure, they're still workarounds), and then Gradle is arguably Kotlin's weakest point (which apparently even JetBrains are seeing, given their investment in Amper).
That said, personally I'd say Kotlin's static typing and performance would be the primary reasons for me to reach for Kotlin over Python, not necessarily expressiveness. Type annotations in Python + mypy etc. just aren't the same experience, and writing performance-sensitive code in Python can be very tricky/hacky when you can't delegate the hot paths to numpy or other existing C/C++/Rust libraries.
Conversely, Python often has a leg up when it comes to fast prototyping and scripting, even with Kotlin Worksheets in IntelliJ IDEA and with kscript.
[1] Which, to be clear, are a nice-to-have thing, not essential, but still impressive that even that was covered, when previously Ruby was the only major language I know of that did it.
sequence { for (x in 0..<10) for (y in 0..<10) yield(x*y) }.toList()
Now, technically, Kotlin doesn't have list comprehensions, only the equivalent of generator expressions in Python, so you have to tack an extra `.toList()` on at the end if you want a list, but you can write pretty much any for comprehension in Python in a similar way in Kotlin.On the other hand, you're not limited to for loops/ifs inside such a generator, but can use fairly arbitrary control flow.
Am I missing something here?
$ cat fib.kts
fun fib() = sequence {
var a = 1; var b = 1
while (true) {
yield(a)
a = b.also { b += a }
}
}
println(fib().take(10).joinToString(" -> "))
println(fib().first { it >= 50 })
$ kotlin fib.kts
1 -> 1 -> 2 -> 3 -> 5 -> 8 -> 13 -> 21 -> 34 -> 55
55
Of course, yield() is a function in Kotlin, not a keyword, but the same functionality is there.I didn't assume you were. My note about it being a good paper was just a general "this is worth reading" recommendation.
> "Can handle" is quite the hedge. You "can" walk across the continent too, but at what cost?
It's not a hedge. You claimed that (tracing) GC can handle cycles, while RC was "the opposite", which I read to mean that you believe it cannot.
While we are at it, let's go through the basics of trial deletion.
Trial deletion first looks at possible candidates for objects involved in a cycle (in the original algorithm, those were objects whose RC got decremented without reaching zero). Then, you do a recursive decrement of their children's (and their children's children's, and so forth) reference counts.
Unlike with regular reference counting decrements, you visit children even if the reference count doesn't reach zero. The net result is that reference counts are reduced only along internal paths, but that objects that are still reachable from external paths have reference counts > 0 after that.
Thus, any object with a reference count of zero after this step must be part of an internal cycle and can be deleted. All other objects have their original reference counts restored.
Because trial deletion operates on reference counts differently, it's not something that you can easily implement as a library, which is why you don't see it much except when a language implementation chooses to go with reference counting over a tracing GC.
> You're saying Python uses RC to handle reference cycles, and doesn't need a GC for that? If so please ask them to update the documentation, because right now it specifically says "you can disable the collector if you are sure your program does not create reference cycles". https://docs.python.org/3/library/gc.html
This is a terminology thing. Python uses a variant (generational) trial deletion approach [1]. It's not a traditional tracing GC, and it's also not inaccurate, because GC can mean more than using a traditional tracing GC.
> Nobody said "real time". I just said "hard guarantee".
I was not sure what you meant, so I answered both, as you may have noticed.
[1] https://github.com/python/cpython/blob/796b3fb28057948ea5b98...
Second, what you seem to consider to be fundamental characteristics of tracing GC and RC is not in fact so fundamental.
For starters, RC absolutely can handle cycles (e.g. through trial deletion). Such implementations may be difficult or impossible to implement as pure library solutions, but there is nothing that says it can't be done. The most prominent example of a programming language that uses such an approach is probably Python.
Nor does the claim that tracing GC cannot provide hard performance guarantees in the general case (while RC does) hold up under closer examination. Leaving aside the problem that it's already non-trivial to provide hard real time performance guarantees for malloc()/free() and ignoring the issue of cascading deletions, it doesn't hold under the more relaxed assumptions discussed downthread.
For starters, we have such predictability only for the single-threaded case, not for arbitrary multi-threaded situations. And even in the single-threaded case, there are real use cases where predicting performance becomes functionally intractable. Examples are implementations of binary decision diagrams or certain persistent data structures, where the presence of shared subgraphs of arbitrary size make predicting performance of individual deallocations impractical.
In contrast, in the single-threaded case we can absolutely bound individual operations of a tracing GC by either a constant or (in the case of arbitrarily sized allocations) make them linear in the number of bytes allocated (e.g. Baker's treadmill).
What is true is that in the absence of cycles, (naive) reference counting will free memory at the earliest opportunity, which is not something we can say for tracing GC.