HNHacker News
TopNewBestAskShowJobs

owlstuffing

342 karma · joined August 12, 2023

submissionscomments
owlstuffing··on Java sealed classes and exhaustive pattern matching
Scala is its own worst enemy in this respect. It’s both too close to Java and too far.

Too far: there are several dialects one can use with it e.g., I can speak Haskell with Scala grammar. Unlike with Java there is no central Scala dialect, so reading/maintaining a Scala codebase can be a challenge.

Too close: its type system, as advanced as it is, is still stuck in Java’s inheritance and all its limitations. Traits, for example, are not runtime components, they dissolve into the hosting class’ single object, giving up the independent identity and flexibility of runtime configured composition. And the Scala 3 `exports` feature that departs Java’s inheritance is just forwarding, not true delegation; it is the inverse of traits: it trades self identity for independent identity (no late-bound self that comes free with impl inheritance).

owlstuffing··on JEP 540: Simple JSON API (Now in Incubator)
This is just a small part of manifold’s JSON integration. And, yes, the inline aspect is mostly for testing, and it’s awesome there.
owlstuffing··on JEP 540: Simple JSON API (Now in Incubator)
You can inline native type-safe JSON directly in Java with the manifold project.

    /*[Dude.json/] {
      "Name": "Scott",
      "Age": 100,
      "Address": {
        "Street": "345 Syracuse Way",
        "City": "Atlantis"
      }
    }
    */

    Dude dude = Dude.fromSource();
            
    out.println(dude.getName());
    out.println(dude.getAge());
    out.println(dude.getAddress().getCity());

https://github.com/manifold-systems/manifold
owlstuffing··on HeidiSQL – Lightweight MariaDB, MySQL, SQL Server, PostgreSQL and SQLite Manager
Delphi?! Interbase?! Is this a Borland reunion?
owlstuffing··on Ada, its design, and the language that built the languages
Ada was designed to solve different problems in harsher environments than other PLs at the time. Mostly, it was designed for the defense and aeronautics industries and had to compete against other PL designs to become a govt standard, similar to how weapons of war are developed and chosen. Think developing for hardcore code audits. There is no way the language could check all the boxes and remain compatible with, say, Pascal or Modula syntax.
owlstuffing··on Design and implementation of DuckDB internals
Analytics with type-safe raw SQL (including DuckDb’s awesome extensions) is pure gold:

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

owlstuffing··on Bring Back Idiomatic Design (2023)
Precisely. 'member CUA?
owlstuffing··on OpenJDK Interim Policy on Generative AI
Many will argue that Oracle is overreacting, and they may not be entirely wrong. But as someone who reviews PRs for open source languages and tooling, their interim actions strike me as both sound and measured.

The number and size of AI-assisted PRs have reached a tipping point. Reviewing them already consumes a significant amount of time, and even filtering out the obvious ones is a drag. More importantly, the risk/reward balance is shifting in the wrong direction. For now, placing constraints on AI-assisted contributions feels like a sensible way to manage that risk.

Will this policy reject or slowdown otherwise beneficial PRs? Potentially. But that is the tradeoff. Until there is a better way to offset risk, this one is probably the least bad strategy.

owlstuffing··on Union types in C# 15
General purpose != multiple dialects, that is the trouble with languages like this - C# is a tower of babel.
owlstuffing··on Union types in C# 15
In isolation, yes, I agree with you. But in the context of the cornucopia of other "carefully evaluated" features mixed into the melting pot, C# is a nightmare of language identities - a jack of all trades, master of none, choose your dialect language. No thanks.
owlstuffing··on Union types in C# 15
F# units are handy, but nothing like Manifold units (Java):

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

owlstuffing··on Union types in C# 15
> Pulling them all into C# just makes C# seem like a big bag of stuff, with no direction.

Agreed. Java is on the same trail.

owlstuffing··on Union types in C# 15
> It doesn't cover ad-hoc unions

Yes and no. C# unions aren’t sealed types, that’s a separate feature. But they are strictly nominal - they must be formally declared:

    union Foo(Bar, Baz);
Which isn’t at all the same as saying:

    Bar | Baz
It is the same as the night and day difference between tuples and nominal records.
owlstuffing··on Cursor 3
It’s not their code, and it’s not for them to understand. The endgame here is that code as we know it today is the “ASM” of tomorrow. The programming language of tomorrow is natural human-spoken language used carefully and methodically to articulate what the agent should build. At least this is the world we appear to be heading toward… quickly.
owlstuffing··on Cursor 3
There is a large and growing segment of executives in the software world that is pushing this model hard, like betting their career on it. To them the “dark factory” is an inevitability. As a consequence, not only are developers choosing this path, but the companies they work for are in varying degrees selecting this path for them.
owlstuffing··on The Windows equivalents of the most used Linux commands
Not having to run a mess of Linux commands to install software.
owlstuffing··on Java 26 is here
"Fat" runtime? Go? Nah.

Go's runtime is thin: goroutines, a GC specialized for concurrency, networking, and little else. Java, by contrast, assumes a JVM plus massive stdlibs to handle everything from enterprise apps to big-data, making its platform genuinely "fat" and layered. Other Java-tier languages, C# included, follow the same model.

owlstuffing··on Java 26 is here
Now that Go is styled as a Java competitor its framing is different. But here's an old golang.org archive for fun:

https://web.archive.org/web/20091113154831/http://golang.org...

The main page title *Go: a systems programming language*

It still sports all the low-level stuff too, pointer arithmetic and all.

owlstuffing··on Java 26 is here
It's replete with oddities and limitations that signal "ah, this is because systems language."

Go’s type system, for example, is very much a systems-language artifact. The designers chose structural typing because it was lighter weight, but provided enough type safety to get by. It sucks though for enterprise app development where your team (and your tooling) are desperate for nominal typing clarity and determinism.

owlstuffing··on Java 26 is here
> I think the reputation you mentioned. . .

Actually no. Go was designed from the beginning as a systems language as a C replacement.

owlstuffing··on Java 26 is here
Kotlin's "delegation" feature isn't true delegation, it's just call forwarding, which is better than nothing, but it falls down pretty quickly as an alternative to implementation inheritance.

The manifold project provides true delegation[1] for Java.

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

owlstuffing··on Java 26 is here
> Maybe this is just a question of taste but I never could get along with Javas (or Kotlin's) tooling

Are you joking? IntelliJ is without a doubt the best dev tooling environment available.

owlstuffing··on Java 26 is here
"industry purposes" likely equates to "enterprise software development." And that assertion is 100% correct.
owlstuffing··on Java 26 is here
Go can't compete with Java bc it's not in the same category as Java.

- Java is a high-level, multi-paradigm programming language

- Go is designed as a systems language to supersede C projects at Google

Now Go identifies as a general purpose language that competes with Java? It's a free country, I guess.

owlstuffing··on Java 26 is here
> We now know that we prefer composition over inheritance

When people say "composition over inheritance" in Java discussions, they usually mean the trivial modeling rule: prefer has-a over is-a.

But that’s not what composition is really about.

The deeper idea is interface composition -- building types by composing multiple behavioral contracts behind a single cohesive surface.

Java provides inheritance and interfaces, but it doesn’t provide first-class delegation or traits. So most developers never really practice interface composition. They either subclass, or they wire objects together and expose the wiring.

The slogan survived. The concept mostly didn’t.

The manifold project, for example, experiments with language-level delegation to make interface composition practical with Java.

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

owlstuffing··on Rethinking Syntax: Binding by Adjacency
Yes, the empty infix operator is often called the "juxt" operator, which is an apt term here.

However, I use the term "binding expressions" intentionally because there’s more going on than ordinary juxtaposition. In a normal juxt expression such as:

    a b c
the evaluation order is static and independent of the type system:

    (a b) c
With binding expressions the precedence is type-directed, so the type system determines which grouping is valid:

    (a b) c
    a (b c)
Additionally, the operation itself can be provided by either operand. For a given expression a b, the compiler may resolve it as:

    a.prefixBind(b)
    b.postfixBind(a)
For example:

    10kg
Here kg is a MassUnit, and MassUnit defines postfixBind(Number) returning Mass, so given there is no left-to-right binding, the expression resolves right-to-left as:

    kg.postfixBind(10)
So while juxtaposition is the syntactic surface, the semantics are type-directed binding.
owlstuffing··on Florida judge rules red light camera tickets are unconstitutional
> California's new speed camera pilot (AB 645) explicitly solves for this... like parking tickets

That makes the Florida judge's framing of red light cameras as a revenue generating scheme even more applicable. More than that, it ambiguates the crime.

owlstuffing··on Rethinking Syntax: Binding by Adjacency
> The drawback is that building an AST now requires a symbol table

Well, yes and no. During AST building a binding expression resolves as an untyped polyadic expression. Only later during the compiler's type attribution phase does a binding expression's structure resolve based on the operand types.

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

> in typical code you don’t have the case of constant values so often.

Agreed. It's not really useful with inlined expressions:

   Schedule contacts.select(contactId) inputForm.getDateTime()
but if you write it like:

   var plumber = contacts.select(contactId)
   var date = inputForm.getDateTime()
   var building = findLocation(warehouse)
   Schedule plumber on date at building
But, honestly, I can't say I personally use it that way ;)

Initially, I wrote it as a science extension to Java: https://github.com/manifold-systems/manifold/tree/master/man...

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.

Page 1 of 9Next →