I mean, yeah, type erasure does give parametricity, but, you can instead design your language so that you monomorphize but insist on parametricity anyway. If you write stable Rust your implementations get monomorphized but you aren't allowed to specialize them - the stable language doesn't provide a way to write two distinct versions of the polymorphic function.
And if you only regard parametricity as valuable rather than essential then you can choose to relax that and say OK, you're allowed to specialize but if you do then you're no longer parametric and the resulting lovely consequences go away, leaving it to the programmers to decide whether parametricity is worth it here.
I don't understand your first paragraph. Monomorphization and parametricity are not in conflict; the compiler has access to information that the language may hide from the programmer. As an existance proof, MLTon monomorphizes arrays while Standard ML is very definitely parametric: http://www.mlton.org/Features
I agree that maintaining parametricity or not is a design decision. However, recent languages that break it (e.g. Zig) don't seem to understand what they're doing in this regard. At least I've never seen a design justification for this, but I have seen criticism of their approach. Given that type classes and their ilk (implicit parameters; modular implicits) give the benefits of ad-hoc polymorphism while mantaining parametricity, and are well established enough to the point that Java is considering adding them (https://www.youtube.com/watch?v=Gz7Or9C0TpM), I don't see any compelling reason to drop parametricity.
My point was that you don't need to erase types to get parametricity. It may be that my terminology is faulty, and that in fact what Rust is doing here does constitute "erasing" the types, in that case what describes the distinction between say a Rust function which is polymorphic over a function to be invoked, and a Rust function which merely takes a function pointer as a parameter and then invokes it ? I would say the latter is type erased.
The Scala solution is the same as Haskell. for comprehensions are the same thing as do notation. The future is probably effect systems, so writing direct style code instead of using monads.
It's interesting that effect system-ish ideas are in Zig and Odin as well. Odin has "context". There was a blog post saying it's basically for passing around a memory allocator (IIRC), which I think is a failure of imagination. Zig's new IO model is essentially pass around the IO implementation. Both capture some of the core ideas of effect systems, without the type system work that make effect systems extensible and more pleasant to use.
One problem with the simulation route is that games in the D&D lineage are usually wildly unbalanced. A, say, level 5 monster could run through endless level 1 NPCs. Also, much of the machinery of our world (e.g. commerce) doesn't really work when then there are incredibly dangerous and malevolent critters scattered throughout.
It's more about the combat model. Everyone is a fanatic who fights until death, despite any casualties their friends and allies have suffered. And weapons and other attacks are mostly harmless. They deal limited damage measured in hit points, which does not affect the combat effectiveness of the target, heals quickly, and does not leave any lasting effects.
In a different combat model, an equally unbalanced monster would avoid unnecessary fights agains groups of armed opponents. Not because it's afraid it would lose, but due to the risk of permanent injuries. Determined defenders could then try to take advantage of that behavior to drive the monster away.
Yup. Same reason I feel safe hiking in big cat territory. You look like a large predator. Only things that consider a large predator as possible prey will seek conflict--and most of the US has no such animal.
The cats know they would win, but a predator at our size range might injure them and keep them from getting their next meal. Thus it's virtually certain they will not attack--and the news supports this. People get hurt when the animal feels it needs to defend itself.
This is one of the things I like about Kenshi. Losing a fight doesn't mean you died in a fight necessarily. Sometimes you're just knocked out and the enemy is satisfied and moves on. Sometimes you're just knocked out and made into a slave which gives you another story arch to follow and challenges to overcome.
The key concept in "parametric polymorphism", which is what programming language nerds mean by generics, is "parametricity" [1]. This is basically the idea that all calls to a generic function should act in the same way regardless of the type of the actual concrete calls. The very first example breaks parametricity, as it multiplies for float, adds for i32, and isn't defined for other types.
It's implementation has the same issues as generics in Zig, which is also not parametric.
It's ok to explore other points in the design space, but the language designer should be aware of what they're doing and the tradeoffs involved. In the case of adhoc (non-parametric) polymorphism, there is a lot of work on type classes to draw on.
I don’t see how that Wikipedia page supports your claim “The key concept in "parametric polymorphism", which is what programming language nerds mean by generics, is "parametricity"”. That page doesn’t even contain the character sequence “generic”.
IMO, https://en.wikipedia.org/wiki/Generic_programming is more appropriate. It talks of “data types to-be-specified-later”, something that this and C generic lack. That’s one of the reasons that I wrote “I _somewhat_ disagree”.
Also, I don’t see how one would define “act in the same way”. A function that fully acts in the same way regardless of the types of its arguments cannot do much with its arguments.
For example, a function “/” doesn’t act in exactly the same way on floats and integers in many languages (5.0/2.0 may return 2,5 while 5/2 returns 2; if you say it should return 2,5 instead you’re having a function from T×T to T for floats but a function from T×T to U for ints; why would you call that “act in the same way”?), “+” may or may not wrap around depending on actual type, etc.
Geometric proofs are really accessible. You don't need any algebra to prove Pythagoras' theorem, or that the sum of the inner angles of a triangle is 180 degrees, for example. Compass and straight-edge construction of simple figures is also fun.
Everything is up to date with the new syntax as far as I'm aware. Also, the compiler and scalafmt can rewrite one to the other. A project can pick whatever style it wants and have CI reformat code to that style.
There's still a working Eclipse plugin? Does Eclipse now support LSP servers?
The most reliable Scala IDE is currently Metals (in VSCode, but other editors work, too). Metals uses directly the compiler for all code intelligence so it's as reliable as the compiler itself.
> or Scala 2, yes, or there was the last I looked. Still the best Scala development experience by some margin, sadly.
I can't find it.
Could you link to that "best Scala development experience by some margin"?
All I know is that the Eclipse plugin is dead since about one decade. But maybe I just missed something.
> the integration/bridging piece is still flaky
What concrete issues do you have?
I'm using Metals on a daily basis and don't know about any such problems.
Could it be that the last time you've seen Scala (if you actually ever seen it at all) was about 10 years ago?
The discussions here on HN regarding Scala seem always massively dishonest, with a lot of people always spreading outright FUD for some reason I don't understand…
What I don’t get because there is LSP and BSP support. What else is needed to get support for scala 3 from an IDE? Obviously, Kotlin coming from Jetbrains will make it receive a lot more love and first class support.
I always find downvoting on stuff like this perplexing. It still isn't there. I know that a lot of Scala people are doing metals and some kind of text editor experience, but if you've used something as powerful as Intellij, the Scala 3 experience is a serious downgrade, and it still is today, even though it's better than it was a year ago.
OP is not being very precise (and in a way that I don't think is helpful). There is nothing imperative in an if expression. Declarative languages can be Turing complete. Declarative languages are a subset of programming languages.
reply