HN Simulatornew | past | comments | lists | submit | shoo's commentslogin

none of our business

Mmm. Changing control flow based on introspection of the call stack is reasonably nasty.

I recall we found a neat use for call stack introspection in one project - not to change control flow but to improve logging. Inside an open_db_connection utility function, to auto-generate an informational name describing which part of the codebase had opened the connection:

E.g. some_backend_process: main -> ... > grandparent -> parent -> open_db_connection

We'd use information from the call stack generate a string "some_backend_process grandparent.parent" describing the call site which could be passed to postgres as the application_name [1] when establishing a connection. Then from the database side, if we had problematic queries at runtime, we had a lot more clues to figure out which part of the backend codebase was responsible [2].

There'd be a way to do something equivalent without peeking at the call stack, by requiring the caller to explicitly pass a descriptive & unique name, but that makes things a bit more error-prone, especially since some devs would be prone to copy-pasting chunks of existing code & reusing the same name everywhere.

[1] https://www.postgresql.org/docs/current/libpq-connect.html#L... [2] https://www.postgresql.org/docs/current/monitoring-stats.htm...


Textbook correct use of call stack introspection

> There'd be a way to do something equivalent without peeking at the call stack, by requiring the caller to explicitly pass a descriptive & unique name

Agree with your tradeoff here. "No instrospection, ever" can also be harmful. Reminds me how 'no global mutable state' also needs to be broken in some cases.


Funny, my logging module for Python does the same (if requested with an optional keyword argument). It fetches the call stack, removes it's own functions, replaces Python library function chains with a single [...] and prepends it to the log output (together with usual date and time).

sounds like intercal's COME FROM statement

> Is this how "MCP" server is typically implemented (no encryption).

No idea. The boring (in a positive sense) answer I'd expect for any backend API server is that encryption in transit is handled by TLS. So I'd expect either the MCP server in question can be configured to support TLS connections & refuse plaintext HTTP connections, or that for a production-like deployment it expects to be deployed behind a reverse proxy that is responsible for terminating TLS.


I agree - they're measuring completely different properties of different populations of things, over completely different time horizons. Comparing them doesn't seem very useful.

Market caps are roughly expected future earnings, discounted back to give some net present value. They're expectations about the profitability of businesses, with expected profits accumulated over forecasts decades into the future. Market caps ignore privately held businesses, small businesses, state owned businesses & economic activity, economic output that might be happening at a household level, etc.

GDP is some peculiar measure of a country's economic output, over one year. It doesn't care if the economic activity is profitable or not & it doesn't care if the surplus of the economic activity is extracted by public companies or not. It's not forward-looking & based on expectations.

all that said, ggm has a fair point that individual investors & retirees with share portfolios directly benefit from the profits of companies whose economic activities may not be particularly pro-social & beneficial to the world. it's similar for climate change -- easy to point the finger at the energy producer, the big dirty brown coal plant. harder to point the finger at the demand side of the same equation - much of which is household demand. but both the individual end consumer households and the energy producer & everyone else involved in the value chain benefit out of the trade, even if the trade is net-negative for the world if we were to properly account for the externalities (e.g. polluting the atmosphere with CO_2 pushes the costs to everyone on the planet, current & future generations, not just the folks benefiting from the trade).


Would writing a recursive backtracker really be easier to reason about and implement?

With one of these solver-based approaches, you encode the problem with decision variables in some fashion, state all the constraints & call solve. There's some art & experience in how to encode & model the problem, but the specification of the model & the problem is fairly declarative.

What's great about general purpose solver-based approaches is that its usually faster (in terms of implementation time & effort) to start getting solutions & they're also much more robust to changes in requirements & the problem statement. That's less of a concern in this toy example, where the problem is small, well-defined & unambiguous, but in a real business/industrial application, the problem statement often changes considerably over time.

I agree that the performance & behaviour of a black box solver may be much harder to reason about than something you custom build by hand & know inside out, but if the general purpose black box solver is 'good enough' for the distributions of problem instances it needs to process, then there's no need to custom-build anything. Throw the black box solver at it -- job's done, and you're left with something that's both quite readable (declarative modelling of the problem, particularly if someone documents the formulation - the meaning of all the decision variables, index sets, constraints, objective terms etc) & flexible to future change.

Custom solvers & heuristics can sometimes be much, much more effective in being able to scale and solve industrial-scale problems, but usually at the expense of being much more effort to set up in the first place, and very fragile to changes in requirements -- if you learn something a few weeks into a project that perturbs the problem statement, maybe it wrecks the particular mathematical structure you were relying upon for a custom solver/heuristic, so you need to chuck out all your work & go back to the drawing board.


cool, i played a fair bit of scorch

misc feedback

  - dominant strategy seems to be drive to point blank range & fire. needs some playtesting & rework to make it interesting for 2 players.
  - how do you bring up help for a reminder of what the controls are once the game is in progress?
  - the arrow keys for controlling the turret are unintuitive. i'd expect left & right arrows to change the barrel angle, like in the original scorched earth, but here they change the power level
  - the visual trajectory preview doesnt seem useful whenever the moon is involved as by the time you fire, the moon has moved the trajectory is wildly different to whatever the preview showed

one perspective i've heard some game developers talk about when prototyping a new game is focusing on trying to improve the length of time a player can have fun before they get sick of it. is it fun for 5 seconds? what could i do to increase that to make it fun for a whole 30 seconds? for 60 seconds?

Great feedback, thank you! I am working on incorporating many of these fixes

If the main problem is unclear & changing requirements, having 2 different implementations of a system that attempt to implement the vague / changing / missing requirements doesn't seem immediately helpful -- they'll almost certainly disagree, and then you can force one to match the other or so on, and have two implementations of some arbitrary thing.

But none of this "implementing stuff" is making progress to solving the issue of unclear / changing / vague / missing requirements.


You don't try to force them to match. You show a few very different implementations that all satisfy the underspecified the requirements. Not in an antagonistic way, but to help clarify and sharpen the requirements. If any implementation would do, then there's no problem.

When they diverge you use the agent to classify bug one one of them or spec is unclear. You can both fix bugs and refine the spec iteratively.

MongoDB's net profit margin has been improving significantly over the last 5 years, increasing from -35% to +2%. This makes the P/E ratio not a very reliable lens to value the stock, vs using P/E ratios to compare mature companies that have relatively stable net profit margins.

To crudely estimate a fundamental valuation for MongoDB as a discounted sequence of future earnings, we'd need some understanding of the main factors that are driving this change in the net profit margin (over the next 5 years do we expect those factors to persist? to decay? to accelerate?), some modelling assumptions & forecasts for how they'll evolve over the next decade or two, and a discount factor.

Out of curiosity, I bashed together a naive NPV valuation, in complete ignorance of MongoDB's underlying business.

Completely unjustified modelling assumptions: suppose MongoDB can grow revenue at +20% / year for 5 years, then +5% / year for the next 5, then hitting a steady state +2.5% / year revenue growth; MongoDB grows net profit margin by +5% every year until hitting a 25% net profit margin, where it tops out; discount factor of 9.5% (= 5% risk free rate + 4.5% equity risk premium); no change in number of shares outstanding (perhaps optimistic, given they issued a bunch of stock within the last 5 years). Projecting this out 20 years & then using a 20x P/E valuation multiple at year 20 for the terminal value gives us an NPV estimate of the value at about $290 / share.

So if you believe MongoDB's business will do about that well, with your fundamental valuation investor hat on you could consider buying some stock if it were offered at, say, half the current market price or less -- assuming there isn't anything more attractive to invest in.

If you believe MongoDB's revenue growth & improvement in net profit margin will be much stronger over the next decade, maybe you'd be comfortable buying closer to the current market price.

(I don't hold any MongoDB stock & find it hard to stomach investing in growth companies vs companies that are more mature & easier to understand, but I appreciate that to value growth stocks you're not going to have much luck using P/B or P/E ratios)


brainfuck is unpleasant to write directly - e.g. the language doesn't have variables, so you need to manually do the bookkeeping of which memory offset is storing what 'variable'. & if you need to refactor your program slightly, in a way that changes the memory layout, maybe you need to manually rework the absolute & relative offsets. So I can appreciate why the author didn't roll up their sleeves to directly write BF - that's neither a productive nor interesting exercise.

