惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Know Your Adversary
Know Your Adversary
博客园 - 叶小钗
量子位
大猫的无限游戏
大猫的无限游戏
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 【当耐特】
博客园 - Franky
有赞技术团队
有赞技术团队
博客园 - 聂微东
腾讯CDC
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Jina AI
Jina AI
Last Week in AI
Last Week in AI
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Cloudbric
Cloudbric
WordPress大学
WordPress大学
W
WeLiveSecurity
V2EX - 技术
V2EX - 技术
博客园_首页
S
Security @ Cisco Blogs
The Last Watchdog
The Last Watchdog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Security Latest
Security Latest
L
Lohrmann on Cybersecurity
T
Threat Research - Cisco Blogs
Forbes - Security
Forbes - Security
宝玉的分享
宝玉的分享
The Register - Security
The Register - Security
The Hacker News
The Hacker News
B
Blog RSS Feed
C
CXSECURITY Database RSS Feed - CXSecurity.com
Schneier on Security
Schneier on Security
T
Troy Hunt's Blog
The GitHub Blog
The GitHub Blog
Hacker News: Ask HN
Hacker News: Ask HN
Spread Privacy
Spread Privacy
Hugging Face - Blog
Hugging Face - Blog
博客园 - 三生石上(FineUI控件)
GbyAI
GbyAI
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
罗磊的独立博客
Blog — PlanetScale
Blog — PlanetScale
M
MIT News - Artificial intelligence
T
Tor Project blog
S
Security Affairs
Security Archives - TechRepublic
Security Archives - TechRepublic
NISL@THU
NISL@THU
P
Proofpoint News Feed
C
Cyber Attacks, Cyber Crime and Cyber Security

Lobsters

CIFSwitch: a non-universal Linux local root vulnerability RIPE NCC session fixation: poaching logins with an Atlas probe GNOME 2.20 but its Web Components Agentic Search for Context Engineering – Leonie Monigatti Garnix is shutting down [not OC] akashina.tngl.sh/jjc Concerning Emacs (and Jazz) Nitpicking the shell history scene in ‘Tron: Legacy’ What's cooking on SourceHut? Q2 2026 The tenth OpenPGP email summit Package managers that package package managers Clojure on Fennel part three: parsing WordPress at 23 Finding Miscompiles for Fun, Not Profit GitHub - creusot-rs/creusot: Creusot helps you prove your Rust code is correct. Announcing Rust 1.96.0 | Rust Blog A Love Letter to Neovim sqlite AGENTS.md Am I a Bad Friend? CSS vs. JavaScript • Josh W. Comeau Erlang Ecosystem Foundation - Supporting the BEAM community A brief note about slot access cost in Common Lisp Keyboard latency probe Rethinking the GNOME clipboard issues Back to the Building Blocks’ Building Blocks Tech Notes: Theseus: translating win32 to wasm Fast is better than slow Content-addressed Rust builds (or, what kache actually caches) Intent to Prototype: Embedding API Canada’s Bill C-22 and the security cost of collecting more data 5 PostgreSQL locking behaviors that trip people up okmij.org Stop advertising in your commits! | AksDev GitHub - mplsllc/macsurf: A modern web browser for Classic Mac OS 9 PowerPC. Real CSS3, ES5 JavaScript, native HTTPS — built with CodeWarrior on the Carbon API. Introducing DoomBench - Can Your Data Stack Run DOOM? What are some of your favourite developer tools? Building a Scalable Ingestion Pipeline with Temporal (Part 1) Converting shallow Git bundles into normal repositories Are you a member of any professional associations? What is a harmonic? An interactive comic about additive synthesis How Virtual Tables Work in the Itanium C++ ABI Using SwiftUI to Build a Mac-assed App in 2026 Rust (and Slint) on a jailbroken Kindle. ~jack/lambda-on-lambda - Serverless Haskell on AWS - sourcehut git Human proof for FOSS contributions Extremely simple internet radio controlled via IRC Announcing BABLR Splitting Konsole views from Helix to run tools | AksDev GitHub - yugr/rust-slides Serving files over HTTP three ways: synchronous, epoll, and io_uring update docs with information about building with build.py (#979) · astral-sh/python-build-standalone@c9c40c5 A Simple Makefile Tutorial On C extensions, portability, and alternative compilers Switching to Colemak | Pedro Alves Just How Bad Was The Intel IAPX432? Nix's Substituter List Is Not a Routing Table Accelerating copy_if using SIMD Lambda on Lambda: Serverless Haskell on AWS | Blog Announcing feed-repeat v1.0 Scaling Akvorado BMP RIB with sharding EYG news: A host of CLI improvements, new guides and new effects The social contract of writing JS Crossword C array types are weird; and related topics Flatpak will depend on systemd – OSnews Migrating from Go to Rust | corrode Rust Consulting A portentous reunion Vivado Licensing Options How my minimal, memory-safe Go rsync steers clear of vulnerabilities the entropy layer of a wavelet codec, on its own GitHub - nferhat/fht-compositor: A dynamic tiling Wayland compositor. Debian SE Linux and PinTheft Does bulk memmove speed up std::remove_if? (No.) 声明式部分更新 | Blog | Chrome for Developers Fully in-browser container builds Dianne Skoll's Web Site - Remind The Architecture of Open Source Applications (Volume 1)Berkeley DB Pardon MIE? - ironPeak Blog “Long-Term Support” doesn’t mean what you think Jira IS Turing-Complete May I recommend thinking of Emacs as your Fortress of Solitude hershey Floodgap Gopher-HTTP gateway gopher://thelambdalab.xyz/1cuneiforth/ HP QuickWeb, Singular And Pointless That one time I used Go panics for flow control A new suite of modern tools coming for editing and publishing RFCs From the Tabletop… The Digital Antiquarian Building a Host-Tuned GCC to Make GCC Compile Faster Are we self-sovereign PKI yet? Claw Patrol: an open-source security firewall for agents | Deno Revised^7 Report on Scheme, Large: Procedural Fascicle Draft is now public A Network Allow-List Won't Stop Exfiltration — André Graf From AFSK to Goertzel – µArt.cz Software For My New Home Server Introducing Neptune: Direct3D virtualization for QEMU AI Agent Bankrupted Their Operator While Trying to Scan DN42 - Lan Tian @ Blog mimalloc: A new, high-performance, scalable memory allocator for the modern era Making wl_shm fast The Soul of Maintaining a New Machine - Third Draft | Books in Progress What is Git made of?
revo
gills.pages. · 2026-06-03 · via Lobsters
⣄⠔⠄⡨⣀⣹⣥⣣⡚⣿⣓⣾⣫⣷⠮⡧⣬⣬⣑⢤⠤⡉⣿⡥⣂⢟⣕⡴⠬⠆⠸⡈⡆⠀⠀⠀⡋⠄⠂⠨⡆⠀⠠⠃⡀⠀⠀⠈⢰⣿
⠩⣽⢟⢭⠶⢷⢵⣻⠿⢍⣟⡅⡧⡭⣽⡯⡯⣶⠭⣽⡢⠱⢿⢧⠓⢥⠨⠧⠉⣡⠐⠀⢑⣀⠂⠈⠆⡅⠀⡀⢥⠤⢁⠀⢣⠀⠀⢘⠽⡏
⠬⡓⣼⢟⢜⡧⣷⣇⣧⡷⢯⣿⣿⣿⡶⣭⠍⣯⣻⢥⠞⣮⣬⣩⠅⢏⠆⠁⡀⠌⢩⡁⢁⠅⠡⢀⠠⠀⢉⢈⠀⠀⡅⠀⡇⠀⠀⠃⠭⣯
⡎⣟⣵⠅⣾⢭⣿⣾⣯⣿⣿⢿⣿⣿⣿⣿⣧⡳⣥⢜⣟⡤⠉⣁⢧⢨⠌⡂⠀⠒⠬⡪⣊⠄⠀⠘⠀⠢⡁⠀⡀⠅⠅⠀⡄⠀⠈⠀⢕⡟
⡕⣧⡗⠎⠷⣯⣿⣿⣷⣿⡻⢵⣿⣿⣿⣭⣿⡿⣟⣇⡧⣿⡭⢨⠫⠮⠄⠖⠀⠆⠦⠕⠁⠅⠀⠆⡁⠁⡀⠀⠄⡉⠁⠀⠄⡀⡂⠀⢼⣇
⠃⣶⣯⠢⡗⣟⣿⡿⣿⣯⢿⣷⢾⢿⣛⣿⣿⣯⡻⣾⡾⣾⢵⣏⣩⠅⠅⠥⠀⠃⠠⠅⠃⠀⡈⠀⠭⠅⠀⠀⠁⠔⠀⠀⢂⠅⠅⠀⠽⡇
⠱⣻⣻⡥⢫⢯⢿⣷⣷⣿⣿⢾⢿⣷⢯⣉⣟⣟⣾⣿⠳⣿⣇⣃⠯⠘⠔⡇⠒⠅⡖⠁⠄⠡⠑⣀⠀⡁⠀⡀⠃⠈⠀⠀⠅⠀⠀⠂⣋⡇
⢂⠵⣓⣿⣍⢯⢯⡯⣟⣝⠷⣟⢝⣋⡏⣧⠯⣿⣿⢯⣼⣯⡂⡂⣟⡧⠐⣅⠂⠥⠏⠀⠂⡅⠅⡁⠁⠄⠠⠊⠀⠨⠀⢈⠀⠄⠉⢘⡟⡆
⡥⣯⢌⡤⢽⣗⣏⠗⢿⣻⡭⡞⡷⣭⢿⡻⡯⡟⣕⣾⢽⢯⡭⠂⡍⠀⠏⠀⢌⠴⠂⠊⡄⢗⠂⠰⠀⠤⠣⠀⠀⠀⠁⠀⠀⠀⠅⠀⢕⡽
⠵⡭⡩⠋⠽⣽⡛⡹⢯⠍⡛⡏⣯⢟⠟⠿⣩⣳⡿⡟⢗⣭⡤⡯⠁⡬⠠⠂⢄⠂⢤⠀⢖⠀⠀⢀⠂⢖⠀⠘⠀⠀⠂⠡⢤⠠⠀⠀⣫⡿
⠀⢰⡇⢂⣃⠙⣧⡵⡙⠇⡷⠶⡷⠶⡟⡙⣩⡌⠯⡺⡍⡲⡸⣆⠼⠅⡱⠌⠡⠂⢄⣠⠃⠀⠀⡂⠈⠂⠠⢀⠀⠀⠀⠔⠀⠂⠂⠀⠨⣯
⡔⠰⠼⣝⢪⢋⢋⠣⣧⡦⣦⡁⡭⠽⡛⠁⡫⢡⡄⠿⡫⣕⣔⢳⠌⢡⡸⠁⠁⠂⣠⡇⠀⠀⠀⠍⠈⠄⠀⠀⢀⠀⠔⠆⠁⠈⠠⠀⡹⡏
⡖⣠⠄⠀⠯⢜⢨⠊⣒⢡⠨⡀⠢⢭⠴⡊⢕⠐⣄⡓⡾⠋⠗⠉⢀⠚⠀⢃⠂⠥⠲⠀⠀⠀⠄⠐⠀⠀⠐⠀⠁⠄⠱⠁⠊⠈⡀⠀⠊⣽
⠀⡉⠒⣃⠰⡀⢁⠘⡉⠪⠋⡲⡅⠍⡎⡪⢣⠽⢭⠍⡥⠁⠂⡰⠠⣄⠥⠐⠀⠣⠄⢀⠐⠁⡀⠀⢐⠐⠀⠠⠁⠂⠄⠠⠀⠁⡀⠐⣫⡟
⠐⢔⠁⠀⠬⠑⠗⠴⠀⠢⡁⢌⠅⢘⠓⡛⠈⡀⠄⠆⠠⠠⠢⢂⠕⠷⠈⢀⠈⡒⠄⠂⠀⠀⠈⠀⡀⠡⠈⠀⠆⡐⠀⠀⠓⠀⠀⠀⢐⢼
⡀⠀⠈⠐⠠⠀⠀⠁⠁⠣⢀⡁⡄⠂⠔⠂⠂⢉⠁⡌⠄⠜⠈⠡⠐⠀⡐⠀⢨⠀⠁⠀⠀⡀⠍⠄⠠⠁⠀⠠⢄⠈⠀⠀⡄⠀⠀⡀⠒⣸
⢘⠉⡒⠤⠌⢀⠑⠕⠀⠄⠄⠄⠀⠄⠑⠉⠨⠀⠄⠀⠂⠃⠀⠀⠈⠄⠄⠠⠈⠀⠀⡀⠠⠁⢠⠁⠁⠀⠐⠱⠀⠀⠀⡐⠀⠉⠄⠀⢸⠾
⠀⠘⠈⡀⠈⠀⠈⠨⠐⠠⠠⠐⡀⡄⢠⠀⢀⠨⠀⠃⠀⠀⡁⡠⠀⠩⠀⠂⠁⠀⠀⠀⢒⡄⠊⠀⠀⢀⠈⠁⠀⠀⠀⠆⠘⠁⠄⠀⠄⣿
⠄⡄⠀⠈⠠⠀⡀⠀⠀⠄⠀⠂⠀⠀⠄⠀⢀⠁⠁⢁⠁⠆⠀⠀⠀⠀⡀⠀⠈⠀⡀⠀⠱⠀⠀⠀⠀⠂⢄⠈⠀⠀⡀⡨⠠⡀⠠⠀⠄⡼
⠠⠀⠁⠊⢀⠀⠠⠁⠁⠂⠂⡄⢄⠐⡀⢀⠊⠂⡀⡁⡀⢀⢀⠠⠀⠄⠂⠡⠠⠁⠀⠀⠀⠂⠀⢠⠒⠀⠀⠀⠐⠢⠀⢀⠀⠀⠄⠄⣿⣿
⠁⠋⠙⠊⠐⠕⠁⡂⠈⠅⠠⠈⠐⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠀⠉⠀⠐⠀⠀⠀⠀⠀⣈⠀⠀⠀⠀⠈⡂⠈⠀⠀⠘⠌⢀⠥
⠀⠀⠀⠀⠔⠔⠀⡀⡉⠀⠀⠀⠂⠠⠠⠀⠄⠄⠀⣀⢀⠀⡈⠀⠌⡐⠈⠈⠀⠀⠀⠀⠅⠀⣐⠉⠄⠀⠀⣂⠠⠁⡈⠀⠄⠄⢀⠣⢶⢿
⠄⠀⠀⡁⠀⠄⠀⠀⠁⠈⠀⠈⠀⠁⠀⠁⡀⠁⠀⠁⠀⠀⠀⡀⠀⠀⠀⠀⠀⠠⡀⠑⠀⠀⠎⠀⢬⢠⠀⢂⠠⠢⠠⠈⡐⠸⠀⡐⣹⢷
⠩⠥⠂⠆⡆⢠⠀⢄⠀⣀⡀⣄⠀⢈⠀⠀⣀⡀⡀⡀⠄⡄⠡⠀⠐⠀⠑⠀⠀⠁⠒⠒⠉⠡⡀⠈⠈⢀⠥⠈⠀⠀⠀⠀⠈⣞⣏⣿⡏⣿
⠾⠝⠷⢿⣯⣿⠧⡧⠭⠣⠭⡭⡮⢭⠶⠶⠶⠦⣗⡶⠽⠭⣿⣶⠷⠵⠮⠽⠿⠮⠿⢷⡶⣖⡷⠲⠞⠷⠾⢿⢷⣿⣿⣿⣿⣯⢇⠟⡧⢈
  

