{"slug": "osprey-gets-the-crown-effects-handlers-and-fewer-copies", "title": "Osprey Gets the Crown: Effects, Handlers and Fewer Copies", "summary": "Deslop added support for Osprey, the functional language built around algebraic effects, inferred types and native LLVM compilation, reading all three Osprey flavors: default `.osp`, native ML `.ospml`, and explicitly selected Python syntax. Deslop keeps Osprey's effects, handler arms, patterns, types and expressions as syntax-tree structure, normalizing identifier and literal spellings so renamed copies of code such as a deterministic clock handler still cluster and rank as duplication, with findings surfaced in the editor and through the MCP tool. The tool also gives Osprey a gold crowned bird in its UI, though the post states the evidence, not the crown, decides the score.", "body_md": "# Osprey Gets the Crown: Effects, Handlers and Fewer Copies\n\nOsprey gets the crown. A functional language built around algebraic effects, inferred types and native compilation deserves tools that understand its code. Deslop now reads all three Osprey flavors: default `.osp`, native ML `.ospml`, and explicitly selected Python syntax. It finds copied structure and brings the findings into the editor and the agent workflow.\n\nAnd yes: it gets a gold crowned bird in the UI. We have favourites.\n\n## [The language worth making a fuss about](#the-language-worth-making-a-fuss-about)\n\nOsprey lets application logic say what it needs through an **effect**, while a **handler** supplies the implementation. That makes the boundary between a capability and its provider explicit. Production code and deterministic tests can share the same application logic.\n\nHere is a small example. The function asks for a clock; the handler chooses the answer.\n\n``` php\neffect Clock { now: fn() -> int }\n\nfn announce() = {\n    let timestamp = perform Clock.now()\n    \"Osprey launch at ${timestamp}\"\n}\n\nlet preview = handler Clock {\n    now => 42\n}\n\nprint(preview(announce))\n```\n\n`perform` requests the capability. `preview` is a reusable handler value. The function stays focused on the announcement, and the checker infers its result type. This is an exceptionally appealing way to write code whose dependencies remain visible and whose tests stay deterministic.\n\nOsprey compiles through LLVM to native binaries, with WebAssembly and C ABI targets for supported workloads. The language is actively evolving; its [documentation](https://www.ospreylang.dev/docs/) describes the current boundaries.\n\n## [Real syntax deserves real analysis](#real-syntax-deserves-real-analysis)\n\nDeslop keeps Osprey's effects, handler arms, patterns, types and expressions as syntax-tree structure. Renaming a function or a binding does not make copied code disappear: identifier spelling normalizes before the structural comparison. Literal spellings normalize too, while their source content remains available to the shared evidence checks.\n\nString interpolation gets proper attention. The code inside `${...}` remains code: a conditional stays a conditional, and addition stays distinct from subtraction. This matters in a language where a concise expression can contain substantial application logic.\n\nComments and imports do not count as copied implementation. Findings use the same measured ranking as other languages, so the largest duplication problems remain at the top. The crown is presentation; the evidence decides the score.\n\n## [When a useful handler becomes six copies](#when-a-useful-handler-becomes-six-copies)\n\nImagine a project with a deterministic clock handler for invoice tests. The next feature needs the same setup for receipts, so the handler gets copied. Then reminders need it too. Each copy grows a slightly different wrapper; names change, a literal changes, and finding the shared implementation becomes harder than searching for the original function name.\n\nThat is the moment structural analysis earns its place. Deslop compares the parsed implementation, gathers the surviving copies into a cluster and ranks the duplicated work. You can inspect the actual occurrences, decide which differences are meaningful, and extract a shared helper when the tests support it. Similar scaffolding alone is insufficient evidence; the copied work matters.\n\nEffects make a capability explicit. A duplicate report makes repeated implementation explicit. Together they give you a useful question: should these tests share a handler, or do they express different policies that deserve separate code? The comparison helps you decide; a score cannot make that design decision for you.\n\n## [A front-row seat in the editor](#a-front-row-seat-in-the-editor)\n\nOpen an `.osp` file with Deslop installed. Osprey participates in the live analysis loop, with findings available through the editor, cluster comparisons and the MCP tools used by coding agents. Its language identity appears in grouping, file rows and the report webviews, alongside icons for every other supported language.\n\nFor a CLI scan of an Osprey project:\n\n```\ndeslop .\n```\n\nStart with the highest-ranked genuine duplicate, compare its occurrences, and decide whether one tested implementation can replace the copies. Osprey gives you reusable capabilities; Deslop helps you spot application logic that deserves the same treatment.\n\nFor an agent, the useful moment comes even earlier. Before generating another test helper or service wrapper, ask `find-similar` about the intended implementation. If a suitable helper already exists, reuse it. After a change, inspect `duplicates`, then open the relevant cluster to compare the source ranges. The MCP tools consult the live analysis session, so this fits inside the editing loop.\n\n## [Three flavors, clear boundaries](#three-flavors-clear-boundaries)\n\nOsprey has default braces syntax, ML layout syntax and a Python-looking surface. Understanding one does not automatically establish correct analysis of the others.\n\nAll three flavors have verified CLI fixtures and real LSP/MCP language-label checks. A leading `# osprey: flavor=python` comment, an explicit `python_sources` entry or a Python project entry opts a `.py` file into Osprey. Ordinary Python files keep their Python identity, and Osprey's Python surface does not inherit ordinary Python's automatic extraction actions.\n\nNative ML `.ospml` uses a grammar verified against Osprey's real source corpus and independent structural checks. Layout, interpolation expressions, and flat-versus-curried calls remain visible syntax. The three parser identities stay distinct in caches and reports, even though the interface gives them the same crowned bird. Cross-flavor clone equivalence is not claimed.\n\nThe [Osprey support guide](https://deslop.live/docs/osprey/) has the configuration details and current integration status. These changes describe the development tree; check your installed Deslop version before expecting them in an older VSIX.\n\n## [Long live the bird](#long-live-the-bird)\n\nEffects that make dependencies explicit. Handlers you can keep and reuse. Types the checker works out. Native compilation. Osprey brings a compelling combination, and we want its tooling to match that ambition.\n\nExplore [Osprey](https://www.ospreylang.dev/), then [install Deslop](https://deslop.live/docs/) and put the crowned bird to work.", "url": "https://wpnews.pro/news/osprey-gets-the-crown-effects-handlers-and-fewer-copies", "canonical_source": "https://deslop.live/blog/osprey-first-class/", "published_at": "2026-10-25 00:00:00+00:00", "updated_at": "2026-11-01 23:20:10.476534+00:00", "lang": "en", "topics": ["developer-tools", "ai-tools", "agent-protocols"], "entities": ["Deslop", "Osprey", "LLVM", "WebAssembly", "MCP"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/osprey-gets-the-crown-effects-handlers-and-fewer-copies", "markdown": "https://wpnews.pro/news/osprey-gets-the-crown-effects-handlers-and-fewer-copies.md", "text": "https://wpnews.pro/news/osprey-gets-the-crown-effects-handlers-and-fewer-copies.txt", "jsonld": "https://wpnews.pro/news/osprey-gets-the-crown-effects-handlers-and-fewer-copies.jsonld"}}