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.

1

"utility" is becoming a signal word for me that a technology is a grift.

When people are talking about stuff they use to solve problems, they talk about the problems. Word processors allow you to write documents. Messaging apps let you talk to friends in real time. IDEs let you develop software.

0
1

These accounts post lots of public domain & creative commons videos:

➡️ @archives - Classic films, TV & animation

➡️ @films - PD & CC films, including sound & silent

➡️ @historicalHistorical Shorts - Weird & ephemeral shorts from various decades

➡️ @documentaries - Documentaries about all sorts of topics

See also these playlists:

FILMS (sound)
fedi.video/w/p/fHrzK7h9WDaR2dm

FILMS (silent)
fedi.video/w/p/sp9msEzM8z5SPZu

DOCUMENTARIES
fedi.video/w/p/tPxJXrsdrXTvcFY

0
0
0
2
0
0
0
1
0

is going to be at 2026!

FOSDEM is the largest free and open source software conference in Europe. The conference will be held on 31st Jan-1st Feb in Brussels. We'll be running a stall, showing off Luanti, giving out stickers and goodies, and talking to visitors about the project.

We need your help to make this happen. Contribute to our collective here: opencollective.com/luanti/cont

0
0
0
0

言葉は生き物だなぁと思う件が昨日あって。

演劇の勉強会でご一緒してる、
かなりお姉様の方が、相手への悪口として
「貴女、オカメチンコ‼️」って言ったんですよ。

講師も相手役の子も、見てるみんなも
「悪口だ」って事はわかったんだけど
正確な意味がわからなくて
何なら「オカメインコ🦜」だと理解してた子も
居て、その子は「可愛い💕って意味で
言ったんだと思ってた」って🤭笑

終わった後、2-30代が一斉に📱で検索して
「おおお!これは結構な悪口だ‼️笑笑」って
なったんだけど、意味がわからなきゃ
悪口も悪口として成立しないので、
やっぱり歳を重ねても
生きた言葉を遣う意識を持たないとダメだなぁ
と思いました。

でも演技中の言葉のチョイスなんて
ほぼ無意識だから、自分の馴染みのある死語が
パッと出て来てしまうのも仕方ないし、
なんていうか残酷な瞬間を
目の当たりにしました😅
ああいうの、ほんのり傷つくだろうなぁ😮‍💨
いつか自分も、そういう立場に立つんだろうな

0

This is Arlo. He's 3-years old and blind. He has been overlooked for adoption again and again, despite being extremely sweet and very confident! Could you or someone you know give this handsome boy a forever home? He's at Another Chance Animal Rescue in Sanford, Maine. For more information, call 207-229-1846 and ask for Debbie. Please boost to help spread the word and let's find Arlo the loving home he deserves. Thank you!

A gorgeous black and white, short-haired cat with big, beautiful yellow eyes. His cute markings give him a darling black nose and lower lip, as if he just kissed an ink blotter. A gorgeous black and white, short-haired cat with big, beautiful yellow eyes. His cute markings give him a darling black nose and lower lip, as if he just kissed an ink blotter. A gorgeous black and white, short-haired cat with big, beautiful yellow eyes. His cute markings give him a darling black nose and lower lip, as if he just kissed an ink blotter.
0
0
0
0
1

저의 주님, 날아다니는 스파게티 괴물 님, 제 입시울을 열어 주소서.
제 입이 당신 찬미를 전하오리다.

"5. 성면의 질서로 제 마음과 일정이 흐르게 하시어, 불안과 혼란을 피하게 하소서."

영광이 미트볼🧆과 소스🥫와 성면(the Holy Noodle)🍝께.
처음과 같이 이제와 항상 영원히. 🍜
라-멘 🍜

2025-11-17T07:51:02+09:00


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

System.IO.readFile 쓰지 마세요.

System.IO.readFile 쓰지 마세요.

System.IO.readFile 쓰지 마세요.

첫째, System.IO.readFileString 을 반환합니다. 이건 심각한 문제입니다. String 을 쓰지 마세요. 외부 세계와 I/O 를 할 때에는 ByteString 을 써야 합니다. 유니코드 문자열을 다룰 때에는 Text 를 쓸 수 있습니다. String 은 시간적으로도 공간적으로 비효율적입니다. 이건 어쩔 수 없습니다. 하스켈은 리눅스 커널보다 오래됐습니다. 그리고 하스켈이 String 을 만들 때에는 아직 하스켈에 모나드도 없던 시절이며, 타입 클래스가 과연 유용하겠는가를 두고 의견이 분분하던 시절이며, 파일 하나가 100 메가바이트가 넘어간다는 것이 과대망상으로 여겨지던 시절입니다. 특히 유니코드보다 더 먼저 나온 언어에 적절한 유니코드 문자열 타입이 있을 수는 없었습니다. 아무튼 String 은 레거시입니다. System.IO.readFile 로 그림 파일을 읽는 프로그래머는 사후세계에서 JPEG XL 파일을 십육진법 표기로 1 바이트씩 읽은 뒤 종이에 그려 내는 형벌에 처해집니다. String 을 쓰지 마세요.

