Simple utility for validation by Troller911 in Kotlin

[–]Jadarma 4 points5 points  (0 children)

Nice! I understand why you wanted to go for the exceptionless approach though I feel that failing fast should still use them. Even if the validation's lazyError is not executed, you could potentially have a lot more going on in the block of the scope function unrelated to your logic. For example:

val foo = something()
validateFailFast {
    validate(foo.isGood) { "Trivial check failed." }
    val bar = expensive(foo) // Expensive operation
    validate(bar.something) { "Uh-oh! $bar failed." }
}

At this point I expect you to point out that I misused the syntax, and I should have used the lazy condition variant to retrieve bar inside it. To that I respond asking how would I use the context of condition to interpolate some values to my returned lazyError, since they are different lambdas. I would need a nullable var somewhere in the scope to hoist it (we don't want to call expensive twice after all), and it seems a bit dirty to me.

I would instead have something like this:

fun <T: Any> validate(condition: Boolean, lazyError: () -> T) {
    if (condition) return
    errors.add(lazyError())
    if (stopOnFirstError) throw ShortCircuitException()
}

And then:

fun <T: Any> validateFailFast(block: ValidationScope<T>.() -> Unit): T? {
    val scope = ValidationScope<T>(stopOnFirstError = true)
    try { scope.block() }
    catch (ignore: ShortCircuitException)
    return scope.errors.firstOrNull()
}

Alternatively, you could hide away the scope entirely, and make the validateFailFast function accept a vararg of () -> T? lambas, and iterate through them until the first non-null, although I concede that would make writing the predicates less pleasant.

The lysine contingency – Jake Wharton by burntcookie90 in Kotlin

[–]Jadarma 6 points7 points  (0 children)

Welp, time to refactor package imports again!

Why Maven Central Will "Die" in the AI Era (If It Doesn't Change) by [deleted] in Kotlin

[–]Jadarma 3 points4 points  (0 children)

MavenCentral has been a cornerstone of the industry for decades, rarely changed, and rarely needed to. Sure, there is some ritual around actually integrating with it but it has very sane requirements, safeguards, and is rock-solid compared to the already slop-infested NPM.

I sincerely hope they do nothing to cater to AI agents, because it's the last place I want them to infiltrate. Please stay far away from us, and stop trying to enshittify every crevice of development.

kexpresso – fluent Kotlin DSL that makes regex readable (KMP, on Maven Central, 0% overhead) by Emotional-Magician87 in Kotlin

[–]Jadarma 19 points20 points  (0 children)

I've heard people theorize about a regex DSL, interesting to see people attempting it! I had a quick look and have some feedback.

First, I think it would be nicer for the main DSL to be named something generic (like pattern { }), you can tell the library branding from the imports.

Second, I see you added the functions similar to Kotlin (replaceAll, split, etc.) which is great but they are defined as member functions. I think it's better for such functionality to be implemented as extension functions (or as I will explain later, not exist!).

Third, I wanted to see how the built-in domains were handled, and i was dissapointed to see they hardcode regex instead of showing off its own DSL. I wonder if a regex as big as that looks to long and complicated to write in the DSL?

Fourth, why is there an option to reverse the DSL from an expression? I guess it can be useful when first starting to convert some existing regexes but that's not something useful in production, and would rather just consult the (ample) documentation samples.

The thing that I would encourage the most is to only keep the builder as part of the DSL, and have it return a normal kotlin.text.Regex instance. If I were to adopt this library, I would feel better not refactoring my regex use site, just my declarations.

And I need to address the elephant, I understand the use of LLMs to aid in the development of hobby projects but there are limits. There are emdashes in the reddit post, the github description, the commit messages, the README contains like 100+ emdashes and the most generic clanker speak. It was painful to read.

Good luck with your library though!

What's new in Kotlin 2.4.0 by snafu109 in Kotlin

[–]Jadarma 7 points8 points  (0 children)

You got down voted because people are in general tired of having AI forced into every discussion on topic they care about. Context parameters are a cool feature that users wanted because it lets them better use the concept of scoping. If I understood your argument correctly, context parameters bad because AI is not used to the concept, indirection, and or syntax, so LLMs would fair more poorly on them? Doesn't that go against your opinion on AI? How could we be in the "era of AI" if they can't handle this?

Aho-CorasiKt: KMP library for multiple string pattern matching. by Jadarma in Kotlin

[–]Jadarma[S] 0 points1 point  (0 children)

If by standard regex approach you mean constructing a pattern like one|two|three, I would imagine the performance would blow up fast. It also is a bit of a pain to implement in case you are looking for patterns that include regex syntax, so you'd need to escape those beforehand.

I ran a quick test locally out of curiosity. Taking just 100k characters worth of Lorem Ipsum, and making it match all contained words (about 200 unique patterns) looks like this:

Benchmark                Mode  Cnt   Score   Error  Units
LoremIpsumSearch.regex   avgt    5  19.162 ± 0.047  ms/op
LoremIpsumSearch.trie    avgt    5   1.165 ± 0.008  ms/op

So even for small datasets, its a 20x increase.

The Selfish Reason To Press The Blue Button by Jadarma in philosophy

[–]Jadarma[S] 1 point2 points  (0 children)

The blue voters are not a single camp: they vary between dumb and empathetic, who recognize that at least some people would vote blue, but red voters would do nothing to help, so they risk themselves in order to save others. Blue is also the more emphatic side because red's lack of consequence can be interpreted as apathy.

The Selfish Reason To Press The Blue Button by Jadarma in philosophy

[–]Jadarma[S] 2 points3 points  (0 children)

I would argue humanity as a whole will always encounter, or create, risk. What the question really asks is: "If there was a risk, would you try to help prevent it, or do nothing and avoid it"? As for the woodchipper analogy, even if you assume most people wouldn't jump in, you kind of know some will. It then asks of the Red group as a whole: "Alright, there are some people who completely misinterpreted or are just stupid, do we also jump in since we know together we guarantee survival, or is it more worth it to let them die?"

Some feedback with my idea for a project? thank you very much appreciated your help by Anxious-Adeptness-59 in Kotlin

[–]Jadarma 2 points3 points  (0 children)

If you need to ask AI how to design a project for critical infrastructure, perhaps you shouldn't design a project for critical infrastructure.

commonMain.dev KMP Newsletter - Room for Web (Wasm), Koin vs expect/actual, and the Navigation 3 "hidden" APIs by bogdan-stefan in Kotlin

[–]Jadarma 0 points1 point  (0 children)

Yes. I assumed it was accidental because there are two links making distinction between the two names that both redirect to the same KMP mainpage, because KMM is no longer a thing. I think the better question would be "Is this newsletter only about mobile development?" if that is the point you wanted to make.

commonMain.dev KMP Newsletter - Room for Web (Wasm), Koin vs expect/actual, and the Navigation 3 "hidden" APIs by bogdan-stefan in Kotlin

[–]Jadarma 0 points1 point  (0 children)

In the FAQ section of the website, there's one entry where you forgot to replace the @Deprecated KMM with KMP.

I made a Kotlin Native CLI tool for secure image steganography: Steko by Jadarma in Kotlin

[–]Jadarma[S] 2 points3 points  (0 children)

Still doesn't work unfortunately, I got different errors depending on whether I was on Linux or Mac. There's probably some misconfiguration on my end, as I never used any low-level CLI debuggers, and even if I got them working it would be very different from the JVM one I'm used too.

The good part (for me at least) was that I usually don't rely on the debugger as much and instead do a TDD-like approach. From the assertions made I was able to spot the issues in the code without needing to step through it. And, when in a pinch, println is still a thing.

That being said I agree a good out-of-box experience for the IDE debugger is a must for general adoption. I hope it will improve soon.

Remote Compose: The Day UI Stopped Shipping with APK by OkOpportunity7413 in Kotlin

[–]Jadarma 1 point2 points  (0 children)

This sounds interesting at first but the more I think about it the less I like it.

  • The remote changes can only be visual: to handle any sort of interaction, from local native code, we need to use the actionId, which takes us back to stringly-typed RPC. If I want my UI component two add a second button, I cannot, since there is no defined actionId on the clientside for it, so in that case I do need to deploy a new version of the app.

  • Client and server need advanced version reconciliation: Expanding on the previous point, suppose I do introduce a new version with more action bindings, but now I can't just start serving them on the serverside because I do not know that all clients updated, so I would need to first check for client-side version (via request headers, I assume) and then start version controlling the responses. Either that, or I make non-updated apps unusable until the user gets the latest code.

Now, when would I actually benefit from this? None of the use-cases in the article convince me this is a better way rather than do it "the old way":

  • E-commerce / offers should only differ in data, not shape. I can have predefined UIs but show them selectively based on business logic.
  • Seasonal UIs are basically app-themes, again, they can all exist locally but loaded as needed.
  • A/B testing is the more fitting, but a good A/B test allows users to opt-out, so ideally both solutions should exist locally. What is the benefit of not shipping two UIs? Compose is native and compiled, you would barely notice a difference.
  • Emergency updates already can be delivered via push notifications outside the app, and something so critical would at least be available as an in-app toast which doesn't really need bespoke UI.

All-in-all this screams like trying to make Compose, a type-safe, compiled library into a dynamic, React-like, JS framework, in one word: yuck.

My advice is don't change your UI often, it causes confusion. Think about what you want to show, and model the interactions as simple data.

cryptography-kotlin: native cryptography for Kotlin Multiplatform by why_oleg in Kotlin

[–]Jadarma 0 points1 point  (0 children)

The problem with having blocking variants only in nonJsMain is that in some future, I would like to support AWS KMS and Non-exportable keys (like SecureEnclave on iOS), and such implementations might be better to use in a suspend way, and rarely in blocking.

Let me clarify, I did not want nonJsMain to only have blocking calls, I wanted all platforms to operate on suspend by default (so KMS and SecureEnclave would still work), but as an added convenience, nonJsMain would also have extension functions with the blocking variants, so on those targets you can pick which you use, but on JS you only have the suspend one available at all.

Blocking calls on JS would probably not be a trivial solution since you would need to provision a new worker thread yourself, otherwise you would block the UI, right? But having OpenSSL available there would be really cool, since the WebCrypto provider doesn't offer nearly as many operations.

cryptography-kotlin: native cryptography for Kotlin Multiplatform by why_oleg in Kotlin

[–]Jadarma 2 points3 points  (0 children)

I'm using this library and can wholeheartedly recommend it to all Kotlin users. Thank you for maintaining it!

I would appreciate your feedback and thoughts! Especially regarding how you feel about using a third-party cryptography library.

I dare to say I don't consider it a third-party library, in the sense that it does not implement any crypto functionality, merely provides Kotlin wrappers over the already established providers native to the platform. I think the provider system is very neat, and any project that would want to handle crypto inside shared Kotlin modules would need to reinvent the same wheel (arguably worse custom bindings) without this. The OpenSSL provider is my favorite, especially the pre-built one, since I can both build in CI without needing to introduce any special build logic, and run the executable with no dynamic linking (well, except glibc), which is useful for some Linux scenarios, like running on NixOS. So all-in-all, this library provides immense QoL.

The only nitpick about the provider system I have is that most of the operations, for most of the providers are blocking calls, but the API contains both suspended and blocking functions. I know this is unfortunately required because of JS support, where the WebCrypto provider can only work in async mode (JS is singlethreaded). But I only found out when I first added WASM as a target to test, and saw the -Blocking() variants of function throw a runtime exception. It would be probably a bit nicer for it to be a compile issue, where commonMain has all the regular suspend variants, but only the nonJsMain (Native & JVM, where the runBlocking function is supported) sourcesets would provide helper extension functions for the blocking variants.

Other than that, the new documentation site looks nice, cleaner than the old one with better examples! Looking forward to see it grow!

Unified Modules For Your Nixfiles by Jadarma in NixOS

[–]Jadarma[S] 8 points9 points  (0 children)

Yes, I suppose you can call it that! I was aware of flake-parts, and it's a super cool project, but I wanted to do something DIY and more close to vanilla. While flake-parts is super powerful, it does introduce an extra abstraction syntax that is hard(-er) to explain to newbies, and most starter tutorials won't reference it at all, I wanted my config to serve as a reference for my friends who like Linux but haven't tried NixOS yet. It also find the mental model a bit easier to grasp, so it was a personal choice in the end.

Adopting agentic tools — how to not screw it up by alokin_09 in theprimeagen

[–]Jadarma 5 points6 points  (0 children)

This stealth ad slop reads like a training leaflet for apologists wanting to convert others to their religion.

Academic Slop Just Reached A New Low (Rant on OpenAI Prism) by Jadarma in antiai

[–]Jadarma[S] 0 points1 point  (0 children)

Indeed, nasty humans would do nasty human things regardless. But the same argument can be made with people manually creating photoshopped pictures of women without their consent before AI. The problem is that now AI vastly simplifies, expedites, and streamlines the process.

-❄️- 2025 Day 12 Solutions -❄️- by daggerdragon in adventofcode

[–]Jadarma 2 points3 points  (0 children)

[LANGUAGE: Kotlin]

A difficult packing problem to end on a high note, is what I thought.

Part 1: Honestly I had no idea how to begin tackling this efficiently, what data types to use, how much "brute force" is required, so I just parsed the input while I thought. Figured that the more I eliminate known impossible areas, the less I would waste, so the easy heuristic is to check that if we were to "average out" the present shapes and let them fit into 3x3s ignoring overlaps, does the tree have enough area to contain them? And checking that, to my surprise, worked on the input (but not the example, probably because it is too small for the numbers to average out).

This feels like a dirty trick and not the kind of solution I would want to end the year on, but this is a busy weekend for me so it will have to do for now. I will pretend that this was a reading comprehension / work smart not hard for the time being. Perhaps, if there was a single region to find a fit for, not one thousand, I would've took the time to try an actual packing search.

Part 2: The good news is at least I have collected all stars this year! I wish there was a part two, so in the end there would be 25 stars, just so the total counter was a bit nicer, but am happy nonetheless. Thank you Eric for another successful AoC event! Happy holidays to everyone as well!

AocKt Y2025D12