Readit News logoReadit News
ljackman commented on Project Loom and Structured Concurrency   javaadvent.com/2020/12/pr... · Posted by u/ingve
jpgvm · 5 years ago
Additionally Kotlin also targets native. `suspend` in Kotlin was very much designed with this in mind as it's easier to implement than something that requires an extensive runtime like Loom.

Kotlin will still support Loom on JVM and there will likely be integration with suspend/flows etc also.

ljackman · 5 years ago
That's a good point. Generally, I opt for languages that either compile away their nicities to avoid runtime hits, such as Rust being compiled to WASM, or languages that bring nicities in runtimes that they _completely own_, such as Java on the JVM.

The problem with Kotlin and the like is that they can't easily compile away their features due to inherent runtime dependencies, e.g. garbage collection, making them poorly suited to environments with a very minimal runtime like WASM, while also being at the mercy of the host language creating runtime abstractions that have mismatches with their own language's features.

Although it'd be unfair for me to say the JVM is designed only for Java; invokedynamic and non-reified generics both assist JVM targetting for non-Java languages such as Clojure.

ljackman commented on Project Loom and Structured Concurrency   javaadvent.com/2020/12/pr... · Posted by u/ingve
ljackman · 5 years ago
`Async`/`await` or something like Kotlin's `suspend` are great language features for certain domains in which a developer needs to manage blocking system calls: in lower-level languages such as Rust or C, you probably don't want to pay for a lightweight "task runtime" Like Go's or Erlang's. They bring not only a scheduling overhead but also FFI complications.

However, for application languages that can afford a few extra nicities like garbage collection, I fail to understand why the stackless coroutine model (`suspend` in Kotlin) or `async`/`await` continue to be the developer's choice. Why do languages like Kotlin adopt these features, specifically?

Manually deciding where to yield in order to avoid blocking a kernel thread seems outside of the domain of problems that those using a _higher level_ language want to solve, surely?

The caller should decide whether to do something "in the background". And this applies to non-IO capabilities too, as sometimes pure computations are also expensive enough to warrant not blocking the current task.

Go and Erlang seem to have nailed this, so I'm glad Java is following in their footsteps rather than the more questionnable strategy of C# and Kotlin. (Lua's coroutines and Scheme's `call-with-current-continuation` deserve an honourable mention too.)

ljackman commented on From Node to Deno   dev.to/aralroca/from-node... · Posted by u/aralroca
sramam · 6 years ago
Permissions are a whitelist.

While the grant is a blanket grant to a program and all dependencies, typically, a well behaved program will seek a limited scope of permissions. Like "https://my-program.com", "https://preferred-analytics.com" etc.

This prevents dependencies from using call back locations that are outside the permitted list, preventing much of the nefarious activity they can dream up.

If a dependency needs access to specific resources, it can advertise this fact and the parent module can in turn request this from the user.

Importantly, the user is explicitly aware of these & controls it in an absolute sense, at run time.

ljackman · 6 years ago
The whitelisting looks great. Even with the remaining concerns I raised in the other comment, the ability to whitelist only allowed domains for network connections is a massive step up security-wise, even if they are allowed for the entire program (until revoked globally).
ljackman commented on From Node to Deno   dev.to/aralroca/from-node... · Posted by u/aralroca
surajrmal · 6 years ago
ljackman · 6 years ago
That's a good start, supporting the dropping of privileges after performing something on startup.

What about keeping the network allowed in the layer handling, say, inbound HTTP connections, but blocking it in the data access layer or purely computational component?

From what I can see, this doesn't work with global boolean flags in the runtime, instead requiring isolated tasks with whitelisted capabilities passed in, some form of "immutable, set-once, dynamically-scoped capability flags", or something like that.

The problem with the global boolean flag approach is that if any part of a service needs it constantly, the entire program gets it, even obscure subdependencies for generating colour pickers.

Don't get me wrong, it's an incremental improvement over's Node.js blase approach. It's also quite niche to see languages support this feature. E was one of them. There was another newer Python-like language with this too, starting with an `M`, but its name escapes me.

I'd recommend Deno's developers look at E a bit more before committing too much to the platform boolean flag approach. Or I've misunderstood their approach and it actually does more than I'm giving it credit for.

ljackman commented on From Node to Deno   dev.to/aralroca/from-node... · Posted by u/aralroca
ljackman · 6 years ago
It looks like a good evolutionary improvement over Node.js. However, I have a concern about its security claims. Perhaps someone on the project can allay these concerns.

My brief skimming of its site indicates that its security model is based around the ability to disable, say, network access for whole Deno programs. However, does it allow starting up with network access, allowing a subset of the program to handle it, and then dropping those rights for the rest of the program, _especially_ subdependencies?

I can't see any mention of a more fine-grained approach: https://deno.land/manual/getting_started/permissions

A modern Node.js web service will have hundreds, if not thousands, of indirect dependencies. Some network access will be required for at least the Express routing, or an equivalent.

For a Deno equivalent, this would amount to enabling network access for all hundreds of those subdependencies, not reproducing the isolation in capability-based security such as WebAssembly nanoprocesses.

Have I missed something here? That doesn't seem like much of an improvement over Node.js except for very small and contained programs. Yes, Deno's dropping of centralised package repositories and package.json might alleviate this problem _somewhat_, but the same fundamental issue seems to remain.

ljackman commented on Kotlin vs. Java   kotlinvsjava.com... · Posted by u/driver733
ljackman · 6 years ago
I wonder whether Project Loom will create a split in the Kotlin ecosystem between coroutine-based concurrency and Loom lightweight thread-based concurrency.

Java will have a similar problem with CompletableFuture and third-party projects like Reactor used in Spring WebFlux.

However, Kotlin baking in language syntax for a competing concurrency model will exacerbate the split.

With Java already having type inference, concise lambdas, and with upcoming records that can already be faked in current versions via Lombok, the value proposition of Kotlin seems questionable outside of Android with its held-back version of Java.

Clojure is another story entirely, offering a very different and compelling way of thinking about computing on the JVM. By contrast, my developing view is that Kotlin is different enough to require learning something new yet not different enough from modern vanilla java to offer substantial advantages.

ljackman commented on The Road to Valhalla   cr.openjdk.java.net/~bria... · Posted by u/efge
billfruit · 6 years ago
While that is interesting to hear, is there a single book that brings someone who hasn't used Java in the last 5 years upto speed, like the book Bjarne Stroustroup's 'A tour of c++' does for c++.
ljackman · 6 years ago
There might be, but unfortunately I don't know it. I learnt Java initially from the first edition of Just Java, read from various other sources about the 1.5 and 1.6 additions it didn't cover, and then learned new features from OpenJDK proposals from 1.7 onwards as they were released.

The biggest impact of the 5 years for working developers has probably been:

* Streaming API and lambdas allowing usual `map`/`filter`/`reduce` transformation pipelines line many other languages (lazy, unlike JS's `Array` methods, parallelism considered via "spliterators" unlike Python).

* Default methods in interfaces, _not_ making them traits, but arguably more "trait-like". It allowed them to add many useful methods onto existing types without needing bifurcate the common APIs.

* A REPL. Probably not a big deal for a professional developer, who likely uses IntelliJ's "Evaluate Expression" feature already for a similar feature, but pretty useful for education I guess.

* Better at being stuffed inside Docker containers with resource limits. Also, max permgen space no longer a problem really (it's where you had to set an upper memory limit when invoking Java programs, which was annoying). Just generally less annoying at being deployed in modern infrasructures.

* APIs like `File.lines` that mean you don't need to recite War and Peace just to do a buffered operation across lines in a file. Generally more ergonomic APIs that finally make basic operations sane.

* Type inference with `var`. Basically the same as C#'s `var` or Go's `:=`.

* More native executable-producing tooling. jlink, jpackager, etc. The dream of ubiquitous, shared Java runtimes installed everywhere didn't really work out, and they seem to have realised that.

* Ecosystem moving away from XML. Still there, just less common. Runtime annotations are used more heavily, which I'm honestly not sure is a massive improvement. Hopefully more lambda-heavy APIs will reduce use of runtime annotations; see Spring WebFlux's functional handlers for annotation-based controllers for a comparison.

There's a lot more, but I'd argue it won't be as immediately visible for the working developer more than those points. Modules were important for the ecosystem, but most devs probably aren't worrying about that day-to-day. Gradle and Maven still dominate the building/packaging side.

ljackman commented on The Road to Valhalla   cr.openjdk.java.net/~bria... · Posted by u/efge
phillipcarter · 6 years ago
> Nullable reference types. Getting rid of null is good, but this proposal became confusing. They mentioned opting in assembly-wide for a while but there was then a conversation about having it just warn in some cases. I need to read the latest literature around this, but it seemed less elegant than Java just adding a monad-like Optional type and not adding loads of special-case operations with question marks everywhere.

Nullable Reference Types (NRTs) is released, so it's important to talk about what exists in an LTS form today rather than something from a draft proposal.

Firstly, there's the surface-level stuff. Reference types can be explicitly be marked as `foo?` to indicate to the compiler that the type is nullable. Mismatches are warnings to ensure backwards compatibility, since billions of lines of perfectly valid code today can't just start emitting errors across an entire codebase.

But the far more interesting side of NRT isn't that, but the compiler analysis that goes into it. It's an incredibly advanced and thorough flow-based typing system that catches numerous complicated scenarios, and a system that can be (and is) improved over time without incurring a risk of a breaking change. This analysis is equally applied to the existing nullable value types, so it's a unified model.

The other interesting side of NRT is that isn't a one-and-done feature. There's a long rollout period where the .NET ecosystem adopts this way of dealing with reference types, and to do so there need to be tools for component authors and application developers to adopt it incrementally and at their own pace. Everything in the design is incredibly deliberate and well thought-out, with numerous past designs (such as a "sidecar" format for annotations and a mechanism for managing updates to that in parallel with a package or framework!). It is imperfect, but perhaps the best that can be done given the constraints a 20 year old language imposes.

That said, I really the world could be different. Since I prefer (and work on) a typed functional language where `null` isn't much of a problem due to a different core language design, the incredible amount of engineering effort that went into NRT for C# feels slightly strange to me. But my only reasonable alternative to not making progress on this problem is, "just use a different language", which most developers do not find reasonable.

Additionally, the pedantic side of me doesn't feel that Java's optional is an any way reminiscent of monadic programming. Java simply lacks numerous features to enable this style of programming in a way that the majority of Java developers would utilize.

ljackman · 6 years ago
Thanks for the clarification on the final NRT behaviour. Just to say, my point about "didn't align with good taste" was itself lacking taste. I'm sure each of those features I critiqued made sense as they were proposed at the time and were just considering different use cases and tradeoffs.

Did it drop the idea of assembly-wide opt-ins to stricter behaviour, meaning all NRTs can be reasoned about in the same way without considering a configuration flag somewhere like PHP? That does sound like an improvement.

Doing the change gradually, without breaking existing code or requiring potentially-ecosystem-breaking opt-ins does seem eminantly sensible and user-friendly. I was being too harsh to C# here. Java's `Optional` doesn't even warn about it itself being null, for example. You need static tooling and code analysis for that. C#'s solution does at least try to solve that, albeit at the cost of more complexity.

I said "monad-like" rather than "monadic" for that reason, but arguably it doesn't even go far enough to be considered monadic-like. Certainly this article would agree: https://blog.developer.atlassian.com/optional-broken/

ljackman commented on The Road to Valhalla   cr.openjdk.java.net/~bria... · Posted by u/efge
jayd16 · 6 years ago
This mostly reads to me as a list of things I miss when I go back to Java.
ljackman · 6 years ago
Fair enough; I do miss keyword and default arguments from C# when using Java. A long list of overloads and argument forwarding to fake default arguments gets old.
ljackman commented on The Road to Valhalla   cr.openjdk.java.net/~bria... · Posted by u/efge
BoorishBears · 6 years ago
I disagree with so many points in your list I don't even know if it's productive to start listing them.

From implying that C# lambdas are not infinitely more useful, powerful, and intuitive than "functional interfaces"

To the issues implying Properties are bad compared to the completely and utterly ridiculous situation in Java (which is exactly how they're implemented in Kotlin by the way).

And your "critique" of "dynamic", do you even know what it's for or how it works? Go read up on what the "DLR" is

You seem to have fundamental issues with the fact C# goes for being a useful language for it's users over being Java. Half your reasons are literally "it doesn't do it how Java does" or "it does X but Java doesn't so X is bad". The other half are complaints about insanely powerful features C# has that have minor issues that in no way take away from the fact.. they're incredibly powerful and useful features.

-

To me the moment you're trying to defend Java generics and type erasure, vs C# which paid the price early and has reaped the rewards for years, you should already you're on the wrong side of things...

ljackman · 6 years ago
FWIW, I could have produced an equally-long list of Java flaws. I'm not terribly attached to either language. I just wanted to challenge the meme that "C# is a better Java" I hear on the Internet every other week.

"Infinitely" more useful seems like a stretch. Both languages made valid design decisions with their lambdas: autogenerated types means not every variant of lambda needs a backing interface, but it also means that the types are a world unto themselves and not integrated with well-established interfaces and abstract classes in the way that Java lambdas are, resulting in conflicting mechanisms for passing code to adhere to a requirement. I find the unification of SAM types and lambdas to be elegant in a class-based OOP language (and actually preferable to the Smalltalk/Ruby block model too), but it's clearly subjective.

My criticism of properties hiding side-effects as attribute reads is mostly derived from one of the earliest books about the CLR; was it "The CLR via C#"? I'll have to check. The critique isn't Java-inspired; getters have the same problem of course. The point is that a getter is a method call, so you expect potential side-effects. You don't expect side-effects from a property read, although C# does tend to use capital letters for properties, to be fair.

While on the topic of CLR, I realise the DLR exposed dynamic typing primarily to make the CLR a better target for dynamic languages; I was arguing that exposing that up to C# wasn't necessary. C# is the flagship CLR language, sure, but that doesn't mean it must expose _every_ feature of it. Java also added `invokedynamic` for similar reasons but didn't feel the need to expose it to its flagship language directly in language syntax.

pron covered the nuances around generic type erasure in another comment better than I did, so I won't reiterate. Like you, I still mildly prefer reified generics over erasure as a language user, but the points raised by pron and Bracha are absolutely real. The ability to do runtime type checks and default values on generics seem like antipatterns, so I'm glad Java doesn't support those _specific_ features of reification even if I like a lot of the others parts.

u/ljackman

KarmaCake day162January 7, 2019
About
An product security manager in the UK.

My website, along with contact details and links to code repos, are at https://volatilethunk.com

View Original