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

推荐订阅源

H
Hackread – Cybersecurity News, Data Breaches, AI and More
C
Check Point Blog
Hacker News: Ask HN
Hacker News: Ask HN
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
WordPress大学
WordPress大学
P
Proofpoint News Feed
V
Visual Studio Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
N
Netflix TechBlog - Medium
C
CXSECURITY Database RSS Feed - CXSecurity.com
博客园 - 聂微东
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
博客园 - 叶小钗
Cisco Talos Blog
Cisco Talos Blog
S
Schneier on Security
T
Threat Research - Cisco Blogs
腾讯CDC
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
The Hacker News
The Hacker News
Google DeepMind News
Google DeepMind News
Microsoft Security Blog
Microsoft Security Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
GbyAI
GbyAI
N
News | PayPal Newsroom
L
LINUX DO - 最新话题
酷 壳 – CoolShell
酷 壳 – CoolShell
P
Palo Alto Networks Blog
T
Tenable Blog
S
Secure Thoughts
T
Threatpost
V2EX - 技术
V2EX - 技术
大猫的无限游戏
大猫的无限游戏
Martin Fowler
Martin Fowler
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Vercel News
Vercel News
罗磊的独立博客
P
Privacy & Cybersecurity Law Blog
Engineering at Meta
Engineering at Meta
小众软件
小众软件
Google DeepMind News
Google DeepMind News
N
News and Events Feed by Topic
Y
Y Combinator Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
C
Cybersecurity and Infrastructure Security Agency CISA
P
Proofpoint News Feed
L
Lohrmann on Cybersecurity
P
Privacy International News Feed
H
Heimdal Security Blog
量子位
B
Blog

Hacker News: Front Page