pipes

clean data flow without nesting

things flow from top to bottom

"hello!!"
  |> string.upper
  |> string.sub(0, 4)
  |> fn(s) s + ", world!" 
  |> inspect

# or with placeholders,
"hello!!"
  |> _:upper() # obj:method() == obj.method(obj)
  |> _:sub(0, 4)
  |> do
    # you can even put any expression here
    #   even do-end blocks
    _ + ", world!"
  end
  |> print

# this is the same, but look at the order of operations
print(log("hello":upper():sub(0, 4) + ", world!"))

errors-as-values

nil and booleans are replaced by atoms

you can’t use a value without handling an error
all crashes are explicit (WIP)

aided massively by pattern matching, ?, orelse, and :unwrap()

# f might be
#   (:ok, "file-contents")
#   or (:err, :IoError)
const f = fs.open({path = "./readme.md"})

# `?` unwraps :ok and panics on :err at top-level
const f2 = fs.open({path = "./readme.md"})?

# crashes if :err
const f = fs.open({path = "./readme.md"}):unwrap()

everything is an expression

no statements, everything (really) always returns a value
…but the code still looks procedural

let x = 10 # this line evaluates to 10
let label = if x > 0 "positive" else "zero"
let a = let b = 5 # this whole line evaluates to 5

fn is_true() 5 + 5 == 10
# both x and is_true are the same function
const x = fn is_true() do # do-end is one too
    # return and break are special
    return 5 + 5 == 10
