Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why not Kotlin? #76

Closed
hakanai opened this issue Aug 9, 2022 · 18 comments
Closed

Why not Kotlin? #76

hakanai opened this issue Aug 9, 2022 · 18 comments

Comments

@hakanai
Copy link

hakanai commented Aug 9, 2022

There have been people posting on Kotlin forum from time to time asking why Kotlin itself doesn't also target .NET.

It currently targets JVM, JS and native. .NET would be a fine addition to the collection.

@LPeter1997
Copy link
Member

Why not X questions are usually quite fruitless for a few reasons.

  • The assumption that we haven't considered X is likely false. In the case of Kotlin, it's the fact that it went out to improve on Java, with a very much reduced feature set compared to C#. C# already ships many-many of the features Kotlin implemented, so the win with the language would be very insignificant, if any.
  • It's usually assumed that X is somehow perfect from all aspects we are focusing on. This is not true. No language is perfect, they just tend to focus on different aspects.
  • It's usually assumed that we are not familiar with the works/feature set of X to get inspired by. This is not true, there are quite a few issues and design documents considering Kotlin features. This is also true for many other languages.
  • Language X likely has major aspects lacking that we really want to focus on. In case of Kotlin, one would be strong compile-time metaprogramming (Metaprogramming and decorators #16, F# Computation Expressions expressed as higher-order macros #29) or the lack of discriminated unions, or true pattern matching ([WIP] Pattern matching #44).

By all means, feel free to tell us what you like or dislike in Kotlin, we have a wish-list label for these sort of issues.

@hakanai
Copy link
Author

hakanai commented Aug 9, 2022

One of the things I like best about it is that it doesn't just target the JVM. But I'm not about to file a ticket to suggest targeting JVM, JS and native as well as .NET because it would be a large undertaking.

The original post I saw on Reddit was worded in a way that made it sound a lot like Kotlin only improves on Java, or only targets the JVM, which is obviously not the case. It's its own language with native support for multiple targets.

@Binto86
Copy link
Contributor

Binto86 commented Aug 9, 2022

Targeting JVM is not completly out of the table, but right now the focus is to get working version of the language targeting .NET.

@LPeter1997
Copy link
Member

But I'm not about to file a ticket to suggest targeting JVM, JS and native as well as .NET because it would be a large undertaking.

Indeed, but it's not an insane idea at all I believe. It would definitely be a very-very long-term goal, but I do think JVM is similar enough to at least try to target it and JS would be really nice for the web ecosystem.

@Binto86
Copy link
Contributor

Binto86 commented Aug 9, 2022

If we could target JS it would make for very useable scenario, where you would have backend in Fresh as well as frontend.

@jl0pd
Copy link

jl0pd commented Aug 9, 2022

I think that language should take most from platform it's targeting. Dotnet was built on mistakes of JVM and supports value types, pointers, keeps generic information at runtime. It doesn't make sense to limit language, so it can run on other platforms.

If we could target JS it would make for very useable scenario

To my knowledge it's possible to build ordinary .net assembly and run it in browser with Web Assembly, which Blazor does. Compilation into JS doesn't make sense either

@hakanai
Copy link
Author

hakanai commented Oct 2, 2022

I know this whole thing is well dead, but just to clear up multiple misunderstandings in the above comment by @jl0pd:

  1. Although there is often a lot of overlap, a runtime is a separate thing from a language. You can compile C# to run on the JVM, and you can compile Java to run on .NET. So saying "Blah platform was blah" and then talking about language features doesn't make sense. At least not in English.

  2. Kotlin supports value types and reified generics too.

  3. Pointers as a feature should not be in a modern programming language because references are a better abstraction than pointers. So saying "yay I can use pointers" is like "yay I have cancer", I guess?

  4. Talking about being "built on mistakes of JVM" is a bit of a weird one-sided way of arguing because supporting pointers was an obvious mistake in itself. A more honest view of the situation would be: ".NET is a different VM from Java and both have their problems. It's too bad that Sun and Microsoft had to split in two directions because if people had just got along, we could have had a single platform that everything ran on by now."

Also it's worth noting that Kotlin gets additional features depending on what it's targeting. For example in Kotlin/JS we get to use dynamic types. So any talk about "lowest common denominator" clearly doesn't apply for a programming language. Kotlin has shown how you can have a single language with features which are target-specific.

Some day, someone will make a .NET compiler for it, but I'm just not sure who will do it.

@Kuinox
Copy link
Member

Kuinox commented Oct 2, 2022

Used Kotlin, and would only use it when the only alternative is Java.
On .NET, C#/F# being available, I don't see any reason to use Kotlin.

@hakanai
Copy link
Author

hakanai commented Oct 3, 2022

Depends on your viewpoint. If I were sitting on .NET and only intending to target .NET, then I'd probably go with F#.

If I were intending to target multiple platforms and had a language which could do all of them, I would use it. But right now, there isn't one, unless you count some weird mix of Java or Kotlin with IKVM.NET and some toolchain to get native.

@Kuinox
Copy link
Member

Kuinox commented Oct 3, 2022

If I were intending to target multiple platforms and had a language which could do all of them

By platform here you mean .NET or Java ?
What use case do you have to need a language that both target the CLR and JVM ?

@333fred
Copy link
Contributor

333fred commented Oct 3, 2022

Although there is often a lot of overlap, a runtime is a separate thing from a language. You can compile C# to run on the JVM, and you can compile Java to run on .NET. So saying "Blah platform was blah" and then talking about language features doesn't make sense. At least not in English.

It absolutely does make sense. There's extremely important implementation differences between the JVM and the CLR that had large influences on both Java/Kotlin and C#, particularly in the aspect of generics. The erasure of generics means that the way variance works in Java/Kotlin is not implementable in the CLR without reimplementing all of generics via erasure, and similarly the way generics work in C# is not implementable on the JVM.

Kotlin supports value types and reified generics too.

Kinda. Kotlin has inlineable functions, which can have reified generics, and it has value classes (I can't remember the exact name of the feature, but it's ahead of Valhalla), which it essentially erases to the underlying components. C#'s type system allows for far more expressiveness around these things than the JVM can express (today), and the design of these features in Kotlin reflects that.

Pointers as a feature should not be in a modern programming language because references are a better abstraction than pointers. So saying "yay I can use pointers" is like "yay I have cancer", I guess?

This is just foolish, sorry. Even modern safe languages like Rust acknowledge that pointers are an important scenario that need to be usable.

Talking about being "built on mistakes of JVM" is a bit of a weird one-sided way of arguing because supporting pointers was an obvious mistake in itself.

This was not a mistake.

@hakanai
Copy link
Author

hakanai commented Oct 4, 2022

By platform here you mean .NET or Java ? What use case do you have to need a language that both target the CLR and JVM ?

For an example that's out there today, consider something like Lucene, where it had to be implemented three separate times for three different targets. If a language existed which targeted all three places, it could have been implemented once.

The erasure of generics means that the way variance works in Java/Kotlin is not implementable in the CLR without reimplementing all of generics via erasure, and similarly the way generics work in C# is not implementable on the JVM.

Sounds like a strawman argument to me.

If I were writing a Kotlin compiler targeting .NET, why would I limit myself to supporting what the JVM supports? I'd have it support reified generics everywhere, not even just on inline functions, and it would compile to the same thing the equivalent C# would compile to.

This is just foolish, sorry. Even modern safe languages like Rust acknowledge that pointers are an important scenario that need to be usable.

I've used multiple languages without pointers by this point, and never found anything I couldn't implement that I wanted to implement. Sure, in C and C++ I was using them, but I haven't missed them in other languages which don't have them.

Pointers are only an "important scenario" for people who can't imagine how to refactor their code to avoid needing them. And pointers are a mistake. Even if in your universe they aren't.

@333fred
Copy link
Contributor

333fred commented Oct 4, 2022

If I were writing a Kotlin compiler targeting .NET, why would I limit myself to supporting what the JVM supports?

This is the wrong way to think about this. You're not limiting yourself to what the JVM supports. You're implementing Kotlin, as specified. And it's not a limitation: erasure-based generics are not all bad, no good. Kotlin's type and star projections can't be implemented on the CLR with its reified generics.

I've used multiple languages without pointers by this point, and never found anything I couldn't implement that I wanted to implement.

Then you have clearly never done any type of native interop (remember Java actually has a pointer type in the standard library so JNI can actually work), IoT projects, driver code, or anything else in that general field. Pointers represent the way memory actually works, and sometimes they are truly the best representation of the reality. Yes, I recommend that people avoid them wherever possible and use safer abstractions, such as Span or ref fields. But sometimes abstractions aren't general enough to cover a use case. Pointers, appropriately cordoned off behind unsafe warnings, and supplemented by safer abstractions to cover the 90+% case, are absolutely not a mistake. They are a tool, like every other tool in the toolbox.

@Kuinox
Copy link
Member

Kuinox commented Oct 4, 2022

For an example that's out there today, consider something like Lucene, where it had to be implemented three separate times for three different targets. If a language existed which targeted all three places, it could have been implemented once.

IMO "Porting" manually is a terrible idea and should never be done.

  1. Software is living and ever changing, and duplicating the logic increase the cost of changing anything.
  2. Manually copying logic in another language is the exact opposite of why a lot of developer, and I, chose this career.

Instead of porting the logic, other solutions are possible.

If a language existed which targeted all three places, it could have been implemented once.

Like C ? Instead of having the library rewritten in multiple language, you could simply bindings calling the native dll.
Your platform need to support AoT.

Sounds like a strawman argument to me.

A single language that behave differently in majors ways depending of what platform you are targeting, is not a single language.

Multitargeting in C# is already a pain, while it's targeting the same language, the same standard library, but with differents versions.

@hakanai
Copy link
Author

hakanai commented Oct 4, 2022

Then you have clearly never done any type of native interop (remember Java actually has a pointer type in the standard library so JNI can actually work), IoT projects, driver code, or anything else in that general field.

I've done all of those. For IoT and driver code I've done it in C. I wouldn't try to use something like Java or C# for that.

And I've done native interop in Kotlin and Java, but in both cases, I have used a pointer type. Not pointers as a language feature.

@333fred
Copy link
Contributor

333fred commented Oct 4, 2022

For IoT and driver code I've done it in C. I wouldn't try to use something like Java or C# for that.

Well, at least for C#, these are absolutely supported scenarios. IoT in particular is a space that .NET has invested and will continue to invest in.

And I've done native interop in Kotlin and Java, but in both cases, I have used a pointer type. Not pointers as a language feature.

It's not a good idea to regard these as separate concepts. Your types are part of the language, and are features of that language. I would hope that, even if you encode language support for pointers as types like any other, your type system has a mechanism for indicating that usage of these types must be done in some sort of unsafe context (something iirc Kotlin and Java do not have), as users should be directed towards safe abstractions whenever possible.

Your arguments came across (at least to me) very differently than you've indicated in your last comment. Encoding pointers as a specific type of type (Pointer[T] in this case, presumably) is a perfectly fine abstraction, but since Draco will be targeting .NET, special support for this is needed. Pointer types are a separate type hierarchy from System.Object: they cannot be used in generics, they cannot be converted to System.Object, etc. Draco will need to enhance its representation of the type system to encompass these details. It's what F# does, for example, and is a perfectly reasonable approach. But you can't just say that it's not part of the language: it very much is, it's just not a specialized syntactic representation.

@hakanai
Copy link
Author

hakanai commented Oct 4, 2022

Well, in the case of Java at least, it comes with the JNA library. So if you don't use that library, it's not part of the language, but then if you use that library, it's now part of the language? So the language includes whatever libraries you happen to use? That's certainly one way to look at the world, but I usually separate the concepts, and usually even separate the standard library from the language.

@333fred
Copy link
Contributor

333fred commented Oct 4, 2022

So if you don't use that library, it's not part of the language, but then if you use that library, it's now part of the language? So the language includes whatever libraries you happen to use? That's certainly one way to look at the world, but I usually separate the concepts

No, that is not what I'm saying. There's a fuzzy line here, but I would absolutely say that "what comes in the box when you run the official installer" is part of the language.

and usually even separate the standard library from the language.

Absolutely not. This is part of the experience of using a language.

Pointer as a Java type is defined in JNA, yes, however Java is working on (maybe it's shipped now?) a better FFI via project panama. It has the moral equivalent of these types. Additionally, as someone who's done work on robotics projects using Java and JNI, I can tell you the lack of direct pointer support in Java is incredibly frustrating for these scenarios.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants