Hacker News new | past | comments | ask | show | jobs | submit login
Kotlin for data analysis (kotlinlang.org)
172 points by saikatsg 4 months ago | hide | past | favorite | 104 comments



I do both Kotlin and Python. More Kotlin than Python to be honest. But I'm pragmatic. Python is where all the action is when it comes to data science, llms, and all the rest. So it's the path of the least resistance. And there's a great argument to not challenge that and just do what everybody else does and put your head down and not criticize any of that. Which is why I use it on a few projects. The library ecosystem is great. Etc. Bla bla bla. But the bottom line is that I don't love python. It's dreary to me. Mediocre. I can't get very excited about any of it. It just seems so backwards.

And it's not necessarily the most efficient path either. The interpreter is not that fast, the language is not that expressive, what passes for package management is a bad joke, etc. I can work with it but I'm not necessarily loving it.

For data engineering, Kotlin has a lot to offer. I wouldn't necessarily recommend it because it's all kind of niche. But it kind of works as well. If you aren't afraid of tinkering with it, there are a lot of other niche solutions out there as well that aren't python.

Kotlin is what I reach for when I want to get stuff done in a hurry. Part of that is just my limitation. It's what I know and I kind of grew up on JVM languages. I'm well aware that's not necessarily optimal and that that's just a bias I have. But objectively, it has a lot of nice things over modern python as well.

Kotlin is a modern language, it's a lot more expressive than python. It has a a great library ecosystem. Including some stuff that does not depend on the JVM. And even though it's kind of niche for a lot of things I use it for (e.g. developing reactive web frontends), it holds up well and rarely disappoints me.

People use python because everybody else uses python. That's it. It's not particularly good at anything it does. But it will get the job done and I can do it. But that just isn't good enough for me. It's the visual basic for data science. And that's not a compliment. Being idiot proof is it's main feature. But that doesn't make it the smart choice.


I work in a codebase that’s mostly kotlin and python and I’ve come to hate the python side.

I used to love python, but I feel like the attempts to tack on typing have really undermined it.

The “freedom” of being untyped is nice for quick little scripting things, but being typed is an absolute godsend in a real codebase.

Instead of making python pseudo-typed with messy annotations, the scientific/research community should have built out tools in an actually typed language. I think Julia hung around for years with the expectation that people were going to do that


Yes but it's reasonable that they didn't. For quick hacky scripts you really want a lightweight syntax that supports interactive REPL exploration. Kotlin is the first language that manages to combine a strict static type system with a Python-weight syntax, and there's a REPL too although I don't think it gets much use. These days notebooks are a better replacement for REPLs anyway when doing data analysis, but Kotlin only got support for such features very recently.


Kotlin isn't the first language offering any of these features, not even remotely.

Even if you look only at the JVM: Scala is much older.


Scala isn't "python weight" as it's much keener on obscure operators and other syntax sugar than Kotlin or Python.


What are the obscure methods in the standard library?

Kotlin has grown into a much quirkier language overall, its grammar is significantly bigger than that of Scala.


I think the point is Kotlin incorporated great stuff from a few languages, Scala being one of them.


... which is the exact opposite of being "the first".


Haskell and SML are even older.


What kind of codebase would be mostly a Kotlin/Python combo?


Kotlin Android app with a Python backend for ML stuff, maybe?

Or maybe they're in one of those places that use microservices with a variety of languages


Kotlin just needs some stubborn people not to use python just because everyone else does, and build up the Kotlin ecosystem. That's how progress is made.


If someone wants to pay me to do this, I have some free time Mondays and Wednesdays.


I'd follow suit


It would help if Jetbrains pushed a lot more focus on the Desktop environment rather than mobile.


I'm not sure how someone could see Kotlin as more expressive than Python, unless I am misinterpreting what expressive means. Python has a good language features and helpful abstractions like list comprehensions.

What makes Kotlin more expressive? I understand it has some functional features but I've never seen anything dramatically flexible.


Kotlin's standard library has ruined me for other languages, especially its collections library. The consistency and comprehensiveness of its approach to collections is unmatched in any language I've tried, including all the big name functional languages. It's hard to get across what's so great about the library in writing because it's not just one standard library function, it's how they all interact with each other and how they interact with the language design—you really just have to try it to understand. The net result is that transforming data from one shape to another flows effortlessly, with the dot operator seamlessly connecting a stream of transformations. The fact that it's the dot operator also means that you get really great autocomplete to help you on your way.

Python, meanwhile, has always felt pretty awkward to me when it comes to data transformations. Comprehensions are okay, but they feel like they are special casing what should be a bunch of standardized helper functions operating on lambdas, as a sort of ugly workaround to the fact that Python refuses to implement proper lambdas. And when you can't use a comprehension, you're stuck with a pretty awkward collection of helper methods that are hard to find and use correctly and which are severely handicapped in expressivity by the lack of a proper lambda.


That's interesting. I've heard complaints about Kotlins standard library in comments like this[1]. I understand they may be nitpicks but they seem annoying in practice.

[1] https://www.reddit.com/r/Kotlin/comments/mh2z5u/comment/gt2n...


That's on a thread that specifically solicited complaints though.

These are all reasonable but some are just lack of familiarity with the JDK standard library, or the reasons why things have to work that way to begin with.

For example, ArrayList not being immutable/thread safe. Although there are collections libraries that give you snapshot based collections, like this one:

https://github.com/Kotlin/kotlinx.collections.immutable

... I've never seen anyone use them because this is almost always the wrong design. Atomicity is usually needed at a coarser grain than a single collection, at which point you're needing to think about locking or transactions anyway, and if it isn't then the JDK standard library already offers concurrent lock-free lists or Collections.synchronizedList() which will give you the same effect. Having an object be mutated out from underneath you by a separate thread is a possibility of basically every language with shared memory. Only Rust tries to solve race conditions in the type system and its solution introduces many other problems.

He also complains that integer width/signedness casts only offer help from both the type system and the runtime! That's pretty good compared to other languages. Then he complains unsigned types are about the underlying bits not the semantic meaning of the number - well, yes, this is unintuitive but exactly the same as every other language because of the weirdness that inherently emerges when mixing signed with unsigned types. Java refuses to add unsigned numbers at all and they have their reasons for that! Unsigned numbers are really only meant for working with binary data formats, not encoding that something can't be negative. Use a jakarta.validation with a framework like Micronaut or Hibernate Validator if you want that.

Likewise for date and times sucking. If you use the long since deprecated classes designed in 1995 then maybe those suck by modern standards, although they're great for beginners. So don't use them: java.time is a modern package that treats timezones rigorously, at the cost of being a bit harder to understand.


Hmm, coroutines are definitely a bit of a mess, but in ways that aren't super relevant when you just want to use them and not implement a framework on top of them. They definitely sacrificed implementation simplicity in favor of interface simplicity.

> don't even try to tell me that anyone uses sealed classes in practice

I use sealed classes for errors all the time.

> Nothing is concurrency safe.

Yes, but I know of no stdlib of a serious alternative that is, so I don't think that's a major concern. Don't use concurrency and you're no worse off than Python (the alternative here), and if your point of comparison is Java or similar then it's the same story there.

> All of the numbers suck. The fact that I can just call Long.toInt().toUByte() and lose a bunch of information and/or wrap a negative value into a positive value, etc, without any kind of help from the type system (maybe returning nullables) or the runtime (throwing exceptions for truncation) is gross.

Similar to the above: yes, it could be better, but it doesn't bring Kotlin's stdlib below any other major language I'm familiar with. Heck, even Rust lets you do those downcasts without a word [0], you're just supposed to know that downcasts can lose information. Lints can help you here if you care, but I don't think a language gets points docked for not having them by default—there's a balance to be struck between too few and too many explicitly-typed failure cases.

> The Map API sucks. Map::getOrElse is literally implemented incorrectly-it will call the "or else" function if the value is present in the map but is null.

That... is fair. I've never actually noticed it before, but it's wrong. The rest of the Map API has always been good for me, though.

> Dates and times suck.

In every language ever.

> I don't like how the default for the collection combinators is to be eager.

They acknowledge that they have no answer here, and neither do I. There's no pattern for Kotlin to follow because only Haskell does lazy-by-default, and Haskell isn't a model most people would want Kotlin to follow.

All in all, I read a comment like this as someone reaching for the things that irk them in a language that they actually really like—which means the items that irk them are either extremely small or actually just broken in all major programming languages.

[0] https://play.rust-lang.org/?version=stable&mode=debug&editio...


> I don't like how the default for the collection combinators is to be eager. Isn't this solved by using Sequences instead?


Yes, but I took their use of "default" to mean that there's slightly more friction to a sequence. It does seem a bit petty given how little friction there is, though.


Thanks for your insight!


Those are literally the same as Java, they’re impossible to fix without breaking interoperability with Java.


No one is arguing Java is expressive.


Couldn't agree more if I tried.

Scope functions are also great.

And the syntactic sugar where `foo({ a -> a })` and `foo { a -> b }` are the same makes code so much more readable.

I've done Python for a project at a previous job for a few months and it made me realize just how awful Python is, especially because you can't chain functions on collections as easily as you can in Kotlin. I also made me realize that I don't like dynamically typed languages.


> And the syntactic sugar where `foo({ a -> a })` and `foo { a -> b }` are the same makes code so much more readable.

That's 1-to-1 copied from Groovy by the way :)


Always strange how genes survived over time.


> `foo({ a -> a })` and `foo { a -> b }` are the same

I am new to kotlin, so I may be missing something obvious, but shouldn't it be "a->a" in the 2nd case, too?


You're right, my brain farted somewhere in the middle.


> Scope functions are also great.

They are useful but I'm not sure they carry their weight. I have to look up the differences often, maybe they're just terribly named?


> Kotlin's standard library has ruined me for other languages, especially its collections library

Scala has it beaten by a long shot, in my opinion, and is hands down the best of any language around collections.


> Python refuses to implement proper lambdas

Python has lambdas. What do you mean by "proper" lambdas?


Lambdas in Python are intentionally second class citizens in that they cannot be full blocks, only a single expression. Technically there's a workaround in that you can define a named function and then refer to it later, but that's enough of a hassle that using lambdas in method calls is much less common in Python than it is in Kotlin.

In Kotlin, much of what would normally be special syntax structures are just function calls that get passed a lambda. That's not possible with Python's single-expression lambda functions, so you get special syntax instead for things like comprehensions.


Multi-line without ugly “lambda” keyword.


As someone who uses Kotlin for work and Python for side projects (and loved Python years ago in college), Python's list comprehension feature is one of the things I hate the most about the language now.

As a simple example using only two collection functions I find it much easier to read

  val hundredOrLessEvenSeconds = (1..1000)
      .toList()
      .filter { it <= 100 }
      .filter { it % 2 == 0 }
      .map { it.seconds }
than

  hundred_or_less_even_seconds = [timedelta(seconds=it) for it in range(1, 1001) if it <= 100 and it % 2 == 0]
But there are tons of helper functions in the collections library to express that in a variety of different ways. But not in a gross code golf way, with clearly named functions

Theres just so much built in https://kotlinlang.org/docs/collections-overview.html

Having lambdas built into the language from the start leads to a ton of expressibility I miss when using python


Not that I especially want to defend Python, but can you elaborate a bit on why you find that chain easier to read? The Python version is straightforward enough - if it's just the absence of newlines you can write

  hundred_or_less_even_seconds = [
    timedelta(seconds=it)
    for it in range(1, 1001)
    if it <= 100 and it % 2 == 0
  ]
Also, I don't know Kotlin well enough, but is what you wrote going to be efficient? The Python version iterates once and creates one list (and you can actually turn it into a generator and make zero lists just by swapping the square brackets for parens); to my untrained eye, it looks like the Kotlin version is going to do more iteration and make four separate lists, three of which are just garbage to be thrown away immediately. Here that probably doesn't matter, but in other cases it might be a big problem; is there an easy/idiomatic way to avoid that?


Its a small example so the efficiency doesn't matter, but you could use sequences when it does https://kotlinlang.org/docs/sequences.html .

Also the map function lets you perform any operations in it. It was a simple example but you could need to perform something slightly more complex than using another standard library function.


It's easier to compose functions in Kotlin. The python version you showed is more ad hoc, and is really one list comprehension.

I particularly like Kotlin's scope functions:

https://kotlinlang.org/docs/scope-functions.html


You can do partials in python too

I do prefer python over kotlin but IMHO semantically they're both beautiful and some of the least frictive languages I've ever used


> it looks like the Kotlin version is going to do more iteration and make four separate lists.

Someone with kotlin experience could comment too, But I don't think it creates four separate lists. The last map function iterates and asks for element from previous function which asks for element from its parent function. So there is only one list.


What if you want to filter on the mapped value in python? Or group by something and work further on the groups? It's almost unreadable after a few operations.


In that case I think the "Pythonic" thing to do would be to have some named intermediate steps:

  foos = (make_foo(bar) for bar in bars)
  acceptable_foos = (foo for foo in foos if acceptable(foo))
  ...
Depending on your circumstances, this may or may not be awkward (coming up with temporary names can be hard), or may or may not be a good idea anyway (naming things can help make the code more self-documenting). I can't reckon how it could become unreadable, per se - what do you mean by that?


That's kinda my point, though. It becomes either awkward or unreadable. You chose awkward in your solution. But simple things as mapping, sorting, filtering quickly becomes unwieldy. Either you have to make it lots of unnecessary steps, potentially also lots of function definitions because of the lack of proper lambdas, or you end up with filter(groupby(map(filter(...)))) trying to figure out what is going on.


What you’re doing, what you’re doing it, and any conditionals are all out of order. If you to translate the Python semantics into say, Rust syntax, you would have something akin to

.map(blah(x,y), |z|, if let (x,y) == conditional(z))


Python's list comprehensions are close to set notation in math. Here's Python:

    [2*x for x in range(n + 1) if x <= 100]
Here's set notation:

    {2*x | x in 0..n, x <= 100}
So it reads pretty easily for those of us used to set notation. Haskell is even more similar to set notation:

    [2*x | x <- [0..n], x <= 100]


Gotta be real, I don't see any difference in readability (assuming it was formatted the same way, and honestly I'd prefer a different variable name than 'it' in both cases but I get that would require more boiler plate in kotlin and 'it' is a common invention).

The main difference imo is that kotlin uses more "syntax" while python uses more "English" to express the same thing. Also the half-open interval for range but that's an arbitrary decision that benefits some cases more than others (although my preference is the closed interval)


There is a sense in which Python uses more syntax, because list comprehensions are a special syntax.


You don't even need to create a range! You can just use:

    List(1000) { i -> i+1 }
Which creates a list of 1 to 1000


    import datetime
    import pandas as pd

    hundred_or_less_even_seconds = (
        pd.Series(range(1, 1000))
        .loc[lambda x: x <= 100]
        .loc[lambda x: x % 2 == 0]
        .map(lambda x: datetime.timedelta(seconds=x))
        .to_list()
    )


Frankly much less clearer/less readability than the Kotlin code.


Pythons list comprehensions are sort of fun, but occupy that space because the language designers throttled the alternatives pretty hard.

I used to write a lot of Python, I now write a lot of Rust, and the Rust iterator chains feel inordinately more powerful, and list comprehensions feel semantically backwards to me now: what you’re doing, what you’re doing it to, and whether to do it conditionally are all out of order.

To me, Python feels “expressive” because you can “do stuff to make it work” not because of any inherent design that lets you properly express what you’re trying to do.


The biggest thing that wouldn't be available in Python would be the DSLs. Often they are not my favorite and overused, but they can be very expressive for things like their charting example https://kotlinlang.org/docs/data-analysis-overview.html#kand...


As somebody who uses and likes both Kotlin and Python (and quite a few other languages), I'd be cautious with using a subjective term such as "more expressive", too, but I can possibly shed some light on where such feelings come from.

Personally, I see Kotlin as the closest thing to a statically typed Smalltalk that we have among major languages, and that's a major draw.

A key part here is that Kotlin closures are fully-featured equivalents of Smalltalk blocks (up to and including even non-local returns [1]), whereas in many other languages that falls short. Java does not allow mutation of local variables and Python restricts lambdas to normal expressions.

I find code whose behavior can be parameterized by code to be an essential feature of modern-day programming and this should be as frictionless as possible.

This is also a situation where syntax matters, and while it isn't quite as nice as Smalltalk, Kotlin's syntax (esp. with trailing closures) make such code as readable as possible in a brace-style language with minimal additional syntactic noise.

In a similar vein, the functionality of Smalltalk's cascades is offered through scope functions [2], especially `.run {}`.

But ultimately, fully-featured closures (and the fact that they are widely used in the standard library) power a lot of the things that people seem to like about Kotlin.

That does not mean that there aren't downsides. The limitations of running on the JVM are one (e.g. while Kotlin has workarounds for the JVM's type erasure, they're still workarounds), and then Gradle is arguably Kotlin's weakest point (which apparently even JetBrains are seeing, given their investment in Amper).

That said, personally I'd say Kotlin's static typing and performance would be the primary reasons for me to reach for Kotlin over Python, not necessarily expressiveness. Type annotations in Python + mypy etc. just aren't the same experience, and writing performance-sensitive code in Python can be very tricky/hacky when you can't delegate the hot paths to numpy or other existing C/C++/Rust libraries.

Conversely, Python often has a leg up when it comes to fast prototyping and scripting, even with Kotlin Worksheets in IntelliJ IDEA and with kscript.

[1] Which, to be clear, are a nice-to-have thing, not essential, but still impressive that even that was covered, when previously Ruby was the only major language I know of that did it.

[2] https://kotlinlang.org/docs/scope-functions.html


I would love to have an excuse to spend most of my time in Kotlin but unfortunately it's not a good fit for the apps I build. It's really a lovely language.

Maybe if Kotlin Multiplatform really takes off.


I think both languages have their strengths. I love Kotlin for its functional programming (map, filter, etc) and strong static typing. But Python has some nice features as well, such as list comprehension, the 'yield' keyword, and annotations are super simple to implement.


Are there things that you find easier to express in a list comprehension format than you do with Kotlin's standard library? I've always found comprehensions to be a bit of a workaround to the fact that Python doesn't have great support for anonymous functions, and I've never found a situation where I'm writing Kotlin really wishing I had a comprehension.


A bit of a contrived example, but something like this (two for statements):

[x*y for x in range (10) for y in range(10)]

It's not often, but occasionally there are moments where I'm writing code in Kotlin and wish I could use a list comprehension. I do prefer Kotlin overall, but there's a few things that I think would be "nice to have" from Python. Especially the yield keyword, such a wonderful way to write your own iterators.


Like this?

  sequence { for (x in 0..<10) for (y in 0..<10) yield(x*y) }.toList()
Now, technically, Kotlin doesn't have list comprehensions, only the equivalent of generator expressions in Python, so you have to tack an extra `.toList()` on at the end if you want a list, but you can write pretty much any for comprehension in Python in a similar way in Kotlin.

On the other hand, you're not limited to for loops/ifs inside such a generator, but can use fairly arbitrary control flow.


You could also build the list directly.

  buildList { for (x in 0..<10) for (y in 0..<10) add(x*y) }


Hmm, I actually prefer Kotlin's version, but maybe that's just because it's what I'm used to:

  (0..10).flatMap { x -> (0..10).map { y -> x * y } }
The flow of the data is more intuitive for me because you don't use variables before they're defined.

> Especially the yield keyword, such a wonderful way to write your own iterators.

Maybe I'm missing something about `yield` in Python—can it do something that Kotlin generators can't?


It's mostly ease of semantics -- in your example you use two layers of map and as a result need to do flatMap instead of just map twice

In py, for list/set/dictionary/generator comprehensions, the format is always the same and always the same as if you were to do it as a normal nested loop, save for the statement being first instead of last (you can also do filters using normal if statement syntax, these go at the end/after all your loops).

I actually like statement first because it gets to the "meat" of the semantics before the context (which loop etc), but end do the day it's all a bit arbitrary

@ yield, there's literally no difference between Python and kotlin. Python also offers a generator comprehension, which is nice, but it has nothing to do with yield

i_am_a_generator = ( x+1 for x in range(10*100) )


Theres the zip function builtin, which I actually would have preferred

  oneToTen.zip(oneToTen2) { x, y -> x * y }


That's not actually equivalent. The initial version they included produces:

  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 ...]
Whereas yours is just:

  [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]


I’ve always liked that the structure of list comprehensions mirror SQL with “SELECT, FROM, WHERE” sections.

But I know that I’m in the minority that likes SQL


They remind me of C#'s LINQ


> the 'yield' keyword

Am I missing something here?

  $ cat fib.kts
  fun fib() = sequence {
    var a = 1; var b = 1
    while (true) {
      yield(a)
      a = b.also { b += a }
    }
  }

  println(fib().take(10).joinToString(" -> "))
  println(fib().first { it >= 50 })
  $ kotlin fib.kts
  1 -> 1 -> 2 -> 3 -> 5 -> 8 -> 13 -> 21 -> 34 -> 55
  55
Of course, yield() is a function in Kotlin, not a keyword, but the same functionality is there.


The mechanism in Kotlin that allows them to limit yield() to a sequence{} block , without introducing a new keyword, is pretty dang cool.


What happens under the hood is that a `sequence {}` call creates an instance of `SequenceScope`, which has `yield()` and `yieldAll()` methods. When executing the block, `this` will reference that particular instance and `yield()` is essentially `this.yield()` and will call the method on the scope instance.

The actual functionality is then provided by the coroutine system, though a lot of the heavy lifting is done by the optimizer to eliminate all or most of the runtime overhead.


I had no idea Kotlin could do this. I never thought to check. I guess with Kotlin being a JVM language, I simply assumed it wasn't possible.

Thank you for providing an example because I was a little confused by a couple other comments mentioning yield...


From your other comment, I'm curious what you like about yield and why you think Kotlin is lacking without it.


This is exactly it for me too. Kotlin is my favorite overall language to code in, but for data analysis I'm going python for ecosystem or Julia if I need performance.


I'm often surprised C# hasn't gained more traction in this regard, but I guess that (despite .NET Core being open) it's a 'Microsoft' problem.


Have you looked at https://www.modular.com/mojo

Sounds like it has a good Python interop story.



The vs code support for Kotlin is pretty bare-bones compared to the IDE. And I'm guessing positron reuses the extension for that; so not that interesting to me.

Part of the appeal of Kotlin is Intellij offering an enormous amount of smart features that other IDEs simply don't have at all for any language.


> The interpreter is not that fast, the language is not that expressive, what passes for package management is a bad joke, etc. I can work with it but I'm not necessarily loving it.

These are rather disingenuous criticisms of python. The utility of any language is measured by its use as a means to some end. It's clear that Python's ecosystem has prospered not just because it's a fad, but because it's actually useful. Not perfect, but useful.

Python can be improved, but I'm sure most other tools/languages can be equally criticized.


Python in data is similar to C in systems: it's not the best language for the job, but it was good enough at a critical point in history that it became the standard by happenstance—there weren't enough things wrong with it to repel the Brownian motion of developers from seeding the ecosystem—and now it's the best language for the job because it's the standard.

> These are rather disingenuous criticisms of python. The utility of any language is measured by its use as a means to some end. It's clear that Python's ecosystem has prospered not just because it's a fad, but because it's actually useful. Not perfect, but useful.

Your criticisms of OP's argument are more disingenuous than OP: no one said Python was a fad or that the ecosystem wasn't useful. See here:

> Python is where all the action is when it comes to data science, llms, and all the rest. So it's the path of the least resistance. And there's a great argument to not challenge that and just do what everybody else does and put your head down and not criticize any of that. Which is why I use it on a few projects. The library ecosystem is great.

They're just saying that Python-the-language isn't their favorite (largely subjective but with a lot of agreement from much of the community) and they mention offhand that Python's package management is a disaster (which is 100% accurate).


