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
0
0
0
0
0
0
0
0
0

This is utterly fascinating, and something I’ve felt for years. If I listen to a piece of music that I’m very familiar with after a bike ride or a swim, the tempo definitely feels really slow. It’s downright weird.

I bet that if you asked me to tap to the rhythm from memory, I’d be off by about 10%, consistently.

theguardian.com/science/2025/m

0
0

[르포] 대피소 어르신들이 위험하다…차가운 바닥 쪽잠·의약품도 없어 송고2025-03-27 16:30 산불 피해자 다수 '지역소멸 우려' 지역 고령자들…1만5천369명 이재민 힘든 사투 끝 안 보이는 대피소 생활에 지쳐가…"막막한데, 돌아갈 곳은 없고" www.yna.co.kr/view/AKR2025...

[르포] 대피소 어르신들이 위험하다…차가운 바닥 쪽잠·...

0

妥協しないプライバシー: Proton VPN を搭載した Vivaldi が登場

日々、変化し続けているウェブ。

独占的なテックジャイアントが支配する世界に、ユーザーは気づきつつあります。プロファイリングよりもプライバシーを、監視よりも主権を、惰性よりも独立を選び始めています。

そして、この変化の中心には、ユーザーを搾取するのではなく、ユーザーを尊重するツールがあります。

だからこそ、私たちは今回の大きな発表は我々の誇りです。 Vivaldi 向け Proton VPN の登場です。

ジャーナリスト、活動家、そしてプライバシーを重視する人々から信頼されている世界トップクラスの VPN が、デスクトップ版 Vivaldi にネイティブで搭載されました。追加のダウンロードも、複雑な設定も一切不要。あなたに合うパワフルなプライバシー保護を実現します。

必然的なパートナーシップ

Vivaldi と Proton は、単なる製品ビジョンを共有しているだけでなく、価値観も共有しています。

私たちはどちらもヨーロッパの企業であり、シリコンバレーの搾取的な手法や中国の国家主導の監視から距離を置いています。あなたの個人データがビジネスの材料になるべきだとは考えていません。

このパートナーシップにより、私たちはユーザーのために技術を作る2つの力を結集します。成長のテクニックや株主向けの資料のためではなく、ウェブを利用する人々のために守ることが目的です。

ヨーロッパの必須事項としてのプライバシー

政府もユーザーも、特に地政学的緊張の高まりを受けて、テクノロジーとの関係を再検討しています。その結果、独立した中立的で、価値観に基づいたソリューションへの需要が大幅に増加しています。

ヨーロッパにはヨーロッパ発の代替案が必要です。実際、誰もがヨーロッパ発の代替案を使う価値があります。Vivaldi と Proton は、まさに完璧な代替案。隠された裏口はもちろんなく、国家による監視もありません。政治的な連携もなく、ウェブを開放的で、安全、そして民主的なものとして保つというコミットメントだけがあるのです。

Proton を選んだわけ

Proton は、たぐいまれなテクノロジー企業として一貫してその実力を証明してきました。侵入的な監視法に立ち向かい、政府を裁判にかけ、世界中のユーザーの権利を守るために戦っています。そのミッションは透明であり、その行動は市場がいかに大きな声で伝えようとも、ものともしません。Proton はスイスの非営利団体によって運営され、政治的な偏りはありません。Vivaldi が政治的に中立であるのと同様に、Proton も中立です。そして、Vivaldi と同じように、Proton もより良いウェブのために戦っています。そして今、私たちはそれを共に行っています。あなたも私たちと一緒に参加しませんか?

Vivaldi ブラウザのウィンドウに Proton VPN のメニューが開かれており、アクティブな VPN 接続が表示されています。

Vivaldi で Proton VPN を有効にする方法

手順:

  1. デスクトップで最新バージョンの Vivaldi を使用していることを確認してください。
  2. ツールバーの「VPN」ボタンをクリックします。
  3. Vivaldi アカウントにログインするか、新しいアカウントを作成します。
  4. スイッチをオンにするだけです。それだけで、あなたのプライバシーは保護されます。

Proton VPN を搭載した最新バージョンの Vivaldi をぜひお試しあれ!

https://vivaldi.com/ja/blog/privacy-without-compromise-proton-vpn-is-now-built-into-vivaldi/

Vivaldi ブラウザのウィンドウに Proton VPN のメニューが開かれており、アクティブな VPN 接続が表示されています。
0