Interesting to see how the author decomposed the problem:

- C raytracer https://github.com/mTvare6/rayfuck/blob/master/ray.c

~~ LLM refactor of the C code ~~>

- SSA-style C raytracer code https://github.com/mTvare6/rayfuck/blob/master/ray_ssa.c

~~ c2dsl.py helper script (compiler) ~~>

- DSL raytracer https://github.com/mTvare6/rayfuck/blob/master/ray.dsl

~~ dsl2bf.py helper script (another compiler) ~~>

BF raytracer https://github.com/mTvare6/rayfuck/blob/master/ray.bf (~22 mb of unreadable nonsense)

The dsl2bf compiler has a bunch of examples of implementing slightly higher level abstractions atop BF primitives. E.g. "go" to move the pointer to a different offset, destructive & non-destructive copies, all the way up to things like division -- BF only natively offers unary addition/subtraction.

If we have a read of the code of the final compiler, dsl2bf.py, the abstractions used in that code are relatively simple: global variables, local variables, lists, dicts, for loops, function definitions & function calls. It is feasible to implement a simple compiler like dsl2bf in BF itself, with sufficient head scratching. Again, quite unpleasant to try it directly in BF, but a next step could be to implement the dsl2bf compiler in the DSL itself - extending it if necessary, then compiling it with itself to produce a dsl2bf compiler implemented in BF.


That does sound like a fun step, I'd already begun experimenting with some optimizations after having received suggestions in reddit to add fork/join primitives. Adding a compiler with these added performance gains sounds reasonable and something which will run quickly. dicts certainly involve some thought there.

I hadn't considered self-hosting the compiler, but having put it into works, I probably will.

This was the render the speed up version gave: https://paste.c-net.org/SpikingCarbs


> dicts certainly involve some thought there

One way to start could be to ignore performance of the data structure.

The first main job dicts are being used for is the `mem` dict mapping a key (variable name) to some value record.

A data structure that supports Store(K, V) & V = Get(K) could be something like an stack allocated array of (Key, Value) pairs, that you search through using linear search to implement Store & Get. It wouldn't be very fast, but you probably don't have too many items in a typical DSL program. You'd need to implement some kind of stack or so on - or perhaps you could get away with reserving some fixed capacity.


Well the problem is that the DSL uses strings, so any representation which keeps variable names as strings still needs storage and comparison, which currently only the fixed type does. Though c2dsl could instead use a unique integer for every string for variables.

The first value of each instruction would then always be one of a fixed set of opcodes, variables their IDs, and numbers left as-is (and we've invented machine code :)). Then (K, V) is always fixed-size and laid out predictably in memory, so the linear-search approach sounds reasonable.


another approach could be to support strings, of length exactly 1. would 256 unique strings be enough to name all the variables (& functions?) in an interesting program?


Yup.

> rg var ray.dsl | wc -l

142

> rg func ray.dsl | wc -l

6

+28 for opcodes, bringing it to 176. So it works for this interesting program, the raytracer, but the compiler likely requires way more. Maybe not the 4 cells I've been using, but 2^16 = 65k would be enough buckets but unique names.


Via google translate:

> It has been discovered that online used bookstores across Japan have been receiving a surge of large orders for books since around August of this year. Interviews with these bookstores reveal reports of "100 books sold per day" and "days where sales have increased fivefold," leading to widespread speculation within the industry that the orders are intended to collect training data for generative AI (artificial intelligence). Further investigation revealed records of over 50 tons of books being exported from Japan to the United States. Is it acceptable for books to be consumed and discarded for AI training?

[...]

> Nippon Television investigated using "Sayari," a tool that analyzes import and export data, and confirmed records that a group company of this major Japanese book distributor exported more than 50 tons of "JAPANESE BOOKS" to the US since last year. Assuming that all the books were heavy hardcovers (calculated at 500 grams), this would amount to the equivalent of 100,000 books.


Guidelines | FAQ | Lists | API | Security | DMCA | Apply to YC | Contact

Search: