- shoosee also: Odd Lots interviewed Jetson Leder-Luis about medicare and medicaid fraud (nov 2024): https://podcasts.apple.com/us/podcast/how-fraudsters-are-bil...
- I'm not an accountant either, that also makes sense.
If instead the exchange had been of real world money for N months of prepaid subscription, that was consumed after N months had passed, that'd be a little different but also presumably quite acceptable to accountants.
Suppose the exchange had been of real world money for N months of prepaid subscription credits that could be stored indefinitely and only consumed if the player chose to actively play during a month. That might turn into an accounting nightmare if those subscription credits didn't expire (maybe cannot recognise the revenue while they are unused, becomes liability on the balance sheet).
I wonder how the accounting rules work for stuff like Eve online where there is an game consumable item (PLEX) that when consumed extends your subscription, can be traded inside the game's economy, and can be purchased with real world money
- yes. see also this thread from 4 months ago discussing accounting for credits, in the context of 1 year expiry for anthropic credits
- Great writeup. Much of this is more about testing, how package dependencies are expressed and many-repo/singlerepo tradeoffs than "microservices"!
Maintaining and testing a codebase containing many external integrations ("Destinations") was one of the drivers behind the earlier decision to shatter into many repos, to isolate the impact of Destination-specific test suite failures caused because some tests were actually testing integration to external 3rd party services.
One way to think about that situation is in terms of packages, their dependency structure, how those dependencies are expressed (e.g. decoupled via versioned artefact releases, directly coupled via monorepo style source checkout), their rates of change, and the quality of their automated tests suites (high quality meaning the test suite runs really fast, tests only the thing it is meant to test, has low rates of false negatives and false positives, low quality meaning the opposite).
Their initial situation was one that rapidly becomes unworkable: a shared library package undergoing a high rate of change depended on by many Destination packages, each with low quality test suites, where the dependencies were expressed in a directly-coupled way by virtue of everything existing in a single repo.
There's a general principle here: multiple packages in a single repo with directly-coupled dependencies, where those packages have test suites with wildly varying levels of quality, quickly becomes a nightmare to maintain. The packages with low quality test suites that depend upon high quality rapidly changing shared packages generate spurious test failures that need to be triaged and slow down development. Maintainers of packages that depend upon rapidly changing shared package but do not have high quality test suites able to detect regressions may find their package frequently gets broken without anyone realising in time.
Their initial move solves this problem by shattering the single repo and trade directly-coupled dependencies with decoupled versioned dependencies, to decouple the rate of change of the shared package from the per Destination packages. That was an incremental improvement but added the complexity and overhead of maintaining multiple versions of the "shared" library and per-repo boilerplate, which grows over time as more Destinations are added or more changes are made to the shared library while deferring the work to upgrade and retest Destinations to use it.
Their later move was to reverse this, go back to directly-coupled dependencies, but instead improve the quality of their per-Destination test suites, particularly by introducing record/replay style testing of Destinations. Great move. This means that the test suite of each Destination is measuring "is the Destination package adhering to its contract in how it should integrate with the 3rd party API & integrate with the shared package?" without being conflated with testing stuff that's outside of the control of code in the repo (is the 3rd party service even up, etc).
- Suppose we were critiquing an article that was advocating the health benefits of black coffee consumption, say, we might raise eyebrows or immediately close the tab without further comment if a claim was not backed up by any supporting evidence (e.g. some peer reviewed article with clinical trials or longitudinal study and statistical analysis).
Ideally, for this kind of theorising we could devise testable falsifiable hypotheses, run experiments controlling for confounding factors (challenging, given microservices are _attempting_ to solve joint technical-orgchart problems), and learn from experiments to see if the data supports or rejects our various hypotheses. I.e. something resembling the scientific method.
Alas, it is clearly cost prohibitive to attempt such experiments to experimentally test the impacts of proposed rules for constraining enterprise-scale microservice (or macroservice) topologies.
The last enterprise project I worked on was roughly adding one new orchestration macroservice atop the existing mass of production macroservices. The budget to get that one service into production might have been around $25m. Maybe double that to account for supporting changes that also needed to be made across various existing services. Maybe double it again for coordination overhead, reqs work, integrated testing.
In a similar environment, maybe it'd cost $1b-$10b to run an experiment comparing different strategies for microservice topologies (i.e. actually designing and building two different variants of the overall system and operating them both for 5 years, measuring enough organisational and technical metrics, then trying to see if we could learn anything...).
Anyone know of any results or data from something resembling a scientific method applied to this topic?
- It'd also have been interesting to see some overall profiling data of the initial program & some discussion of which optimisations to investigate based on that profiling data.
When investigating performance issues its often very helpful to run with profiling instrumentation enabled and start by looking at some top-down "cumulative sum" profiler output to get a big picture view of which functions/phases are consuming most of the running time, to see where it may be worth spending some effort.
Getting familiar with linux's perf [1] tool is also helpful, both in terms of interpreting summary statistics from perf stat (instructions per cycle, page faults, cache misses, etc) that can give clues what to focus on, but also being able to use it to annotate source line by line with time spent.
I'm not familiar with rust, but e.g. the rustc compiler dev guide has a tutorial on how to profile rustc using perf [2]
[1] Brendan Gregg's Linux perf examples is an excellent place to start https://www.brendangregg.com/perf.html [2] https://rustc-dev-guide.rust-lang.org/profiling/with_perf.ht...
- 3 points
- > Rather than getting stuck in front-end minutiae, the tutorial goes straight to generating working assembly code, from very early on
Good summary.
I had no background in compilers or related theory but read Jack Crenshaw's Let's Build a Compiler tutorials some time ago. My main take away from reading half a dozen or so of these tutorials was that building a simple compiler for a toy language was a small project that was well within my grasp and ability, not a huge undertaking that required mastery of esoteric pre-requisites or a large amount of planning.
I got a lot of enjoyment messing about with toy compiler projects related to Brainfuck.
Why Brainfuck? It's a beautiful little toy language. Brainfuck has 8 instructions, each instruction is 1 character, so parsing reduces to getting a char and switching on it. I guess it depends on what you want to explore. If you want to focus on writing recursive descent parsers, not the best choice!
One initial project could be to compile (transpile) from Brainfuck source to C source. You can do this as a source to source compiler without any internal representation by transforming each Brainfuck operation to a corresponding C statement. Brainfuck is specified in terms of a single fixed length array of bytes, and a pointer - an index into that array - that can be moved around, and basic manipulations of the byte it is pointing it. So on the C side you need two variables: one for the array and a second, an index for the pointer.
A second project could be compiling from Brainfuck to assembly language, skipping C. You'd need to read a few tutorials/reference docs about your chosen assembly language and learn how to run the assembler to compile tiny assembly programs into native executables. You could explore some examples of what output assembly programs you get when you compile small Brainfuck programs to C and then compile those C programs to assembly. You could write a direct source to source compiler without an internal representation, where each Brainfuck operation is directly mapped to a snippet of assembly instructions. Once you've got this working, you can compile a Brainfuck program into an assembly program, and then use the usual toolchain to assemble that into a native executable and run it.
There's also lots of projects in another direction, treating Brainfuck as the target language. Imagine that your job is to write Brainfuck programs for a CPU that natively executes Brainfuck. Try writing a few tiny Brainfuck programs by hand and savour how trying to do almost anything involves solving horrible little puzzles. Maybe it'd be much easier to do your job if you, the Brainfuck programmer, didn't have to manually track which index of the array is used to store what. You could invent a higher level language supporting concepts like local variables, where you could add two local variables together and store the results in a third local variable! Maybe you could allow the programmer to define and call their own functions! Maybe you could support `if` blocks, comparisons! You could have a compiler that manages the book-keeping of memory allocation and mapping complex high level abstractions such as integer addition into native Brainfuck concepts of adding one to things and moving left or right. Projects in this direction let you explore more stuff about parsers (the input syntax for your higher level language is richer), internal representations, scopes and so on.
- i'd also recommend uthermal -- former pro sc2 player, he's got a really good attitude & makes a lot of entertaining videos
- hypothesis: expected upvotes = views of comment thread * probability your comment is read given someone reads the comment thread * probability of upvote given someone read your comment
If you make a "great" comment but the comment thread isn't popular, no/few upvotes
If you make a "great" comment in a really popular thread but it's buried down the comment tree where others are less likely to see it, no/few upvotes
Let's define by "great" comment we mean one that readers of that comment upvote at a high rate.
You'll likely get more votes by making a pretty good comment relatively early in a popular comment thread, at a time of the day when many people are reading HN, rather than an absolutely fantastic comment in some thread that hardly any one reads.
There's path dependence -- if there's two equally "great" comments contributed to a thread, and one is made 30 minutes earlier, it's likely that the earlier one accrues a bunch of votes and sub-threads, secures the best real estate at the top of the thread, and ends up with many more votes than the other one.
These may make it harder to identify if the content or topic is having much impact on the accrued votes.
Could perhaps normalise for that by adding metrics for the number of votes that the submission got, or the total number of votes of all comments in the thread, then see if that can explain some of the variation. Measuring the duration between when the comment thread opened and when the comment was posted could be interesting too.
i hope after enough corrections for topic popularity, time of day, how fast you commented, it becomes clear that your best topic is fire truck efficiency, and we can look forward to frequent comments about fire truck efficiency going forward
- "Using LLMs at Oxide" [0], as seen on the HN frontpage yesterday, had a bit to say about LLMs as writers
> LLM-generated prose undermines a social contract of sorts: absent LLMs, it is presumed that of the reader and the writer, it is the writer that has undertaken the greater intellectual exertion. (That is, it is more work to write than to read!) For the reader, this is important: should they struggle with an idea, they can reasonably assume that the writer themselves understands it — and it is the least a reader can do to labor to make sense of it.
> If, however, prose is LLM-generated, this social contract becomes ripped up: a reader cannot assume that the writer understands their ideas because they might not so much have read the product of the LLM that they tasked to write it. If one is lucky, these are LLM hallucinations: obviously wrong and quickly discarded. If one is unlucky, however, it will be a kind of LLM-induced cognitive dissonance: a puzzle in which pieces don’t fit because there is in fact no puzzle at all. This can leave a reader frustrated: why should they spend more time reading prose than the writer spent writing it?
- Separately from this study, here's an interesting opinion piece by John Ioannidis titled "The Challenge of Reforming Nutritional Epidemiologic Research", published in JAMA 2018:
https://statmodeling.stat.columbia.edu/wp-content/uploads/20...
via Andrew Gelman's blog: https://statmodeling.stat.columbia.edu/2019/01/26/article-po...> Assuming the meta-analyzed evidence from cohort > studies represents life span–long causal associations, for > a baseline life expectancy of 80 years, eating 12 hazelnuts > daily (1 oz) would prolong life by 12 years (ie, 1 year per > hazelnut), drinking 3 cups of coffee daily would achieve > a similar gain of 12 extra years, and eating a single man- > darin orange daily (80 g) would add 5 years of life. Con- > versely, consuming 1 egg daily would reduce life expec- > tancy by 6 years, and eating 2 slices of bacon (30 g) daily > would shorten life by a decade, an effect worse than > smoking. Could these results possibly be true? - I wondered how much of this is inflation -- after adjusting for CPI inflation, $160 in 2020 is worth $200 in today's dollars [$], so the price of that ddr4 kit is 10% higher in real terms.
- > Useless fake ones where if you accept you get a reminder of the rules.
Like phishing training, but for meeting attendance. Fail the test and accept a decoy meeting and you must complete a round of mandatory training in how to distinguish a useless meeting from one that is worth attending.
I wonder if enterprises would buy this? Phishing training companies make a living.
- Roll 2d6, sum result. Your CI migration target is:
2. migrate secret manager. Roll again 3. cloud build 4. gocd 5. jenkins 6. gitlab 7. github actions 8. bamboo 9. codepipeline 10. buildbot 11. team foundation server 12. migrate version control. Roll again - Jack Crenshaw's 1988-1995 series Let's Build a Compiler [1]
Graydon Hoare's 2002 talk `"One Day Compilers" or how I learned to stop worrying and love static metaprogramming` [2] (implements a compiler for a DSL that's a subset of makefile syntax in < 400 lines of code using ocaml toolchain)
edit: on second thoughts, aiming to ship a game in a novel _compiled_ language in a 7 day language+game jam is probably a lot more optimistic than aiming for an interpreted language.
- What is a minimal-ish programming language that could be used to express some interesting class of games?
It's easy to think of pathologically trivially useless "languages" that could "make a game". E.g. the single instruction language where the instruction P is defined to mean "execute a game of pong". Or a zero instruction language where the empty program is defined to mean "execute a game of pong".
Also easy to think of existing minimal programming languages that could technically be used to implement games. E.g. brainfuck is a beautifully minimal language with only 8 instructions, supporting character IO - so you could make a text based adventure game with it, but this would be unpleasant and there isn't anything about brainfuck that makes it suited to game dev.
Another idea could be to have a non Turing complete language where you declare data for entities etc to be executed by some game engine/runtime. E.g. it might be possible to define a language for declaring data & entities to express a few different but similar games (e.g. spanning pong --- breakout, or one specialised for simple card games, or so on).
- Service oriented architecture seems like a pretty good idea.
I've seen a few regrettable things at one job where they'd ended up shipping a microservice-y design but without much thought about service interfaces. One small example: team A owns a service that runs as an overnight job making customer specific recommendations that get written to a database, and then team B owns a service that surfaces these recommendations as a customer-facing app feature and directly reads from that database. It probably ended up that way as team A had the data scientists and team B had the app backend engineers for that feature and they had to ship something and no architect or senior engineer put their foot down about interfaces.
That'd be pretty reasonable design if team A and team B were the same team, so they could regard the database as internal with no way to access it without going through a service with a well defined interface. Failing that, it's hard to evolve the schema of the data model in the DB without a well defined interface you can use to decouple implementation changes from consumers and where the consuming team B have their own list of quarterly priorities.
Microservices & alternatives aren't really properties of the technical system in isolation, they also depend on the org chart & which teams owns what parts of the overall system.
SOA: pretty good, microservices: probably not a great idea, microservices without SOA: avoid.
For anyone unfamiliar with SOA, there's a great sub-rant in Steve Yegge's 2011 google platforms rant [1][2] focusing on Amazon's switch to service oriented architecture.
[1] https://courses.cs.washington.edu/courses/cse452/23wi/papers... [2] corresponding HN thread from 2011 https://www.hackerneue.com/item?id=3101876
- Probably works OK for a small project with a close knit team of skilled contributors where there's some well defined structure and everyone has sufficient high level understanding of that structure to know what kinds of dependencies are or are not healthy to have.
But, unless you have some way of enforcing that access between different components happens through some kind of well defined interfaces, the codebase may end up very tightly coupled and expensive or impractical to evolve and change, if shared memory makes it easy for folks to add direct dependencies between data structures of different components that shouldn't be coupled.
- the census bureau annual poverty report includes both poverty measures: https://www.census.gov/library/publications/2024/demo/p60-28...
(the most recent poverty report isn't currently downloadable due to the recent government shutdown)
Your question about why the official poverty measure is still used at all is a good one. I'd speculate that if the official poverty measure is tangled up with legislation, it may not be simple for government bureaus to update the measure and eliminate usage of the old measure without someone passing some new laws. If the poverty measure partly defines who does or doesn't receive certain benefits then changing it could be fairly political. If the supplemental poverty measure indicates that e.g. 12% not 10% of families fall below the poverty line, then that implies 20% more funding is necessary for some benefits.