end

comp

execute any (really) expression at compile time

any script can be compiled into bytecode and get any value baked in

revo -b script.rv
revo script.rvo

the compile-time VM does not differ from the runtime one

# asks for a ling of input at build-time
# then keeps the result at run-time
const x = comp read() 

const long = do
    let t = 0
    for x in 0..100
        t += x
    t # similar to rust's {},
      #   revo do-end blocks return the last value
end

procedural macros

along with an AST-substituting macro system,

this lets you just get an iterator over the raw ast tokens, run any code to transform them
, then return back a table of the new ast

# > num, num, num -> Sigma^4_n=1(a * b + c)
proc cmul!(iter) do
  print("inner: ", add3!(10,20,12))
  print("peek: ", iter:peek())
  match iter:peek()
  | (:number, n) => print("is number", n)
  | (other, n)   => print(other, n)
  | x            => print("not tuple: ", x)

  let a = 10 + (iter:next_of(:number))
  let b = iter:next_of(:number)
  let c = iter:next_of(:number)

  let acc = 0
  for i in 1..5 do
  	acc += a * b + c
  end

  {(:number, acc)}
end

print(cmul!(10,20,30))

pattern matching

destructure and branch in place

you will be using atoms and tuples, they are beautiful solutions to their problems

match (:ok, 42)
| (:ok, v)  => v
| (:err, e) => panic(e)
| _         => panic()
| _         => panic()
# _ is wildcard, when nothing else matched
# if you want to grab the actual value
# , just put any binding name there

