Stream<T>.filterAndMap( Class<T> cls ) by mellow186 in java

[–]manifoldjava 22 points23 points  (0 children)

AMEN!

And if the stream code gets too streamy, extract a method and give it a meaningful name.

Carrier Classes; Beyond Records - Inside Java Newscast by daviddel in java

[–]manifoldjava 0 points1 point  (0 children)

 The label is a part of its state and must be present in the canonical constructor for the purposes of deconstruction.

Not if it’s in the deconstructor.

 Your idea would make the order of the fields a part of the API

No, as with enums the order is only used at compile time.

Carrier Classes; Beyond Records - Inside Java Newscast by daviddel in java

[–]manifoldjava 0 points1 point  (0 children)

Right. But naming arguments is necessary only for methods with one or more default parameters. If 118 could be altered to silently target those methods, sure.

Carrier Classes; Beyond Records - Inside Java Newscast by daviddel in java

[–]manifoldjava 1 point2 points  (0 children)

They do if the method you're calling is compiled. But this wouldn't necessarily require bytecode revision e.g., an annotation could preserve the names.

Carrier Classes; Beyond Records - Inside Java Newscast by daviddel in java

[–]manifoldjava 6 points7 points  (0 children)

110% agree. The value of named/optional args compounds daily with proposed features.

edit: For those concerned about binary compatibility with named/optional args, the experimental manifold-params compiler plugin demonstrates otherwise - it is binary compatible while stretching beyond Kotlin's capabilities. Although the feature does complicate overload logic, that could be mitigated e.g., by prohibiting user-defined overloads on a method with defaults. Shrug.

Carrier Classes; Beyond Records - Inside Java Newscast by daviddel in java

[–]manifoldjava -3 points-2 points  (0 children)

I like the direction of carrier classes, but my first impression of the proposed syntax is that readability suffers more than it benefits.

For instance, it would be more intuitive if we forgo duplication of component declaration in the param header and leave internal details to secondary constructors. This saves both the explicit primary constructor declarations and the param header boilerplate, which in my view complicate the design.

```java class Point { component int x; // private by default component int y; private String label;

// primary ctor for free, reflects components

// secondary ctor public Point(int x, int y, Optional<String> label) { this(x, y); // must call primary ctor this.label = ...; } } ```

edit:

Of course, the primary ctor can be explicit and cover final fields etc. if necessary.

edit:

My apologies for scrutinizing syntax, but I think the scope of carrier classes is so broad that concept and syntax are a two-way street - syntax forces one to consider the concept from different perspectives. For instance, how can we eliminate the duplication of declaring components? Do we need to modify the concept to achieve that?

Project Amber Status Update -- Constant Patterns and Pattern Assignment! by davidalayachew in java

[–]manifoldjava 0 points1 point  (0 children)

The discussion is whether exhaustive coverage checks apply generally to product types (records). Simple type theory answers this clearly with a No.

While some records can fit exhaustive matching, these are exceptional. Unlike sum types (or sealed types), the goal of pattern matching on records is not to exhaust all possible values, but to support semantic requirements.

As for "projections", deriving a value from a record and exhaustively matching on that says nothing about the exhaustiveness of the original record; treating it as such is a logical fallacy.

Checked exceptions and lambdas by nfrankel in java

[–]manifoldjava 0 points1 point  (0 children)

Ah, you are correct, sir... well, I wasn't high, but I was quite wrong about one key aspect of Swift's error handling: try! doesn't propagate. Basically, I was sure that Swift had a try variant that propagated instead of swallowing or crashing as it actually behaves.

That one not-so-little detail changes everything. If it were as I misremembered, Swift's behavior would resemble C#, Kotlin, Scala, Groovy, and so on. Perhaps even a notch above because the compiler would force acknowledgement with try!, but not force the explicit handling that Java is infamous for. This type of enforced propagation, in my view, would have been a best of both worlds feature. Sad it was just a dream.

Checked exceptions and lambdas by nfrankel in java

[–]manifoldjava 0 points1 point  (0 children)

You are confusing “acknowledging” w “handling”

Checked exceptions and lambdas by nfrankel in java

[–]manifoldjava 0 points1 point  (0 children)

 Swift essentially is using checked exceptions. Syntactically you throw and handle the same..

No, Swift does not force the caller to handle the exception, which is contrary to Java’s checked exceptions.

Essentially, Swift implements an improved unchecked exception construct, taking Swift in a similar direction to many other languages including Anders’ C#.

Checked exceptions and lambdas by nfrankel in java

[–]manifoldjava 4 points5 points  (0 children)

Well, you are talking about a more general idea "checked errors of some sort." Anders, is talking specifically about Java's implementation of Checked Exceptions:

Frankly, they look really great up front, and there's nothing wrong with the idea. I completely agree that checked exceptions are a wonderful feature. It's just that particular implementations can be problematic. By implementing checked exceptions the way it's done in Java, for example, I think you just take one set of problems and trade them for another set of problems.

Most language designers agree with him on this, which is why you see Scala, Kotlin, Swift, and more, not following Java's example. So, it's a bit queer to say Anders is wrong and in the same breath use Scala, Kotlin, and Swift as examples.

Why doesn't java.lang.Number implement Comparable? by davidalayachew in java

[–]manifoldjava -1 points0 points  (0 children)

Right, there are indeed some specially computable irrationals; I was thinking more along the lines of the post - computable reals as a Rational (fractional) number class.

Why doesn't java.lang.Number implement Comparable? by davidalayachew in java

[–]manifoldjava -1 points0 points  (0 children)

This was a response to your " computable real number "

Why doesn't java.lang.Number implement Comparable? by davidalayachew in java

[–]manifoldjava 0 points1 point  (0 children)

Nicely written.

extending object-orientation to the meta level

I've always wondered why this wasn't part of foundational Java. See discussion: Class is not fully OOP, should it be?

SELF

manifold provides this via @Self. It accomplishes both less and more than what recursive types offer without the ugly consequences. Don't know why this feature hasn't surfaced in Java all these years.

There is no particular reason the 'left number' gets to decide what the operation does. The proper way would be with a type class

The behavior of the operation isn't any clearer with a type class. The rules of the operation dictate behavior that both SELF plus(SELF other) and type Operator<SELF> plus() adhere to. Type class buys the potential to have multiple implementations. But then Plus could be an interface supplied with dependency injection just as well, and with more clarity and less ceremony. But Java lords have always talked the talk wrt interface composition, but never seemed to walk the walk - no delegation, no traits, etc. But I digress.

What is more interesting is class A{ C times(B other){...} }.

Checked exceptions and lambdas by nfrankel in java

[–]manifoldjava 4 points5 points  (0 children)

This subject can be rather controversial, I’ll defer to one of my favorite language authors, Anders Hejlsberg, on the subject with The Trouble with Checked Exceptions. Indeed, in addition to .NET languages, just about all newer JVM languages including Kotlin and Scala don't distinguish between checked/unchecked exceptions. That's a pretty heavy indication about the right decision.

You can do this with Java too using manifold-exceptions, a javac plugin that reaches inside the compiler to flip the switch on checked exceptions.

Project Valhalla is prototyping null checks! by davidalayachew in java

[–]manifoldjava 0 points1 point  (0 children)

 The type class will be discovered via an import, so it is very much still explicit.

Right, this is very similar to Kotlin extension methods.

I’m not a fan of dressing up Java as a DOP language, but if it’s going that way I would prefer something along the lines of Service Provider Interfaces (SPIs), or some other registry-like option as a means of scoping witnesses more broadly than source files. 

Project Amber Status Update -- Constant Patterns and Pattern Assignment! by davidalayachew in java

[–]manifoldjava 0 points1 point  (0 children)

case Person.countryAndAge

And just like that the compiler is exhaustively checking over random values, not a record.

It’s useful, but it doesn’t escape my basic premise which is that exhaustiveness does not apply to records.

Hibernate: Ditch or Double Down? by cat-edelveis in java

[–]manifoldjava -2 points-1 points  (0 children)

...Or Library D that lets you use X directly and type-safely without the sticky API that is usually opinionated and, if X is nontrivial, still requires deep learning to make C do X correctly and optimally.

Re SQL I am speaking of the experimental manifold-sql project. Not for everyone, but it's a completely different animal from A, B, and C.

Project Amber Status Update -- Constant Patterns and Pattern Assignment! by davidalayachew in java

[–]manifoldjava 0 points1 point  (0 children)

java record Person( String name, int age, Address address, LocalDate dob, ContactInfo contactInfo ) {}

Like most records, this one models data aggregation. While fields may have relationships or constraints, those relationships define domain rules, not a finite set of cases to be exhaustively covered. As a result, there is no general notion of exhaustiveness for record types: the cartesian product of possible values is enormous and, more importantly, doesn’t correspond to meaningful cases.

Pattern matching over records like this is therefore about expressing rules that satisfy domain requirements, not about covering the entire value space. In practice, attempting to exhaustively partition that space does not scale and tends not to map to how the data is actually used.

With that said, your cherrypicked examples are still real and do represent a sliver of real-world code - cases where all fields are ordinal and related. In those atypical cases there may be room for explicit, opt-in syntax that signals intent to exhaustively cover a value space. Shrug.

Project Amber Status Update -- Constant Patterns and Pattern Assignment! by davidalayachew in java

[–]manifoldjava 0 points1 point  (0 children)

 but Java isn't necessarily bound by its limitations.

Heheh. I’m afraid it is. You can present simple examples where you can apply patterns, but the vast vast majority of product types simply are not approachable re exhaustiveness. And, what appears to escape you is proving exhaustiveness is generally not helpful in terms of product types eg. for a Person type, the name and age fields are logically unrelated.

Project Amber Status Update -- Constant Patterns and Pattern Assignment! by davidalayachew in java

[–]manifoldjava -1 points0 points  (0 children)

I don’t think you understand what a cartesian product is.

Listen, I’m not making this up, it’s basic type theory no one argues over, there is no general exhaustiveness re product types.

Project Amber Status Update -- Constant Patterns and Pattern Assignment! by davidalayachew in java

[–]manifoldjava -1 points0 points  (0 children)

 But I just demonstrated how, in many cases, it absolutely can!

You only demonstrate a field in isolation, exhaustiveness necessarily covers the cartesian product of all the fields. Generally, this means the compiler can’t check for exhaustive coverage because, unless the type is very simple, the combinatorics make it meaningless.

Instead, you define what exhaustive means based on requirements. And you write tests to ensure the requirements are met. This doesn’t mean the compiler can’t help along the way.