SPICE simulation → oscilloscope → verification with Claude Code — Lucas Gerads GitHub - GainSec/AutoProber: Hardware hacker’s flying probe automation stack for agent-driven target discovery, microscope mapping, safety-monitored CNC motion, probe review, and controlled pin probing. Introducing Claude Opus 4.7 Qwen Studio The Future of Everything is Lies, I Guess: Where Do We Go From Here? GitHub - SeanFDZ/macmind: Single-layer transformer in HyperTalk for the classic Macintosh Virginia Bans Sale of Geolocation Data Show HN: Agent-cache – Multi-tier LLM/tool/session caching for Valkey and Redis Ancient DNA reveals pervasive directional selection across West Eurasia [pdf] AI cybersecurity is not proof of work Moving a large-scale metrics pipeline from StatsD to OpenTelemetry / Prometheus GitHub - Nightmare-Eclipse/RedSun: The Red Sun vulnerability repository GitHub - SethPyle376/hiraeth: Local AWS emulator focused on fast integration testing, with SQS support, SQLite-backed state, and a debug-friendly web UI. A Better Ludum Dare; Or, How to Ruin a Legacy GitHub - macOS26/Agent: Any AI, replaces Claude Code, Cursor, OpenClaw. Over 18 LLM providers (Claude, OpenAI, Gemini, Ollama, Zai, HF, Qwen) wired into a native Mac app that writes code, builds Xcode projects, bumps versions, manages git, automates Safari, use AppleScript, JS or Accessibility, extend Agent! w/ MCP Servers, run tasks from your iPhone via Messages. YouTube now lets you turn off Shorts I Made a Terminal Pager Burgers | マクドナルド公式 Commands — HackerNews CLI documentation ChatGPT for Excel PiCore - Raspberry Pi Port of Tiny Core Linux Live Nation illegally monopolized ticketing market, jury finds Google Broke Its Promise to Me. Now ICE Has My Data. Founding Engineer at Adaptional | Y Combinator CRISPR takes important step toward silencing Down syndrome’s extra chromosome GitHub - saffron-health/libretto: The AI toolkit for building reliable browser automations US v. Heppner (S.D.N.Y. 2026) no attorney-client privilege for AI chats [pdf] Unexpected €54k billing spike in 13 hours: Firebase browser key without API restrictions used for Gemini requests Fragments: April 14 Cal.com Goes Closed Source: Why AI Security Is Forcing Our Decision | Cal.com - Scheduling Software for Online Bookings Laravel raised money and now injects ads directly into your agent Codex Hacked a Samsung TV Tech Valuations Back to Pre-AI Boom Levels A perfectable programming language — Soter GitHub - halfwhey/claudraband: Claude Code for the Power User Partnership through Play: Investigating How Long-Distance Couples Use Digital Games to Facilitate Intimacy Textbooks and Methods of Note-Taking in Early Modern Europe (2008) Eternity in six hours: Intergalactic spreading of intelligent life (2013) Seven countries now generate 100% of their electricity from renewable energy Tell HN: OpenAI silently removed Study Mode from ChatGPT Pro Max 5x Quota Exhausted in 1.5 Hours Despite Moderate Usage Show HN: Oberon System 3 runs natively on Raspberry Pi 3 (with ready SD card) Tell HN: docker pull fails in spain due to football cloudflare block Bring Back Idiomatic Design No one owes you supply-chain security GitHub - xsawyerx/curl-doom: DOOM, played over cURL Apple update turns Czech mate for locked-out iPhone user The Grand Line Cache TTL silently regressed from 1h to 5m around early March 2026, causing quota and cost inflation Building a Z-Machine in the worst possible language The peril of laziness lost Iran war: We spoke to the man making Lego-style AI videos that experts say are powerful propaganda AI Will Be Met With Violence, and Nothing Good Will Come of It GitHub - duguyue100/midnight-captain: Inspired by Midnight Commander, tailored to my taste. How to build a `git diff` driver · Jamie Tanna | Software Engineer Center for Responsible, Decentralized Intelligence at Berkeley The Local Universe’s Expansion Rate Is Clearer Than Ever, but Still Doesn’t Add Up - A new synthesis of astronomical measurements confirms a persistent mismatch that could point to physics beyond current models The disturbing white paper Red Hat is trying to erase from the internet – OSnews NetBlocks (@netblocks@mastodon.social) The Future of Everything is Lies, I Guess: Annoyances ‘Abhorrent’: the inside story of the Polymarket gamblers betting millions on war Productive procrastination — Max van IJsselmuiden maps, territory and LMs 447 Terabytes per Square Centimetre at Zero Retention Energy: Non-Volatile Memory at the Atomic Scale on Fluorographane Show HN: Pardonned.com – A searchable database of US Pardons 20 Years on AWS and Never Not My Job The Seasons are Wrong The FAA wants gamers to apply for air traffic control jobs Artemis II crew splashes down near San Diego after historic moon mission Why weekends are under threat We gave an AI a 3 year retail lease in SF and asked it to make a profit | Andon Labs How a dancer with ALS used brainwaves to perform live On filing the corners off my MacBooks Installing every* Firefox extension OpenClaw’s memory is unreliable, and you don’t know when it will break Steve Blank Nowhere Is Safe Chimpanzees in Uganda locked in vicious 'civil war', say researchers watgo - a WebAssembly Toolkit for Go linux/Documentation/process/coding-assistants.rst at master · torvalds/linux GitHub - callumlocke/json-formatter: Makes JSON easy to read. Founding Product Engineer at Bild AI | Y Combinator A compelling title that is cryptic enough to get you to take action on it GitHub - Keychron/Keychron-Keyboards-Hardware-Design: Industrial design files for Keychron keyboards and mice. 100+ models with CAD assets in STEP, DXF, DWG, and PDF. Source-available, with commercial use allowed for original compatible accessories within the license terms. [ANNOUNCE] WireGuardNT v0.11 and WireGuard for Windows v0.6 Released 1D-Chess Helium Is Hard to Replace Keeping a Postgres queue healthy — PlanetScale Serenity Forge (@serenityforge.com) Our response to the Axios developer tool compromise Do Americans read print books, e-books or audiobooks more? Uncharted island soon to appear on nautical charts The Problem That Built an Industry Fragments: April 2 Python Release Python install manager 26.1 Bitcoin miners are losing $19,000 on every BTC produced as difficulty drops 7.8% God sleeps in the minerals Harness engineering: leveraging Codex in an agent-first world Apple Silicon and Virtual Machines: Beating the 2 VM Limit What have been the greatest intellectual achievements? The APL Programming Language Source Code
beyondloom.com
2026-06-23 · via Hacker News: Front Page

Vector Graphics in Lil