const response = match "hello!"
| "hello!"              => "hi!"
| x when (x:len() > 10) => ""
| x when string?(x)     => x + " to you too!"
| _                     => ":("

let f = match read({path = "./readme.md"})
| (:ok, file) => file
| (:err, error) when error == :FileDNE
	=> panic("file does not exist")
| (error) => panic("error")
| x => panic("unknown: ", x)

fibers

i made all your blocking code become non-blocking by just adding a spawn before it

fn serve(peer, message) do
  peer:send(message)?
end

while :true do
  # accept the next connection; if none is ready, this fiber parks until the
  # runtime sees a connection on the listening socket.
  let conn = server:accept()?
  # the only thing you have to do to make it async is to add `spawn` here! 
  spawn serve(conn, port - 1)
end

tables

represent everything

used for
- module exports
- arrays
- maps

let t = {1, 2, 3, key = "value"}
let rec = {name = "revo", version = 1}
rec.name
t[0]

let mt = {
    name = fn(self) self.name,
    set_version = fn(self, v) self.version = v,
    DELTA = 0.0,
}

# a metatable is just a "table overlay"
# which you can slap onto other tables
set_metatable(rec, mt)
let rec = {name = "revo", version = 2}
set_metatable(rec2, mt)
# name does not exist in rec or rec2,
# but you can still call them
assert_eq(rec:version(), 1)
assert_eq(rec2:version(), 2)
assert_eq(rec.DELTA, rec2.DELTA)

convenient typing

the type system is optional, but very well-integrated

untyped code works just fine, but

typed code is faster and gets optimized better (and ensures code correctness at compile-time!)
most of your code is going to be inferred automatically

type Result =
    (:ok, any)
  | (:err, atom)


struct User {
  name: string = "me",
  age: int = 21,

  fn get_age(self) -> Result
    (:ok, self.age),
}

# type is inferred
let user = User{}

print(user:get_age())

first-class tests

they’re just closures and they fail when you return an error. the ? postfix operator propagates errors, giving you a pretty simple experience

fn add(a, b) a + b

suite "add" do
  test "addition" do
    expect(add(20, 22) == 42)?
    expect(add(20, 22) != 22)?
  end
  
  test/skip "adds two tables" do
    expect(add({1,2}, {3, 4}) == {4,6})?
  end
end

quick start

you can get the latest release from (the github releases page)[https://github.com/if-not-nil/revo/releases]

from source

the only dependency is zig version 0.16.0:
the repository is also available on codeberg

cd /tmp
git clone https://github.com/if-not-nil/revo
zig build -Doptimize=ReleaseFast # static build with vendored 
./zig-out/bin/revo -e 'print("hello " + "world")'

# then, put that binary in your path
cp ./zig-out/bin/revo ~/.local/bin/revo

usage

please check revo -h first

revo script.rv   # run script
revo             # start repl
revo -e "1 + 2"  # inline code

revo -b script.rv              # script.rv -> script.rvo
revo -b -o output.rvo script   # custom output path
revo --bench1 script.rv        # benchmarks script.rv
revo --test script.rv          # runs with test blocks
revo --dis script.rv           # bytecode disassembly

lsp

release builds bundle the LSP, revo --lsp starts it
debug builds skip it by default
see ./lsp for setup and feature details