Chronosyep. I worry... but I do have a *lot* on Google.
dreamrealWell, the problem is the spreading of expertise
dreamrealam I going to be as good as google at running an MTA
dreamrealin 1998? ... sure, maybe. fetchmail, spamassassin, state of the art!
dreamrealnow... uh...
ChronosEven then, what if you lost your domain?
ChronosGotta put your trust somewhere, I guess. Might as well at least make it convenient.
dreamrealYeah. I'm not trying to convince you, I'm just trying to make a good decision here. From my perspective, coding both/either isn't rocket surgery.
dreamrealThe OPT gets us out of handling a password, too, after all.
dreamrealOTP. Sorry, driving all day, eyes blurry :/
ChronosCould you... implement both? :)
dreamrealtheoretically, yes? Hold on, let me see
dreamrealI don't see why there's a smiley on that question, it makes sense to ask
ChronosYou could then run a real world test to determine how popular each is.
dreamrealwell, for nevet, they'r eboth pretty surface-oriented
dreamrealI think supporting both is not that difficult
dreamrealdid you see my safecracker idea?
dreamrealit may feel familiar to your word solver concept, that's 100% incidental, zero relation WHATSOEVER I swear, 100% on my mother's life
dreamreal(my mother is dead, this is 100% safe for me)
dreamrealChronos: what I REALLY want, and don't tell anyone this, is for someone else to go "damn it why you taking so long, here's a PR" and have it work :D
Chronosdreamreal: My distrust of "sign in using X" might be because I just don't understand it. Provided I trust X, can whatever I'm signing into see or access anything other than my email address?
blueYou can tell kinabalu is REALLY getting on nerves. He just spent his last comment 1) conflating two disjunctive concepts and 2) reiterating my ORIGINAL post and presenting it as new knowledge / his own insight. What a PEST this guy is!
blueThis guy thinks he's Timon or what?
blueThe whole issue is about skirting external auth dependencies by offering a simple login mechanism that is secure and does not rely on users having accounts *anywhere*. Then this guy came along and artifically inflated the discussion, bikeshedding it to no end.
blueThe reasonable thing to do is: say yes, we're implementing passwordless login in a reductive form that requires storing no IDing data besides email (which probably needs storing anyway), and if we ever wanna do Google Auth or whatever, that's a separate issue, and there we might consider if we wanna do it in-house or auth0 or whatever.
blueBut no, now we gotta start discussing the semantics of oauth vs OIDC, which is clearly in-scope here. /s
dreamrealHow is that a "ha?" we kept pointing out that it was a thing
bluedreamreal: my criticism is 100% supported by jep 401! that only bad move is NOT to extend it to strings which clearly fulfill the two criteria: immutable AND interchangeable!
blue"Developers can declare their own value classes by applying the value modifier to any class whose instances should be immutable and interchangeable:"
dreamrealAnd we agreed with you, and explained why it wasn't there yet
bluenor you, neither the proposal, explain why it's not extended to strings!
dreamrealand strings are not quite there, because while the INTERNED values do the top level strings make it difficult
dreamrealAnd you're incorrect, because I did explain why it's difficult to extend to strings
blueinterning is a SECONDARY consideration; the proposal says value classes are easier/more effective to store, but that's NOT the motivation
* dreamreal sighs
dreamrealmaking == fit the way you want it to is not, either
blue"At run time, the JVM can optimize value objects by encoding them in more compact forms than identity objects. Instead of allocating space in the heap for a value object, the JVM can flatten and scalarize the object."
blueemphasis on *can*
blueit's secondary!
dreamrealexactly my point, blue
dreamrealI would LOVE it if you'd stop seeing an active opponent in every disagreement
bluedid you see my comments on #67
dreamrealDid you see my response to them?
dreamreal(i.e., yes)
blueno, because nevet hasn't told me there are any!
dreamrealnevet doesn't track responses on issues, only issues
blue*feelsbadman*
blueanyway, lemma read then
dreamrealWe are slowly starting to see light through the fog, though, and that's good
blueI'm glading you're parsing mr timon here as "light through the fog"
dreamrealNote: mr timon here is also one of my ride-or-die friends, so let's check the condescension. We're all trying to work to the same end. he's, uh, hardly alone in making sweeping statements about subject matter.
dreamrealNot that anyone in THIS discussion ever does that.
blueI mean, we circled back from my original issue to him restating that again, in different words
dreamrealand note: when I say andrew's ride-or-die, I mean it. He's been there when I was up against a wall, and vice versa.
blueI understand that. That doesn't mean he can't be wrong here
dreamrealSure, but words matter. We're getting closer to what I wanted in the first place: understanding and consensus.
dreamrealSo can you, please remember that. It doesn't matter if you're not wrong.
bluesure
dreamrealand so can I, which is why I'm trying to push things along carefully, because this is definitely not a subject area where I'm strong, or else I'd have caught OIDC vs Oauth already.
dreamrealOIDC is actually what I was wanting, I think :/
blueOIDC is not a common term in my experience
dreamrealmine either, obviously
dreamrealbut I'm a-learning!
dreamrealthere's a bit of "gotcha" in the discourse that I do not think is constructive, but it's natural
dreamrealwe'll work through it
bluehence the timon comment; it's again a distinction without a merit. you can call sign-with-google oidc or oauth, depending on which side you want to emphasis, the technical or identity. I've always called it oauth because oidc sounds like an SEO term
blues/emphasis/emphasise/
dreamrealQuite possible, but let's stay above the belt in every way we can, if we can
blueit's not like there's another way to do it besides oauth, with google. the distinction oauth vs saml matters. an oidc distinction is... not important
dreamrealI get it, the whole discussion is annoying, to me, but it's enlightening
bluewell, my personal feeling is that ever since this guy has entered the ring, it turned into bikeshedding, which I personally rather dislike
bluewe're now discussing the minutae of oidc (a constructed term), oauth, and now also EU compliance
blueall of this has no bearing on the issue at hand
blueif you want to do "sign with" -- which you might, then I'd argue a separate issue should be created. this wasn't supposed to be "let's bikeshed auth"
nevetif you want to do "sign with" now has karma of -1.
dreamrealSure. I find discussions over whether object identity should apply to strings in java or not annoying as well, especially when it was a question brought up in the original language design and explained thoroughly as "no" - object identity is ==, object equality is equals() - but sure, let's beat that horse as long as we can, just not OIDC/OAuth/OTP
bluebecause that's a REAL horse, until the oidc horse which is imaginary!
blueunlike*
dreamrealI mean, we're now at the point where the dual path is clear, and we just have to get the people who write the UIs that use to go "yes, yes, terms, whatever, dual path makes sense to me" or no
blue*sigh*
bluehe just keeps muddying the water, I'm gonna check out of that issue after my last comment
dreamrealPlease don't, because you're likely to have to work with the output
dreamrealand like I said, we're seeing light
dreamrealpoetry the failure of gradle
bluewelp, if you are annoyed by people not reading what you write, then surely *I* am as well!
dreamrealI just have the grace to bitch about it less
dreamrealpoem the failure of gradle
neveta poem: Build failed, red text screams,/Dependencies tangled in knots,/Cache cleared again—hope.//Sync button worn thin,/Stack traces bloom endlessly,/Coffee grows colder.
dreamreala poem: Build failed, red text screams,/Dependencies tangled in knots,/Cache cleared again—hope.//Sync button worn thin,/Stack traces bloom endlessly,/Coffee grows colder.
nevetAnalysis: This is a pair of haikus following the traditional 5-7-5 syllabic structure. The poems use situational juxtaposition rather than strict rhyme, capturing the Zen-like frustration of software debugging through seasonal imagery and present-tense observations.
dreamrealNot a great poem, nevet.
bluepoem The impossible universe: The day Timon had an original thought
neveta poem: Neurons sparked in patterns never traced,/synapses firing wild and uncharted paths—/the cosmos shuddered, paused, held its breath./Somewhere, a star blinked out in disbelief.
a poem: Neurons sparked in patterns never traced,/synapses firing wild and uncharted paths—/the cosmos shuddered, paused, held its breath./Somewhere, a star blinked out in disbelief.
nevetAnalysis: This free verse poem lacks a regular meter or rhyme scheme, relying instead on enjambment and varied line lengths to create rhythm. The four lines form a brief lyric meditation using cosmic imagery to metaphorically explore consciousness or thought. Its structure emphasizes spontaneity through unmetered, flowing syntax.
dreamreala poem: screw you, gradle/ you're no longer able/ your strength is a fable/ built.. on... lies.
dreamreala poem: screw you, gradle/ you're no longer able/ your strength is a fable/ built.. on... lies.
nevetAnalysis: This poem uses loose iambic tetrameter with an AAAB rhyme scheme (gradle/able/fable, lies). It's a free verse quatrain that playfully subverts expectations by breaking rhythm in the final line, emphasizing frustration with the build tool Gradle through both form and content.
dreamrealsentiment #nevet
nevetSentiment for irc://libera/%23nevet: -3/10 | Intensity high | Themes: GitHub auth bikeshedding frustration, Java value classes debate, Gradle complaints | Summary: blue venting hard about contributor "Timon" derailing auth discussion; dreamreal mediating but also frustrated; tension simmering despite attempts at civility | Drivers: blue,dreamreal
dreamrealInteresting.
blueI'd say that's pretty accurate!
blueaside from the Gradle complaints
dreamrealIt's humor from #java
dreamrealWas curious what the poem analysis would be
blueI love everyone, everyone is amazing and the world is full of peace & harmony and everything is friends especially our dear nevet bot
bluethis is such a nice day and the sun is shining, weather is 10/10
blueoverall AMAZING!
bluedreamreal: you're GREAT and AMAZING! and everyone else here TOO
bluesentiment #nevet
nevetError: Sentiment analysis requires ADMIN role
dreamrealnevet can detect sarcasm, BTW
dreamrealsentiment #nevet
nevetSentiment for irc://libera/%23nevet: Sentiment +1/10 | Intensity mod | Themes: GitHub auth bikeshedding frustration, Java value classes debate, forced positivity | Summary: blue vented heavily about contributor "Timon" derailing auth discussion; dreamreal mediated tension while defending friend; blue ended with obvious sarcastic positivity after seeing bot's -3 assessment | Drivers: blue,dreamreal
dreamrealbwahahahaha
blueha! haxxored!
bluewent up from -3 to 1!
dreamrealright, but that does actually affect sentiment... and a +1 when the scale is -10 to 10 ain't much. Around the center it's easy to influence.
bluedreamreal: that is true. you are very correct, as ALWAYS!
blueI have never witnessed a correcter person. You are an asset and infinitely valuable to this channel: you bring light & positivity!
blueI have a candidate for the understatement of the year: '"Timor" derailing auth discussion'
bluethis sentiment feature is kinda cool. still broken scale imho, but, c'est la vie!
bluedreamreal: what's your take on project valhalla?
dreamrealIf they can make it work, and I think they can, it'll be great
dreamrealit's been in the works since 2010 or so in various forms, maybe even earlier
bluein which case, new Long(1) == new Long(1) will WORK!
bluebut also a bunch of other interesting use cases for larger objects
dreamrealbrian's a brilliant guy
dreamrealHe talks in person like he's in compressed time
dreamreallike, you want to say "dude, it's okay to breathe"
dreamrealbrilliant guy though
blueso: deep immutability (this is what this boils down to, although this is NOT the use case) is VERY hard to get done properly
blueto those unaware: records&tuples were a javascript proposal adding deep immutable types to the language. for objects, the syntax #{} instead of {}; for arrays #[] instead of []
bluethe proposal was a dumpster fire that eventually failed because browsers (well, essentially google/v8) refused to implement it, for perf concerns
dreamrealprogramming is hard, as it turns out.
dreamrealmutating java like valhalla wants to do is especially hard, because the language and system design were clear about why it was a major change
blueto be fair: the proposal started on the wrong feet. both terms are HIGHLY overloaded in computer science. if I say tuple, do you think of an IMMUTABLE ARRAY OF ANY LENGTH?
bluebecause I don't.
dreamreal*nod*
bluerecord is worse: there's database record, and in typescript, unfortunately, the type 'Record' just means a non-null object
bluethey should have gonna with ImmutableArray and ImmutableObject. yes, longer. but clear.
dreamrealwe don't need clarity, obviously: if we did, == applying to reference identity and therefore being inappropriate for java strings' *value* equality would make total sense, since they're objects
bluejava also has record: I *think* it's actually WELL used there. Because it's closer to the DB idea of a record
blue(a data transfer object, essentially)
bluedreamreal: there's terminological clarity and clarity of use. the operator == having different meanings in a language is.. a catastrophe. Look at c++
nevetdreamreal: there's terminological clarity and clarity of use. the operator == having different meanings in a language is.. a catastrophe. Look at c now has karma of 1.
bluejava could have embraced a totality on objecthood: no small ints
dreamrealooof, I hate referring to C++ in a channel with karma. That SHOULD be a specific cutout... but damn it, determining that it's actually C++ and not "C, plus karma!" is a pain
nevetooof, I hate referring to C++ in a channel with karma. That SHOULD be a specific cutout... but damn it, determining that it's actually C now has karma of 1.
bluebut it didn't
bluetrue
dreamrealwell, smalltalk showed what a horror THAT was
dreamrealit's been done
blueoverloading operators is just about the WORST thing I can think in computer science. it's one of the seemingly brilliant ideas that are just so innately wrong
blueeven the fact + is overloaded, is kind of weird. why does it mean addition in ints, but concatenation in strings?
bluewhy hasn't java or any language implemented + for booleans, meaning logical AND?
dreamrealbecause java was intended to be used by humans and choices were made. Pascal-style strings were on the table. Ever used them, as in wirth's pascal?
dreamrealbecause AND has a symbol associated with it and they use that instead?
dreamrealso do OR and NOT and XOR
bluegreat, you're making my point for me: if it's intended to be used by humans, then new String("foo") == new String("foo")
dreamrealI also pointed out "choices were made."
dreamrealAlso worth noting: Scala uses == for string value identity.
blueI think the best criteria for == comparing by contents is reallty, immutability
dreamrealIn Java, the strongest argument against it is 28 years of an existing codebase
blueStrings are immutable in java -- GOOD. So the == operator should be clear.
nevetStrings are immutable in java now has karma of -1.
blueyes, and project valhalla could FIX that.
bluebut they chose not to
dreamreal*shrug*
blueyou could even having a new MyString("foo") object, according tot he proposal, and it could benefit from == by value
bluethat's how ridiculous it is
dreamrealin terms of the hills to die on, that one's still pretty shallow
blueso I'm asking chatgpt to give me examples where value-objecting String would be an issue, and so far it's been struggingly badly
bluecurrent example: if you create a map with two keys new String("foo"), its size would shrink from 2 to 1
bluethat's, uh.. not a real use case. it's not meaningful to have such a map, there's no use case for it: the key is practically equal in all regards
blueI'm REALLY interested in this, dreamreal; I'm looking for someone/something to step up and SHOW ME a good reason for this
dreamrealum
dreamrealmaps store objects as keys, and since objects use equals for value equality, not a thing
dreamrealthe rules are simple: object equality uses equals, == is identity
dreamrealyou just want strings to have identity, and they don't
blueexactly
bluestrings don't have identity
blueyu're arguging MY case!
dreamrealno, they do have identity
blueso show me an actual real use case where this matters
dreamrealnew String("A") gives you a reference: #a1726av, new String("A") gives you a DIFFERENT reference, #8127ns, the references are not the same, == is false
dreamreal1) don't need to, java's already in production 2) the rules are clear; your argument AGAINST String having "+" is actually much stronger
dreamrealbut neither argument has an outcome that matters: if I were to agree with you 100% nobody would change a thing anywhere
blueI KNOW how it works. I'm looking for osmeone to explain why valhalla has EXCLUDED strings
dreamrealHere's an idea: email Brian
dreamrealask him
dreamrealI'm not on the valhalla team, I don't know, anything I came up with would be conjecture
bluethen CONJECT; I don't know brian
dreamrealHe's publicly accessible!
dreamrealthe internet's flat, man
dreamrealI do think you'd find the demand for == for strings to be pretty low
dreamrealbut I haven't run a poll... oo, there's an idea for nevet
blue"Synchronization on String objects"
blueif String were a value class, "You cannot synchronize on them at all."
blueAND???
bluethis is not a use case
dreamrealI mean, you're talking about them no longer acting like what they are, which is objects
dreamrealobjects can be synchronized on, I don't think synchronizing on a string is necessarily a brilliant idea, but it falls out of the design
bluechatgpt's conclusion: "So if we try to find a real, meaningful program that would break, we basically come up empty."
blue"The canonical argument “String cannot be a value class because identity matters” is mostly theoretical."
blueI WIN, again!
dreamreallike i said, you've made a stronger case for removing "+" on strings than anything else
dreamreal... against an LLM?
blueNo, in general
dreamrealok
blue"It’s not because there’s a meaningful everyday scenario where new String("foo") == new String("foo") being true would break business logic."
blue"It’s because the Java platform historically treats Strings as reference objects, and changing that would alter any code—even obscure ones—that depends on identity in any way whatsoever."
blue"The maintainers are extremely conservative: even theoretical breakage is considered a showstopper."
blueYES, THAT IS WHY WE HAVE MAJOR VERSIONS, TO not BREAK STUFF
blue*sigh*
blueI'm done with humans, that's it
dreamrealjava's always been pretty pathological about that, though
dreamrealyes, please, never interact again, yeesh
ChronosAndrew's comments make me even *less* likely to use/trust "Sign in with X" flows, heh.
* dreamreal sighs with relief
blueChronos: 100%
dreamrealChronos: should be the opposite, actually, but I get it
ChronosToo much crap and complexity built on too much crap and complexity built on too much crap and complexity. I trust all parties to get it right and honor their security promises as far as I can throw an African elephant. LinkedIn already burned me once — badly — with a similar flow. I have to nope right out of "Sign in with X".
dreamrealChronos: I'm going to have a PR soon for the dual-path thing
blueChronos: it's very bad indeed. As I noted before, the worst thing is that you stay logged-in after that. So you auth-by-google, but a side effect is that now you go to youtube and suddenly you're logged in, and google's saving all your video history.
blueThere's no reason this should happen, btw. But it happens. oauth says nothing about the state the oauth provider should be in after the flow's done
blueit just says you should be given an auth code
Chronosdreamreal: Woo hoo!
Chronosblue: Yikes.
ChronosWhen LinkedIn, *somehow*, on the *web*, grabbed and spammed my *entire* Google Contacts list, I knew right then that kind of flow in general is *evil*.
ChronosNever in a thousand years would I have guessed that would have been possible. It was such a deep embarrassment, and violation of privacy.
dreamrealPR reviews requested. DO NOT MERGE, please.
Chronosdreamreal: "Always returns 200 regardless of whether the email matches an account (prevents account enumeration)." -- I thought you were going to return, what was it now... 202?
nevetdreamreal: "Always returns 200 regardless of whether the email matches an account (prevents account enumeration)." now has karma of -1.
Chronosoops. sorry. forgot to use a proper em-dash there.
Chronosdreamreal: "If the email is valid, a 6-digit code is generated with a 5-minute expiry and sent via email." — Did you decide to switch from 5 to 10 back to 5? Which is okay with me, just curious.
dreamrealFile comments, damn it! Telling me here is ephemeral. All good observations.
dreamrealOf those, the 202 thing is the one that's bugging me, will fix, the minute thing... meh, I'm working on GDPR requirements right now and that will be bundled in
dreamrealI have no objections to the GDPR in concept but the application requirements are inconsistent and maddening
dreamrealBut I have a plan
ChronosYou know... I wonder what happens if I use a dash dash in a me... testing...
* Chronos says -- what does this do? -- where does it go?
nevet* Chronos says -- what does this do? now has karma of -1.
ChronosInteresting!
dreamrealooof
dreamrealgross
dreamrealew
dreamreal:D
dreamrealemergent systems, yuck :D
* Chronos chuckles
dreamrealsentiment #nevet
nevetSentiment for irc://libera/%23nevet: +2/10 | Intensity mod | Themes: GitHub auth bikeshedding frustration, Java value classes debate, bot sentiment gaming, Project Valhalla | Summary: Tension from auth discussion frustration has cooled; blue tested sentiment manipulation with sarcasm; dreamreal amused by bot's sarcasm detection; conversation shifted to lighter technical topics | Drivers: blue,dreamreal
dreamrealthere's a lot of emergent design in nevet
ChronosHey, that's... damn good.
dreamrealkarma's an utter pain because it fights emergent design pretty regularly
dreamrealwhat, the sentiment analysis?
dreamrealyou wanna know the history there? :D
dreamrealit goes back to SURIAL!
dreamrealhe used to get all butthurt when people would say "chill out, you're being pretty negative here" - so I wrote a bayesian emulator trained off of his stuff in #java, and had it generate 300 statements from "him" as represented by bayes, and graded the sentiment from there
dreamreallike, "what would we think of a bot that was *trained* by your content, would we think it was negative"
dreamrealthe answer was quite surprising: "God, yes"
Chronosdreamreal: Yes, the sentiment analysis.
Chronosdreamreal: ha! :)
dreamrealI really wish surial hadn't left, but ... man, he cost as much as he provided or more, by being a jerk
dreamreal"Let me provide you a wagyu steak of knowledge, served with a heaping helping of charred kale seasoned by utter contempt, noob."
ChronosI recall the nick but not the personality behind the nick.
dreamreallombok author
dreamrealtended to be, uh, slightly ascerbic
dreamrealrather opinionated, like someone who goes "I really think this longstanding aspect of java isn't convenient for me, so I HATE JAVA despite being the one person who is actually enraged by this thing"
ChronosSounds like Zhivago that used to frequent #c
dreamrealOOOO I REMEMBER HIM!
dreamrealyeah
Chronosdreamreal: hahahaha
dreamrealor pudge on #perl
* Chronos hugs blue
dreamrealhey I didn't say it was blue
dreamrealpr dibblego in #scala, may tony morris be forever remembered
dreamrealoh wow, claude KNOWS WHO TONY MORRIS IS
dreamrealhahahaha
dreamrealIMMORTALITY AS AN ASSHOLE!
dreamrealthat's... pretty bad, if dibblego was so memorable that the LLMs remember him as being a jerk
dreamrealI mean, he IS pretty memorable: "I am a total asswipe douchenozzle because... hold on, checking the 8 ball... I have autism! No, wait, shaking it again... oh MY BACK IS INJURED"
dreamrealChronos: new push to the branch, actually fixed the things you pointed out, and thank you as always
dreamrealall this damn GDPR talk... grrr
blueblame timon on that
dreamrealhe's not wrong
dreamrealand fixing GDPR issues in the future is a lot harder than fixing them now
bluehe's being unnecessarily alarmit and FUDing
bluealarmist*
blueI'm the only one here who lives in Europe, to my knowledge
dreamrealI disagree: we have GDPR issues in another app we work on, and it's a true pain in the rear
blueI RAN a website/business in Europe
blueSo I tihnk I can be trusted on this GDPR nonsense
dreamrealyou are not, however, the only one who WORKS in Europe :D
bluethe GDPR is pretty straightforward. if you collect more than you need to collect, ie collect for the sake of collection, THEN it gets ugly
blueif you collect what you NEED to allow users to be users... it's trivial.
dreamrealthe main concern *I* have for GDPR is right to remove and collect; both issues are addressed.
bluewhat right to collect?
dreamrealuser have a right to download their data and contributions
dreamrealIANAL but andrew and I work with some
dreamrealso I added a hook to download posts and comments contributed by the user
blueyou don't need to mechanise it. it the user asks, you can provide it
blueas long as no users asks, it's theoretical
blueYAGNI
bluestop listening to timon
dreamreal1) shut up, don't tell me who to listen to 2) providing the endpoint for THAT was among the easiest aspects of the whole thing
dreamrealthat fell out of the data model almost by implication
blueeasy doesn't mean good!
blueliterally. how can I take a guy seriously who derailed a discussion about a SECURE auth measure into GDPR nonsense?
dreamrealI don't know how to answer that, because I could see it AND it's valuable
Chronosblue: Where in Europe do you live? If you don't mind saying.
ChronosHoly crap. My IRC client is giving me "xxx is typing" messages. Must be from some of the recent IRCv3 updates.
dreamrealwhich client are you on?
ChronosIRCCloud
ChronosI actually pay for it! (gasp!)
* dreamreal spots the dumbie
dreamrealbut that's fascinating. I didn't know libera even tried to do ircv3
ChronosI briefly considered installing TheLounge following their easy 200 step process, and configuring it correctly using another 200 step process, and keeping it up-to-date by following yet another easy 200 step process, but then I paid for IRCCloud.
Chronosdreamreal: Libera.Chat recently (like, within the last 2 weeks, or so) upgraded their IRC servers to a newer version that supports some new IRCv3 features.
* dreamreal just uses weechat like a masculine man who uses masculine manly things like a lumberjack
ChronosApparently, including typing indicators.
dreamrealI wonder when the other clients are gonna catch up
ChronosOver the years I've switched back and forth between irssi-on-Linux-VPS and IRCCloud.
ChronosWhen my IRCCloud subscription ends, maybe I'll try WeeChat. Does it have a mobile client that can connect to an instance of WeeChat?
dreamrealI don't think so, it would BE the mobile client, but it DOES have a sort of c/s architecture; I don't know how complete it is.
dreamrealsenpai apparently supports ircv3 but it's written in go
dreamrealgo doesn't bother me much but senpai looks very twee
dreamrealany further comments on that PR?
dreamrealI'd love to commit it so I can 1) pretend the issue's closed 2) hand it off to other people
Chronosdreamreal: lgtm.
dreamrealThanks!
dreamrealblue: merged, btw: dual-path, plus docs, all merged. I'm going to set up the prod deployment to support it, although obviously the UI is trailing now.
blueI'd been thinking about it, and I wonder how much I want to translate the actual back to primate paths. you see, using nextjs/primate is *a bit* of an overkill. they *both* are fullstack frameworks
bluethe actual backend*
blueso the level of indirection is significant. you have real backend, then 'fake' backend, then frontend
dreamrealare you talking about primate *replacing* the rest endpoints? talking to the DB directly?
blueI'm not. I'm just thinking where the seams would lie between the real backend and primate (or nextjs, for that matter)
dreamreal*nod*
blueboth are backends. primate could even run java -- or kotlin code -- via wasm. although that's somewhat futuristic given >=java 25 and some limitations without a jvm, no idea if your code specifically relies on that
nevetboth are backends. primate could even run java -- or kotlin code now has karma of -1.
blue(specifically=reflection)
blueat this point in time, I'm thinking about this: primate generates an openapi client using the spec. then, it exposes those paths directly via a /rest subpath
bluethe frontend using primate, whatever it is, talks directly to these subpaths
bluethough I'm not entirely convinced yet this is the best way to go about it
dreamrealand THEY redirect content to the actual backend, you mean?
blueyes. it's not even a proper redirect, the request is likely piped 1:1, almost
dreamreal*nod*
dreamrealI mean, that makes sense to me
dreamrealit's a little heavier - it adds a few ms to every interaction, but most interactions should be pretty quick
bluelike, I truly need to think about what having an interim backend even means. so one thing it means: we avoid any CORS nonsense. CORS is an absolute nightmare
dreamrealit is, but I'm going to have to address it anyway
dreamrealthe backend is already set up to accept CORS requests from different domains
blueby having the interim backend and the frontend on exactly the same domain (or subdomain), you completely eliminate this error category. it is probably worth having only for *that*
dreamreal*nod*
bluebut what else? like, what does the interim primate (or nextjs) backend add, exception indirection?
blueexcept*
dreamrealnot a lot, but that's probably a GOOD thing
bluewell, let's think what nevet *can't* do, at least in its current form & scope
blueit can't do SSR - it's not meant to do that
dreamrealSSR = ?
blueserver-side rendering
blueare you familiar with SPA/SSR/hydration, or should I shortly explain?
dreamrealno, I just needed to know what the acronym was, with you now
blueok. anyway, if you have a pure frontend (say, react) talk to nevet's backend -- which is a possibilities -- you would never get SSR. only SPA. that means your initial request is an empty HTML
nevetok. anyway, if you have a pure frontend (say, react) talk to nevet's backend -- which is a possibilities now has karma of -1.
bluethere's also of course the question of what static server serves those resources, which is yet another layer
bluenormally, that would be nginx
blueor apache, for the traditionalists
dreamrealI'm not going to be deploying httpd, it's nginx on my server, caddy's a possibility but ... it's nginx
bluebut let's assume for a moment that's a piece of the puzzle. in that case, your first contentful paint would be... not good
dreamrealmy thought was that each subdomain was *self-contained*
dreamrealso it's foo.bytecode.news and rest.bytecode.news, and everything is on those two domains for foo.bytecode.news to render
dreamrealthe nginx config does the proxy passthrough for both domains, and cert management
bluethere's also things like jwt/cookie management, and auth, which need to be address
blueaddressed, even
dreamrealwell, auth is part of the rest stuff - that's all the 67 stuff we just did, jwt is part of it too (and has been for a while), aad cookies are up to the front end
bluewhere I can see a primate backend shine is, composing complex operations on top of simple REST queries
dreamrealthe back end doesn't use them
bluefor example, the login sequence is composed of several API calls, but it might be hidden away under just one path
dreamrealright now, with OTP, we SHOULD be able to deploy *right now* with no OIDC providers set up
dreamrealsure
dreamrealI'm reorganizing the docs, btw
bluethis brings me to an organisational point: we need deployment docs. if I am to write a frontend, I need to be able to easily run nevet locally. docker could work, though I'd prefer nspawn (not a purist though -- if you furnish me with a Containerfile, I'll take care of it myself)
blue(why did nevet not pick up my last message as karma?)
blueI guess maybe cutoff limits
dreamrealyep
dreamrealI'm working on the docs, you SHOULD be able to run the backend in a container really easily
bluewell, that's the only way to properly test it and come across real implementation issues
dreamrealdpcker compose up db backend # should do it
bluecan you provide a Containerfile (or a Dockerfile, same thing really)?
bluealso, that'd probably require making the repo public?
dreamrealwhy would it require making it public? You have access to the repo: you can literally clone it, do `mvnd package`, then run docker
dreamreal(doing the build IN docker is bonkers mad, don't do that)
bluewhat's mvnd? the idea of a container is to avoid me having to have all these tools locally
dreamrealI get that, but yikes
dreamrealmain requirement for nevet is having java 25
dreamrealif you have that, you're done
blueI might have that; BUT, that's something ideally you shouldn't need to have
dreamrealjava 25 + the repo: ./mvnw package -DskipTests=true (if you know the repo is in known-good state)
blueiirc the only reason I have java 25 is because I was messing around with wasm :P
dreamrealyes, well, I agree but making the repo public and putting up a public container is a step I'm not ready for
bluetell you waht. can you bake a CP step from, say, ./repo, into the container?
bluethat's a good compromise, no?
dreamrealthat's literally what teh dockerfile does :D
blueyes but I meant the source code. the rest happens inside the container
blueso I can just do `git pull`, then rebuild the image
dreamrealoh, you CAN do that but it's a waste of 15 minutes
bluenot for me -- I use nspawn, which gives me essentially native performance
nevetnot for me now has karma of -1.
dreamrealit nets you NO win whatsoever
dreamrealI'm not familiar with nspawn, so I don't know - there's no ACTUAL barrier to building in a container outside of the container mechanism sucking
blueall you need to do is install mvnd inside the container and run it, no?
dreamrealit's just very slow and with far less CPU access; mvnd does parallel builds, if you have it installed, so I deploy nevet within about 30 second for a full rebuild, the full build with tests is about 1:40 on my M3
dreamrealonly if the container has full thread access
bluebonus is you get assurance the desired mvnd version is used for building
dreamrealit's going to be limited to the container's resources
blueso you get full reproducibility
bluewhich is perfect
dreamreal./mvnw gets you that already :D
blue*sigh*
bluefine, I'll do it YOUR way
dreamrealthat's the maven wrapper, I *do* lock the maven version, and maven's usually pretty good about it anyway
blueit's not you ever accept a suggestion of mine!
dreamrealwell, if any of your suggestions were good... but more seriously, I have a major project that does mvn builds in the container, and that process SUCKS for java
dreamrealand there's literally no win: cp app.jar into the container is the right way to go until we go graalvm. When we do THAT, you'll get your container builds.
bluealso chatgpt says there's no difference in speed between running mvn in docker or without
dreamreal(and builds will take 30 min, not 1;40 or 15 minutes.)
blueunless apparently, you're on mac
bluegreat
dreamrealI'm sure chatgpt does.
dreamrealIt's wrong, but hey.
blueyou know what? I don't care. I'll take your Containerfile and just edit it to fit MY purposes. It's not like I need to ask you for permission
dreamrealfor maven single-threaded, it's probably pretty close; docker's overhead wouldn't matter much. for parallel builds, it's a lot more severe.
dreamrealThere you go!
dreamrealjust don't commit it to main until I can approve it.
blueya
jreicherdreamreal: where's the discussion of why Strings aren't value classes? I feel like I've missed something (and I'm a bit curious about what everyone thinks)
dreamrealjreicher: I dunno, I don't live and die on valhalla discussion
dreamrealbut now my wife has made dinner and she's a lot prettier than you guys are
jreicherOh I thought there had been a discussion you had participated in
jreicherThat's not fair. You haven't seen me dresesd up.
blue[INFO] BUILD FAILURE
blue[ERROR] No goals have been specified for this build. You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: pre-clean, clean, post-clean, validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes,
jreicherblue: just saw earlier you said new String("foo") == new String("foo"). I'm guessing you think that should be true?
bluejreicher: yes
blue[ERROR] Failed to execute goal io.github.git-commit-id:git-commit-id-maven-plugin:9.0.2:revision (default) on project streampack:
blue[ERROR] The plugin io.github.git-commit-id:git-commit-id-maven-plugin:9.0.2 has unmet prerequisites:
blue[ERROR] Required Java version 11 is not met by current version: 1.8.0_482
jreicherRight. i think that's a useful way to talk about the real problem. Compare with 5 == 5, which is actually true. What's the massive difference between the two expressions?
blue➜ bytecode.news main ✓ java -version
bluehm, I guess it takes openjdk 8
blueTHIS IS WHY I HATE THIS NONSENSE
jreicherI don't know if you're reacting to what I said or the errors you're pasting
bluejreicher: no difference
jreicherThere absolutely is a difference. It's obvious, and large.
blueI was reacting to the errors I was pasting
bluewhat's the difference?
jreicher"new"
blueoh, you're gettign me wrong
blueI also think new Long(1) == new Long(1) should be true
bluewhich it will be, under valhalla
jreicherThe point I'm making is that new... == new... can't mean the same thing as literal == literal
jreicherSo even if you made it work the way you want, you have to supply a different meaning to == in the context of new
jreicherOr, put another way, the result of the comparison is not the same thing as the meaning of the comparison.
blueso, to go back to first principles, my position is that immutable variables: long, Long, int, Integer, String, should always parse == as 'by value'
jreicherThere's no such thing as an immutable variable. (I know that's horribly pedantic, but I want to tease out what you "really" mean
jreicherBecause if I do int x = 5, there's only one variable there
jreicherBut if I do Foo x = new Foo(), there could be too, if Foo is mutable
jreicher^too^two
bluecome on. you know what I mean. String s = new String("foo"); you can't change JUST 'f' to 'b'. You can rebind the variable to a new value, you cannot mutate it
jreicherOr more, actually, depending on how many mutable attributes Foo has
jreicherNo, I THINK I know what you mean, but I want to make sure I'm right.
bluesame for int i = 1; i = 2 is not mutation, but rebinding
jreicherOK, so you're talking about an immutable object there, right?
jreichernew String("foo") constructs an immutable object. That's what you mean?
blueyes. as do new Long, new Integer, or int, or long
jreicherYep. But if we do int x = 5, there's no construction at all. And that's what matters. Not mutability, but construction. Values aren't constructed.
blueThis is where we get into the territory of, to my taste, a distinction without merit. What matters to me is, can you think of a case where two "foo" objects differ in any meaningful (=real) way?
jreicherYes. At compile time. That's why this matters.
jreicherCompilers can do some value analysis. They can't do any immutable object analysis, becauses the objects don't exist yet.
blueYes, but you're pulling the cart before the horses here -- you're talkign about how it's technically currently done in the JVM. I'm talking about a use case
nevetYes, but you're pulling the cart before the horses here now has karma of -1.
blueI would like you to describe a use case where the distinction is important
bluelike, a real situation where it's good to have two strings "foo", and be able to compare them by identity -- but not by value
nevetlike, a real situation where it's good to have two strings "foo", and be able to compare them by identity now has karma of -1.
jreicherIf you already know the strings are "foo" then the scenario begs the question. We need to ask about this distinction where at least one of the strings is unknown.
blueI'll play devil's advocate for you
bluea real 'use case' is if you're writing a compiler in java, and objects are coming in, and you want to track (by identity) if you've already seen an object or not
jreicherOK...
bluethe rebuttal to this is: this is *not* a real use case. compilers aren't written this way: it's not effective at all, and you wouldn't be comparing references for that
bluemy personal issue is, no one has given me a real use case for comparing strings by identity and not value
bluemaybe it's all moot to you, but to me it'd help me understand why the == and .equals distinction makes sense, if it does
jreicherSo you're saying because nobody would ever compare with identity, that operation shouldn't even exist?
blueessentially yes: I'm saying, the only meaningful comparison of two strings is by value (=contents). the comparison by identity is not meaningful
blueyou would never construct two "foo" Strings and expect them to differ: for what purpose?
bluealso, consider the implications of this for project valhalla:
bluevalue class Point(int x, String y) {}
bluePoint p1 = new Point(1, "hi"); Point p2 = new Point(1, "hi"); p1 == p2; // false, string comparison broke it!
bluethe bottom line here: comparison by reference *only* makes sense for mutable objects, where the truthiness of the check could vary over time. but the two strings "foo" and "foo" will always be the same
blueiow: the original story of `new String("foo")` is meaningless
blues/original/origin/
dreamrealno, those would not be uneqial because of string comparison
dreamrealyou don't seem to grok references
dreamrealthink of them as pointers
bluewhat are you talking about?
jreicherOK, then for the sake of argument, how would you feel about the Java compiler throwing an error for == used on Strings. Meaning we change the == to being undefined in that case, and you can only use equals()
bluejreicher: THAT would be a huge improvement already!
dreamrealchar **c1=malloc(10); char **c2=malloc(10); strncpy(c1, "hello", 6); strncpy(c2, "hello", 6); // are c1 and c2 equal? Why not?
bluedreamreal: dude, you're COMPLETELY missing the point. you're talking about implementation. I'm talking about MEANING
bluejava is NOT a low-level manipulate-the-memory-directly language, the point holds not
jreicherblue: but the meaning of String, at least at the moment, is that it's not a value.
dreamrealI disagree, bevause that's literally where == is playing in
bluejreicher: that's the interpretation of the java language, but that's also my criticism
bluefor example, it is NOT the interesting of the javascript language
blues/interesting/interpretation/
jreicherIn that case we're not talking about == vs equals(). You're objecting to Java not having a primitive string type.
blueif you want to weave it that way, sure: the argumentation would be that strings are immutable, and as such, inherently primitive (as they are in js)
blueI don't mind shifting my argument there, that's fine by me, it's all the same to me
jreicherimmutability does not a value make. I think you need to separate those two things.
jreicherThe value is part of the STATIC definition of the type.
bluethe point remains that two occurences of the value "foo" (regardless if you do it via new String("foo"), or an idealised string primitive), are one and the same: the distinction here is invalid
jreicherIt's immutable as a consequence, but that's not the essential nature of it.
jreicherThere's no "foo" value in Java. It doesn't exist.
bluedo you mean it would be possible to constract a language where parts of a string are immutable? like c? sure
blueconstruct*
jreicherNo. I'm not talking about immutability at all. It's irrelevant.
jreicherThe only question that matters is value vs object
bluejreicher: then that's the criticism. values are much more important than object identity, for strings
jreicherThere are no string values in Java.
blueyes, I never claimed there were
jreicherOK. Then maybe we move on to the next part. Do you know why?
bluewhy it's implemented/done this way?
jreicherNot so much implemented as designed. It's a design decision, not an implementation decision.
blueis the history really relevant here?
jreicherIt's not history. The reasons for the decision still apply. If I was designing something like this now I'd probably do the same.
blueOK, what are the reasons?
jreicherMy understanding is that they wanted (needed?) all the value types to have a finite, fully determined range of values. That's true of everything "philosophically "considered a value, including enums. Strings are really very, very special in having a range of values constrained only by the memory available at runtime.
blueAnd strings would be unbounded?
jreicherStrings are currently unbounded AFAIK.
jreicherIn principle.
blueThat argumentation makes little sense to me, why would you want to impose that kind of restriction?
jreicherWould you be comfortable with an int type that was unbounded?
jreicher(It would be fine if you were; I'm just trying to get to the heart of the issue)
blueCan't say I would, but I can also not say it's relevant to the string discussion
blue(btw: having an unbounded int type such as BigInt in JS is immensely useful!)
jreicherNo argument with it being useful. But why would you be uncomfortable with it? That's probably worth teasing out.
blueI guess... I haven't thought about it, but I can't say I would and I can't say I wouldn't, I don't have an opinion on it, to be honest
jreicherOK. Well for the sake of argument we decide that our language is not going to have any unbounded value types, then the notion of string you are advocating is ruled out before we even start thinking about string.
jreicher...if we decide...
blueIs this not purely theoretical? I mean, JS doesn't have that problem. The ECMAScript standard allows up to 2^53-1 characters, but it's usually memory-bounded/limited by the engine.
jreicherJS has different problems. ;)
blueYes, but comparing strings by == isn't one of them, that's the crux of the matter
jreicherBut seriously I think the only way to make sense of the issue to take the big picture of all the tradeoffs. I'm sure I don't have the full picture, but I know enough to believe that a small view doesn't make sense.
blueTo be honest, I can't see downsides. If you compare all strings by value you can easily memoise them and save memory.
jreicherTo do what you want you either have to make string a value type, in which case you compromise a more fundamental decision in java, or you have to overload the meaning of == to cater for something which isn't a value type, which again compromises a more fundamental decision.
blueYes, I'd make it a value type. What fundamental decision I would compromise, the boundedness?
jreicherYep
jreicherAnd maybe that's ok
blueThen why allow new Long(1) == new Long(1) => true under valhalla, what's the difference?
jreicherI think so, yes, although I'm not sufficiently familiar with valhalla. I think a better comparison might be with what's in the JDK right now for bool. Just a moment...
jreicherIt jumped out at me recently that there's no non-generic version of the functions in java.util.function for boolean. AFAIK stuff like IntConsumer and IntPredicate exist so that if you have an (unboxed) int you don't have to incur the cost of boxing it to pass to e.g. Consumer<Integer> or anything like that. So they're saying that something like Consumer<Boolean> would not be expensive. Why? Because the boxed values are already
jreicherconstructed. There's only two of them.
jreicherSo anything that can be done without incurring this kind of runtime cost will be allowed
blueThere's another aspect I haven't mentioned, jreicher.
jreicherMm?
blueConsider this method: `public static boolean test(String a, String b) { return a == b }`
blueThis method returns true, or false, depending on the *origin* story of the strings. That's a big red flag, in my eyes.
bluetest("foo", "foo") => true, test("foo", new String("foo")) => false
bluethat's bad: there's no way for me, in the `test` function, to know what the origin story of a and b is
blueso I would *always* use .toEquals, instead
blueor .equals, I mean
bluethat means the == operator is *completely* useless for strings
blueto use it properly, I need full knowledge of the origin story of the string: contructed per new String, or per ""
bluethat's ridiculously broken, in my eyes
bluein any non trivial codebase, I will never have full knowledge of the origin story of a string
blueit even gets more complex that test("foo", "fo"+"o") will yield true. even dynamically created strings partake of it
bluebut now say I've extracted "o" to String o = "o";
bluesuddenly, test("foo", "fo"+o) => false
bluegenerally, extracting a direct value in a language to a variable should not create unintended side-effects; here it does
blue(or better said: in a *high-level* language; if you manage memory yourself as in c, you get value expansions and contractions all the time)
blueincidentally, this is a criticism I have of TypeScript. { foo: "bar" } passed directly to a function would satisify the exact type { foo: "bar" }; extracting this to a variable: const a = { foo: "bar" }; will expand it, resulting in a's type being { foo: string }
bluethat makes refactoring a nightmare
bluein my opinion, unless you gave TS a proper type: say, const a: { foo: string } = { foo: "bar" }; it should keep it narrowed, but it doesn't
blueautoexpanding/weird magic is crazily confusing, especially in high-level languages
jreicherblue: why would you not do `return a == b || a.equals(b)`? I think that's using object identity in exactly the way it's somewhat intended; as an optimisation
jreicher(I suspect equals() is implemented this way for String anyway)
bluejreicher: I could, but why should the language force me to do it? The language implies a distinction (== vs equals) without merit
blueif I could just do == for strings, none would be the worse for it
jreicherAnd I'm suggesting that the language doesn't give two hoots about == vs equals. It just "knows" that it has no notion of strings-as-values and everything else is a consequence that it doesn't care about.
blueWe're word-juggling at this stage; you're saying the language has no notion of strings-as-values, and I don't disagree -- that's a reductive form of my criticism
nevetWe're word-juggling at this stage; you're saying the language has no notion of strings-as-values, and I don't disagree now has karma of -1.
jreicherblue: because I do indeed thing your criticism reduces to something else. You are criticising the consequence o a decision that was made on unrelated grounds.
jreicherPlease note I have never said == for strings working the way you say is a bad idea. This is why.
blueThat's quite possible, jreicher. But even with knowledge of the decision's grounds (boundedness), I still think it was the wrong decision. Sure, telling people to just "suck it up and that's how Java does things, and you're a n00b if you don't get it" (dreamreal style), is possible. It's just not very useful.
blueI don't care about being a good or bad Java programmer -- I care about using languages that help me not do crazy nonsense. That's why I use very strict linting rules for JavaScript, because JavaScript has its fair share of brokenness.
nevetI don't care about being a good or bad Java programmer now has karma of -1.
jreicherOK, I'll put in some of my own opinion here. I believe most people expect the runtime of operators to be bounded in any language that does not have operator overloading. (That last bit is important.) So I believe there is an expectation that == should have bounded runtime. You can probably see where I'm going.
jreicherAnd I have some experience with the flip side of this. The number of corporate application problems I have had to deal with because some idiot dev though string comparisons on a database came for free...
blueSo you're talking about runtime optimisations?
jreicherNot optimisations. The fundamental definition of the performance. The predictability of it. The expectation.
blueWell, if such an expectation exists, I certainly cannot see it being used in JS.
jreicherI did say JS has different problems. :)
blueTrue... for example, I don't use the == operator in JS, at all.
blueThe coercion rules are arbitary and an endless source of confusion.
blueI also configure my eslint to only allow boolean expressions in `if`, i.e., no casting. if("foo") would pop up as an error.
jreicherThat's why predictability in language is important. And on the flip of the flip side I'm all in favour of having unpredictable performance in contexts where performance is not the primary concern.
jreicherAnd in those contexts I would be completely on your side about something like the meaning of ==
blue(reason: if ("") "hi" -> undefined; if ("1") "hi" => "hi"
jreicher(probably)
blue(since the real check you want here is probably: if (str !== ""), or better expressed: if(str.length > 0)
blueanyway, yes
bluepredictability is superimportant. overloading operators is very confusing
bluedreamreal at least agreed that + for strings is weird... unfortunately, it's become an almost global standard
jreicherOh interesting. I missed that comment.
jreicherBut what I've been saying probably supports that. It's an operator with unbounded performance. Possibly the only one in Java. (I have to think about that)
blueJS is totally weird on that, btw: [] + [] is ""... that's funky
jreicherI guess you could say "new" is in that category also. I think it's an operator.
bluenew is definitely an operator
jreicherPeople who defend string + probably say it implies new
jreicher...and is right to do so
blueyou know, come to think of it, my real pet peeve isn't even `new`. It's just the fact that `String foo = "foo";` is fundamentally different to 'just' "foo"
blueIOW: we can leave the operator new completely out of the discussion. It's not even the crux of the matter, to be honest
jreicherNot sure I'm following, but you have my interest. Can you elaborate?
blueAs said, consider my example from earlier:
bluetest("foo", "foo") is true
bluetest("foo", "fo"+"o") is also true
blueString o = "o"; test("foo", "fo"+o) is false
bluethere's no `new` involved anywhere here
bluewe've only extracted "o" onto a variable, and broken things with it
bluethat's... unpredictable.
bluethis class of errors can never happen in JS. It's impossible to extract a value to a variable and break stuff with it.
blueit's a category error that doesn't exist in JS
blueAs a programmer, it's important to me to be able to refactor such things with the utter confidence that I'm not breaking anything. Java fails that promise.
blueAs a Java programmer, I now need to be *aware* of the implementation detail of `test`, namely that it uses `==`.
blueBut I can't always do that -- nor should I. `test` might be coming from somewhere else, or I might not even be able to look into it
nevetBut I can't always do that now has karma of -1.