Hacker Newsnew | past | comments | ask | show | jobs | submit | usefulcat's commentslogin

Is compressed debug info a thing? It seems likely to compress well, and if it's rarely used then it might be a worthwhile thing to do?

It is: https://maskray.me/blog/2022-01-23-compressed-debug-sections

But the compression ratio isn't magical (approx. 1:0.25, for both zlib and zstd in the examples given). You'd probably still want to set aside debuginfo in separate files.


They could and they did. That meant that Spain ended up importing more and exporting less, which would have been bad for Spanish businesses.

There’s a lot more to “wealth” than just having a bunch of stuff. Especially in the long term, since most “stuff” will wear out or otherwise decay over time.


Ideally a logging library should at least not make it easy to make that kind of mistake.

This isn't really something the logging library can do. If the language provides a string interpolation mechanism then that mechanism is what the programmers will reach for first. And the library cannot know that interpolation happened because the language creates the final string before passing it in.

If you want the builtin interpolation to become a noop in the face runtime log disabling then the logging library has to be a builtin too.


I feel like there's a parallel with SQL where you want to discourage manual interpolation. Taking inspiration from it may help: you may not fully solve it but there are some API ideas and patterns.

A logging framework may have the equivalent of prepared statements. You may also nudge usage where the raw string API is `log.traceRaw(String rawMessage)` while the parametrized one has the nicer naming `log.trace(Template t, param1, param2)`.


You can have 0 parameters and the template is a string...

The point of my message is that you should avoid the `log(string)` signature. Even if it's appealing, it's an easy perf trap.

There are many ideas if you look at SQL libs. In my example I used a different type but there other solutions. Be creative.

    logger.log(new Template("foo"))`
    logger.log("foo", [])
    logger.prepare("foo").log()

And none of those solve the issue.

You pass "foo" to Template. The Template will be instantiated before log ever sees it. You conveniently left out where the Foo string is computed from something that actually need computation.

Like both:

    new Template("doing X to " + thingBeingOperatedOn)

    new Template("doing " + expensiveDebugThing(thingBeingOperatedOn))
You just complicated everything to get the same class of error.

Heck even the existing good way of doing it, which is less complicated than your way, still isn't safe from it.

    logger("doing {}", expensiveDebugThing(thingBeingOperatedOn))
All your examples have the same issue, both with just string concatenation and more expensive calls. You can only get around an unknowing or lazy programmer if the compiler can be smart enough to entirely skip these (JIT or not - a JIT would need to see that these calls never amount to anything and decide to skip them after a while. Not deterministically useful of course).

Yeah, it's hard to prevent a sufficiently motivated dev from shooting itself in the foot; but these still help.

> You conveniently left out where the Foo string is computed from something that actually need computation.

I left it out because the comment I was replying to was pointing that some logs don't have params.

For the approach using a `Template` class, the expectation would be that the doc would call out why this class exists in the first place as to enable lazy computation. Doing string concatenation inside a template constructor should raise a few eyebrows when writing or reviewing code.

I wrote `logger.log(new Template("foo"))` in my previous comment for brevity as it's merely an internet comment and not a real framework. In real code I would not even use stringy logs but structured data attached to a unique code. But since this thread discusses performance of stringy logs, I would expect log templates to be defined as statics/constants that don't contain any runtime value. You could also integrate them with metadata such as log levels, schemas, translations, codes, etc.

Regarding args themselves, you're right that they can also be expensive to compute in the first place. You may then design the args to be passed by a callback which would allow to defer the param computation.

A possible example would be:

    const OPERATION_TIMEOUT = new Template("the operation $operationId timed-out after $duration seconds", {level: "error", code: "E_TIMEOUT"});
    // ...
    function handler(...) {
      // ..
      logger.emit(OPERATION_TIMEOUT, () => ({operationId: "foo", duration: someExpensiveOperationToRetrieveTheDuration()}))
    }
This is still not perfect as you may need to compute some data before the log "just in case" you need it for the log. For example you may want to record the current time, do the operation. If the operation times out, you use the time recorded before the op to compute for how long it ran. If you did not time out and don't log, then getting the current system time is "wasted".

All I'm saying is that `logger.log(str)` is not the only possible API; and that splitting the definition of the log from the actual "emit" is a good pattern.


Unless log() is a macro of some sort that expands to if(logEnabled){internalLog(string)} - which a good optimizer will see through and not expand the string when logging is disabled.

Ideally, but realistically, I have never heard of any major programming language that allows you to express "this function only accepts static constant string literal".

Python has LiteralString for this exact purpose. It's only on the type checker level, but type checking should be part of most modern Python workflows anyway. I've seen DB libraries use this a lot for SQL parameters.

https://typing.python.org/en/latest/spec/literal.html#litera...


Beyond LiteralString there is now also t-strings, introduced in Python 3.14, that eases how one writes templated strings without loosing out on security. Java has something similar with Template class in Java 21 as preview.

We have this in c++ at Google. It's like securitytypes::StringLiteral. I don't know how it works under the hood, but it indeed only allows string literals.

Even PHP has that these days via static analysis https://phpstan.org/writing-php-code/phpdoc-types#other-adva...

In Rust, this can almost be expressed as `arg: &'static str` to accept a reference to a string whose lifetime never ends. I say “almost” because this allows both string literals and references to static (but dynamically generated) string.