Dr. Allen Vincent Hershey developed some of the first digital typefaces, described by simple sequences of straight line-segments. These were originally published in his 1967 report Calligraphy for Computers.

The hershey module for the Decker ecosystem is concerned with laying out text using these typefaces. Decker’s scripting language, Lil, is of an unusual APL-influenced design. This article will explore Lil in the context of 2-dimensional vector graphics, expanding upon examples also discussed in the interactive documentation linked above.

Foundations

A point is an (x,y) pair of numbers describing rectangular coordinates on a canvas- a drawing surface. Points are represented in Lil as lists with a length of 2:

point:(3,-5)

A stroke is a list of points representing a sequence of lines to draw on the canvas, and thus also a list of lists of numbers. Given a list of four points, the stroke connects the first point to the second, the second point to the third, and the third point to the fourth. If there are N points in a stroke, it describes N-1 connected lines. We might also call a stroke a “polyline”:

stroke:((list 3,-5),(list 2,5),(list 0,3))

A path is a list of strokes, and thus also a list of lists of points, and a list of lists of lists of numbers. A path can represent the strokes that make up a single shape- like the letter “A”- or a sequence of letters representing an entire word or sentence. The strokes within a path are ragged: they may vary in length.

path:(list (list 1,2),(list 3,4)),
     (list (list 5,6),(list 7,8),(list 9,10))

The hershey.textpath[] function assembles a complex path based on a Lil string using the glyphs of a font, each of which is a simpler path:

p:hershey.textpath[hf_futura "ABC"]

Thus constructed, we can draw the text path to a canvas c using either an explicit each loop or the equivalent shorthand @ operator. The Decker canvas widget can draw strokes with the canvas.line[] function, given an appropriate list of lists of numbers:

each stroke in p
 c.line[stroke]
end

c.line @ p

Wherever possible, Decker’s scripting APIs are designed to work as collective operations, applying to a large data structure at once. Drawing a single straight line-segment is the simple case for a more general polyline-drawing operation. If canvas.line[] could only draw a single straight line-segment, we would have to explicitly manage the off-by-one relationship between the N points of a path and the N-1 lines they represent. For example,

each stroke in p
 each point i in stroke
  if i>0
   canvas.line[stroke[i-1] point]
  end
 end
end

A small ergonomic flaw like this would be magnified as it appeared throughout a program, obscuring the simplicity of the programmer’s actual intent.1

Path-Mangling

Now that we can obtain and render interesting paths, let’s look at manipulating them.

Combining paths is easy: Lil’s , operator concatenates lists. Concatenating a list of strokes and a list of strokes results in a list of strokes.

Scaling paths is more interesting. As discussed previously, many of Lil’s arithmetic operators will implicitly conform over nested listy structures. Multiplying a scalar number by a list of numbers spreads the multiplication to each element of the list, and the same process works recursively for nested lists. We can therefore uniformly scale points, strokes, or paths with simple multiplication2:

(11,22,33)*2
# (22,44,66)

((list 3,-5),(list 2,5),(list 0,3))*2
# ((6,-10),(4,10),(0,6))

A non-uniform scale runs into trouble. We now want to multiply the x-coordinates of every point nested inside the path with a different value from the y-coordinates. If we multiply our path by a pair of numbers, the * operator doesn’t implicitly know that we want to “push” that conforming process down to the innermost pairs. When * is given lists to the left and to the right with different lengths, it treats the right list as if it were repeated or truncated to match the length of the left list:

(1,2,3,4)*(10,100)
# (10,200,30,400)

If we first enclose the right operand with list, * will repeat the element contained in that length-1 list and pair it up with each element of the left argument:

(1,2,3,4)*list(10,100)
# ((10,100),(20,200),(30,300),(40,400))

For a path, we need to enclose the right operand twice: once to spread the scale to each stroke of the path, and then again to spread the scale to each point of the stroke:

p * list list scalex,scaley

Scaling the x or y axis by a negative number will mirror a path horizontally or vertically, respectively:

p * list list -1,1

Translating a path can use the same trick as scaling, but with + instead of *:

p + list list transx,transy

To shear horizontally, we need to offset the x coordinate of every point in a path proportionally to the y-coordinate. We can use the last primitive to extract the y-coordinates of all the points in a path. The @ operator allows us to “push” last down into the right operand. The last of a path is a stroke. The last of each stroke is a list of points. The last of each of each path is a list of lists of y-coordinates:

p: (list (list 1,2),(list 3,4)),(list (list 5,6),(list 7,8),(list 9,10))

last p
# ((5,6),(7,8),(9,10))

last @ p
# ((3,4),(9,10))

last @ @ p
# ((2,4),(6,8,10))

Let’s call this kind of list of lists of scalars derived from the points in a path a peel.

To turn the y-coordinate peel back into a proper path, we can multiply each scalar by a pair, reusing our nonuniform scaling idiom:

(last @ @ p)*list list(10,0)
# (((20,0),(40,0)),((60,0),(80,0),(100,0)))

Thus, for a complete horizontal shear:

p + (last @ @ p)*list list shearx,0

A vertical shear looks very similar:

p + (first @ @ p)*list list 0,sheary

If you wanted to transpose a path, you could peel out the x and y coordinates separately and blend them back together using the same sort of idiom, but you could also use the rev (reverse) primitive directly to swap the elements of each point:

rev @ @ p

Transpositions aren’t often useful alone, but combining a mirror and a transpose produces a 90 degree rotation.

A more general way to rotate a path is to take advantage of Lil’s heading, mag, and unit primitives.

The mag primitive calculates the vector magnitude of a number or list of numbers. For a single number, this is the absolute value. For a pair of numbers- like a point- it gives the Euclidean distance between that point and the origin. It also has special conforming behavior: it descends recursively through nested lists until it arrives at a number or flat list of numbers. This behavior makes it perfect for producing a peel from a path:

p: (list (list 1,2),(list 3,4)),(list (list 5,6),(list 7,8),(list 9,10))

mag p
# ((2.236068,5),(7.81025,10.630146,13.453624))

The heading primitive conforms like mag, but produces a peel of angles (in radians) between the origin and each point:

heading p
# ((1.107149,0.927295),(0.876058,0.851966,0.837981))

Used together, mag and heading decompose a path (in rectangular coordinates) into polar coordinates. The unit primitive converts a peel of angles as obtained from heading and produces a path where every point has unit distance from the origin (mag 1). For any path p3,

p ~ (mag p)*unit heading p

A complete path rotation around the origin by angle radians is therefore:

(mag p)*unit angle+heading p

Primitives like unit also offer a loop-free way to construct various strokes like regular polygons, arcs, and ovals. Enclosing the result with list gives us a path:

on ngon sides radius do
 list radius*unit 2*pi*(range sides+1)/sides
end

This completes a set of Lil idioms for affine transformations of paths.

Complex Effects:

What else can we do?

If we start with a path that is centered about its origin, we could scale every point in the path by its own mag, producing a perspective distortion. Given a tween value t that varies between 0 and 1 and a few appropriately-chosen constants,

p*.3+(mag p)*.01*t

If we generate a stroke of random [-1,1] offsets, we could add it to every stroke in a path in order to create a rudimentary line-boil-like effect. The length of our random stroke doesn’t matter, since it will be truncated or extended automatically by +, but having roughly as many points as the maximum stroke in the path will make the results look a bit better. Let’s say 25 points:

p+list 2 window random[3 2*25]-1

Offsetting the points of a path by multiple offset sinusoids produces a different kind of wiggly effect, more like a flag flapping in the wind or the rippling surface of a liquid. To manipulate each axis separately, we’ll use a similar idiom to our shear effect. In this example f is a frame counter that continuously increments, like sys.frame:

px:first @ @ p
((sin(f/4)+.20*px)*list list 1,0)+
((sin(f/5)+.30*px)*list list 0,1)+p

Combine more sinusoids blended into both axes for a more chaotic, subtly richer effect:

px:first @ @ p
py:last  @ @ p
((sin(f/4)+.20*px)*list list 1.5,0.6)+
((sin(f/5)+.30*px)*list list 0.6,0.2)+
((cos(f/7)+.05*py)*list list 0.0,1.2)+
((cos(f/2)+.04*py)*list list 0.1,0.2)+p

These techniques are just scratching the surface of what’s possible in a few lines of Lil!

Why not do some tinkering of your own with the examples in the hershey module’s interactive docs?

back