둘째, System.IO.readFileFilePath 를 요구합니다. FilePath 도 사실 String 입니다. 그냥 별명(type synonym)이에요. 이것은 String 이기 때문에 비효율적이며, String 은 문자열이지 바이트열이 아니기 때문에 (인코딩을 전혀 통제할 수 없기 때문에) 파일 경로를 표현하는 타입으로 부적절합니다.

해결책: 먼저 System.OsPath 의 설명을 읽어 보세요. 그리고, file-io 패키지의 System.File.OsPath 모듈을 읽어 보세요. 여기 있는 함수들의 설명을 openBinaryFile 부터 하나씩 읽어보고 쓰세요. 이것들은 파일 경로에 OsPath 를 쓰기 때문에 String 의 비효율이 없고 인코딩도 올바르게 처리할 수 있습니다. 입출력 데이터에는 ByteString 을 씁니다. 바이트열을 유니코드 문자열로 변환할 때에는 예를 들어 Data.Text.Encoding.decodeUtf8Lenient 를 쓸 수 있습니다. 그럼 이제

  • 간단히 System.File.OsPath.readFile' 에게 OsPath 를 넘기고 ByteString 을 효율적으로 받아 와서 국밥처럼 든든하게 메모리에 올려 두고 작업을 하든지
  • 전국구 마법사라면 복대는 기본이라고 외치며 withBinaryFile앙갓썸Iteratee I/O 로 절묘하게 엮어서 뭔가 개멋있게 하든지
  • 하스켈 갓고수이기 때문에 흑마법사답게 보일러실 문을 따고 지하로 들어가 포… 포… 으악! P 로 시작하는 그것을 획득하여 누구도 예상할 수 없는 타이밍에 hGetBuf 의 암기를 슉. 슈슉. 슈슈슉. 슉. 날리든지

아무튼 이제는 String 을 놓아주어야 합니다.

6
1
0
1
0
1

連合をすぐに辞めることは無いけど、MisskeyHQがこれから作ろうとしてる負荷の少ない連合システムに移行して、その連合システムと互換性ないサーバーは将来的にやり取りできなくなるかも

完全に切り替えるのは数年後になると思うからそれまでは大丈夫だけども

2
1
1
1

Spoiler: Solution to November's IBM Ponder This

I had fun doing this month's IBM Ponder This because the solution pretty much falls out when you get the types right.

godbolt.org/z/P5aaEMv3P

The problem asks for a substring, astronomically [1] far from the start, of a string constructed using astronomically many operations each causing exponential growth.

But if you use a functional definition of a string that exactly expresses what you want, ie. define a string to be a function that maps subranges to (Hughes) lists of characters, you can write down the solution in a very naive way modulo having a separate method to compute the length of the strings (that turns out to be a textbook example).

In my experience these IBM problems usually require highly problem-specific code with a boring brute force loop. But as this current problem's solution is so generic I thought I'd share:

godbolt.org/z/P5aaEMv3P

(I have no way of checking my solution. Everything is modulo typos!)

BTW This reminds me of image processing pipelines that (dually) pass requests (of subranges) backwards rather than images forward.

[1] TBH astronomy doesn't even come close to these sizes

(Noticed one of the comments refers to the name of a type as "rope" because that was what I originally called it. Ignore.)

Compiler Explorer - Haskell

