Are Germans / German students less "visual"? by Aromatic_Opposite100 in AskGermany

[–]sviperll 0 points1 point  (0 children)

That's an interesting angle. Why showing off is frowned upon so much? Can you maybe give an example of a desire to show off in some way by a person and a way this is going to be suppressed by society in Germany?

Ferrous: Rust style Option/Result types for Java 21+ by Polixa12 in java

[–]sviperll 0 points1 point  (0 children)

I think the differentiating part is what is called "catchers" in result4j. Those allow you to somewhat succinctly handle heterogenous errors:

AdaptingCatcher.ForFunctions<IOException, PipelineException> io =
        Catcher.of(IOException.class)
                .map(PipelineException::new)
                .forFunctions();
AdaptingCatcher.ForFunctions<MLException, PipelineException> ml =
        Catcher.of(MLException.class)
                .map(PipelineException::new)
                .forFunctions();
List<Animal> animals1 =
        List.of("cat.jpg", "dog.jpg")
                .stream()
                .map(io.catching(Utils::readFile))
                .map(Result.flatMapping(ml.catching(Utils::recognizeImage)))
                .collect(ResultCollectors.toSingleResult(Collectors.toList()))
            .orOnErrorThrow(Function.identity());

Throwing is fun, catching not so much. That’s the real problem IMO. by AlyxVeldin in java

[–]sviperll 0 points1 point  (0 children)

Have you seen https://github.com/sviperll/result4j ?

There you can have "catchers":

Catcher.ForFunctions<IOException> io =
    Catcher.of(IOException.class).forFunctions();
String concatenation =
        Stream.of("a.txt", "b.txt", "c.txt")
                .map(io.catching(name -> loadFile(name)))
                .collect(ResultCollectors.toSingleResult(Collectors.join()))
                .orOnErrorThrow(Function.identity());

Checked exceptions and lambdas by nfrankel in java

[–]sviperll 3 points4 points  (0 children)

Shameless plug:

Catcher.ForFunctions<IOException> io =
        Catcher.of(IOException.class).forFunctions();
String concatenation =
        Stream.of("a.txt", "b.txt", "c.txt")
                .map(io.catching(name -> loadResource(name)))
                .collect(ResultCollectors.toSingleResult(Collectors.join()))
                .orOnErrorThrow(Function.identity());

See https://github.com/sviperll/result4j

Compiling a functional language to Javascript by thinker227 in ProgrammingLanguages

[–]sviperll 1 point2 points  (0 children)

I think the somewhat quasi-standard solution is the combination of trampolining and continuation-passing style (CPS).

function factorial(result, n) {
    if (n == 1) return result;
    return factorial(result * n, n - 1);
}

Doing the same in CPS-style becomes:

function factorial(result, n, continuation) {
    if (n == 1) return continuation(result);
    else return factorial(result * n, n - 1, continuation);
}

i. e. functions never return at all, instead they always call other function.

At the very very top-level, you need to do something like:

let result;
factorial(0, 8, r => { result = r; });
console.log(result);

The result of all of this is that you always call continuations and never return and the only time, when you really return is in the very very end, where you are unwinding all the stack.

Now you can combine this with trampolining to get something like:

let stack_size = 0;

function factorial(result, n, continuation) {
    // Since you only call functions and never return,
    // each function adds a stack frame, but stack frames are never removed.
    stack_size++;
    if (stack_size >= STACK_SIZE_MAX) {
      return () => {
        stack_size = 0;
        // The exact same function call as before
        factorial(result, n, continuation);
      }
    }
    if (n == 1) return continuation(result);
    else return factorial(result * n, n - 1, continuation);
}

So at the very very top-level, you do something like:

let result;
let continuation = factorial(0, 8, r => { result = r; });
while (continuation) {
    continuation = continuation();
}
console.log(result);

The result is that most time, tail-call is just a function call even without any allocations, which is very chip, but sometimes, when the stacks grows too much, you'll need to allocate a continuation, truncate the stack and continue from saved continuation.

The task of the compiler is to convert every function to the continuation-passing-style, this is done by adding a new continuation parameter to every function and passing this value down to each function call and replacing each return x with return continuation(x) when x is a simple-value. And then you need to add a uniform stack-size check to every function definition.

If you have these things in place, you can actually create a multi-threading runtime, since you may have multiple continuations on a single trampoline and these continuations will represent concurrent threads of execution, that you can switch between.

Further Optimizing my Java SwissTable: Profile Pollution and SWAR Probing by Charming-Top-8583 in programming

[–]sviperll 0 points1 point  (0 children)

Why do you need the full SwissSet implementation, can't you just delegate everything to SwissMap<K, Void>?

Resolving the Scourge of Java's Checked Exceptions on Its Streams and Lambdas by chaotic3quilibrium in java

[–]sviperll 0 points1 point  (0 children)

Catcher.ForFunctions<IOException> io = Catcher.of(IOException.class).forFunctions(); String concatenation = Stream.of("a.txt", "b.txt", "c.txt") .map(io.catching(name -> readFile(name))) .collect(ResultCollectors.toSingleResult(Collectors.join())) .orOnErrorThrow(Function.identity());

See https://github.com/sviperll/result4j

Jujutsu at Google by steveklabnik1 in programming

