HNHacker News
TopNewBestAskShowJobs

owlstuffing

343 karma · joined August 12, 2023

submissionscomments
owlstuffing··on Rethinking Syntax: Binding by Adjacency
Author here.

Yes, technically this is a form of backtracking, similar to what a parser does. The key difference is that the search is drastically constrained by the type system: reductions are only attempted where the types actually support a binding operator. Unlike a parser exploring all grammar possibilities, this mechanism prunes most candidates automatically, so the compiler efficiently "solves" the expression rather than blindly exploring every syntactic alternative.

Here is the high-level explanation of the mechanism:

https://github.com/manifold-systems/manifold/tree/master/man...

But the short answer is that it’s not parser-style backtracking over a grammar.

The Java parser still produces a normal AST for the sequence of tokens. What happens afterward is a type-directed binding phase where adjacent expressions may bind if their types agree on a binding operator. The compiler effectively reduces the expression by forming larger typed expressions until it reaches a stable form.

The algorithm favors left associativity, but since a type can implement the binding operator as either the left or right operand, the overall structure of the expression can emerge in different ways depending on the participating types.

So rather than exploring grammar productions, the compiler is solving a set of type-compatible reductions across the expression.

For example:

    2026 March 10
reduces roughly like this:

    (2026 (March 10))
    → March.postfixBind(2026)  // → LocalYearMonth
    → [retreat]                // → no binding with 10
    → March.prefixBind(10)     // → LocalMonthDay
    → .postfixBind(2026)       // → LocalDate
And if `Month` binds with `Range<Integer>`:

    2026 March 10 to 13
can reduce as:

    (2026 (March ((10 to) 13)))
The meaning is therefore determined entirely by which types participate in binding e.g., `LocalDate`, `Month`, `Integer`, `Range`, etc. and which reductions they define.

If a competing interpretation exists but the types don’t support the necessary bindings, it simply never forms.

In that sense it behaves less like a traditional parser and more like a typed reduction system layered on top of the Java AST.

owlstuffing··on If You Can't Own the PR, Please Don't Open One
100% agree.

The frequency of primarily AI-guided PRs is getting out of hand, particularly the whole codebase oriented type: “this PR improves performance, fixes bugs, and refactors random chunks of code.” The cherry on top is the author never attempting to verify the claims of the PR.

A PR should be a focused, cohesive body of code that targets a predetermined, well articulated goal.

Personally, I do not review widely scoped PRs esp. the AI-driven ones. Wasted far too much time chasing down false positive claims and reviewing junk code.

owlstuffing··on Optional/Named Arguments for Java
Explores advanced optional parameters & named arguments as a Java compiler plugin. Complete IDE integration available with IntelliJ.

Key features

- Optional parameters -- Define default values directly in methods, constructors, and records

- Named arguments -- Call methods using parameter names for clarity and flexibility

- Flexible defaults -- Use expressions, reference earlier parameters, and access local methods and fields

- Customizable behavior -- Override default values in subclasses or other contexts

- Safe API evolution -- Add parameters or change defaults without breaking binary or source compatibility

- Eliminates overloads and builders -- Collapse boilerplate into a single, expressive method or constructor

- IDE-friendly -- Fully supported in IntelliJ IDEA and Android Studio

owlstuffing··on Rethinking Syntax: Binding by Adjacency
What if these were real, type-safe expressions in Java:

    2025 July 19   // → LocalDate  
    300M m/s       // → Velocity  
    1 to 10        // → Range<Int>  
    Schedule Alice Tues 3pm  // → CalendarEvent
That's the idea behind binding expressions — a compiler plugin I built to explore what it would mean if adjacency had operator semantics. It lets adjacent expressions bind based on their static types, forming new expressions through type-directed resolution.

Details here: https://github.com/manifold-systems/manifold/blob/master/doc...

owlstuffing··on Type-Safe JDBC: Schema-First Native SQL in Java
This project explores schema-first, native SQL as a JDBC-enabled sublanguage in Java. The goal is to eliminate lossy intermediate subsystems (ORMs, DSLs) without sacrificing Java’s static type-safety guarantees. You write native SQL inline, bind parameters safely, and get fully typed results.

Under the hood Manifold’s compiler plugin synthesizes schema and result types on demand and validates queries at compile time.

owlstuffing··on The Missing Semester of Your CS Education – Revised for 2026
> If somebody can get a lot done with a tool, then it's a good tool.

Does "getting it done with pliers" make them a good wrench?

