Live data from Hacker News

Why Kotlin is my next programming language (2015)

medium.com

161–170 of 185 posts

Re: Why Kotlin is my next programming language (2015)

#161

>Kotlin costs nothing to adopt! It’s open source, but that’s not what I mean here. What I mean is there’s a high quality, one-click Java to Kotlin converter tool, and a strong focus on Java binary compatibility. The costs of adopting a new language are greatly more significant than implied here. The time it takes to learn it. The time it turns to learn the tools that are specific to it. And if you put it into product…

My experience has been that the learning curve for Kotlin is extremely shallow if you're an experienced Java developer. This is not just my experience but also the experience of building a team that's working with Kotlin all day. One reason the cost is low, is that there aren't really many tools specific to Kotlin (or any, really). You can use the same IDEs, the same build toolchains, the same libraries, even the sam…

Upvoted you, but adding on: a competent Java developer can pick up Kotlin in, literally, three hours. The mappings to Java concepts are trivial, but the language's niceties quickly bear themselves out as you go.

Re: Why Kotlin is my next programming language (2015)

#162
post #50

Hmm, this does seem like a pretty tasteful design in many ways. The declaration-site variance for generics is a pretty good idea, but is still inadequate to deal with functional collections. (I use the term "functional" as opposed to simply "immutable": an immutable collection has no update operations at all, while a functional collection has functional update operations: for example, given a set S and an element X,…

The correct signature for that method is something like (don't know whether this is the syntax) fun with (F elt)

I guess you mean (note the return type)

  fun with(elt: F): FunctionalSet
That's an interesting suggestion, but I don't see any indication that Kotlin provides for type lower bounds in generic function constraints. (It does have type upper bounds; see the bottom of this page: http://kotlinlang.org/docs/reference/generics.html).

Re: Why Kotlin is my next programming language (2015)

#163
post #74

It's the least sexy name for a programming language this century

Groovy won that 10 years ago.

Groovy was named by its creator, James Strachan, in 2003. By 2006 (i.e. 10 years ago), he had been managed out and a business sort without technical knowledge had taken over. He's since slowly wrecked Groovy's sexy brand and placed it firmly in the Java camp. I tried reversing the trend with stuff like "grOOvy", and the Groovy grrrrrrowl, Ooooooooo, and Vy (for "victory") but that business person running Groovy skuttled the effort, appearing far more interested in retaining his centralized control over Groovy branding. Groovy's since been handed over to Apache, being run by a 10-member "Project Management Committee", only 4 of which actually do any technical work on Groovy's code base. The other 6, including the "PMC Chair", just do administrative fuss.

Re: Why Kotlin is my next programming language (2015)

#164

Earlier quoted context omitted.

Do you need a test to verify that your compiler correctly checks the type signature? (Actually, that could be occasionally useful in the face of implicit conversions)

My compilers have test suites.

And the compiler that generates the assert also has a test suite for that.

Re: Why Kotlin is my next programming language (2015)

#165
post #156

Earlier quoted context omitted.

Here's a test I wrote recently. The code in question is part of a nodejs service that talks to a database and produces json objects to be used by a web client application. There is a definition for the schema to a fruit table. Fruit: { list_id: 32 } The list_id indicates that this isn't a real table, but is actually stored in the list_options table. So my code has to generate a different query then for a normal table…

Ok, good example on some levels, though it's doing a lot of interfacing with untyped parts. In a real-world scenario I would be looking to extend the type safety by using thrift or similar rather than json, and ideally a strongly typed datastore (for a static list like this, probably plain old code rather than a database). That aside, what pieces could actually go wrong in a statically typed language? You can't typo…

> So yeah, assuming this was for part of an existing system where I'd already tested generic facilities like database access and JSON serialization, I wouldn't feel the need to write this test at all.

But this is the generic facility for database access. This is just an additional special case it has to handle. Does that change your perspective on whether you would write a test for it?

> That aside, what pieces could actually go wrong in a statically typed language?

Well, I could type the SQL wrong, but let's assume we are working in a sufficiently awesome statically typed language that would catch that kind of error.

I could filter on the wrong column, with the wrong operator, with the wrong value, on the wrong table. I could decode the name column using the wrong encoding. I could return multiple rows per option. I could do a huge number of other things that I couldn't think of. These may not be really likely to be mistakes I'd make (this is a pretty simple task), but several refactorings down the line, I can easily see an issue being introduced.

At the end of the day, even in a statically typed language where much of the functionality would be verified by the compiler, I'd still like to have a test on this.

> Ok, good example on some levels, though it's doing a lot of interfacing with untyped parts

Hmm... the fact that it deals with the boundary of the system and the fact that it deals only with converting data from one format to another might render it a poor sample (i.e. there's not really much interesting logic). I can come up with another if you are interested.

Re: Why Kotlin is my next programming language (2015)

#166

Earlier quoted context omitted.

And you don't need tests to make sure the assertions are there?

Interesting point :) At some point you have to assume something is there and correct (e.g., you don't write tests to check whether the tests are there, also you assume the testing tools work, ...). In static languages you also assume the programmer set the right type for the function argument, so you might as well assume to have an assertion in the critical code of the functional languages.

> At some point you have to assume something is there and correct

If you excel at compositional design then this may work OK but a lot of code bases I have worked on just need a good ol' refactor to sort the mess out. And then the "there and correct" part could fail due to human error, or the new person not knowing the old assumptions etc. The asserts are a step in the right direction in documenting the assumptions though. Types go one level better by both documenting the interface, and enforcing that contract at compile time.

Re: Why Kotlin is my next programming language (2015)

#167
post #156

Earlier quoted context omitted.

Ok, good example on some levels, though it's doing a lot of interfacing with untyped parts. In a real-world scenario I would be looking to extend the type safety by using thrift or similar rather than json, and ideally a strongly typed datastore (for a static list like this, probably plain old code rather than a database). That aside, what pieces could actually go wrong in a statically typed language? You can't typo…

> So yeah, assuming this was for part of an existing system where I'd already tested generic facilities like database access and JSON serialization, I wouldn't feel the need to write this test at all. But this is the generic facility for database access. This is just an additional special case it has to handle. Does that change your perspective on whether you would write a test for it? > That aside, what pieces could…

> But this is the generic facility for database access. This is just an additional special case it has to handle.

Presumably it would be using a lower layer - or more likely an existing library - for doing the actual query though?

> I could filter on the wrong column,

Not if you've got a typed representation of which column's which

> with the wrong operator,

Not if equality is the only operator available. This is one of my biggest reasons for using wrapper types around IDs - you shouldn't treat IDs as integers, because the idea of adding or multiplying or > with the wrong value,

How? You have to use the passed ID for something, and it can't do anything else.

> on the wrong table.

So make the table part of the type. A list ID is a different thing from a user ID, they shouldn't be compatible.

> I could decode the name column using the wrong encoding.

Encoding should absolutely be handled with types.

> I could return multiple rows per option.

Hmm, maybe. But I can't see how you'd do that by accident.

> At the end of the day, even in a statically typed language where much of the functionality would be verified by the compiler, I'd still like to have a test on this.

I started out thinking the same thing (I moved from Java/Python to Scala). I've gradually reduced the amount of tests I write over four years as I've found them to not add value. I was as surprised as anyone, and even privately entertained the thought that maybe I was some kind of super-programmer who was smarter than all those people who needed tests, but that month or two of trying to do stuff in Django made it very clear that it wasn't me, it was the language.

> Hmm... the fact that it deals with the boundary of the system and the fact that it deals only with converting data from one format to another might render it a poor sample (i.e. there's not really much interesting logic). I can come up with another if you are interested.

Yeah, happy to if you're interested. It's a useful exercise in thinking it through for myself as much as anything.

Re: Why Kotlin is my next programming language (2015)

#168
post #167

Earlier quoted context omitted.

> So yeah, assuming this was for part of an existing system where I'd already tested generic facilities like database access and JSON serialization, I wouldn't feel the need to write this test at all. But this is the generic facility for database access. This is just an additional special case it has to handle. Does that change your perspective on whether you would write a test for it? > That aside, what pieces could…

> But this is the generic facility for database access. This is just an additional special case it has to handle. Presumably it would be using a lower layer - or more likely an existing library - for doing the actual query though? > I could filter on the wrong column, Not if you've got a typed representation of which column's which > with the wrong operator, Not if equality is the only operator available. This is one…

> I started out thinking the same thing (I moved from Java/Python to Scala).

Ah, Scala. I could be prepared to believe that this is true for Scala (and similarly advanced typed systems). It is when people claim they write fewer tests in java than in python that I found it really dubious.

> Yeah, happy to if you're interested. It's a useful exercise in thinking it through for myself as much as anything.

Ok here's another test:

These are action objects, they represent a sequence of user actions on a JobExtra.

        const actions = [
            JobExtra.actions.load(undefined),
            JobExtra.actions.field('changeAmount', Money.actions.set(new Decimal("12.45"))),
            JobExtra.actions.field('certifiedForemanRelated', Checkbox.actions.set(true)),
            JobExtra.actions.field('appliedPercentage', Percentage.actions.set(new Decimal("4.5")))
        ]
I construct the final state by reducing across all those actions

        const state = _.reduce(actions, (state, action) => JobExtra.reducer(state, action), undefined)
I verify that the job extra is considered valid afterwards.

        strictEqual(true, isJobExtraValid(state))
To be considered valid:

1. The changeAmount must be set to non-zero 2. The certifiedFormanRelated must be false or the appliedPercentage must be true

But, if the user modifies the appliedPercentage, the certifiedFormanRelated should be automatically set to true.

So this, and a number of related tests verify that under different sequences of actions I end up the result I expected.

Is there a way to push this into the type system?

Re: Why Kotlin is my next programming language (2015)

#169

Earlier quoted context omitted.

Tests that verify the behavior of functions when they are passed data of a type that does not support the behavior that the function expects to be supported. I find this to be a very common case.

I find this to be a rare case. Of course, YMMV. But I don't see or write tests in dynamic languages that verify behavior when I pass an inappropriate type. I trust that it'll produce an error when it tries to use operations that the type doesn't support.

Maybe I'm misunderstanding you, but it sounds like you mean that you trust it to produce that error when it's running (ie. in production). If that's the case, couldn't you do the same for all kinds of bugs and not bother writing tests at all? Put another way, what is different from this class of bug, which you don't think is worth testing, and other classes of bugs, which it sounds like you do?

Re: Why Kotlin is my next programming language (2015)

#170

Earlier quoted context omitted.

Tests that verify the behavior of functions when they are passed data of a type that does not support the behavior that the function expects to be supported. I find this to be a very common case.

I address this problem by checking the type at run-time via an assertion. Depending on where you are in the security vs efficiency spectrum, you may opt to ignore those assertions in production. Writing specific tests for that looks very inefficient to me but maybe I am missing something.

For sure, and if you're someone who loves runtime assertions for type mis-matches, then I think you'd really love static type assertions, which are basically the same thing, but checked earlier, making bugs they find cheaper.

I agree that writing specific tests for that is very inefficient, and that few people (myself included) actually do it. I just also think the fact that people don't really write tests for a (anecdotally) common cause of bugs, and instead wait to see them in their production logs, is an anti-pattern, rather than a positive thing.

Post reply on HN