26 ms·
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
by poikroequ 2y ago
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.
- lolinder 2y agoAre 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.
- poikroequ 2y agoA 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.
- lolinder 2y agoHmm, 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?
- hughesjj 2y agoIt'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) )
- Larrikin 2y agoTheres the zip function builtin, which I actually would have preferred oneToTen.zip(oneToTen2) { x, y -> x * y }
- lolinder 2y agoThat'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]
- rbehrends 2y agoLike 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.
- robch 2y agoYou could also build the list directly. buildList { for (x in 0..<10) for (y in 0..<10) add(x*y) }
- parpfish 2y agoI’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
- heavyset_go 2y agoThey remind me of C#'s LINQ
- Larrikin 2y agoFrom your other comment, I'm curious what you like about yield and why you think Kotlin is lacking without it.
- rbehrends 2y ago> 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.
- yen223 2y agoThe mechanism in Kotlin that allows them to limit yield() to a sequence{} block , without introducing a new keyword, is pretty dang cool.
- rbehrends 2y agoWhat 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.
- poikroequ 2y agoI 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...