-- See "Ponder This" Nov 2025 -- https://research.ibm.com/haifa/ponderthis/challenges/November2025.html import Control.Monad hiding (join) -- Note this is expository code and contains far more than the solution -- which is just a couple of lines. -- First we write a naive solution that works for really small problems. -- Just for testing. -- church n f x: Church numeral, ie. apply f n times to x. church 0 f x = x church n f x = church (n - 1) f (f x) -- First problem rewrite1 'G' = "T" rewrite1 'T' = "CA" rewrite1 'C' = "TG" rewrite1 'A' = "C" -- Print result of applying rewrite 5 times to "cat" test1 = do putStrLn $ "Rewrite1^5 \"CAT\":" print $ church 5 (concatMap rewrite1) "CAT" -- As a warmup consider this rewrite system: -- 0 -> 1 -- 1 -> 10 -- It's not hard to show that after k rewrites -- ...0 ends up with this length... len0 k = fib (k + 1) -- and 1 ends up with this length... len1 k = fib (k + 2) fib :: Integer -> Integer fib n = fst (fib' n) where fib' 0 = (0, 1) fib' k = let (a, b) = fib' (k `div` 2) c = a * (2 * b - a) d = a * a + b * b in if odd k then (d, c + d) else (c, d) -- I want two slightly different implementations -- with two different string representations. -- So let me abstract a bit to save typing: class StringLike a where -- Make a string from a single character. single :: Char -> a -- Concatenate one string after another of given length. join :: a -> Integer -> a -> a -- We want a lazy representation of strings so that when we -- concatenate together more than the number of atoms in the -- universe we don't run out of memory. -- Define a "rope" to be function which when given `i` tells you -- what character is at position `i`. type UltraLazyString = Integer -> Char instance StringLike UltraLazyString where join f l g i = if i < l then f i else g (i - l) single c = const c -- First note that with these rules: -- G -> T -- T -> CA -- C -> TG -- A -> C -- Then under quotient G, A -> 0 and T, C -> 1 we get the same -- rules as the 01 rewrite. So we can reuse `len0` and `len1` -- to compute the lengths. -- Here's a generic implementation for applying a rewrite -- of the form x -> y rule1:: StringLike a => Char -> (Integer -> a) -> Integer -> a rule1 letter c' k = if k == 0 then single letter else c' (k - 1) -- Here's a generic implementation for applying a rewrite -- of the form x -> yz assuming that `rewrite^k y` is `len1 k`. rule2:: StringLike a => Char -> (Integer -> a) -> (Integer -> a) -> Integer -> a rule2 letter c' a' k = if k == 0 then single letter else let k' = k - 1 in join (c' k') (len1 k') (a' k') -- Now the rules as given. g, t, c, a :: StringLike r => Integer -> r g = rule1 'G' t t = rule2 'T' c a c = rule2 'C' t g a = rule1 'A' c -- Redo the naive computation as a check. test2 = do putStrLn $ "redo of rewrite1^5 \"cat\":" print $ [(c 5 :: UltraLazyString) i | i <- [0..len1 5 - 1]] ++ [(a 5 :: UltraLazyString) i | i <- [0..len0 5 - 1]] ++ [(t 5 :: UltraLazyString) i | i <- [0..len1 5 - 1]] -- We need two tricks: -- 1. The obvious one that we only need `rewrite1^k` "c" because it is -- already very long. -- 2. We only need `k` to be 500 or less or so because applying `k` an even number -- of times just keeps extending the string and 500 iterations gets you -- something longer than 10^100. -- These are strange tricks because they both involve writing less code :) -- So magically we can get away with the following. -- It's 10^100 (or whatever) times faster than the naive solution but -- not instant. test3 = do putStrLn $ "Solution to first problem:" print [c @UltraLazyString 500 i | i <- [10 ^ 100 .. 10 ^ 100 + 1000 - 1]] -- But we can do better: -- Now define a string to be a function that given a range (instead -- of one index) prepends the appropriate substring to a list of -- characters. type UltraLazyString' = Integer -> Integer -> [Char] -> [Char] -- When we join two strings we need to handle the case where -- the range we request is split between the summands. instance StringLike UltraLazyString' where join f l g i j = if j < l -- range falls in f then f i j else if i >= l -- range falls in g then g (i - l) (j - l) -- split over f and g. else f i l . g 0 (j - l) single c i j = if j > i then (c :) else id test4 = do putStrLn $ "Better solution to first problem" print $ c @UltraLazyString' 500 (10 ^ 100) (10 ^ 100 + 1000) [] -- Now the second problem -- G -> T, -- T -> CA, -- C -> BR, -- A -> I, -- R -> B, -- B -> IS, -- I -> TG, -- S -> C -- Under the quotient R, G -> G; B, T -> T; I, C -> C; S, A -> A we get same rules -- as the first problem so again so lengths can be computed with `len0` and `len1`. -- The code is just like before. rewrite2 'G' = "T" rewrite2 'T' = "CA" rewrite2 'C' = "BR" rewrite2 'A' = "I" rewrite2 'R' = "B" rewrite2 'B' = "IS" rewrite2 'I' = "TG" rewrite2 'S' = "C" g', t', c', a', r', b', i', s' :: StringLike r => Integer -> r g' = rule1 'G' t' t' = rule2 'T' c' a' c' = rule2 'C' b' r' a' = rule1 'A' i' r' = rule1 'R' b' b' = rule2 'B' i' s' i' = rule2 'I' t' g' s' = rule1 'S' c' -- A quick check test5 = do putStrLn $ "Naive method rewrite2^10 \"R\":" print $ church 10 (concatMap rewrite2) "R" putStrLn $ "Fast method to rewrite2^10 \"R\":" print $ r' @UltraLazyString' 10 0 (len1 10) [] -- Repeating the comments above (except we now have period 4 instead of 2) -- we can write: test6 = do putStrLn $ "Solution to second problem" print $ r' @UltraLazyString' 500 (10 ^ 100) (10 ^ 100 + 1000) [] main = do test1 test2 test3 test4 test5 test6

godbolt.org

0
0

ActivityPub、例えると

ある家の人が手紙を送られたい人 (フォロワー)全員に手紙を送る => 知ってる人全員のポストに手紙を入れる みたいになってるから、送られたい人が1万人とかになってくると1万人分手紙を送らないといけなくなる = コストがかかる

一応町 (ioとか)が一つの郵便箱で全員の手紙を受け取れるようにしてるとそこに送るだけで大丈夫になるけど、それでもじゃあ1万人全員がそれぞれ違う町に住んでたりしたら結局は最初と変わらない

0
0
1
0
1
1
1
1
1