owlstuffing··on The Missing Semester of Your CS Education – Revised for 2026
Right on. Git is good at what it does, but its CLI is too low-level. It feels more like an assembly language than an end-user language, and a haphazard one at that.

There are wrappers that make it much more approachable. IntelliJ’s Git frontend, for example, is pretty nice.

owlstuffing··on Emulated Windows 3.11 in the Browser
Windows 3.x did not have preemptive multitasking, apps had to yield in the message loop (cooperative multitasking). This meant that an instantaneous response was possible, but often wasn't, at all. Win95 brought true preemptive multitasking, which was a breath of fresh air.
owlstuffing··on Emulated Windows 3.11 in the Browser
Indeed! The UI in general is more intuitive compared with mod flat bs.
owlstuffing··on A16z partner says that the theory that we’ll vibe code everything is wrong
Imagine a 20 person engineering team that hallucinates on a regular basis and is incapable of innovation.
owlstuffing··on A DuckDB-based metabase alternative
> I think we lost the plot as an industry

I get your point, but generally with most enterprise-scale apps you really don’t want your transactional DB doubling as your data warehouse. The “push-based” operation should be limited to moving data from your tx environment to your analytical one.

Of course, if the “analytics” are limited to simple static reports, then a data warehouse is overkill.

owlstuffing··on Garment Notation Language: Formal descriptive language for clothing construction
Read the docs

eg. Darts: https://github.com/khalildh/garment-notation/blob/main/garme...

owlstuffing··on Show HN: Pg-typesafe – Strongly typed queries for PostgreSQL and TypeScript
Something parallel to this and completely amazing: manifold-sql[1].

1. https://github.com/manifold-systems/manifold/blob/master/man...

owlstuffing··on Show HN: ROX – a minimal language with explicit errors and no magic
Looks like a decent start. No UDTs? Not on GitHub? AI generated?
owlstuffing··on Slop Terrifies Me
Yep, and...

4. the quality gap has closed considerably

e.g., the function and durability of your $8k watch and a $300 watch are effectively imperceptible

The gap is closing from both ends (cheap manufacturing, access to tech, etc.)

owlstuffing··on The history of C# and TypeScript with Anders Hejlsberg [video]
Right... But Go is exclusively structurally typed, whereas Java with the manifold compiler plugin complements the type system's nominal foundation -- a class can still implement a structural interface nominally. Doing so enforces intention and helps both people and tooling comprehend code faster and more efficiently. But the general idea is to use an interface structurally where it otherwise can't be used nominally or doing so is more complicated.
owlstuffing··on Why DuckDB is my first choice for data processing
100% agree.

> Writing SQL code

Language integration is paramount for med/lg projects. There's an experimental Java lang project, manifold-sql [1], that does the impossible: inline native DuckDB SQL + type-safety.

    """
    [.sql/] SELECT station_name, count(*) AS num_services
      FROM 'http://blobs.duckdb.org/train_services.parquet'
      WHERE monthname(date) = 'May'
      GROUP BY ALL
      ORDER BY num_services DESC
      LIMIT 3
    """
    .fetch()
    .forEach(row -> out.println(row.stationName + ": " + row.numServices));
1. https://github.com/manifold-systems/manifold/blob/master/doc...
owlstuffing··on What Dynamic Typing Is For
That is a pretty fair assessment, and I'll avoid the nominal v. structural subject, but in my experience the difference between static and dynamic typing comes down to metaprogramming. For instance, much of Python's success stems from its dynamic metaprogramming capabilities. By contrast Java's limitations wrt metaprogramming prevent it from competing in areas such as ML and data science / analytics.

One of the most untapped and misunderstood areas in language design is static metaprogramming. Perhaps this is what you meant by "inadequate compilers", but there is no reason why Java can't provide compile-time metaprogramming. With a comprehensive implementation it can compete directly with dynamic metaprogramming, with the benefits of static analysis etc., which is a game changer.

owlstuffing··on MS-DOS development resources
16-bit Borland C++ is also available: https://winworldpc.com/product/borland-c/20
owlstuffing··on OCaml as my primary language
I agree w that, but I think Scala has deeper problems.

It tries to be a better Java and a better OCaml at the same time. This split personality led to Scala’s many dialects, which made it notorious for being difficult to read and reason about, particularly as a mainstream language contender.

Above all, Scala is considered a functional language with imperative OOP qualities. And it more or less fits that description. But like it or not primarily functional languages don’t have a strong reputation for building large maintainable enterprise software.

That’s the quiet part no one says out loud.

It’s like how in academic circles Lisp is considered the most pure and most powerful of programming languages, which may be true. At the same time most real-world decision makers see it as unsuitable as a mainstream language. If it were otherwise, we’d have seen a Lisp contend with imperative langs such as Java, C#, TypeScript, etc.

I’ve always attributed this disconnect to the fact that people naturally model the world around them as objects with state — people don’t think functionally.

owlstuffing··on Inside OS/2 (1987)
> Aggregation is not inheritance, rather a workaround, using delegation

Although the designers of COM had the right idea, they implemented delegation in just about the worst way possible. Instead of implementing true delegation with multiple interface inheritance, similar to traits, they went pure braindead compositional. The result: unintuitive APIs that led to incomprehensible chains of QueryInferface calls.

owlstuffing··on Try the Mosquito Bucket of Death
Oh, how I’ve never wanted downvote power more.
owlstuffing··on SQLx – Rust SQL Toolkit
Quite similar to manifold-sql[1], which is arguably better integrated into Java than SQLx is into Rust. Inline native SQL in Java is *inherently type-safe*, no mapping -- query types, query results, query parameters all projected types at compile-time.

    int year = 2019;
    . . .
    for(Film film: "[.sql/] select * from film where release_year > :rel_year".fetch(year)) {
        out.println(film.title);
    }
1. https://github.com/manifold-systems/manifold/blob/master/man...
owlstuffing··on The Tabs vs. Spaces war is over, and spaces have emerged victorious
This is yet another reason why source code sb stored in parsed AST form.
owlstuffing··on AI overviews cause massive drop in search clicks
> The overviews are also wrong and difficult to get fixed.

No different from Google search results.

owlstuffing··on TODOs aren't for doing
Replace the not-TODOs with NOTEs.

For example, this TODO:

   //todo: factor this out in case X
…is a NOTE, albeit a gratuitous one.

Because if X ever happens, the note won’t matter anyway, since you will have had to grok all the related code to refactor. You will see this note while you’re refactoring the surrounding code and smirk, “yep, that’s right”, or “no, it doesn’t really fall out that way.” Either way, most TODOs/NOTEs like this just get in the way.

owlstuffing··on Rethinking Syntax: Binding by Adjacency
What if these were real, type-safe expressions in Java:

    2025 July 19   // → LocalDate  
    299.8M m/s     // → Velocity  
    1 to 10        // → Range<Integer>  
    Schedule meeting with Alice on Tuesday at 3pm  // → CalendarEvent
That's the idea behind binding expressions — a compiler plugin I built to explore what it would mean if adjacency had operator semantics. It lets adjacent expressions bind based on their static types, forming new expressions through type-directed resolution.

Details here: [https://github.com/manifold-systems/manifold/blob/master/doc...](https://github.com/manifold-systems/manifold/blob/master/doc...)

owlstuffing··on Row Polymorphic Programming
The manifold project[1] for Java provides that feature as "Structural Interfaces" which supports polymorphic variants.

The project also supports tuples that behave similarly.

    var person = (name: "Joe", age: 35);
    . . .
    Person p = person; // tuple's name, age properties satisfy Person record
1. https://github.com/manifold-systems/manifold
owlstuffing··on Row Polymorphic Programming
I hadn't come across the "Row" polymorphism term before, but it sounds more like structural typing -- for example TypeScript, and to a lesser degree Go, have structural interfaces that provide "row polymorphic" programming.

You could go further with variant structural typing, basically this is a broader form of type checking based on call compatibility, which answers the question -- is B#foo() callable as an A#foo()?

For instance, your `area` example requires `double` result types, otherwise a row type having `width` and `length` defined as `integer` columns doesn't satisfy `area`. But, result types are naturally covariant -- `integer` is a subset of `double` -- which permits us to accept `integer` in the implementation of `area`.

Similarly, parameter types are naturally contravariant -- `Shape` is contravariant to `Triangle`, thus `B#foo(Shape)` is call-compatible as a `A#foo(Triangle)`, therefore I can pass a Triangle to `B#foo(Shape)`.

The manifold project[1] for Java is one example where the type system is enhanced with this behavior using structural interfaces.

Note, this goes further with parametric types where function result types and parameter types define variance and other constraints.

1. https://github.com/manifold-systems/manifold

owlstuffing··on My Database Is My Application: Rethinking Webhook Logic with DuckDB and SQL
Yep. Using DuckDB against conventional data sources such as JSON and CSV or even Parquet has amazing potential. Paired with manifold[1]--a Java library that makes it all type safe--and it's a game changer.

1. https://github.com/manifold-systems/manifold/blob/master/doc...

← PreviousPage 2 of 9Next →