I have no qualms with the OPs comment other than the same criticisms I highlighted could be applied to just about any other language in a similarly vague context. So what justice do those criticisms do if we're not being specific about them?

For example > Package management is a disaster > The interpreter is slow > The syntax is not expressive

Is your particular experience with pip bad? Or is it poetry/conda or another upstart project? Are you working with a monorepo? In what use case is the interpreter slow? The syntax is not expressive (for what)?

My point about tooling/utility is that how you use a tool matters a lot (and maybe I didn't express that in my original reply).


> People use python because everybody else uses python. That's it. It's not particularly good at anything it does. But it will get the job done and I can do it. But that just isn't good enough for me. It's the visual basic for data science. And that's not a compliment. Being idiot proof is it's main feature. But that doesn't make it the smart choice.

I'll leave this here as well, I think it sufficiently implies the notion of Python being a fad and not particularly useful.


JetBrains wrote a really good article to showcase how you can analyze your GitHub stars with their data analysis tools: https://blog.jetbrains.com/kotlin/2024/08/track-and-analyze-...


While I came to Kotlin for Android, I'll admit that I've been making things look like nails so that I can use the Kotlin hammer.


Kotlin aside, what is the deal with many websites not letting me zoom on mobile? (It is hard to see what is going on in the notebooks without zooming in.)


I find that annoying as well. Luckily on Firefox Android at least that can be fixed with a browser setting (Settings > Accessibility > Always enable zoom).


I do the same on Safari on iPhone. Enable the accessibility setting and browsers can't lock your zoom anymore.


Thanks! I didn't know that setting existed and I always wanted this behavior.


IIRC this used to be propagated back in the early HTML5 days. At least that's how it got to my personal website. I might've got it from html5boilerplate.com or a similar site.


In Firefox mobile go to accessibility settings and turn on zoom on all websites.


I can zoom in on safari/iphone


Inspired by an SQL tutorial that was #1 on this site earlier this year, I created (cloned) one for learning the Kotlin Dataframe API.

https://2x2xplz.github.io/Dataframe100Examples/


My issue with Kotlin is the same as my issue with Groovy. Both are interesting and definitely something new, but... under the hood it's JVM and come with the Java baggage. Some see it as an advantage, I see it as a burden. My clients are using mostly Python and Golang and I have grown to like simple toolchains and the results I am getting. Another point against Kotlin is the fact that my clients like to keep things simple and lean and are against introducing another programming language to their stack unless they absolutely have to.


I agree. I want to avoid the JVM. Also some functional features in Kotlin like immutable data structures are shallow and can be circumvented.

Also, practically it's only really viable to use IntelliJ as editor, since the language server in e.g. VS Code is pretty bad.


Same. I like Kotlin and used it for AOC, but I dislike the JVM. A great standalone Kotlin would be one of my most used languages.


Great languages don't exist in isolation.

Kotlin without its main platforms (JVM and Android) and the ecosystem of Java libraries doesn't stand a chance against the current landscape of modern hybrid languages. Unless something major happens on the WebAssembly front maybe, but even there I don't see how Kotlin would be particularly well positioned.


True, but the JVM is so cumbersome that I will use something else instead.


You can also try to use Kotlin Multiplatform to compile to JavaScript, Native and WASM. JVM was just the initial platform target.


I find it odd that kotlin-jupyter notebooks still use the `.ipynb` file extension.


Maybe a little odd, but it did start with Python. I mean, Jupyter stands for Julia, Python, and R already - so it's not too weird they just keep using the same file format.


Jupyterk ;)


I've yet to find anything that beats R's ggplot, both in terms of DSL and graphic design defaults.


Kotlin Notebooks are supported only in the Ultimate version of IDEA


The Jetbrains plugin is. However, the Github page (https://github.com/Kotlin/kotlin-jupyter) states:

> For other Jupyter clients, you'll need to install the Kotlin Kernel separately using conda, pip, or sources.

I think `pip install kotlin-jupyter-kernel` is all you need to add Kotlin to a standard Jupyter environment. I don't know if editors can deal with this stuff, though.


Talk to me when I can write spark code using kotlin.


or Mojo :)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: