Filter
Exclude
Time range
-
Near
Canโ€™t See Someoneโ€™s Last Seen on Telegram? Hereโ€™s Why & What to Do ๐Ÿš€ webstick.blog/telegram-last-โ€ฆ #TelegramHiddenStatus #LastSeenError #FindUser #ChatPrivacy #AppSettings #TechGuide #FixNow
12
That's a job of findUser, but it's leaking information via that 404.
2
145
Let name = findUser(this)... If name.isDeveloper() // check dev status return "Ohanz is OpenToConnect() ๐Ÿ‘จโ€๐Ÿ’ปโ™ ๏ธโค"
1
2
17
Let name = findUser(this)... If name.isDeveloper() // check dev status return "Ohanz is OpenToConnect() ๐Ÿ‘จโ€๐Ÿ’ปโ™ ๏ธโค"
2
2
25
Clean or dangerous? Optional<User> user = findUser(id); if (user.isPresent()) { sendEmail(user.get()); } Why might this not be the best way to use Optional? What would a senior engineer suggest instead?
9
3
38
16,675
Replying to @SumitM_X
Classic case of Optional being treated like itโ€™sโ€ฆ not optional ๐Ÿ˜… Optional is never null. This code defeats the whole purpose. return findUser(id) .map(User::getEmail) .orElse(null); Or if absence is exceptional, use orElseThrow(). Optional โ‰  fancy null wrapper. Use it properly ๐Ÿ‘€
4
428
Replying to @SumitM_X
In general returning "null" for a user does not really make sense... either return a "ANONYMOUS" (or alike) or throw an exception: return findUser(id).orElse("ANONYMOUS"); or return findUser(id).orElseThrow(new UserNotFoundException("The user %d couldn't be found".format(id));
1
1
4
367
Replying to @SumitM_X
Issues: - Optional itself should never be null - Calling get() without checking isPresent() can throw - Returning null reintroduces null-handling trying to avoid Or better, donโ€™t return null at all: return findUser(id) .map(User::getEmail);
4
3,501
Replying to @SumitM_X
This code defeats the purpose of Optional. Instead of guarding against null, you're checking the Optional reference itself. The correct pattern is to use its API to handle presence or absence: return findUser(id) // Returns Optional<User> .map(User::getEmail) // If a User is present, get the email .orElse(null); // If not, return null Even better, avoid null entirely and return Optional<String>.
1
5
2,501
Replying to @SumitM_X
never check if an Optional is null. if an api returns Optional, the contract is that it will always return an object (either empty or full), never null. checking user != null implies you don't trust findUser to follow the basic rules of the type system.
3
1,033
Replying to @SumitM_X
This code can be simplified using the Optional class's map function to avoid explicit null checks, making it more concise and readable For example- you can use return findUser(id).map(User::getEmail).orElse(null); to achieve the same result.
1
10
2,516
Jan 31
Review this code : Optional<User> user = findUser(id); if (user != null) { return user.get().getEmail(); } return null;
22
8
93
34,847
Rust patterns that make your TypeScript actually type-safe Most TS codebases claim to be "type-safe" but panic at runtime constantly. Here's how to write TypeScript that borrows Rust's obsession with correctness. --- 1. Result types instead of throwing Rust doesn't have exceptions. Every error is a value you handle explicitly. TypeScript has exceptions, but you can choose not to use them. ๐๐š๐ (๐ฌ๐ญ๐š๐ง๐๐š๐ซ๐ ๐“๐’): `๐—๐—’๐—‰๐–พ๐—Œ๐–ผ๐—‹๐—‚๐—‰๐— ๐–ฟ๐—Ž๐—‡๐–ผ๐—๐—‚๐—ˆ๐—‡ ๐—‰๐–บ๐—‹๐—Œ๐–พ๐–ด๐—Œ๐–พ๐—‹(๐—ƒ๐—Œ๐—ˆ๐—‡: ๐—Œ๐—๐—‹๐—‚๐—‡๐—€): ๐–ด๐—Œ๐–พ๐—‹ { ๐–ผ๐—ˆ๐—‡๐—Œ๐— ๐–ฝ๐–บ๐—๐–บ =ฬต ๐–ฉ๐–ฒ๐–ฎ๐–ญ.๐—‰๐–บ๐—‹๐—Œ๐–พ(๐—ƒ๐—Œ๐—ˆ๐—‡); // ๐–ข๐–บ๐—‡ ๐—๐—๐—‹๐—ˆ๐— ๐—‚๐–ฟ (!๐–ฝ๐–บ๐—๐–บ.๐–พ๐—†๐–บ๐—‚๐—…) ๐—๐—๐—‹๐—ˆ๐— ๐—‡๐–พ๐— ๐–ค๐—‹๐—‹๐—ˆ๐—‹('๐–ฌ๐—‚๐—Œ๐—Œ๐—‚๐—‡๐—€ ๐–พ๐—†๐–บ๐—‚๐—…'); // ๐–ข๐–บ๐—‡ ๐—๐—๐—‹๐—ˆ๐— ๐—‹๐–พ๐—๐—Ž๐—‹๐—‡ ๐–ฝ๐–บ๐—๐–บ; } // ๐–ข๐–บ๐—…๐—…๐–พ๐—‹ ๐—๐–บ๐—Œ ๐—‡๐—ˆ ๐—‚๐–ฝ๐–พ๐–บ ๐—๐—๐—‚๐—Œ ๐—๐—๐—‹๐—ˆ๐—๐—Œ ๐–ผ๐—ˆ๐—‡๐—Œ๐— ๐—Ž๐—Œ๐–พ๐—‹ =ฬต ๐—‰๐–บ๐—‹๐—Œ๐–พ๐–ด๐—Œ๐–พ๐—‹(๐—‚๐—‡๐—‰๐—Ž๐—); ` ๐†๐จ๐จ๐ (๐‘๐ฎ๐ฌ๐ญ-๐ฌ๐ญ๐ฒ๐ฅ๐ž): `๐—๐—’๐—‰๐–พ๐—Œ๐–ผ๐—‹๐—‚๐—‰๐— ๐—๐—’๐—‰๐–พ ๐–ฑ๐–พ๐—Œ๐—Ž๐—…๐—<๐–ณ, ๐–ค> = | { ๐—ˆ๐—„: ๐—๐—‹๐—Ž๐–พ; ๐—๐–บ๐—…๐—Ž๐–พ: ๐–ณ } | { ๐—ˆ๐—„: ๐–ฟ๐–บ๐—…๐—Œ๐–พ; ๐–พ๐—‹๐—‹๐—ˆ๐—‹: ๐–ค }; ๐–ฟ๐—Ž๐—‡๐–ผ๐—๐—‚๐—ˆ๐—‡ ๐—‰๐–บ๐—‹๐—Œ๐–พ๐–ด๐—Œ๐–พ๐—‹(๐—ƒ๐—Œ๐—ˆ๐—‡: ๐—Œ๐—๐—‹๐—‚๐—‡๐—€): ๐–ฑ๐–พ๐—Œ๐—Ž๐—…๐—<๐–ด๐—Œ๐–พ๐—‹, ๐—Œ๐—๐—‹๐—‚๐—‡๐—€> { ๐—๐—‹๐—’ { ๐–ผ๐—ˆ๐—‡๐—Œ๐— ๐–ฝ๐–บ๐—๐–บ = ๐–ฉ๐–ฒ๐–ฎ๐–ญ.๐—‰๐–บ๐—‹๐—Œ๐–พ(๐—ƒ๐—Œ๐—ˆ๐—‡); ๐—‚๐–ฟ (!๐–ฝ๐–บ๐—๐–บ.๐–พ๐—†๐–บ๐—‚๐—…) { ๐—‹๐–พ๐—๐—Ž๐—‹๐—‡ { ๐—ˆ๐—„: ๐–ฟ๐–บ๐—…๐—Œ๐–พ, ๐–พ๐—‹๐—‹๐—ˆ๐—‹: '๐–ฌ๐—‚๐—Œ๐—Œ๐—‚๐—‡๐—€ ๐–พ๐—†๐–บ๐—‚๐—…' }; } ๐—‹๐–พ๐—๐—Ž๐—‹๐—‡ { ๐—ˆ๐—„: ๐—๐—‹๐—Ž๐–พ, ๐—๐–บ๐—…๐—Ž๐–พ: ๐–ฝ๐–บ๐—๐–บ }; } ๐–ผ๐–บ๐—๐–ผ๐— (๐–พ) { ๐—‹๐–พ๐—๐—Ž๐—‹๐—‡ { ๐—ˆ๐—„: ๐–ฟ๐–บ๐—…๐—Œ๐–พ, ๐–พ๐—‹๐—‹๐—ˆ๐—‹: '๐–จ๐—‡๐—๐–บ๐—…๐—‚๐–ฝ ๐–ฉ๐–ฒ๐–ฎ๐–ญ' }; } } // ๐–ข๐—ˆ๐—†๐—‰๐—‚๐—…๐–พ๐—‹ ๐–ฟ๐—ˆ๐—‹๐–ผ๐–พ๐—Œ ๐—’๐—ˆ๐—Ž ๐—๐—ˆ ๐—๐–บ๐—‡๐–ฝ๐—…๐–พ ๐–ป๐—ˆ๐—๐— ๐–ผ๐–บ๐—Œ๐–พ๐—Œ ๐–ผ๐—ˆ๐—‡๐—Œ๐— ๐—‹๐–พ๐—Œ๐—Ž๐—…๐— = ๐—‰๐–บ๐—‹๐—Œ๐–พ๐–ด๐—Œ๐–พ๐—‹(๐—‚๐—‡๐—‰๐—Ž๐—); ๐—‚๐–ฟ (๐—‹๐–พ๐—Œ๐—Ž๐—…๐—.๐—ˆ๐—„) { ๐–ผ๐—ˆ๐—‡๐—Œ๐—ˆ๐—…๐–พ.๐—…๐—ˆ๐—€(๐—‹๐–พ๐—Œ๐—Ž๐—…๐—.๐—๐–บ๐—…๐—Ž๐–พ.๐–พ๐—†๐–บ๐—‚๐—…); } ๐–พ๐—…๐—Œ๐–พ { ๐–ผ๐—ˆ๐—‡๐—Œ๐—ˆ๐—…๐–พ.๐–พ๐—‹๐—‹๐—ˆ๐—‹(๐—‹๐–พ๐—Œ๐—Ž๐—…๐—.๐–พ๐—‹๐—‹๐—ˆ๐—‹); } ` Now errors are in the type signature. You can't ignore them. --- 2. Option types for nullable values Rust has `Option<T>` for "maybe exists, maybe doesn't." TypeScript has `T | null | undefined` but people handle it inconsistently. ๐๐š๐: `typescript function findUser(id: string): User | null { return db.get(id) ?? null; } const user = findUser('123'); console.log(user.email); // Runtime error if null ` ๐†๐จ๐จ๐: `typescript type Option<T> = | { some: true; value: T } | { some: false }; function findUser(id: string): Option<User> { const user = db.get(id); return user ? { some: true, value: user } : { some: false }; } const result = findUser('123'); if (result.some) { console.log(result.value.email); // Type-safe } else { console.log('User not found'); } ` Can't access `.value` without checking `.some` first. --- 3. Exhaustive pattern matching Rust's `match` forces you to handle every case. TypeScript's `switch` doesn't. You can forget cases silently. ๐๐š๐: `๐—๐—’๐—‰๐–พ๐—Œ๐–ผ๐—‹๐—‚๐—‰๐— ๐—๐—’๐—‰๐–พ ๐–ฒ๐—๐–บ๐—๐—Ž๐—Œ = '๐—‰๐–พ๐—‡๐–ฝ๐—‚๐—‡๐—€' | '๐—Œ๐—Ž๐–ผ๐–ผ๐–พ๐—Œ๐—Œ' | '๐–พ๐—‹๐—‹๐—ˆ๐—‹'; ๐–ฟ๐—Ž๐—‡๐–ผ๐—๐—‚๐—ˆ๐—‡ ๐—๐–บ๐—‡๐–ฝ๐—…๐–พ๐–ฒ๐—๐–บ๐—๐—Ž๐—Œ(๐—Œ๐—๐–บ๐—๐—Ž๐—Œ: ๐–ฒ๐—๐–บ๐—๐—Ž๐—Œ) { ๐—Œ๐—๐—‚๐—๐–ผ๐— (๐—Œ๐—๐–บ๐—๐—Ž๐—Œ) { ๐–ผ๐–บ๐—Œ๐–พ '๐—‰๐–พ๐—‡๐–ฝ๐—‚๐—‡๐—€': ๐—‹๐–พ๐—๐—Ž๐—‹๐—‡ '๐–ซ๐—ˆ๐–บ๐–ฝ๐—‚๐—‡๐—€...'; ๐–ผ๐–บ๐—Œ๐–พ '๐—Œ๐—Ž๐–ผ๐–ผ๐–พ๐—Œ๐—Œ': ๐—‹๐–พ๐—๐—Ž๐—‹๐—‡ '๐–ฃ๐—ˆ๐—‡๐–พ!'; // ๐–ฅ๐—ˆ๐—‹๐—€๐—ˆ๐— '๐–พ๐—‹๐—‹๐—ˆ๐—‹' - ๐–ผ๐—ˆ๐—†๐—‰๐—‚๐—…๐–พ๐—Œ ๐–ฟ๐—‚๐—‡๐–พ, ๐–ป๐—‹๐–พ๐–บ๐—„๐—Œ ๐–บ๐— ๐—‹๐—Ž๐—‡๐—๐—‚๐—†๐–พ } } ` ๐†๐จ๐จ๐: `๐—๐—’๐—‰๐–พ๐—Œ๐–ผ๐—‹๐—‚๐—‰๐— ๐–ฟ๐—Ž๐—‡๐–ผ๐—๐—‚๐—ˆ๐—‡ ๐—๐–บ๐—‡๐–ฝ๐—…๐–พ๐–ฒ๐—๐–บ๐—๐—Ž๐—Œ(๐—Œ๐—๐–บ๐—๐—Ž๐—Œ: ๐–ฒ๐—๐–บ๐—๐—Ž๐—Œ): ๐—Œ๐—๐—‹๐—‚๐—‡๐—€ { ๐—Œ๐—๐—‚๐—๐–ผ๐— (๐—Œ๐—๐–บ๐—๐—Ž๐—Œ) { ๐–ผ๐–บ๐—Œ๐–พ '๐—‰๐–พ๐—‡๐–ฝ๐—‚๐—‡๐—€': ๐—‹๐–พ๐—๐—Ž๐—‹๐—‡ '๐–ซ๐—ˆ๐–บ๐–ฝ๐—‚๐—‡๐—€...'; ๐–ผ๐–บ๐—Œ๐–พ '๐—Œ๐—Ž๐–ผ๐–ผ๐–พ๐—Œ๐—Œ': ๐—‹๐–พ๐—๐—Ž๐—‹๐—‡ '๐–ฃ๐—ˆ๐—‡๐–พ!'; ๐–ผ๐–บ๐—Œ๐–พ '๐–พ๐—‹๐—‹๐—ˆ๐—‹': ๐—‹๐–พ๐—๐—Ž๐—‹๐—‡ '๐–ฅ๐–บ๐—‚๐—…๐–พ๐–ฝ!'; ๐–ฝ๐–พ๐–ฟ๐–บ๐—Ž๐—…๐—: ๐–ผ๐—ˆ๐—‡๐—Œ๐— _๐–พ๐—‘๐—๐–บ๐—Ž๐—Œ๐—๐—‚๐—๐–พ: ๐—‡๐–พ๐—๐–พ๐—‹ = ๐—Œ๐—๐–บ๐—๐—Ž๐—Œ; ๐—๐—๐—‹๐—ˆ๐— ๐—‡๐–พ๐— ๐–ค๐—‹๐—‹๐—ˆ๐—‹(`๐–ด๐—‡๐—๐–บ๐—‡๐–ฝ๐—…๐–พ๐–ฝ ๐—Œ๐—๐–บ๐—๐—Ž๐—Œ: ${_๐–พ๐—‘๐—๐–บ๐—Ž๐—Œ๐—๐—‚๐—๐–พ}`); } } ` Add a new status? TypeScript errors until you handle it. --- 4. Branded types for validation Rust newtypes prevent mixing incompatible types. TypeScript's structural typing lets you pass any string anywhere. ๐๐š๐: `๐—๐—’๐—‰๐–พ๐—Œ๐–ผ๐—‹๐—‚๐—‰๐— ๐–ฟ๐—Ž๐—‡๐–ผ๐—๐—‚๐—ˆ๐—‡ ๐—Œ๐–พ๐—‡๐–ฝ๐–ค๐—†๐–บ๐—‚๐—…(๐–พ๐—†๐–บ๐—‚๐—…: ๐—Œ๐—๐—‹๐—‚๐—‡๐—€) { ... } ๐–ฟ๐—Ž๐—‡๐–ผ๐—๐—‚๐—ˆ๐—‡ ๐–ฝ๐–พ๐—…๐–พ๐—๐–พ๐–ด๐—Œ๐–พ๐—‹(๐—Ž๐—Œ๐–พ๐—‹๐–จ๐–ฝ: ๐—Œ๐—๐—‹๐—‚๐—‡๐—€) { ... } ๐–ผ๐—ˆ๐—‡๐—Œ๐— ๐–พ๐—†๐–บ๐—‚๐—… = '๐—Ž๐—Œ๐–พ๐—‹@๐–พ๐—‘๐–บ๐—†๐—‰๐—…๐–พ.๐–ผ๐—ˆ๐—†'; ๐–ฝ๐–พ๐—…๐–พ๐—๐–พ๐–ด๐—Œ๐–พ๐—‹(๐–พ๐—†๐–บ๐—‚๐—…); // ๐–ข๐—ˆ๐—†๐—‰๐—‚๐—…๐–พ๐—Œ ๐–ฟ๐—‚๐—‡๐–พ. ๐–ฃ๐—‚๐—Œ๐–บ๐—Œ๐—๐–พ๐—‹. ` ๐†๐จ๐จ๐: `๐—๐—’๐—‰๐–พ๐—Œ๐–ผ๐—‹๐—‚๐—‰๐— ๐—๐—’๐—‰๐–พ ๐–ค๐—†๐–บ๐—‚๐—… = ๐—Œ๐—๐—‹๐—‚๐—‡๐—€ & { ๐—‹๐–พ๐–บ๐–ฝ๐—ˆ๐—‡๐—…๐—’ __๐–ป๐—‹๐–บ๐—‡๐–ฝ: '๐–ค๐—†๐–บ๐—‚๐—…' }; ๐—๐—’๐—‰๐–พ ๐–ด๐—Œ๐–พ๐—‹๐–จ๐–ฝ = ๐—Œ๐—๐—‹๐—‚๐—‡๐—€ & { ๐—‹๐–พ๐–บ๐–ฝ๐—ˆ๐—‡๐—…๐—’ __๐–ป๐—‹๐–บ๐—‡๐–ฝ: '๐–ด๐—Œ๐–พ๐—‹๐–จ๐–ฝ' }; ๐–ฟ๐—Ž๐—‡๐–ผ๐—๐—‚๐—ˆ๐—‡ ๐–ค๐—†๐–บ๐—‚๐—…(๐—Œ: ๐—Œ๐—๐—‹๐—‚๐—‡๐—€): ๐–ค๐—†๐–บ๐—‚๐—… | ๐—‡๐—Ž๐—…๐—… { ๐—‹๐–พ๐—๐—Ž๐—‹๐—‡ ๐—Œ.๐—‚๐—‡๐–ผ๐—…๐—Ž๐–ฝ๐–พ๐—Œ('@') ? ๐—Œ ๐–บ๐—Œ ๐–ค๐—†๐–บ๐—‚๐—… : ๐—‡๐—Ž๐—…๐—…; } ๐–ฟ๐—Ž๐—‡๐–ผ๐—๐—‚๐—ˆ๐—‡ ๐–ด๐—Œ๐–พ๐—‹๐–จ๐–ฝ(๐—Œ: ๐—Œ๐—๐—‹๐—‚๐—‡๐—€): ๐–ด๐—Œ๐–พ๐—‹๐–จ๐–ฝ { ๐—‹๐–พ๐—๐—Ž๐—‹๐—‡ ๐—Œ ๐–บ๐—Œ ๐–ด๐—Œ๐–พ๐—‹๐–จ๐–ฝ; } ๐–ฟ๐—Ž๐—‡๐–ผ๐—๐—‚๐—ˆ๐—‡ ๐—Œ๐–พ๐—‡๐–ฝ๐–ค๐—†๐–บ๐—‚๐—…(๐–พ๐—†๐–บ๐—‚๐—…: ๐–ค๐—†๐–บ๐—‚๐—…) { ... } ๐–ฟ๐—Ž๐—‡๐–ผ๐—๐—‚๐—ˆ๐—‡ ๐–ฝ๐–พ๐—…๐–พ๐—๐–พ๐–ด๐—Œ๐–พ๐—‹(๐—Ž๐—Œ๐–พ๐—‹๐–จ๐–ฝ: ๐–ด๐—Œ๐–พ๐—‹๐–จ๐–ฝ) { ... } ๐–ผ๐—ˆ๐—‡๐—Œ๐— ๐–พ๐—†๐–บ๐—‚๐—… = ๐–ค๐—†๐–บ๐—‚๐—…('๐—Ž๐—Œ๐–พ๐—‹@๐–พ๐—‘๐–บ๐—†๐—‰๐—…๐–พ.๐–ผ๐—ˆ๐—†')!; ๐–ผ๐—ˆ๐—‡๐—Œ๐— ๐—Ž๐—Œ๐–พ๐—‹๐–จ๐–ฝ = ๐–ด๐—Œ๐–พ๐—‹๐–จ๐–ฝ('๐Ÿฃ๐Ÿค๐Ÿฅ'); ๐–ฝ๐–พ๐—…๐–พ๐—๐–พ๐–ด๐—Œ๐–พ๐—‹(๐–พ๐—†๐–บ๐—‚๐—…); // ๐–ณ๐—’๐—‰๐–พ ๐–พ๐—‹๐—‹๐—ˆ๐—‹! ๐–ข๐–บ๐—‡'๐— ๐—†๐—‚๐—‘ ๐—๐—๐–พ๐—†. ` Primitive types but compiler-enforced separation. --- 5. Builder pattern for complex construction Rust uses builders for objects with many optional fields. TypeScript just has massive option objects that nobody validates. ๐๐š๐: `๐—๐—’๐—‰๐–พ๐—Œ๐–ผ๐—‹๐—‚๐—‰๐— ๐—‚๐—‡๐—๐–พ๐—‹๐–ฟ๐–บ๐–ผ๐–พ ๐–ข๐—ˆ๐—‡๐–ฟ๐—‚๐—€ { ๐—๐—ˆ๐—Œ๐—?: ๐—Œ๐—๐—‹๐—‚๐—‡๐—€; ๐—‰๐—ˆ๐—‹๐—?: ๐—‡๐—Ž๐—†๐–ป๐–พ๐—‹; ๐—๐—‚๐—†๐–พ๐—ˆ๐—Ž๐—?: ๐—‡๐—Ž๐—†๐–ป๐–พ๐—‹; ๐—‹๐–พ๐—๐—‹๐—‚๐–พ๐—Œ?: ๐—‡๐—Ž๐—†๐–ป๐–พ๐—‹; } // ๐–ถ๐—๐–บ๐—'๐—Œ ๐—‹๐–พ๐—Š๐—Ž๐—‚๐—‹๐–พ๐–ฝ? ๐–ถ๐—๐–บ๐— ๐–บ๐—‹๐–พ ๐—๐—๐–พ ๐–ฝ๐–พ๐–ฟ๐–บ๐—Ž๐—…๐—๐—Œ? ๐–ถ๐—๐—ˆ ๐—„๐—‡๐—ˆ๐—๐—Œ. ๐–ผ๐—ˆ๐—‡๐—Œ๐— ๐–ผ๐—ˆ๐—‡๐–ฟ๐—‚๐—€: ๐–ข๐—ˆ๐—‡๐–ฟ๐—‚๐—€ = { ๐—๐—ˆ๐—Œ๐—: '๐—…๐—ˆ๐–ผ๐–บ๐—…๐—๐—ˆ๐—Œ๐—' }; ` ๐†๐จ๐จ๐: `๐—๐—’๐—‰๐–พ๐—Œ๐–ผ๐—‹๐—‚๐—‰๐— ๐–ผ๐—…๐–บ๐—Œ๐—Œ ๐–ข๐—ˆ๐—‡๐–ฟ๐—‚๐—€๐–ก๐—Ž๐—‚๐—…๐–ฝ๐–พ๐—‹ { ๐—‰๐—‹๐—‚๐—๐–บ๐—๐–พ ๐—๐—ˆ๐—Œ๐— = '๐—…๐—ˆ๐–ผ๐–บ๐—…๐—๐—ˆ๐—Œ๐—'; ๐—‰๐—‹๐—‚๐—๐–บ๐—๐–พ ๐—‰๐—ˆ๐—‹๐— = ๐Ÿช๐Ÿข๐Ÿช๐Ÿข; ๐—‰๐—‹๐—‚๐—๐–บ๐—๐–พ ๐—๐—‚๐—†๐–พ๐—ˆ๐—Ž๐— = ๐Ÿง๐Ÿข๐Ÿข๐Ÿข; ๐—‰๐—‹๐—‚๐—๐–บ๐—๐–พ ๐—‹๐–พ๐—๐—‹๐—‚๐–พ๐—Œ = ๐Ÿฅ; ๐—Œ๐–พ๐—๐–ง๐—ˆ๐—Œ๐—(๐—๐—ˆ๐—Œ๐—: ๐—Œ๐—๐—‹๐—‚๐—‡๐—€): ๐—๐—๐—‚๐—Œ { ๐—๐—๐—‚๐—Œ.๐—๐—ˆ๐—Œ๐— = ๐—๐—ˆ๐—Œ๐—; ๐—‹๐–พ๐—๐—Ž๐—‹๐—‡ ๐—๐—๐—‚๐—Œ; } ๐—Œ๐–พ๐—๐–ฏ๐—ˆ๐—‹๐—(๐—‰๐—ˆ๐—‹๐—: ๐—‡๐—Ž๐—†๐–ป๐–พ๐—‹): ๐—๐—๐—‚๐—Œ { ๐—‚๐–ฟ (๐—‰๐—ˆ๐—‹๐— < ๐Ÿข || ๐—‰๐—ˆ๐—‹๐— > ๐Ÿจ๐Ÿง๐Ÿง๐Ÿฅ๐Ÿง) { ๐—๐—๐—‹๐—ˆ๐— ๐—‡๐–พ๐— ๐–ค๐—‹๐—‹๐—ˆ๐—‹('๐–จ๐—‡๐—๐–บ๐—…๐—‚๐–ฝ ๐—‰๐—ˆ๐—‹๐—'); } ๐—๐—๐—‚๐—Œ.๐—‰๐—ˆ๐—‹๐— = ๐—‰๐—ˆ๐—‹๐—; ๐—‹๐–พ๐—๐—Ž๐—‹๐—‡ ๐—๐—๐—‚๐—Œ; } ๐—Œ๐–พ๐—๐–ณ๐—‚๐—†๐–พ๐—ˆ๐—Ž๐—(๐—†๐—Œ: ๐—‡๐—Ž๐—†๐–ป๐–พ๐—‹): ๐—๐—๐—‚๐—Œ { ๐—๐—๐—‚๐—Œ.๐—๐—‚๐—†๐–พ๐—ˆ๐—Ž๐— = ๐—†๐—Œ; ๐—‹๐–พ๐—๐—Ž๐—‹๐—‡ ๐—๐—๐—‚๐—Œ; } ๐–ป๐—Ž๐—‚๐—…๐–ฝ(): ๐–ข๐—ˆ๐—‡๐–ฟ๐—‚๐—€ { ๐—‹๐–พ๐—๐—Ž๐—‹๐—‡ { ๐—๐—ˆ๐—Œ๐—: ๐—๐—๐—‚๐—Œ.๐—๐—ˆ๐—Œ๐—, ๐—‰๐—ˆ๐—‹๐—: ๐—๐—๐—‚๐—Œ.๐—‰๐—ˆ๐—‹๐—, ๐—๐—‚๐—†๐–พ๐—ˆ๐—Ž๐—: ๐—๐—๐—‚๐—Œ.๐—๐—‚๐—†๐–พ๐—ˆ๐—Ž๐—, ๐—‹๐–พ๐—๐—‹๐—‚๐–พ๐—Œ: ๐—๐—๐—‚๐—Œ.๐—‹๐–พ๐—๐—‹๐—‚๐–พ๐—Œ }; } } ๐–ผ๐—ˆ๐—‡๐—Œ๐— ๐–ผ๐—ˆ๐—‡๐–ฟ๐—‚๐—€ = ๐—‡๐–พ๐— ๐–ข๐—ˆ๐—‡๐–ฟ๐—‚๐—€๐–ก๐—Ž๐—‚๐—…๐–ฝ๐–พ๐—‹() .๐—Œ๐–พ๐—๐–ง๐—ˆ๐—Œ๐—('๐–บ๐—‰๐—‚.๐–พ๐—‘๐–บ๐—†๐—‰๐—…๐–พ.๐–ผ๐—ˆ๐—†') .๐—Œ๐–พ๐—๐–ฏ๐—ˆ๐—‹๐—(๐Ÿฆ๐Ÿฆ๐Ÿฅ) .๐–ป๐—Ž๐—‚๐—…๐–ฝ(); ` Defaults clear. Validation enforced. Immutable result. --- 6. No silent coercion Rust doesn't let you compare different types. TypeScript does. And it's a footgun. ๐๐š๐: `๐—๐—’๐—‰๐–พ๐—Œ๐–ผ๐—‹๐—‚๐—‰๐— ๐–ผ๐—ˆ๐—‡๐—Œ๐— ๐–ผ๐—ˆ๐—Ž๐—‡๐— = '๐Ÿง'; ๐—‚๐–ฟ (๐–ผ๐—ˆ๐—Ž๐—‡๐— > ๐Ÿฅ) { // '๐Ÿง' > ๐Ÿฅ ๐—‚๐—Œ ๐—๐—‹๐—Ž๐–พ (๐—Œ๐—๐—‹๐—‚๐—‡๐—€ ๐–ผ๐—ˆ๐—†๐—‰๐–บ๐—‹๐—‚๐—Œ๐—ˆ๐—‡) ๐–ผ๐—ˆ๐—‡๐—Œ๐—ˆ๐—…๐–พ.๐—…๐—ˆ๐—€('๐–ฌ๐—ˆ๐—‹๐–พ ๐—๐—๐–บ๐—‡ ๐Ÿฅ'); } ` ๐†๐จ๐จ๐: `๐—๐—’๐—‰๐–พ๐—Œ๐–ผ๐—‹๐—‚๐—‰๐— // ๐–ค๐—‡๐–บ๐–ป๐—…๐–พ ๐—Œ๐—๐—‹๐—‚๐–ผ๐— ๐—†๐—ˆ๐–ฝ๐–พ ๐—‚๐—‡ ๐—๐—Œ๐–ผ๐—ˆ๐—‡๐–ฟ๐—‚๐—€.๐—ƒ๐—Œ๐—ˆ๐—‡ { "๐–ผ๐—ˆ๐—†๐—‰๐—‚๐—…๐–พ๐—‹๐–ฎ๐—‰๐—๐—‚๐—ˆ๐—‡๐—Œ": { "๐—Œ๐—๐—‹๐—‚๐–ผ๐—": ๐—๐—‹๐—Ž๐–พ, "๐—Œ๐—๐—‹๐—‚๐–ผ๐—๐–ญ๐—Ž๐—…๐—…๐–ข๐—๐–พ๐–ผ๐—„๐—Œ": ๐—๐—‹๐—Ž๐–พ, "๐—‡๐—ˆ๐–จ๐—†๐—‰๐—…๐—‚๐–ผ๐—‚๐—๐– ๐—‡๐—’": ๐—๐—‹๐—Ž๐–พ } } ๐–ผ๐—ˆ๐—‡๐—Œ๐— ๐–ผ๐—ˆ๐—Ž๐—‡๐—: ๐—‡๐—Ž๐—†๐–ป๐–พ๐—‹ = ๐—‰๐–บ๐—‹๐—Œ๐–พ๐–จ๐—‡๐—('๐Ÿง', ๐Ÿฃ๐Ÿข); ๐—‚๐–ฟ (๐–ผ๐—ˆ๐—Ž๐—‡๐— > ๐Ÿฅ) { // ๐–ญ๐—ˆ๐— ๐—‚๐—'๐—Œ ๐–บ๐–ผ๐—๐—Ž๐–บ๐—…๐—…๐—’ ๐–ผ๐—ˆ๐—†๐—‰๐–บ๐—‹๐—‚๐—‡๐—€ ๐—‡๐—Ž๐—†๐–ป๐–พ๐—‹๐—Œ ๐–ผ๐—ˆ๐—‡๐—Œ๐—ˆ๐—…๐–พ.๐—…๐—ˆ๐—€('๐–ฌ๐—ˆ๐—‹๐–พ ๐—๐—๐–บ๐—‡ ๐Ÿฅ'); } ` Strict mode catches this. Always use it. --- 7. Immutable by default Rust requires `mut` to make things mutable. TypeScript lets everything mutate unless you say otherwise. ๐๐š๐: `๐—๐—’๐—‰๐–พ๐—Œ๐–ผ๐—‹๐—‚๐—‰๐— ๐—‚๐—‡๐—๐–พ๐—‹๐–ฟ๐–บ๐–ผ๐–พ ๐–ด๐—Œ๐–พ๐—‹ { ๐—‚๐–ฝ: ๐—Œ๐—๐—‹๐—‚๐—‡๐—€; ๐—‡๐–บ๐—†๐–พ: ๐—Œ๐—๐—‹๐—‚๐—‡๐—€; } ๐–ผ๐—ˆ๐—‡๐—Œ๐— ๐—Ž๐—Œ๐–พ๐—‹: ๐–ด๐—Œ๐–พ๐—‹ = { ๐—‚๐–ฝ: '๐Ÿฃ', ๐—‡๐–บ๐—†๐–พ: '๐– ๐—…๐—‚๐–ผ๐–พ' }; ๐—Ž๐—Œ๐–พ๐—‹.๐—‡๐–บ๐—†๐–พ = '๐–ก๐—ˆ๐–ป'; // ๐–ฌ๐—Ž๐—๐–บ๐—๐–พ๐—Œ. ๐–ญ๐—ˆ ๐—๐–บ๐—‹๐—‡๐—‚๐—‡๐—€. ` ๐†๐จ๐จ๐: `๐—๐—’๐—‰๐–พ๐—Œ๐–ผ๐—‹๐—‚๐—‰๐— ๐—‚๐—‡๐—๐–พ๐—‹๐–ฟ๐–บ๐–ผ๐–พ ๐–ด๐—Œ๐–พ๐—‹ { ๐—‹๐–พ๐–บ๐–ฝ๐—ˆ๐—‡๐—…๐—’ ๐—‚๐–ฝ: ๐—Œ๐—๐—‹๐—‚๐—‡๐—€; ๐—‹๐–พ๐–บ๐–ฝ๐—ˆ๐—‡๐—…๐—’ ๐—‡๐–บ๐—†๐–พ: ๐—Œ๐—๐—‹๐—‚๐—‡๐—€; } ๐–ผ๐—ˆ๐—‡๐—Œ๐— ๐—Ž๐—Œ๐–พ๐—‹: ๐–ด๐—Œ๐–พ๐—‹ = { ๐—‚๐–ฝ: '๐Ÿฃ', ๐—‡๐–บ๐—†๐–พ: '๐– ๐—…๐—‚๐–ผ๐–พ' }; ๐—Ž๐—Œ๐–พ๐—‹.๐—‡๐–บ๐—†๐–พ = '๐–ก๐—ˆ๐–ป'; // ๐–ณ๐—’๐—‰๐–พ ๐–พ๐—‹๐—‹๐—ˆ๐—‹ // ๐–ฎ๐—‹ ๐—Ž๐—Œ๐–พ ๐–ฑ๐–พ๐–บ๐–ฝ๐—ˆ๐—‡๐—…๐—’ ๐—Ž๐—๐—‚๐—…๐—‚๐—๐—’ ๐—๐—’๐—‰๐–พ ๐–ด๐—Œ๐–พ๐—‹ = ๐–ฑ๐–พ๐–บ๐–ฝ๐—ˆ๐—‡๐—…๐—’<{ ๐—‚๐–ฝ: ๐—Œ๐—๐—‹๐—‚๐—‡๐—€; ๐—‡๐–บ๐—†๐–พ: ๐—Œ๐—๐—‹๐—‚๐—‡๐—€; }>; ` Make mutation explicit, not the default. --- 8. Phantom types for state machines Rust uses phantom types to track state at compile time. TypeScript can do this too, but almost nobody does. ๐๐š๐: `๐—๐—’๐—‰๐–พ๐—Œ๐–ผ๐—‹๐—‚๐—‰๐— ๐–ผ๐—…๐–บ๐—Œ๐—Œ ๐–ข๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—๐—‚๐—ˆ๐—‡ { ๐—‰๐—‹๐—‚๐—๐–บ๐—๐–พ ๐–ผ๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—๐–พ๐–ฝ = ๐–ฟ๐–บ๐—…๐—Œ๐–พ; ๐–ผ๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—() { ๐—๐—๐—‚๐—Œ.๐–ผ๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—๐–พ๐–ฝ = ๐—๐—‹๐—Ž๐–พ; } ๐—Œ๐–พ๐—‡๐–ฝ(๐–ฝ๐–บ๐—๐–บ: ๐—Œ๐—๐—‹๐—‚๐—‡๐—€) { ๐—‚๐–ฟ (!๐—๐—๐—‚๐—Œ.๐–ผ๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—๐–พ๐–ฝ) ๐—๐—๐—‹๐—ˆ๐— ๐—‡๐–พ๐— ๐–ค๐—‹๐—‹๐—ˆ๐—‹('๐–ญ๐—ˆ๐— ๐–ผ๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—๐–พ๐–ฝ'); // ... } } ๐–ผ๐—ˆ๐—‡๐—Œ๐— ๐–ผ๐—ˆ๐—‡๐—‡ = ๐—‡๐–พ๐— ๐–ข๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—๐—‚๐—ˆ๐—‡(); ๐–ผ๐—ˆ๐—‡๐—‡.๐—Œ๐–พ๐—‡๐–ฝ('๐—๐–พ๐—…๐—…๐—ˆ'); // ๐–ฑ๐—Ž๐—‡๐—๐—‚๐—†๐–พ ๐–พ๐—‹๐—‹๐—ˆ๐—‹ ` ๐†๐จ๐จ๐: `๐—๐—’๐—‰๐–พ๐—Œ๐–ผ๐—‹๐—‚๐—‰๐— ๐—๐—’๐—‰๐–พ ๐–ฃ๐—‚๐—Œ๐–ผ๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—๐–พ๐–ฝ = { ๐—‹๐–พ๐–บ๐–ฝ๐—ˆ๐—‡๐—…๐—’ ๐—Œ๐—๐–บ๐—๐–พ: '๐–ฝ๐—‚๐—Œ๐–ผ๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—๐–พ๐–ฝ' }; ๐—๐—’๐—‰๐–พ ๐–ข๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—๐–พ๐–ฝ = { ๐—‹๐–พ๐–บ๐–ฝ๐—ˆ๐—‡๐—…๐—’ ๐—Œ๐—๐–บ๐—๐–พ: '๐–ผ๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—๐–พ๐–ฝ' }; ๐–ผ๐—…๐–บ๐—Œ๐—Œ ๐–ข๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—๐—‚๐—ˆ๐—‡<๐–ฒ๐—๐–บ๐—๐–พ> { ๐—‰๐—‹๐—‚๐—๐–บ๐—๐–พ ๐–ผ๐—ˆ๐—‡๐—Œ๐—๐—‹๐—Ž๐–ผ๐—๐—ˆ๐—‹(๐—‰๐—‹๐—‚๐—๐–บ๐—๐–พ ๐—Œ๐—๐–บ๐—๐–พ: ๐–ฒ๐—๐–บ๐—๐–พ) {} ๐—Œ๐—๐–บ๐—๐—‚๐–ผ ๐–ผ๐—‹๐–พ๐–บ๐—๐–พ(): ๐–ข๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—๐—‚๐—ˆ๐—‡<๐–ฃ๐—‚๐—Œ๐–ผ๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—๐–พ๐–ฝ> { ๐—‹๐–พ๐—๐—Ž๐—‹๐—‡ ๐—‡๐–พ๐— ๐–ข๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—๐—‚๐—ˆ๐—‡({ ๐—Œ๐—๐–บ๐—๐–พ: '๐–ฝ๐—‚๐—Œ๐–ผ๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—๐–พ๐–ฝ' }); } ๐–ผ๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—(๐—๐—๐—‚๐—Œ: ๐–ข๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—๐—‚๐—ˆ๐—‡<๐–ฃ๐—‚๐—Œ๐–ผ๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—๐–พ๐–ฝ>): ๐–ข๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—๐—‚๐—ˆ๐—‡<๐–ข๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—๐–พ๐–ฝ> { ๐—‹๐–พ๐—๐—Ž๐—‹๐—‡ ๐—‡๐–พ๐— ๐–ข๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—๐—‚๐—ˆ๐—‡({ ๐—Œ๐—๐–บ๐—๐–พ: '๐–ผ๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—๐–พ๐–ฝ' }); } ๐—Œ๐–พ๐—‡๐–ฝ(๐—๐—๐—‚๐—Œ: ๐–ข๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—๐—‚๐—ˆ๐—‡<๐–ข๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—๐–พ๐–ฝ>, ๐–ฝ๐–บ๐—๐–บ: ๐—Œ๐—๐—‹๐—‚๐—‡๐—€) { // ๐–ข๐–บ๐—‡ ๐—ˆ๐—‡๐—…๐—’ ๐–ผ๐–บ๐—…๐—… ๐—‚๐–ฟ ๐–ผ๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—๐–พ๐–ฝ } } ๐–ผ๐—ˆ๐—‡๐—Œ๐— ๐–ผ๐—ˆ๐—‡๐—‡ = ๐–ข๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—๐—‚๐—ˆ๐—‡.๐–ผ๐—‹๐–พ๐–บ๐—๐–พ(); ๐–ผ๐—ˆ๐—‡๐—‡.๐—Œ๐–พ๐—‡๐–ฝ('๐—๐–พ๐—…๐—…๐—ˆ'); // ๐–ณ๐—’๐—‰๐–พ ๐–พ๐—‹๐—‹๐—ˆ๐—‹: ๐—‡๐—ˆ๐— ๐–ผ๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—๐–พ๐–ฝ ๐–ผ๐—ˆ๐—‡๐—Œ๐— ๐–ผ๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—๐–พ๐–ฝ = ๐–ผ๐—ˆ๐—‡๐—‡.๐–ผ๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—(); ๐–ผ๐—ˆ๐—‡๐—‡๐–พ๐–ผ๐—๐–พ๐–ฝ.๐—Œ๐–พ๐—‡๐–ฝ('๐—๐–พ๐—…๐—…๐—ˆ'); // ๐–ฎ๐–ช ` Illegal states become unrepresentable. --- The mindset shift: Rust: Make invalid states impossible to represent TypeScript default: Let anything happen, hope for the best TypeScript with discipline: Make invalid states impossible to represent --- You don't need Rust to write correct code. You need Rust's mindset applied to whatever language you're using. Make errors explicit. Make invalid states unrepresentable. Make the compiler your ally. That's type safety. Not just slapping `: string` on everything.

1
7
210
Spring tiene una joya escondida que muchos ignoran: Spring Cache โšก Con una sola anotaciรณn (@ Cacheable) puedes hacer que los resultados de un mรฉtodo se guarden en memoria. Asรญ la prรณxima vez que se invoque con los mismos parรกmetros, Spring devuelve el resultado directamente del cachรฉ sin volver a ejecutar la lรณgica. Veamos un ejemplo muy simple: @ Cacheable("users") public User findUser(Long id) { return userRepository.findById(id).orElseThrow(); } ๐Ÿ’ก La primera vez, se ejecuta el mรฉtodo. La segunda, tercera, etcโ€ฆ La respuesta viene del cache. Lo interesante es que Spring Cache no es una implementaciรณn en sรญ, es una abstracciรณn que puedes conectar con mรบltiples motores: - Caffeine: Rรกpido y en memoria (ideal para apps pequeรฑas o locales). - Redis: Distribuido, perfecto para entornos escalables. - Ehcache / Hazelcast: Opciones robustas para enterprise. Tambiรฉn contamos con otras anotaciones que nos ayudan a controlar diferentes aspectos: @ CacheEvict: Limpia una entrada. @ CachePut: Actualiza sin invalidar. @ Caching: Combina varias reglas. ๐Ÿ‘€ La decisiรณn clave es elegir bien que cachear y que no. No todo debe ir al cache: cachear datos dinรกmicos o con mucha rotaciรณn puede hacer mรกs daรฑo que bien.
4
10
252
Caching Brain Teaser 1 - @Cacheable Null Puzzle ๐Ÿงฉ '''java @Cacheable("users") public User findUser(String id) { return null; } ''' What happens? Does Spring cache null or call DB every time? ๐Ÿ‘‰ Hint: We can change the settings.
3
211
31 May 2025
Prรธver et par Oberliga-finduser i dag: * Mechtersheim Mร… vinne i kampen for รฅ (mulig) overleve og et ferdigspilt Eppeldorn som slipper inn nesten 3 i snitt og som er fryktelig svake borte skal slรฅs hjemme til 2.45 i #odds.
1
2
850
20 May 2025
Comparing Structured Concurrency approaches in #Java: JEP 505 (left) vs Jox (right). Both implement the same logic: run `findUser` and `fetchOrder` in parallel, and combine their results. Any failure interrupts the other tasks, and when they terminate, propagates the exception.
1
4
18
1,304
16 Jan 2025
Replying to @vmfunc
actual backdoor also more likely to be named something like setcolor or finduser
3
185