For Rust’s macros, a literal can be expressed as `$arg:lit`. This does allow other literals as well, such as int or float literals, but typically the generated code would only work for a string literal.


c++20 offers `consteval` to make this clear, but you can do some simple macro wizardry in c++11 to do this:

    #define foo(x) ( \
        (void)std::integral_constant<char, (x)[0]>::value, \
        foo_impl(x) \
    )
(the re-evaluation of x doesn't matter if it compiles). You can also use a user-defined literal which has a different ergonomic problem.

Not the language, but the linter can do it. IntelliJ inspections warn you if you do it: https://www.jetbrains.com/help/inspectopedia/StringConcatena...

it does seem like something a good static analysis tool should be able to catch though

Regarding the failure of internal components--there are some 'failure' modes which I had not even contemplated previously.

I have a TV that's only about 5-6 years old and has a built in Roku. It mostly works fine, but the built in hardware is simply not fast enough to play some streaming services, specifically some stuff on F1TV. And before anyone asks, it's not a bandwidth problem--I have gigabit fiber and the TV is using ethernet.

Anyway, between that, general UI sluggishness and the proliferation of ads in the Roku interface, I switched to an Apple TV and haven't looked back.


Best example I've yet seen of Betteridge's law.

> it’s worth calling out just how hard this problem is for retailers and issuers.

I'm having a hard time finding much sympathy. They could always, oh I don't know.. maybe just not sell gift cards? Or have a much lower maximum amount?

I mean yeah, you could take the view that technically the blame really lies with the people trying to use gift cards for theft, but that's not going to be productive.


You could make much the same observation about online search results.

Talk is cheap; actions are what matters. Based on their actions (or lack thereof), the group you're describing must be a very small minority indeed.


They aren't in Congress, they are working in the states, I would guess. The Republicans in Congress mostly volunteered for a spinectomy when Trump was elected again.


Can you name any currently serving?


That's part of it: many felt the winds and simultaneously made the choice to "focus on family" and step back from politics during the 2nd Trump administration.

But the wheel turns, and there's going to be a lot of folks in the party with very sharp axes to grind during the lame duck period.


Yeah, and I'm sure the Pelosi wing of the Democratic Party will be first in line to help rehabilitate their image.

Entirely true, and also quite underwhelming compared to an engine failure.

Personally I'd be a lot more interested in the cause(s) of the failure and how it was handled.


How would an exchange enforce the trade through rule without any outside market data?


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

Search: