What is Hackers' Pub?

Hackers' Pub is a place for software engineers to share their knowledge and experience with each other. It's also an ActivityPub-enabled social network, so you can follow your favorite hackers in the fediverse and get their latest posts in your feed.

0
0
0
1
0
0

🍝 저의 주님, 날아다니는 스파게티 괴물 님, 저를 보호하시어 살펴주소서.
😋 어서 구원하시어 혼자 내버려 두지 마소서.

🍝 날아다니는 스파게티 괴물 님께서 여러분과 함께.
😋 또한 주교의 면발과 함께 하소서.
🍝 기도합시다.
지극히 선하신 스파게티 괴물 님, 사람들이 더욱더 완전한 것을 이루기 위해서 서로 협조하여 일하게 해주셨으니,
저희 기도를 들으시고 저희가 항상 우정을 품고, 모든 이들을 위한 박애로 끊임없이 일하게 하소서.

"7. 진리와 정의를 따르며 일할 수 있도록, 주님의 소스가 저희 내면을 강하게 하소서."

🍝 날아다니는 스파게티 괴물 님께서 여러분과 함께.
😋 또한 주교의 면발과 함께 하소서.
🍝 전능하신 스파게티 괴물 님, 미트볼🧆과 소스🥫와 성면🍝께서는 여기 모인 모든 이에게 강복하소서.
😋 라-멘 🍜.

🍝 날아다니는 스파게티 괴물 님을 찬미합시다.
😋 주님 감사합니다.

2026-01-02T15:16:39+09:00


0
0
0
0
0
0
1
0
1
1

DC가 비교적 덜 해롭던 시기가 있었기는 하나 DC가 (어려운 상황) 청소년들의 해방구, 안식처, 휴식 공간인 것처럼 주장하는 사람들하곤 도저히 이야기 나누기가 어려웠음. 그리고 2025년 기준으로 디시-아카 기준 덜 해로운 갤이 있을진 몰라도 미성년자와 멘탈이 취약한 사람에게 안전한 갤은 없다고 단언할 수 있다.

RE: https://bsky.app/profile/did:plc:a6qvfkbrohedqy3dt6k5mdv6/post/3mbg7ultfxk2z

0
0
1

[단독] 일베는 안되고 클리앙은 된다… 부천시의 이상한 인터넷 검열

n.news.naver.com/article/053/0

ㅋㅋㅋ 조선일보의 바램은
일단 클리앙을 일베의 대척점인 극좌로 놓아서
일베의 비정상적인면을 희석시키고, 클리앙 이미지를 안좋게 하고 싶나 본데

요즘 클리앙이 뭐 많이 썩었어도, 일베에 비할정도는 아니야.

무려 네이버, 조선쪽 댓글인데, 댓글마저 일베와 기자를 비난하는 중. ㅋㅋㅋㅋ

0
0
0

GPLv2 affirmation…

I don’t generally post here as people have probably noticed, but here’s a pdf of a recent court ruling, and this turns out to be the easiest way for me to link to a copy of it, since I don’t really maintain any web presence normally and I don’t want to post pdf’s to the kernel mailing lists or anything like that.

And the reason I want to post about it, is that it basically validates my long-held views that the GPLv2 is about making source code available, not controlling the access to the hardware that it runs on.

The court case itself is a mess of two bad parties: Vizio and the SFC. Both of them look horribly bad in court - for different reasons.

Vizio used Linux in their TVs without originally making the source code available, and that was obviously not ok.

And the Software Freedom Conservancy then tries to make the argument that the license forces you to make your installation keys etc available, even though that is not the case, and the reason why the kernel is very much GPLv2 only. The people involved know that very well, but have argued otherwise in court.

End result: both parties have acted badly. But at least Vizio did fix their behavior, even if it apparently took this lawsuit to do so. I can’t say the same about the SFC.

Please, SFC - stop using the kernel for your bogus legal arguments where you try to expand the GPLv2 to be something it isn’t. You just look like a bunch of incompetent a**holes.

The only party that looks competent here is the judge, which in this ruling says

Plaintiff contends the phrases, “machine-readable” and “scripts used to control compilation and installation” support their assertion in response to special interrogatory no. 4 that Defendant should “deliver files such that a person of ordinary skill can compile the source code into a functional executable and install it onto the same device, such that all features of the original program are retained, without undue difficulty.”

The language of the Agreements is unambiguous. It does not impose the duty which is the subject of this motion.

Read as a whole, the Agreements require Vizio to make the source code available in such a manner that the source code can be readily obtained and modified by Plaintiff or other third parties. While source code is defined to include “the scripts used to control compilation and installation,” this does not mean that Vizio must allow users to reinstall the software, modified or otherwise, back onto its smart TVs in a manner that preserves all features of the original program and/or ensures the smart TVs continue to function properly. Rather, in the context of the Agreements, the disputed language means that Vizio must provide the source code in a manner that allows the source code to be obtained and revised by Plaintiff or others for use in other applications.

In other words, Vizio must ensure the ability of users to copy, change/modify, and distribute the source code, including using the code in other free programs consistent with the Preamble and Terms and Conditions of the Agreements. However, nothing in the language of the Agreements requires Vizio to allow modified source code to be reinstalled on its devices while ensuring the devices remain operable after the source code is modified. If this was the intent of the Agreements, the Agreements could have been readily modified to state that users must be permitted to modify and reinstall modified software on products which use the program while ensuring the products continue to function. The absence of such language is dispositive and there is no basis to find that such a term was implied here. Therefore, the motion is granted.

IOW, this makes it clear that yes, you have to make source code available, but no, the GPLv2 does not in any way force you to then open up your hardware.

My intention - and the GPLv2 - is clear: the kernel copyright licence covers the software, and does not extend to the hardware it runs on. The same way the kernel copyright license does not extend to user space programs that run on it.

0
0
0

I’ve just created a new Django starter pack on FediDevs 👀

It collects non-human accounts only: Django projects, conferences, podcasts, news, and community initiatives.
No personal accounts, just things you may want to follow once and forget.

👉 fedidevs.com/s/Nzk4/?v=1

If you know other Django-related project accounts on the Fediverse, please reply and suggest them.
Happy to keep improving this together 💚

Please reboot 🙏

CC @fedidevs

0
0
1

전세사기를 방지하기 위해 확인해야할 서류들은 다음과 같습니다.

** 중개대상물 확인 설명서.. 에 ( 개업 공인중개사 세부사항 확인 - >실제 권리관계 또는 공시되지
않은 권리사항 ) 확인해서 중개인 설명과 일치하는지 확인

** 전입세대 열람원, 확정일자 부여 현황 서류는 집주인, 이미 계약한 임차인만 뗄 수 있는 서류이므로
돈 받고 중개하는 중개인에게 요구할 것.. 만약 거절한다면 사기 가능성, 계약하지 말아야..
** 받아야 할 서류( 임대차 계약서, 중개대상물 확인 설명서, 등기부 등본, 세금 납입 증명서,
전입세대 열람원, 확정일자 부여 현황 ) 곤란하다 거절하면 계약하지 말아야..

해지권 - 나중에 서류와 실제 내용이 다르면 즉시 계약해지하고 집주인이 손해배상한다는 내용
그런데 해지권은 개인적으로 생각하기에 있으나마나..

0
0
0
0
0

전세사기를 방지하기 위해 확인해야할 서류들은 다음과 같습니다.

** 중개대상물 확인 설명서.. 에 ( 개업 공인중개사 세부사항 확인 - >실제 권리관계 또는 공시되지
않은 권리사항 ) 확인해서 중개인 설명과 일치하는지 확인

** 전입세대 열람원, 확정일자 부여 현황 서류는 집주인, 이미 계약한 임차인만 뗄 수 있는 서류이므로
돈 받고 중개하는 중개인에게 요구할 것.. 만약 거절한다면 사기 가능성, 계약하지 말아야..
** 받아야 할 서류( 임대차 계약서, 중개대상물 확인 설명서, 등기부 등본, 세금 납입 증명서,
전입세대 열람원, 확정일자 부여 현황 ) 곤란하다 거절하면 계약하지 말아야..

해지권 - 나중에 서류와 실제 내용이 다르면 즉시 계약해지하고 집주인이 손해배상한다는 내용
그런데 해지권은 개인적으로 생각하기에 있으나마나..

0
1
2
0

Number of people who go bankrupt every year because of medical bills or illness-related work loss:

🇦🇺 0
🇨🇦 0
🇩🇰 0
🇫🇮 0
🇫🇷 0
🇩🇪 0
🇮🇸 0
🇮🇪 0
🇮🇹 0
🇯🇵 0
🇳🇱 0
🇳🇴 0
🇵🇹 0
🇪🇸 0
🇸🇪 0
🇬🇧 0
🇺🇸 530,000

There’s a lesson there.

0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0

저도 패치나 번역 찾으러 가본 적이 있긴 한데, 2010-2015 기준으로 제 주변 사람들은 디씨를 거의 안 갔습니다. 몇몇 유행에 민감한 친구들 말고는... 디시 김유식이 하이텔 출신인 것처럼, PC통신과 디시의 관계도 부정하긴 어려울텐데, 이글루 시기까지만 해도 같이 놀긴 했거든요. 어느 시점부터 디씨-일베-극우화가 어떤 선을 넘은게 아닌가 생각하고 있음.

0

Wrote about designing type-safe sync/async mode support in TypeScript. Making object({ sync: syncParser, async: asyncParser }) automatically infer as async turned out to be trickier than expected.

Designing type-safe sync/async...

Designing type-safe sync/async mode support in TypeScript

I recently added sync/async mode support to Optique, a type-safe CLI parserfor TypeScript. It turned out to be one of the trickier features I'veimplemented—the object() combinator alone needed to compute a combined modefrom all its child parsers, and TypeScript's inference kept hitting edge cases. What is Optique? Optique is a type-safe, combinatorial CLI parser for TypeScript, inspired byHaskell's optparse-applicative. Instead of decorators or builder patterns,you compose small parsers into larger ones using combinators, and TypeScriptinfers the result types. Here's a quick taste: import { object } from "@optique/core/constructs";import { argument, option } from "@optique/core/primitives";import { string, integer } from "@optique/core/valueparser";import { run } from "@optique/run";const cli = object({ name: argument(string()), count: option("-n", "--count", integer()),});// TypeScript infers: { name: string; count: number | undefined }const result = run(cli); // sync by default The type inference works through arbitrarily deep compositions—in most cases,you don't need explicit type annotations. How it started Lucas Garron (@lgarron) opened an issue requestingasync support for shell completions. He wanted to provideTab-completion suggestions by running shell commands likegit for-each-ref to list branches and tags. // Lucas's example: fetching Git branches and tags in parallelconst [branches, tags] = await Promise.all([ $`git for-each-ref --format='%(refname:short)' refs/heads/`.text(), $`git for-each-ref --format='%(refname:short)' refs/tags/`.text(),]); At first, I didn't like the idea. Optique's entire API was synchronous, whichmade it simpler to reason about and avoided the “async infection” problem whereone async function forces everything upstream to become async. I argued thatshell completion should be near-instantaneous, and if you need async data, youshould cache it at startup. But Lucas pushed back. The filesystem is a database, and many usefulcompletions inherently require async work—Git refs change constantly, andpre-caching everything at startup doesn't scale for large repos. Fair point. What I needed to solve So, how do you support both sync and async execution modes in a composableparser library while maintaining type safety? The key requirements were: parse() returns T or Promise<T> complete() returns T or Promise<T> suggest() returns Iterable<T> or AsyncIterable<T> When combining parsers, if any parser is async, the combined resultmust be async Existing sync code should continue to work unchanged The fourth requirement is the tricky one. Consider this: const syncParser = flag("--verbose");const asyncParser = option("--branch", asyncValueParser);// What's the type of this?const combined = object({ verbose: syncParser, branch: asyncParser }); The combined parser should be async because one of its fields is async.This means we need type-level logic to compute the combined mode. Five design options I explored five different approaches, each with its own trade-offs. Option A: conditional types with mode parameter Add a mode type parameter to Parser and use conditional types: type Mode = "sync" | "async";type ModeValue<M extends Mode, T> = M extends "async" ? Promise<T> : T;interface Parser<M extends Mode, TValue, TState> { parse(context: ParserContext<TState>): ModeValue<M, ParserResult<TState>>; // ...} The challenge is computing combined modes: type CombineModes<T extends Record<string, Parser<any, any, any>>> = T[keyof T] extends Parser<infer M, any, any> ? M extends "async" ? "async" : "sync" : never; Option B: mode parameter with default value A variant of Option A, but place the mode parameter first with a defaultof "sync": interface Parser<M extends Mode = "sync", TValue, TState> { readonly $mode: M; // ...} The default value maintains backward compatibility—existing user code keepsworking without changes. Option C: separate interfaces Define completely separate Parser and AsyncParser interfaces withexplicit conversion: interface Parser<TValue, TState> { /* sync methods */ }interface AsyncParser<TValue, TState> { /* async methods */ }function toAsync<T, S>(parser: Parser<T, S>): AsyncParser<T, S>; Simpler to understand, but requires code duplication and explicit conversions. Option D: union return types for suggest() only The minimal approach. Only allow suggest() to be async: interface Parser<TValue, TState> { parse(context: ParserContext<TState>): ParserResult<TState>; // always sync suggest(context: ParserContext<TState>, prefix: string): Iterable<Suggestion> | AsyncIterable<Suggestion>; // can be either} This addresses the original use case but doesn't help if async parse() isever needed. Option E: fp-ts style HKT simulation Use the technique from fp-ts to simulate Higher-Kinded Types: interface URItoKind<A> { Identity: A; Promise: Promise<A>;}type Kind<F extends keyof URItoKind<any>, A> = URItoKind<A>[F];interface Parser<F extends keyof URItoKind<any>, TValue, TState> { parse(context: ParserContext<TState>): Kind<F, ParserResult<TState>>;} The most flexible approach, but with a steep learning curve. Testing the idea Rather than commit to an approach based on theoretical analysis, I createda prototype to test how well TypeScript handles the type inference in practice.I published my findings in the GitHub issue: Both approaches correctly handle the “any async → all async” rule at thetype level. (…) Complex conditional types likeModeValue<CombineParserModes<T>, ParserResult<TState>> sometimes requireexplicit type casting in the implementation. This only affects libraryinternals. The user-facing API remains clean. The prototype validated that Option B (explicit mode parameter with default)would work. I chose it for these reasons: Backward compatible: The default "sync" keeps existing code working Explicit: The mode is visible in both types and runtime (via a $modeproperty) Debuggable: Easy to inspect the current mode at runtime Better IDE support: Type information is more predictable How CombineModes works The CombineModes type computes whether a combined parser should be sync orasync: type CombineModes<T extends readonly Mode[]> = "async" extends T[number] ? "async" : "sync"; This type checks if "async" is present anywhere in the tuple of modes.If so, the result is "async"; otherwise, it's "sync". For combinators like object(), I needed to extract modes from parserobjects and combine them: // Extract the mode from a single parsertype ParserMode<T> = T extends Parser<infer M, unknown, unknown> ? M : never;// Combine modes from all values in a record of parserstype CombineObjectModes<T extends Record<string, Parser<Mode, unknown, unknown>>> = CombineModes<{ [K in keyof T]: ParserMode<T[K]> }[keyof T][]>; Runtime implementation The type system handles compile-time safety, but the implementation also needsruntime logic. Each parser has a $mode property that indicates its executionmode: const syncParser = option("-n", "--name", string());console.log(syncParser.$mode); // "sync"const asyncParser = option("-b", "--branch", asyncValueParser);console.log(asyncParser.$mode); // "async" Combinators compute their mode at construction time: function object<T extends Record<string, Parser<Mode, unknown, unknown>>>( parsers: T): Parser<CombineObjectModes<T>, ObjectValue<T>, ObjectState<T>> { const parserKeys = Reflect.ownKeys(parsers); const combinedMode: Mode = parserKeys.some( (k) => parsers[k as keyof T].$mode === "async" ) ? "async" : "sync"; // ... implementation} Refining the API Lucas suggested an important refinement during ourdiscussion. Instead of having run() automatically choose between sync andasync based on the parser mode, he proposed separate functions: Perhaps run(…) could be automatic, and runSync(…) and runAsync(…) couldenforce that the inferred type matches what is expected. So we ended up with: run(): automatic based on parser mode runSync(): enforces sync mode at compile time runAsync(): enforces async mode at compile time // Automatic: returns T for sync parsers, Promise<T> for asyncconst result1 = run(syncParser); // stringconst result2 = run(asyncParser); // Promise<string>// Explicit: compile-time enforcementconst result3 = runSync(syncParser); // stringconst result4 = runAsync(asyncParser); // Promise<string>// Compile error: can't use runSync with async parserconst result5 = runSync(asyncParser); // Type error! I applied the same pattern to parse()/parseSync()/parseAsync() andsuggest()/suggestSync()/suggestAsync() in the facade functions. Creating async value parsers With the new API, creating an async value parser for Git branches lookslike this: import type { Suggestion } from "@optique/core/parser";import type { ValueParser, ValueParserResult } from "@optique/core/valueparser";function gitRef(): ValueParser<"async", string> { return { $mode: "async", metavar: "REF", parse(input: string): Promise<ValueParserResult<string>> { return Promise.resolve({ success: true, value: input }); }, format(value: string): string { return value; }, async *suggest(prefix: string): AsyncIterable<Suggestion> { const { $ } = await import("bun"); const [branches, tags] = await Promise.all([ $`git for-each-ref --format='%(refname:short)' refs/heads/`.text(), $`git for-each-ref --format='%(refname:short)' refs/tags/`.text(), ]); for (const ref of [...branches.split("\n"), ...tags.split("\n")]) { const trimmed = ref.trim(); if (trimmed && trimmed.startsWith(prefix)) { yield { kind: "literal", text: trimmed }; } } }, };} Notice that parse() returns Promise.resolve() even though it's synchronous.This is because the ValueParser<"async", T> type requires all methods to useasync signatures. Lucas pointed out this is a minor ergonomic issue. If onlysuggest() needs to be async, you still have to wrap parse() in a Promise. I considered per-method mode granularity (e.g., ValueParser<ParseMode, SuggestMode, T>), but the implementation complexity would multiplysubstantially. For now, the workaround is simple enough: // Option 1: Use Promise.resolve()parse(input) { return Promise.resolve({ success: true, value: input });}// Option 2: Mark as async and suppress the linter// biome-ignore lint/suspicious/useAwait: sync implementation in async ValueParserasync parse(input) { return { success: true, value: input };} What it cost Supporting dual modes added significant complexity to Optique's internals.Every combinator needed updates: Type signatures grew more complex with mode parameters Mode propagation logic had to be added to every combinator Dual implementations were needed for sync and async code paths Type casts were sometimes necessary in the implementation to satisfyTypeScript For example, the object() combinator went from around 100 lines to around250 lines. The internal implementation uses conditional logic based on thecombined mode: if (combinedMode === "async") { return { $mode: "async" as M, // ... async implementation with Promise chains async parse(context) { // ... await each field's parse result }, };} else { return { $mode: "sync" as M, // ... sync implementation parse(context) { // ... directly call each field's parse }, };} This duplication is the cost of supporting both modes without runtime overheadfor sync-only use cases. Lessons learned Listen to users, but validate with prototypes My initial instinct was to resist async support. Lucas's persistence andconcrete examples changed my mind, but I validated the approach with aprototype before committing. The prototype revealed practical issues (likeTypeScript inference limits) that pure design analysis would have missed. Backward compatibility is worth the complexity Making "sync" the default mode meant existing code continued to workunchanged. This was a deliberate choice. Breaking changes should requireuser action, not break silently. Unified mode vs per-method granularity I chose unified mode (all methods share the same sync/async mode) overper-method granularity. This means users occasionally writePromise.resolve() for methods that don't actually need async, but thealternative was multiplicative complexity in the type system. Designing in public The entire design process happened in a public GitHub issue. Lucas, Giuseppe,and others contributed ideas that shaped the final API. TherunSync()/runAsync() distinction came directly from Lucas's feedback. Conclusion This was one of the more challenging features I've implemented in Optique.TypeScript's type system is powerful enough to encode the “any async means allasync” rule at compile time, but getting there required careful design work andprototyping. What made it work: conditional types like ModeValue<M, T> can bridge the gapbetween sync and async worlds. You pay for it with implementation complexity,but the user-facing API stays clean and type-safe. Optique 0.9.0 with async support is currently in pre-release testing. Ifyou'd like to try it, check out PR #70 or install the pre-release: npm add @optique/core@0.9.0-dev.212 @optique/run@0.9.0-dev.212deno add --jsr @optique/core@0.9.0-dev.212 @optique/run@0.9.0-dev.212 Feedback is welcome!

hackers.pub · Hackers' Pub

Link author: 洪 民憙 (Hong Minhee)@hongminhee@hackers.pub

0