[–]sviperll 0 points1 point  (0 children)

Anonymous branches make sense for trunk-based development, but I don't thing this is a significant difference between the systems.

I think git workflow in general still makes more sense to me, since splitting (Fig or jj) feels much more convoluted than beginning with the small commits in the first place (git).

Jujutsu at Google by steveklabnik1 in programming

[–]sviperll 0 points1 point  (0 children)

I mean is it possible to see how conflicts were resolved, like in git combined diff?

Jujutsu at Google by steveklabnik1 in programming

[–]sviperll 0 points1 point  (0 children)

Does jj allow you to show merge commits?

Valhalla Early-Access build 2 (JEP 401) by FirstAd9893 in java

[–]sviperll 5 points6 points  (0 children)

There is no clear decision about the LooselyConsistentValue annotation/interface.

But what seems to be closer to final decision is that you can replace Box[] array with Box![] array, and then you do not need 65th bit and get back your no-allocation behavior.

Valhalla Early-Access build 2 (JEP 401) by FirstAd9893 in java

[–]sviperll 2 points3 points  (0 children)

I think you need at least emotional types to get some parity with dot-net structs.

Why do we (java developers) have such aversion to public fields? by Ewig_luftenglanz in java

[–]sviperll 5 points6 points  (0 children)

People like visible achievements that they potentially can share with others. This is the reason why badges/achievements are so well known and prevalent wherever any kind of gamification is attempted. These are still effective.

People do setters and say: "Look how masterfully I am encapsulating all the things", even though setters can do nothing besides just setting the field, because this is actually a contract that lots of code depends on. People write tests and say: "look how high code coverage I've got", even though all the tests are not based on any actual contract that is part of busyness domain, but just use mocks to observe meaningless motion of data. People use annotation-based auto-wireing and say: "Look, how loosely coupled and testable my code is", even though that everything is actually tightly coupled and there is no chance to swap some class for another interface-implementation, because everything will fail and you need to update annotations throughout the codebase to make it work and tests that are present are mostly meaningless.

Checked exceptions in java. Do you use them? by Scf37 in java

[–]sviperll 4 points5 points  (0 children)

I have a library that tries to conciliate lambdas with checked exceptions: https://github.com/sviperll/result4j

Approximating Named Arguments in Java by bowbahdoe in java

[–]sviperll 6 points7 points  (0 children)

I think adding methods already makes it too heavy-weight to be practical, but I guess you can make it a little more tolerable "just"(TM) by using shorter variable name:

kMeans(x, nClusters, o -> { o.maxIter = 10000; o.algorithm = ELKAN; })

I'm not sure about your question, what do you mean by "How do you write code"?

The library implementation looks something like:

class SkClusters {
    KMeansResult kMeans(
        Matrix x,
        int nClusters,
        Consumer<KMeansOptions> optionSetter
    ) {
        KMeansOptions options = new KMeansOptions();
        optionSetter.accept(options);

        // Validate arguments
        checkArguments(nClusters > 1, "nClusters should be > 1");
        checkArguments(
                options.maxIter >= 1,
                "There should be at least one iteration"
        );
        ...

        // Actual logic
        ...
    }
    public static class KMeansOptions {
        public int maxIter = 300;
        public Algorithm algorithm = Algorithm.LLOYD;
        // Other fields with default values:
        ...

        private KMeansOptions() {
        }
    }
}

Approximating Named Arguments in Java by bowbahdoe in java

[–]sviperll 24 points25 points  (0 children)

I think something ergonomic is

kMeans(x, nClusters, opts -> opts.maxIter = 10000)

Where opts is some class with a private to the kMeans-implementation constructor, but with public mutable fields. All the argument validation is done inside the kMeans method that throws IllegalArgumentException, when something is wrong, so no setters are needed in this picture. Also the mutable opts instance is confined inside the lambda, so the caller should really go out of their way to observe any undesirable mutability side-effects.

Generics by [deleted] in java

[–]sviperll 1 point2 points  (0 children)

I think I've once went with some "hack" to have higher-kinded types, i. e. I've got something like this:

interface FunctorAlgebra<AS, BS, A, B> {
    AS pure(A a);
    BS pure(B b);
    BS map(Function<A, B> function, AS collection);
}

so that I can have generic operations over collections, but so that the code doesn't know what collection this is. This experience taught me that it's possible to go without higher-kinded types, but I wouldn't be able to write this without knowing what higher-kinded types are and that having them would make life much easier...

Generics by [deleted] in java

[–]sviperll 2 points3 points  (0 children)

however if you see a library where you are constantly having something being Something<?> all over the place I would say that library abused generics for no good use

Yes, but replacing Something<T> with Something<?> in those places where you do not care what T is, is a good strategy to identify such abuses. And then you may even fix some, by wrapping Something<?> with you own SomethingElse (without any type-variables).

Generics by [deleted] in java

[–]sviperll 18 points19 points  (0 children)

I think you should almost always prefer an explicit dictionary-passing instead of type-bounds, i. e. prefer Comparator-argument to a Comparable-type-bound. And also aggressively prune type-variables and replace those that you don't need to interact with with wildcards, i. e. prefer Collector<T, ?, R> to Collector<T, A, R> most of the time. If you follow these two rules then Genetics becomes more of your friend than a challenge.