サウジのムハンマド皇太子は自分に都合の悪いジャーナリストの殺害を指示する程度に権力を持った悪人なんだけど、そいつがゲーム好きでゲーム会社のSNKを買収してんだわ。そのSNK新作の格ゲー餓狼cotwにクリロナがプレイアブルキャラとして発表されたんだけど、なぜかってクリロナ今はサウジでプレーしてるから。そういう構図が気持ち悪いんだわ。
e-sports Wcup が去年サウジで開催されてて、今年もやるんだろうけど、それにプロゲーマーが嬉々として参加してんのも、みっともねえって思う。オメーらこんな悪人が対戦ゲーム文化の今後を担っていいのか、ケツ持ちでいいのかっていう。

0

Occasionally I say something on here I rethink or regret and delete before there is any engagement.

Sometimes I’m given feedback and declare I’ve deleted my post because that’s the right thing to do.

*Once engagement happens*, I think it’s quite important to be open about being wrong or unwise.

So I’m always slightly taken aback when people reply with excoriating confidence and then just quietly delete their post after I point them at some further info

0
0
0

[재업] 대전에서 한겨레와 만나요🍞 한겨레가 곧 37번째 생일을 맞이합니다. 이를 기념해 독자님들과 만나는 자리를 마련했는데요. 어떠한 주제로 꾸릴지 고민하다 ‘민주주의’에 대한 이야기를 나누기로 했습니다. 다사다난한 겨울이었지만, 한밭(대전의 옛 이름) 가득 피어날 민주주의를 기대하면서요.

0
0
0
0
0
1
0
0
0

Writing a tiny undo/redo stack in JavaScript

Link: blog.julik.nl/2025/03/a-tiny-u
Discussion: news.ycombinator.com/item?id=4

UI Algorithms: A Tiny Undo Stack

I’ve needed this before - a couple of times. Third time I figured I needed something small, nimble - yet complete. And - at the same time - wondering about how to do it in a very simple manner. I think it worked out great, so let’s dig in. Undo histories and managers Most UIs will have some form of undo functionality. Now, there are generally two forms of it: undo stacks and version histories. A “version history” is what Photoshop history gives you - the ability to “paint through” to a previous state of the system. You can add five paint strokes, and then reveal a stroke you have made 4 steps back. But most apps won’t need that. What you will need is an undo stack, which can be specced out as follows: An undoable action gets performed and gets pushed onto the stack. If undo is requested, the stack is popped and the rollback action gets applied for the popped action. If an action was undone, you can redo that action. If you have undone 2 actions, you can redo 2 actions. If you push an undoable action onto the stack in presence of actions that can be redone, they get discarded - there is no branching, remember? If you are curious how “the big guys” used to do it - check out the NSUndoManager documentation So, as I usually like to do, I want to understand the API that would be optimal. For this use case - drawing - I had the following workflow: When you draw a stroke the input points get added to currentStroke When you release the pen the currentStroke gets appended to strokes and reset for the next stroke. I wanted something like this: let addStroke = () => strokes.push(currentPaintStroke); let removeStroke = () => strokes.pop(); undoThing.push(addStroke, removeStroke); // then, on user action undoThing.undo(); // calls removeStroke() undoThing.redo(); // calls strokes.push(...) again The perils of stack pointers Simplest thing in the world. Now, if you look at most recommended (and some existing!) implementations of an undo stack, you will find they usually make use of a stack with a pointer. Like here and here - you would have a stack, usually represented as a JS array, and some kind of pointer or an index that you would use to index into it. And while it is workable and standard, it just didn’t jive with me well. See, using an index into an array usually makes JS code susceptible to two things, which bite me every single time: Indexing into a nonexistent index - hello undefined checks Mistakes in offsets when calling Array.slice and Array.splice. Oh, and confusing slice and splice, of course. The fact that Ruby and JS have different semantics for slice - one uses the index bounds, the other uses two offsets - doesn’t help things. And what happens if an API uses offsets into a vector? Exactly: confusion whether those offsets are inclusive or exclusive. Oh, and the offsets change after you mutate the array, which makes it even more painful. Could we not index? So what came to mind was this: we effectively have two stacks, not one. We have an undoStack (things that can be rolled back) and a redoStack - things that can be rolled forward. All the things we do with our undo-redo actions actually do not change the pointer - they move things from one stack to another. And rules change between these two stacks! We erase the redoable actions when we add a new undoable action, remember? So while an undoable stack will rarely get “nullified”, the redoable stack likely will be nullified frequently. Once this became clear, the implementation practically wrote itself: function createUndoStack() { let past = []; let future = []; return { push(doFn, undoFn) { doFn(); past.push({doFn, undoFn}); // Adding a new action wipes the redoable steps future.length = 0; }, undo() { let action = past.pop(); if (action) { action.undoFn(); future.unshift(action); } }, redo() { let action = future.unshift(); if (action) { action.doFn(); past.push(action); } } }; } So instead of trying to save resources by having just one array (and miserably failing with off-by-one index errors), we can embrace dynamically sized arrays and just forget indices altogether. Neat! Let’s add a couple more methods to display our UI: get canUndo() { return past.length > 0; }, get canRedo() { return future.length > 0; } The pass-by-reference problem There is a catch with our implementation though. JS is pass-by-reference for pretty much all of its types. This means, that when we create a closure over a value - currentStroke in this case - the closure will keep addressing whatever is stored in currentStroke right now. And these doFn and undoFn are very particular in a specific behavioral trait: they must be idempotent. No matter how many times you call them, they should lead to the same result. If we just do this: let doFn = () => strokes.push(currentStroke) each time we call doFn - whatever is currentStroke in the calling scope will end up getting pushed onto the strokes stack. That’s not what we want - we want the doFn to use a cloned copy of the currentStroke, and we want it to do so always. Same for the undoFnx - although in this case there is no need for it to know what’s stored in strokes nor what the currentStroke used to be, as we are not going to resume drawing that currentStroke. Modern JS has a thing for this called structuredClone(), which is perfect for the occasion: push(doFn, undoFn, ...withArgumentsToClone) { const clonedArgs = structuredClone(withArgumentsToClone); const action = { doWithData() { doFn(...clonedArgs); }, undoWithData() { undoFn(...clonedArgs); }, }; action.doWithData(); // Adding a new action wipes the redoable steps past.push(action); future.length = 0; } and we’ll amend our functions accordingly. Instead of closuring over currentStroke we’ll make it an argument: let appendStroke = strokes.push.bind(strokes); undoStack.push(appendStroke, () => strokes.pop(), currentStroke); with the push() of our undoStack taking care of making a deep clone for us. Nice! The complete definition then becomes: function createUndoStack() { const past = []; const future = []; return { push(doFn, undoFn, ...withArgumentsToClone) { const clonedArgs = structuredClone(withArgumentsToClone); const action = { doWithData() { doFn(...clonedArgs); }, undoWithData() { undoFn(...clonedArgs); }, }; action.doWithData(); // Adding a new action wipes the redoable steps past.push(action); future.length = 0; }, undo() { let action = past.pop(); if (action) { action.undoWithData(); future.unshift(action); } }, redo() { let action = future.shift(); if (action) { action.doWithData(); past.push(action); } }, get undoAvailable() { return past.length > 0; }, get redoAvailable() { return future.length > 0; }, clear() { past.length = 0; future.length = 0; return true; } } } export {createUndoStack}; Robust, small, and no indexing errors. My jam.

