owlstuffing
Yep. Interface-based (true) delegation between objects would be my go-to if it existed.
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).
/*[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/manifoldhttps://github.com/manifold-systems/manifold/blob/master/doc...
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.
https://github.com/manifold-systems/manifold/tree/master/man...
Agreed. Java is on the same trail.
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.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.
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.
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.
Actually no. Go was designed from the beginning as a systems language as a C replacement.
The manifold project provides true delegation[1] for Java.
1. https://github.com/manifold-systems/manifold/blob/master/man...
Are you joking? IntelliJ is without a doubt the best dev tooling environment available.
- 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.
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...
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.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.
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...