blog.julik.nl · Julik Tarkhanov

0
0
0
0
0
0
0
0
0
0
0
0

Researchers at Harvard Business School and University of Toronto used unique data to quantify the value of open source.

Takeways:

* Supply-side (cost to recreate) is ~$4.15B, but demand-side (value to firms) is $8.8T. Shows massive cost savings & productivity boost from OSS.

* If OSS didn't exist, firms would need to spend an estimated 3.5 times more on software than they currently do. OSS provides a massive, often invisible, productivity boost.

* A tiny fraction of OSS developers create the vast majority of value. Only 5% of developers are responsible for over 96% of the demand-side value

* Firms should not just "free ride" on OSS but actively contribute to the ecosystem, as this is far cheaper than recreating the software themselves.

Source:
hbs.edu/ris/Publication%20File

Working Paper 24-038
The Value of Open
Source Software
Manuel Hoffmann
Frank Nagle
Yanuo Zhou
(Harvard Business School)
0
0
0
0
0

If you are running an open source or open internet project that’s being hobbled by AI crawlers, at Fastly, our Fast Forward program will protect you. We’ve committed nearly $100M to supporting the open web, and already deliver every Python package, every Ruby gem, every Rust crate, every Kubernetes download, and MANY more. We can help your project too. https://www.fastly.com/fast-forward

RE: https://www.threads.net/@gergelyorosz_/post/DHrUAu5OaWC

0
0

Miyazaki is right. The latest version of OpenAI‘s image generation technology has resulted in a flood of users sharing images on social media that have been transformed in the style of Studio Ghibli, the legendary Japanese animation studio.

Hayao Miyazaki's reaction to AI generated art “I am utterly disgusted. I would never wish to incorporate this technology into my work at all. I strongly feel that this is an insult to life itself. I feel like we are nearing the end of times. We humans are losing faith in ourselves.”
0
0
0
0
0
0
0
0
0
0

If you are running an open source or open internet project that’s being hobbled by AI crawlers, at Fastly, our Fast Forward program will protect you. We’ve committed nearly $100M to supporting the open web, and already deliver every Python package, every Ruby gem, every Rust crate, every Kubernetes download, and MANY more. We can help your project too. https://www.fastly.com/fast-forward

RE: https://www.threads.net/@gergelyorosz_/post/DHrUAu5OaWC

0
0
0
0
0
0
0
0